-2006-05-28 Jean-Louis Martineau <martineau@zmanda.com>
+2006-09-05 Jean-Louis Martineau <martineau@zmanda.com>
+ * Amanda 2.5.1 released.
+ * configure.in: AM_INIT_AUTOMAKE(amanda, 2.5.1).
+ * NEWS: Change in amanda-2.5.1
+
+2006-08-30 Jean-Louis Martineau <martineau@zmanda.com>
+ * server-src/dumper.c: Typo in error message.
+
+2006-08-29 Jean-Louis Martineau <martineau@zmanda.com>
+ * client-src/selfcheck.c: Print error message to stdout before
+ calling error().
+
+2006-08-28 Jean-Louis Martineau <martineau@zmanda.com>
+ * server-src/dumper.c (log_msgout): Seek to begining of file.
+
+2006-08-28 Jean-Louis Martineau <martineau@zmanda.com>
+ * server-src/reporter.c: Report if a dump was successfully retried.
+
+2006-08-28 Jean-Louis Martineau <martineau@zmanda.com>
+ * server-src/amstatus.pl.in: Correct size for retried dump.
+
+2006-08-25 Jean-Louis Martineau <martineau@zmanda.com>
+ * client-src/runtar.c: Check that strcmp(argv[3], "--create") == 0.
+
+2006-08-24 Jean-Louis Martineau <martineau@zmanda.com>
+ * common-src/statfs.c (scale): Macro replaced by a function.
+
+2006-08-24 Jean-Louis Martineau <martineau@zmanda.com>
+ * server-src/chunker.c: Use STREAM_BUFSIZE for stream_accept.
+ * server-src/taper.c: Use STREAM_BUFSIZE for stream_accept.
+
+2006-08-24 Maitreyee Karmarkar <maitreyee.zmanda.com>
+ * man/xml-source/amcheck.8.xml: amcheck xml man page change
+
+2006-08-23 Kevin Till <ktill@zmanda.com>
+ * server-src/driver.c: fix typo
+
+2006-08-23 Jean-Louis Martineau <martineau@zmanda.com>
+ * server-src/driver.c (dumper_result): Decrement pendings_aborts.
+ * server-src/driver.c (handle_dumper_result): Don't send duper result
+ to chunker if we aborted it.
+ * server-src/driverio.c (dumper_cmd, chunker_cmd): Don't close the fd
+ on ABORT.
+ * server-src/dumper.c: Accept ABORT command.
+
+2006-08-23 Jean-Louis Martineau <martineau@zmanda.com>
+ * restore-src/restore.c (restore): Set bytes_read to the return value
+ of read_file_header.
+
+2006-08-22 Jean-Louis Martineau <martineau@zmanda.com>
+ * tape-src/output-tape.c: Works if EOVERFLOW is not defined.
+
+2006-08-21 Jean-Louis Martineau <martineau@zmanda.com>
+ * amandad-src/amandad.c, common-src/rsh-security.c,
+ common-src/ssh-security.c, restore-src/restore.c,
+ server-src/changer.c, server-src/dumper.c: Fix sentinel warning.
+
+2006-08-21 Jean-Louis Martineau <martineau@zmanda.com>
+ * example/amanda.conf.in: Typo.
+
+2006-08-21 Jean-Louis Martineau <martineau@zmanda.com>
+ * server-src/driverio.c: Fix bogus "(unsigned long)-1".
+
+2006-08-21 Jean-Louis Martineau <martineau@zmanda.com>
+ * server-src/driver.c (start_some_dumps): Remove bogus free_assignedhd.
+
+2006-08-21 Maitreyee Karmarkar <maitreyee.zmanda.com>
+ * server-src/amcheck.c: Check specific clients
+ * man/amcheck.8: add the multiple client check format
+
+2006-08-18 Ian Turner <ian@zmanda.com>
+ * tape-src/amtapetype.c: Don't crash on exit
+
+2006-08-17 Paddy Sreenivasan <paddy@zmanda.com>
+ * server-src/driverio.c:
+ * server-src/changer.c:
+ * restore-src/amfetchdump.c:
+ * recover-src/extract_list.c:
+ * oldrecover-src/extract_list.c:
+ * common-src/util.c:
+ * common-src/stream.c:
+ * common-src/file.c:
+ * common-src/dgram.c: Fix warnings
+
+2006-08-17 Kevin Till <ktill@zmanda.com>
+ * common-src/stream.c: Loop 5 times (ntries > 5) on select error
+
+2006-08-14 Paddy Sreenivasan <paddy@zmanda.com>
+ * client-src/sendsize.c: Fix warning
+ * server-src/reporter.c: Fix warnings
+
+2006-07-28 Jean-Louis Martineau <martineau@zmanda.com>
+ * Amanda 2.5.1b2 released.
+ * configure.in: AM_INIT_AUTOMAKE(amanda, 2.5.1b2).
+
+2006-07-28 Jean-Louis Martineau <martineau@zmanda.com>
+ * server-src/driver.c (find_diskspace): Make sure size > 0.
+
+2006-07-28 Jean-Louis Martineau <martineau@zmanda.com>
+ * server-src/planner.c: Don't check new disk.
+
+2006-07-28 Jean-Louis Martineau <martineau@zmanda.com>
+ * server-src/planner.c: Always log if full size estimate is larger
+ than the available tape space.
+
+2006-07-28 Jean-Louis Martineau <martineau@zmanda.com>
+ * server-src/planner.c: Always log if the latest full dump will be
+ overwritten soon.
+
+2006-07-27 Jean-Louis Martineau <martineau@zmanda.com>
+ * common-src/clock.c (timesub): Don't make a negative time.
+
+2006-07-27 Jean-Louis Martineau <martineau@zmanda.com>
+ * man/xml-source/amanda.conf.5.xml: Tell which file are loaded.
+ * man/xml-source/amanda-client.conf.5.xml: Ditto.
+
+2006-07-26 Jean-Louis Martineau <martineau@zmanda.com>
+ * NEWS: for 2.5.1b2.
+
+2006-07-26 Jean-Louis Martineau <martineau@zmanda.com>
+ * common-src/util.h (CONFTYPE_HOLDING): New conftype.
+ * common-src/util.c (conf_init_holding, conf_set_holding,
+ get_conftype_hold): New fonction.
+ * example/amanda.conf.in: Example of new holdingdisk value.
+ * man/xml-source/amanda.8.xml: Example.
+ * man/xml-source/amanda.conf.5.xml: Document it.
+ * server-src/amadmin.c (disklist_one): Print holdingdisk value.
+ * server-src/conffile.c: Parse new CONF_HOLDING type.
+ * server-src/conffile.h (dumptype_get_to_holdingdisk): Change macro.
+ * server-src/diskfile.c (parse_diskline): dumptype_get_to_holdingdisk.
+ * server-src/driver.c: Use new CONFTYPE_HOLDING value.
+
+2006-07-26 Jean-Louis Martineau <martineau@zmanda.com>
+ * client-src/selfcheck.c: Fix bug found by coverity.
+ * common-src/debug.c: Fix bug found by coverity.
+
+2006-07-25 Jean-Louis Martineau <martineau@zmanda.com>
+ * server-src/amflush.c: Typo.
+
+2006-07-25 Jean-Louis Martineau <martineau@zmanda.com>
+ * server-src/amflush.c: Correct test for driver_stream.
+
+2006-07-25 Jean-Louis Martineau <martineau@zmanda.com>
+ * client-src/clientconf.c: Default CLN_AMANDATES to /etc/amandates.
+ * common-src/util.c (conf_init_size): Type is CONFTYPE_SIZE.
+ * server-src/conffile.c (getconf_taperalgo): New function.
+ * server-src/conffile.h (getconf_taperalgo): Prototype.
+ * server-src/driver.c: Use getconf_taperalgo.
+
+2006-07-25 Jean-Louis Martineau <martineau@zmanda.com>
+ * client-src/clientconf.c (client_getconf_boolean): New function.
+ * client-src/clientconf.h (client_getconf_boolean): Prototype.
+ * server-src/conffile.c (getconf_boolean): New function.
+ * server-src/conffile.h (getconf_boolean): Prototype.
+ * restore-src/amidxtaped.c: Use getconf_boolean.
+ * server-src/amflush.c: Use getconf_boolean.
+ * server-src/planner.c: Use getconf_boolean.
+
+2006-07-25 Jean-Louis Martineau <martineau@zmanda.com>
+ * server-src/getconf.c: Don't print BUGGY.
+ * changer-src/chg-chio.pl.in: Don't parse BUGGY.
+ * changer-src/chg-iomega.pl.in: Don't parse BUGGY.
+ * changer-src/chg-zd-mtx.sh.in: Don't parse BUGGY.
+ * man/xml-source/amgetconf.8.xml: Don't parse BUGGY.
+ * server-src/amverifyrun.sh.in: Don't parse BUGGY.
+ * server-src/amverify.sh.in: Don't parse BUGGY.
+
+2006-07-25 Jean-Louis Martineau <martineau@zmanda.com>
+ * restore-src/restore.c: Cleanup.
+ * restore-src/amrestore.c: Don't fsf if the last read return 0.
+
+2006-07-25 Jean-Louis Martineau <martineau@zmanda.com>
+ * client-src/selfcheck.c: Fix bug found by klocwork.
+ * common-src/rsh-security.c: Fix bug found by klocwork.
+ * common-src/ssh-security.c: Fix bug found by klocwork.
+ * server-src/planner.c: Fix bug found by klocwork.
+
+2006-07-25 Jean-Louis Martineau <martineau@zmanda.com>
+ * tape-src/output-tape.c (tape_tape_open): mt is declared inside #ifdef.
+
+2006-07-25 Jean-Louis Martineau <martineau@zmanda.com>
+ * server-src/amcheck.c: Fix quoting.
+
+2006-07-25 Jean-Louis Martineau <martineau@zmanda.com>
+ * client-src/clientconf.c: client_getconf* validate the type.
+ * common-src/util.c (get_conftype_*): New function.
+ * common-src/util.h (get_conftype_*): Prototype.
+ * server-src/conffile.c: getconf* validate the type.
+ * server-src/conffile.h: Use get_conftype_* function.
+
+2006-07-25 Jean-Louis Martineau <martineau@zmanda.com>
+ * client-src/clientconf.c: New AMANDATES client config option.
+ * client-src/clientconf.h: New AMANDATES client config option.
+ * client-src/amandates.c: Use AMANDATES.
+ * client-src/amandates.h: Use AMANDATES.
+ * client-src/selfcheck.c: Use AMANDATES.
+ * client-src/sendbackup-gnutar.c: Use AMANDATES.
+ * client-src/sendsize.c:: Use AMANDATES.
+ * common-src/util.h : New CONF_AMANDATES.
+ * man/xml-source/amanda-client.conf.5.xml: Document it.
+
+2006-07-25 Jean-Louis Martineau <martineau@zmanda.com>
+ * client-src/clientconf.c: New GNUTAR_LIST_DIR client config option.
+ * client-src/clientconf.h: New GNUTAR_LIST_DIR client config option.
+ * client-src/selfcheck.c: Use GNUTAR_LIST_DIR.
+ * client-src/sendbackup-gnutar.c: Use GNUTAR_LIST_DIR.
+ * client-src/sendsize.c: Use GNUTAR_LIST_DIR.
+ * common-src/util.h: New CONF_GNUTAR_LIST_DIR.
+ * man/xml-source/amanda-client.conf.5.xml: Document it.
+
+2006-07-25 Jean-Louis Martineau <martineau@zmanda.com>
+ * client-src/calcsize.c, client-src/killpgrp.c,
+ client-src/rundump.c, client-src/runtar.c,
+ client-src/selfcheck.c, client-src/sendbackup.c,
+ client-src/sendsize.c, common-src/amanda.h,
+ common-src/debug.c, oldrecover-src/amrecover.c,
+ recover-src/amrecover.c, restore-src/amfetchdump.c,
+ restore-src/amidxtaped.c, server-src/amadmin.c,
+ server-src/amcheck.c, server-src/amcleanupdisk.c,
+ server-src/amflush.c, server-src/amindexd.c,
+ server-src/amlabel.c, server-src/amlogroll.c,
+ server-src/amtape.c, server-src/amtrmidx.c,
+ server-src/amtrmlog.c, server-src/chunker.c,
+ server-src/driver.c, server-src/dumper.c,
+ server-src/getconf.c, server-src/planner.c,
+ server-src/reporter.c, server-src/taper.c: dbrename ot the config dir.
+
+2006-07-25 Jean-Louis Martineau <martineau@zmanda.com>
+ * common-src/amanda.h: Define DBG_SUBDIR_SERVER, DBG_SUBDIR_CLIENT
+ and DBG_SUBDIR_CLIENT.
+ * amandad-src/amandad.c, changer-src/chg-scsi.c,
+ changer-src/chg-scsi-chio.c, client-src/calcsize.c,
+ client-src/killpgrp.c, client-src/rundump.c, client-src/runtar.c,
+ client-src/selfcheck.c, client-src/sendbackup.c,
+ client-src/sendsize.c,
+ oldrecover-src/amrecover.c, recover-src/amrecover.c,
+ restore-src/amfetchdump.c, restore-src/amidxtaped.c,
+ restore-src/amrestore.c, server-src/amadmin.c,
+ server-src/amcheck.c, server-src/amcleanupdisk.c,
+ server-src/amflush.c, server-src/amindexd.c,
+ server-src/amlabel.c, server-src/amlogroll.c,
+ server-src/amtape.c, server-src/amtrmidx.c,
+ server-src/amtrmlog.c, server-src/chunker.c,
+ server-src/diskfile.c, server-src/driver.c,
+ server-src/dumper.c, server-src/getconf.c,
+ server-src/infofile.c, server-src/planner.c,
+ server-src/reporter.c (dbopen): Use DBG_SUBDIR_SERVER,
+ DBG_SUBDIR_CLIENT or DBG_SUBDIR_CLIENT.
+
+2006-07-25 Jean-Louis Martineau <martineau@zmanda.com>
+ * client-src/calcsize.c: Get config on argument.
+ * client-src/killpgrp.c: Get config on argument.
+ * client-src/rundump.c: Get config on argument.
+ * client-src/runtar.c: Get config on argument.
+ * client-src/sendbackup.c: Call program with config as argument.
+ * client-src/sendbackup-dump.c: Call program with config as argument.
+ * client-src/sendbackup-gnutar.c: Call program with config as argument.
+ * client-src/sendbackup.h: Add global g_options.
+ * client-src/sendsize.c: Call program with config as argument.
+
+2006-07-23 Jean-Louis Martineau <martineau@zmanda.com>
+ * client-src/sendbackup-gnutar.c: Fix bug found by splint.
+ * client-src/sendsize.c: Fix bug found by splint.
+
+2006-07-22 Jean-Louis Martineau <martineau@zmanda.com>
+ * server-src/taper.c: Fix amfree(mem_splitbuf).
+
+2006-07-22 Jean-Louis Martineau <martineau@zmanda.com>
+ * server-src/diskfile.c, server-src/taper.c: Fix memory leak found
+ by coverity.
+
+2006-07-22 Jean-Louis Martineau <martineau@zmanda.com>
+ * server-src/taper.c: Fix split_buffer allocation problem.
+
+2006-07-22 Jean-Louis Martineau <martineau@zmanda.com>
+ * client-src/selfcheck.c, common-src/security-util.c,
+ restore-src/restore.c, server-src/diskfile.c: Fix memory leak found
+ by coverity.
+
+2006-07-20 Jean-Louis Martineau <martineau@zmanda.com>
+ * changer-src/chg-scsi.c, changer-src/scsi-changer-driver.c,
+ client-src/amandates.c, client-src/calcsize.c,
+ client-src/selfcheck.c, client-src/sendbackup.c,
+ client-src/sendsize.c, common-src/security-util.c,
+ recover-src/extract_list.c, restore-src/restore.c,
+ server-src/amindexd.c, server-src/diskfile.c,
+ server-src/driver.c, server-src/reporter.c,
+ server-src/tapefile.c, server-src/taper.c: Fix memory leak found
+ by coverity.
+
+2006-07-19 Jean-Louis Martineau <martineau@zmanda.com>
+ * client-src/selfcheck.c : Read client config file.
+ * client-src/sendbackup.c: Read client config file.
+ * client-src/sendsize.c : Read client config file.
+
+2006-07-19 Jean-Louis Martineau <martineau@zmanda.com>
+ * amandad-src/amandad.h (g_option_t): Add 'char *config';
+ * amandad-src/amandad_util.c (parse_g_options): Parse 'config='.
+ * common-src/amfeatures.h (fe_req_options_config): New amfeature.
+ * common-src/amfeatures.c (am_init_feature_set):
+ set fe_req_options_config.
+ * server-src/amcheck.c: Send 'config=' in global options.
+ * server-src/dumper.c: Send 'config=' in global options.
+ * server-src/planner.c: Send 'config=' in global options.
+
+2006-07-19 Jean-Louis Martineau <martineau@zmanda.com>
+ * amandad-src/amandad.c: Call dbopen("amandad").
+ * changer-src/chg-scsi.c: Call dbopen("server").
+ * changer-src/chg-scsi-chio.c: Call dbopen("server").
+ * client-src/calcsize.c: Call dbopen("client").
+ * client-src/getfsent.c: Call dbopen(NULL).
+ * client-src/killpgrp.c: Call dbopen("client").
+ * client-src/rundump.c: Call dbopen("client").
+ * client-src/runstar.c: Call dbopen("client").
+ * client-src/runtar.c: Call dbopen("client").
+ * client-src/selfcheck.c: Call dbopen("client").
+ * client-src/sendbackup.c: Call dbopen("client").
+ * client-src/sendsize.c: Call dbopen("client").
+ * common-src/amanda.h (dbopen, debug_open): Take a 'char * subdir'
+ argument.
+ * common-src/bsd-security.c: Call dbopen(NULL).
+ * common-src/debug.c (debug_open): Call debug_setup_1(subdir)
+ * common-src/debug.c (debug_setup_1): Take a subdir argument,
+ add it to dbgdir.
+ * common-src/file.c: Call dbopen(NULL).
+ * common-src/statfs.c: Call dbopen(NULL).
+ * common-src/token.c: Call dbopen(NULL).
+ * oldrecover-src/amrecover.c: Call dbopen("client").
+ * recover-src/amrecover.c: Call dbopen("client").
+ * restore-src/amfetchdump.c: Call dbopen("server").
+ * restore-src/amidxtaped.c: Call dbopen("server").
+ * restore-src/amrestore.c: Call dbopen("server").
+ * server-src/amadmin.c: Call dbopen("server").
+ * server-src/amcheck.c: Call dbopen("server").
+ * server-src/amcleanupdisk.c: Call dbopen("server").
+ * server-src/amflush.c: Call dbopen("server").
+ * server-src/amindexd.c: Call dbopen("server").
+ * server-src/amlabel.c: Call dbopen("server").
+ * server-src/amlogroll.c: Call dbopen("server").
+ * server-src/amtape.c: Call dbopen("server").
+ * server-src/amtrmidx.c: Call dbopen("server").
+ * server-src/amtrmlog.c: Call dbopen("server").
+ * server-src/chunker.c: Call dbopen("server").
+ * server-src/diskfile.c: Call dbopen("server").
+ * server-src/driver.c: Call dbopen("server").
+ * server-src/dumper.c: Call dbopen("server").
+ * server-src/getconf.c: Call dbopen("server").
+ * server-src/infofile.c: Call dbopen("server").
+ * server-src/planner.c: Call dbopen("server").
+ * server-src/reporter.c: Call dbopen("server").
+ * server-src/taper.c: Call dbopen("server").
+
+2006-07-17 Jean-Louis Martineau <martineau@zmanda.com>
+ * server-src/chunker.c: Fix rt computation.
+ * server-src/dumper.c: Fix dumptime computation.
+ * server-src/taper.c: Fix rt computation.
+
+2006-07-17 Jean-Louis Martineau <martineau@zmanda.com>
+ * NEWS: Klocwork defects fixed.
+ * NEWS: Coverity defect fixed.
+
+2006-07-14 Jean-Louis Martineau <martineau@zmanda.com>
+ * Makefile.am (pkgdata_DATA): add ReleaseNotes.
+
+2006-07-14 Jean-Louis Martineau <martineau@zmanda.com>
+ * Amanda 2.5.1b1 released.
+ * configure.in: Remove -Werror.
+
+2006-07-14 Jean-Louis Martineau <martineau@zmanda.com>
+ * client-src/sendsize.c: Use read/write to copy tar snapshot file.
+ * client-src/sendbackup-gnutar.c: Ditto.
+
+2006-07-13 Jean-Louis Martineau <martineau@zmanda.com>
+ * common-src/stream.c (stream_accept): Loop 5 times on select error.
+
+2006-07-13 Jean-Louis Martineau <martineau@zmanda.com>
+ * server-src/dumper.c: The datafd is not scheduled at start,
+ add test for it.
+ * common-src/stream.c (tcpm_recv_token): Set error_msg.
+
+2006-07-12 Jean-Louis Martineau <martineau@zmanda.com>
+ * common-src/util.c (free_new_argv): Move out of
+ #ifndef HAVE_LIBREADLINE.
+
+2006-07-12 Jean-Louis Martineau <martineau@zmanda.com>
+ * server-src/amadmin.c (tape): Report the number of new tapes instead
+ of "a new tape" for each tapes.
+ * server-src/reporter.c (output_tapeinfo): Ditto.
+
+2006-07-12 Jean-Louis Martineau <martineau@zmanda.com>
+ * server-src/taperscan.c (changer_taper_scan): Report error from
+ changer_find.
+
+2006-07-11 John Franks jrfranks@zmanda.com
+ * configure.in: Fix multiple definition of readline during cygwin
+ compile.
+
+2006-07-11 Paddy Sreenivasan <paddy@zmanda.com>
+ * common-src/pipespawn.c : Fixed compiler warning
+
+2006-07-11 Jean-Louis Martineau <martineau@zmanda.com>
+ * man/xml-source/amtapetype.8.xml: No default value for -e.
+
+2006-07-11 Jean-Louis Martineau <martineau@zmanda.com>
+ * common-src/util.c: Don't conftoken_ungetc(ch) if ch == EOF.
+ * server-src/reporter.c: Check tp == NULL.
+
+2006-07-11 Jean-Louis Martineau <martineau@zmanda.com>
+ * tape-src/tapetype.c: Make -e an needed argument.
+ * man/xml-source/amtapetype.8.xml: Update man page.
+
+2006-07-11 Jean-Louis Martineau <martineau@zmanda.com>
+ * changer-src/chg-zd-mtx.sh.in: Remove .conf from changerfile.
+
+2006-07-11 Jean-Louis Martineau <martineau@zmanda.com>
+ * recover-src/extract_list.c (check_file_overwrite): Renamed from
+ check_file_overwite.
+ * recover-src/extract_list.c (check_file_overwrite): Do the path check
+ in the correct order (from left ro right).
+
+2006-07-11 Jean-Louis Martineau <martineau@zmanda.com>
+ * common-src/file.c (debug_agets): Remove call to dbprintf.
+
+2006-07-10 Jean-Louis Martineau <martineau@zmanda.com>
+ * recover-src/extract_list.c (add_to_unlink_list, do_unlink_list,
+ free_unlink_list): New function to manage unlink_list.
+ * recover-src/extract_list.c (check_file_overwite): Check all
+ component of an EXTRACT_LIST_ITEM, if a component is not a
+ directory, add it to the unlink_list.
+ * recover-src/extract_list.c (extract_files): Call do_unlink_list and
+ free_unlink_list, rename buf to cwd.
+
+2006-07-10 Jean-Louis Martineau <martineau@zmanda.com>
+ * common-src/pipespawn.c (pipespawnv_passwd): Add prototype.
+ * common-src/pipespawn.c (pipespawn, pipespawn): Remove 2 NULL
+ parameters to the pipespawnv_passwd call.
+ * common-src/pipespawn.c (pipespawnv_passwd): Remove passwdvar and
+ passwdfd parameters, add passwdvar and local variable.
+ Don't use memcpy to set passwdfd.
+ * common-src/pipespawn.h (pipespawnv_passwd): Remove prototype.
+
+2006-07-07 Jean-Louis Martineau <martineau@zmanda.com>
+ * common-src/security-util.c (stream_read_sync_callback): Remove bogus
+ call of callback.
+
+2006-07-07 Kevin Till <ktill@zmanda.com>
+ * common-src/bsd-security.c: use STREAM_BUFSIZE instead of -1
+ * common-src/bsdtcp-security.c: ditto
+ * common-src/krb4-security.c: ditto
+ * common-src/security-util.c: ditto
+ * restore-src/amidxtaped.c: ditto
+
+2006-07-07 Jean-Louis Martineau <martineau@zmanda.com>
+ * common-src/util.c (get_conftoken): Remove duplicate conftoken_ungetc.
+
+2006-07-07 Jean-Louis Martineau <martineau@zmanda.com>
+ * common-src/security-util.c: Validate and report big packet size.
+
+2006-07-07 Jean-Louis Martineau <martineau@zmanda.com>
+ * oldrecover-src/Makefile.am: Typo.
+
+2006-07-07 Jean-Louis Martineau <martineau@zmanda.com>
+ * client-src/sendsize.c: Typo.
+
+2006-07-06 John Franks <jrfranks@zmanda.com>
+ * common-src/genversion.c:
+ Remove reference to error(). This causes a compile
+ error on cygwin.
+
+2006-07-06 Jean-Louis Martineau <martineau@zmanda.com>
+ Klocwork bug 128, 170, 182, 470, 517
+ * changer-src/chg-scsi.c: Validate drivenum, check count_file.
+ * client-src/sendsize.c: Validate level.
+ * oldrecover-src/amrecover.c: Use tm.
+ * recover-src/amrecover.c: Use tm.
+ * server-src/infofile.c (delete_txinfofile): Use local variable.
+
+2006-07-06 Jean-Louis Martineau <martineau@zmanda.com>
+ * server-src/taper.c: Check for cur_filename.
+ * tape-src/output-file.c: Use vstrextend.
+ * tape-src/tapeio.c: Check for r.
+
+2006-07-06 Jean-Louis Martineau <martineau@zmanda.com>
+ Fix splint warning
+ * oldrecover-src/extract_list.c (clean_tape_list): Cleanup for splint.
+ * recover-src/extract_list.c (clean_tape_list): Cleanup for splint.
+ * server-src/amindexd.c: Add a /*@i@*/.
+ * server-src/conffile.c: Cast to off_t for conf_init_am64.
+ * server-src/driver.c: Cast to unsigned to print pid_t.
+ * server-src/find.c (strip_failed_chunks): Cleanup for splint.
+
+2006-07-06 Jean-Louis Martineau <martineau@zmanda.com>
+ Klocwork bug 114
+ * server-src/amindexd.c: Free their_feature_string.
+ Klocwork bug 130
+ * restore-src/amrestore.c: Test maximum value for rst_flags->blocksize.
+ Klocwork bug 294
+ * common-src/genversion.c: Check NULL result of malloc.
+ Klocwork bug 294
+ * client-src/selfcheck.c: Check NULL result of fdopen.
+ Klocwork bug 539, 542
+ * oldrecover-src/extract_list.c: Fix pfn2->next = fn2.
+ * recover-src/extract_list.c : Ditto
+ Klocwork bug 268, 272, 543, 544
+ * oldrecover-src/extract_list.c: Check for cmd != NULL.
+ * recover-src/extract_list.c : Ditto
+ Klocwork bug 510
+ * restore-src/amidxtaped.c: Check for argv != NULL.
+ Klocwork bug 435
+ * changer-src/scsi-linux.c: Make buffer one larger.
+ Klocwork bug 520
+ * changer-src/scsi-changer-driver.c (OpenDevice): Validate parameters.
+ Klocwork bug 182
+ * changer-src/chg-scsi.c (clean_tape): Check usagetime != NULL.
+
+2006-07-05 Jean-Louis Martineau <martineau@zmanda.com>
+ Klocwork bug 551
+ * regex-src/regcomp.c (allocset): Check for p->g->sets
+ and p->g->setbits
+
+2006-07-05 Jean-Louis Martineau <martineau@zmanda.com>
+ Klocwork bug 169, 170, 181
+ * changer-src/chg-scsi.c: Validate input.
+
+2006-07-05 Jean-Louis Martineau <martineau@zmanda.com>
+ Klocwork bug 282
+ * common-src/file.c (rmpdir): Check for p == NULL.
+
+2006-07-05 Jean-Louis Martineau <martineau@zmanda.com>
+ Klocwork bug 524
+ * common-src/dgram.c (dgram_send_addr): Set addr_save earlier.
+
+2006-07-05 Jean-Louis Martineau <martineau@zmanda.com>
+ Klocwork bug 495
+ * server-src/taper.c (file_reader_side): Maximum value for
+ fallback_splitsize.
+
+2006-07-05 Jean-Louis Martineau <martineau@zmanda.com>
+ Klocwork bug 532
+ * recover-src/display_commands.c: Check for cmd != NULL.
+ * oldrecover-src/display_commands.c: Ditto
+
+2006-07-05 Jean-Louis Martineau <martineau@zmanda.com>
+ Klocwork bug 410
+ * restore-src/restore.c (restore): Check for tmp_filename.
+
+2006-07-05 Jean-Louis Martineau <martineau@zmanda.com>
+ Klocwork bug 234
+ * server-src/driver.c: Check for h and activehd >= 0.
+
+2006-07-05 Jean-Louis Martineau <martineau@zmanda.com>
+ Klocwork bug 338 and 390
+ * server-src/reporter.c (handle_partial, handle_strange): Check result
+ of handle_success.
+
+2006-07-05 Jean-Louis Martineau <martineau@zmanda.com>
+ Klocwork bug 558
+ * client-src/selfcheck.c (check_options, check_disk): Check for
+ calcprog == NULL
+
+2006-07-05 Jean-Louis Martineau <martineau@zmanda.com>
+ Klocwork bug 521
+ * client-src/clientconf.c (add_client_conf): Check result of realloc.
+
+2006-07-05 Jean-Louis Martineau <martineau@zmanda.com>
+ Klocwork bug 447 and 449
+ * restore-src/restore.c: Check for valid sendbackup request.
+
+2006-07-05 Jean-Louis Martineau <martineau@zmanda.com>
+ Klocwork bug 407
+ * restore-src/restore.c (restore): Set statinfo.st_size.
+
+2006-07-05 Jean-Louis Martineau <martineau@zmanda.com>
+ Klocwork bug 189
+ * common-src/file.c (sanitise_filename): Never return NULL.
+
+2006-07-05 Jean-Louis Martineau <martineau@zmanda.com>
+ * amandad-src/Makefile.am: Remove tape-src and libamtape.
+ * client-src/Makefile.am: Remove tape-src and libamtape.
+ * man/Makefile.am: Cleanup.
+ * oldrecover-src/Makefile.am: Remove tape-src and libamtape.
+ * recover-src/Makefile.am: Remove tape-src and libamtape.
+
+2006-07-05 Jean-Louis Martineau <martineau@zmanda.com>
+ Klocwork bug 236
+ * server-src/driver.c (handle_dumper_result): Check for
+ dumper->ev_read != NULL.
+
+2006-07-05 Jean-Louis Martineau <martineau@zmanda.com>
+ Klocwork bug 553
+ * restore-src/restore.c (search_a_tape): Check for desired_tape == NULL.
+
+2006-07-05 Jean-Louis Martineau <martineau@zmanda.com>
+ Klocwork bug 556 and 557
+ * common-src/security-util.c (bsd_recv_security_ok): Check result of
+ strtok, check service == NULL.
+
+2006-07-05 Jean-Louis Martineau <martineau@zmanda.com>
+ Klocwork bug 161
+ * client-src/calcsize.c (calc_load_file): Return NULL if fopen fail.
+ * client-src/calcsize.c (main): check NULL result from calc_load_file.
+
+2006-07-05 Jean-Louis Martineau <martineau@zmanda.com>
+ Klocwork bug 84
+ * server-src/amflush.c (main): Check return of lookup_disk.
+
+2006-07-05 Jean-Louis Martineau <martineau@zmanda.com>
+ Klocwork bug 62, 85, 459, 463, 466, 469, 555, 559
+ * common-src/security-util.c: Check result of fdopen.
+ * client-src/sendsize.c : Ditto.
+ * server-src/amcheck.c : Ditto.
+ * server-src/amflush.c : Ditto.
+
+2006-07-05 Jean-Louis Martineau <martineau@zmanda.com>
+ Klocwork bug 159, 375, 377, 379, 508, 509, 513, 519
+ * common-src/bsd-security.c: Replace malloc by alloc.
+ * common-src/bsdudp-security.c: Ditto
+ * common-src/genversion.c: Ditto
+ * recover-src/amrecover.c: Ditto
+ * restore-src/amidxtaped.c: Ditto
+ * server-src/reporter.c: Ditto
+
+2006-07-05 Jean-Louis Martineau <martineau@zmanda.com>
+ Klocwork bug 562 and 475
+ * recover-src/set_commands.c (cd_dir): Check result of rindex.
+ * oldrecover-src/set_commands.c (cd_dir): ditto.
+
+2006-07-05 Jean-Louis Martineau <martineau@zmanda.com>
+ Klocwork bug 552
+ * restore-src/restore.c (load_manual_tape): Alloc space for cur_tapedev.
+
+2006-07-05 Jean-Louis Martineau <martineau@zmanda.com>
+ Klocwork bug 406
+ * restore-src/restore.c (restore): Check for final_filename.
+
+2006-07-05 Jean-Louis Martineau <martineau@zmanda.com>
+ Klocwork bug 318
+ * server-src/list_dir.c (add_dir_list_item): Check for cur_list->next.
+
+2006-07-05 Jean-Louis Martineau <martineau@zmanda.com>
+ Klocwork bug 17, 32
+ * server-src/amadmin.c (disklist_one): Check localtime return NULL.
+ * server-src/amadmin.c (info_one) : Ditto.
+
+2006-07-05 Jean-Louis Martineau <martineau@zmanda.com>
+ Klocwork bug 2, 83, 128, 384, 478, 504, 505, 506, 517, 566, 567
+ * server-src/amadmin.c (seqdatestr): Check localtime return NULL.
+ * common-src/util.c (construct_datestamp, construct_timestamp,
+ conf_print): Ditto.
+ * oldrecover-src/amrecover.c (main): Ditto.
+ * oldrecover-src/uscan.l (ll_parse_date): Ditto.
+ * recover-src/amrecover.c (main): Ditto.
+ * recover-src/uscan.l (ll_parse_date): Ditto.
+ * server-src/amflush.c (main): Ditto.
+ * server-src/reporter.c (handle_success): Ditto.
+
+2006-07-05 Jean-Louis Martineau <martineau@zmanda.com>
+ Klocwork bug 470
+ * client-src/sendsize.c (add_diskest): Check for level value.
+
+2006-07-05 Jean-Louis Martineau <martineau@zmanda.com>
+ Klocwork bug 372
+ * server-src/reporter.c (nicedate): Check month value.
+
+2006-07-05 Jean-Louis Martineau <martineau@zmanda.com>
+ Klocwork bug 20
+ * server-src/amadmin.c (tape): Limit nb_days to 10000.
+
+2006-07-05 Jean-Louis Martineau <martineau@zmanda.com>
+ Klocwork bug 21
+ * server-src/amadmin.c (balance): Test 'later' after it is set.
+
+2006-07-05 Jean-Louis Martineau <martineau@zmanda.com>
+ * common-src/alloc.c (internal_vstralloc): Don't return NULL.
+
+2006-07-05 Jean-Louis Martineau <martineau@zmanda.com>
+ * server-src/infofile.c (open_txinfofile): Use local variable.
+
+2006-06-29 Jean-Louis Martineau <martineau@zmanda.com>
+ * restore-src/restore.c (label_of_current_slot): Close the tapefd if
+ the label mismatch.
+
+2006-06-29 Jean-Louis Martineau <martineau@zmanda.com>
+ * server-src/find.c (strip_failed_chunks):
+ - Get a **output_find as parameter.
+ - Check the label before remove a valid chunk.
+ - Memory management fix.
+
+2006-06-28 Jean-Louis Martineau <martineau@zmanda.com>
+ * common-src/security-util.c: Improve message for .amandahosts.
+
+2006-06-27 Ian Turner <ian@zmanda.com>
+ * common-src/fileheader.c: Fix a bug where spanned dumps would
+ always fail.
+
+2006-06-27 Jean-Louis Martineau <martineau@zmanda.com>
+ * server-src/amcheck.c: Fix test for holdingdisk negative size.
+
+2006-06-27 Jean-Louis Martineau <martineau@zmanda.com>
+ * configure.in: Don't set DEFAULT_TAPE_DEVICE if it is not set.
+ * client-src/clientconf.c: Work DEFAULT_TAPE_DEVICE not set.
+ * common-src/genversion.c: Work DEFAULT_TAPE_DEVICE not set.
+ * recover-src/amrecover.c: Work DEFAULT_TAPE_DEVICE not set.
+ * server-src/getconf.c: Work DEFAULT_TAPE_DEVICE not set.
+
+2006-06-27 Jean-Louis Martineau <martineau@zmanda.com>
+ Patch by Paul Bijnens
+ * server-src/amcheck.c: Check for access(hdp->diskdir, X_OK).
+
+2006-06-27 Jean-Louis Martineau <martineau@zmanda.com>
+ * server-src/conffile.c (getconf_byname): Check for kt->keyword != NULL.
+ * client-src/clientconf.c (client_getconf_byname): Ditto
+
+2006-06-22 Jean-Louis Martineau <martineau@zmanda.com>
+ * recover-src/extract_list.c: check_file_overwite.
+
+2006-06-22 Jean-Louis Martineau <martineau@zmanda.com>
+ * recover-src/extract_list.c: Do the cleanup of the extract list
+ at the extraction time
+ * oldrecover-src/extract_list.c: Ditto.
+
+2006-06-22 Jean-Louis Martineau <martineau@zmanda.com>
+ * NEWS: Add new features.
+ * ReleasesNotes: New files.
+
+2006-06-22 Jean-Louis Martineau <martineau@zmanda.com>
+ * docs/Makefile.am (pkgdata_DATA): Add amaespipe.8.txt amcrypt.8.txt
+ amcrypt-asym-ossl.8.txt amcrypt-ossl.8.txt amfetchdump.8.txt
+ * docs/amaespipe.8.txt: New file.
+ * docs/amcrypt.8.txt: New file.
+ * docs/amcrypt-asym-ossl.8.txt: New file.
+ * docs/amcrypt-ossl.8.txt: New file.
+ * docs/amfetchdump.8.txt: New file.
+
+2006-06-22 Jean-Louis Martineau <martineau@zmanda.com>
+ * docs/Makefile.am (pkgdata_DATA): Add howto-auth.txt.
+ * docs/howto-auth: Documentation on auth.
+ * docs/*.txt: Update from xml-docs
+
+2006-06-22 Jean-Louis Martineau <martineau@zmanda.com>
+ * man/xml-source/amanda.conf.5.xml: Add notes about bsdudp and bsdtcp.
+ * man/xml-source/amanda-client.conf.5.xml: Ditto.
+
+2006-06-22 Jean-Louis Martineau <martineau@zmanda.com>
+ * recover-src/extract_list.c (is_empty_dir): New function.
+ * recover-src/extract_list.c: Print a warning if cwd is not empty.
+
+2006-06-22 Jean-Louis Martineau <martineau@zmanda.com>
+ * server-src/amadmin.c: Allow 'p' and 'P' in --sort argument.
+
+2006-06-22 Jean-Louis Martineau <martineau@zmanda.com>
+ * server-src/amadmin.c: Print errstr returned by match_disklist.
+ * server-src/amcheck.c: Print errstr returned by match_disklist.
+ * server-src/amflush.c: Print errstr returned by match_disklist.
+ * server-src/diskfile.c (match_disklist): Return an error str.
+ * server-src/diskfile.h (match_disklist): New prototype.
+ * server-src/planner.c: Print errstr returned by match_disklist.
+ * server-src/reporter.c: Accept host/disk as arguments.
+
+2006-06-22 Jean-Louis Martineau <martineau@zmanda.com>
+ * server-src/amindexd.c (uncompress_file): Set LC_ALL=C before
+ executing sort.
+
+2006-06-22 Jean-Louis Martineau <martineau@zmanda.com>
+ * server-src/driver.c (wait_children, kill_children): New function.
+ * server-src/driver.c (wait_for_children): Use wait_children and
+ kill_children.
+ * server-src/driver.c (main): Use wait_children.
+ * server-src/driverio.c (taper_cmd, chunker_cmd): Close socket on QUIT
+ or ABORT command.
+
+2006-06-22 Jean-Louis Martineau <martineau@zmanda.com>
+ * common-src/amfeatures.c (am_init_feature_set): Set
+ fe_amrecover_feedme_tape.
+ * common-src/amfeatures.h (fe_amrecover_feedme_tape): New amfeatures.
+ * common-src/fileheader.c (print_header): Fix.
+ * recover-src/extract_list.c: Use fe_amrecover_feedme_tape.
+ * restore-src/amfetchdump.c: Print error if get_lock == 0.
+ * restore-src/amidxtaped.c: Call send_message if get_lock == 0.
+ * restore-src/restore.c: Split search_tapes in 5 functions.
+ * restore-src/restore.h (send_message): prototype.
+
+2006-06-22 Jean-Louis Martineau <martineau@zmanda.com>
+ * man/xml-source/amfetchdump.8.xml: Document -O and new -o.
+ * restore-src/amfetchdump.c: Replace -o by -O
+
+2006-06-22 Jean-Louis Martineau <martineau@zmanda.com>
+ * client-src/clientconf.c (parse_client_conf): Fix segmentation fault.
+ * server-src/conffile.c (parse_server_conf): Fix segmentation fault.
+
+2006-06-21 Kevin Till <ktill@zmanda.com>
+ * changer-src/chg-juke.sh.in
+ * changer-src/chg-manual.sh.in
+ * changer-src/chg-mcutil.sh.in
+ * changer-src/chg-multi.sh.in
+ * changer-src/chg-mtx.sh.in
+ * changer-src/chg-rait.sh.in
+ * changer-src/chg-disk.sh.in
+ * changer-src/chg-zd-mtx.sh.in
+ * changer-src/chg-null.sh.in
+ * changer-src/chg-chs.sh.in
+ * client-src/patch-system.sh.in
+ * amplot/amplot.sh.in
+ * server-src/amcrypt-ossl.sh.in
+ * server-src/amrmtape.sh.in
+ * server-src/amcleanup.sh.in
+ * server-src/amverifyrun.sh.in
+ * server-src/amaespipe.sh.in
+ * server-src/amdump.sh.in
+ * server-src/amcrypt.sh.in
+ * server-src/amcrypt-ossl-asym.sh.in
+ * server-src/amcheckdb.sh.in
+ * server-src/amfreetapes.sh.in
+ * server-src/amverify.sh.in
+ change /bin/sh to @SHELL@ for configure to pick up the correct
+ shell. Sourceforge bug 1466655
+ * man/xml-source/amcrypt-ossl-asym.8.xml: it's backup-privkey.pem
+
+2006-06-20 Kevin Till <ktill@zmanda.com>
+ * common-src/security-util.c: ignore EINTR in net_writev
+ patch by Jean-Louis Martineau.
+
+2006-06-20 John Franks <jrfranks@zmanda.com>
+ * server-src/conffile.c:
+ Remove Duplicate keyword table entries and alphabetize
+ to make future duplicates easier to spot...
+
+ * server-src/taper.c:
+ Fix compiler warnings when no mmap function is present.
+
+2006-06-20 John Franks <jrfranks@zmanda.com>
+ * server-src/diskfile.c:
+ Default boolean values without parameters to yes if
+ no value is present in configuration file. This
+ maintains backward compatibility and is logical since
+ a value such as "index" reads as an assertion of fact.
+
+2006-06-19 Jean-Louis Martineau <martineau@zmanda.com>
+ * docs/wishlist.txt: Remove features done in 2.5.0/2.5.1
+
+2006-06-19 Jean-Louis Martineau <martineau@zmanda.com>
+ * man/xml-source/amanda.conf.5.xml: amrecover_check_label and
+ amrecover_do_fsf default to yes.
+ * server-src/conffile (init_dumptype_defaults): DUMPTYPE_INDEX set to 1.
+ * server-src/diskfile.c (parse_diskline): index set from
+ dumptype_get_index.
+
+2006-06-16 Jean-Louis Martineau <martineau@zmanda.com>
+ * server-src/amstatus.pl.in: Match quotes in DONE line.
+
+2006-06-16 Kevin Till <ktill@zmanda.com>
+ * example/amanda-client.conf.in:
+ correct DEFAULT_TAPE_SERVER/DEFAULT_SERVER
+ * server-src/amcrypt-ossl-asym.sh.in:
+ set RANDFILE for openssl to place entropy file.
+ * server-src/amcrypt-ossl.sh.in: ditto
+
+2006-06-16 Jean-Louis Martineau <martineau@zmanda.com>
+ * amandad-src/amandad.c : Use strcasecmp to compare auth.
+ * client-src/selfcheck.c : Ditto
+ * client-src/sendbackup.c : Ditto
+ * restore-src/amidxtaped.c: Ditto
+ * server-src/amindexd.c : Ditto
+
+2006-06-16 Jean-Louis Martineau <martineau@zmanda.com>
+ * server-src/amindexd.c (reply, lreply, fast_lreply): Correct use
+ of arglist_start and arglist_end..
+ * server-src/amindexd.c (lreply_backend): Remove function.
+
+2006-06-16 Jean-Louis Martineau <martineau@zmanda.com>
+ * common-src/bsd-security.c (stream_read_callback): Send error to the
+ callback.
+
+2006-06-16 Jean-Louis Martineau <martineau@zmanda.com>
+ * recover-src/extract_list.c: Typo.
+ * restore-src/restore.c: Typo.
+
+2006-06-16 Jean-Louis Martineau <martineau@zmanda.com>
+ * client-src/clientconf.c: Allow include.
+ * client-src/clientconf.c (read_confline): Don't crash.
+ * server-src/conffile.c (read_confline): Don't crash.
+ * recover-src/amrecover.c: Exit if error in conf file.
+
+2006-06-16 Jean-Louis Martineau <martineau@zmanda.com>
+ * common-src/arglist.h: Typo.
+ * recover-src/extract_list.c: handle MESSAGE from amidxtaped.
+
+2006-06-16 Jean-Louis Martineau <martineau@zmanda.com>
+ * common-src/amfeatures.c (am_init_feature_set): Set
+ fe_amrecover_message.
+ * common-src/amfeatures.h (am_feature_e): Add fe_amrecover_message.
+ * common-src/arglist.h (printf_arglist_function3): Prototype.
+
+2006-06-16 Jean-Louis Martineau <martineau@zmanda.com>
+ * restore-src/restore.c (send_message): New function that send message
+ to stderr and/or amrecover.
+ * restore-src/restore.c: Call send_message on some error path.
+
+2006-06-16 Jean-Louis Martineau <martineau@zmanda.com>
+ * common-src/event.c (event_loop_wait, event_wait): Take an
+ event_handle_t * as parameter.
+ * common-src/event.h: New prototype.
+ * common-src/bsd-security.c: Call event_wait(bs->ev_read).
+ * common-src/krb4-security.c: Call event_wait(ks->ev_read).
+ * common-src/krb5-security.c: Call event_wait(ks->ev_read).
+ * common-src/security-util.c: Call event_wait(ss->ev_read).
+
+2006-06-15 Kevin Till <ktill@zmanda.com>
+ * man/xml-source/amcrypt-ossl-asym.8.xml: it's .am_passphrase
+ * server-src/amcrypt-ossl-asym.sh.in: export PATH
+ * server-src/amcrypt-ossl.sh.in: export PATH
+
+
+2006-06-15 Jean-Louis Martineau <martineau@zmanda.com>
+ * server-src/amcheck.c: -w doesn't change the test selection.
+ * man/xml-source/amcheck.8.xml
+
+2006-06-15 Jean-Louis Martineau <martineau@zmanda.com>
+ * server-src/planner.c: Log empty disklist and no DLE selected.
+
+2006-06-14 Jean-Louis Martineau <martineau@zmanda.com>
+ * common-src/bsd-security.c: Use %u to print in_port_t data.
+ * common-src/bsdudp-security.c: Ditto.
+
+2006-06-14 Jean-Louis Martineau <martineau@zmanda.com>
+ * changer-src/chg-disk.sh.in: Return the number of slot in output of
+ the -info command.
+ * changer-src/chg-zd-mtx.sh.in: Ditto.
+
+2006-06-14 Jean-Louis Martineau <martineau@zmanda.com>
+ * changer-src/chg-zd-mtx.sh.in: Accept changerfile that already
+ have the .conf suffix.
+
+2006-06-13 Jean-Louis Martineau <martineau@zmanda.com>
+ * amandad-src/amandad.c (s_ackwait): Resend the REP on receive of a
+ duplicate REQ.
+
+2006-06-13 Jean-Louis Martineau <martineau@zmanda.com>
+ * common-src/security-util.c (bsd_recv_security_ok): Set error only
+ if we get an error.
+
+2006-06-12 Jean-Louis Martineau <martineau@zmanda.com>
+ * server-src/driver.c: usetimestamps is a warning.
+
+2006-06-12 Kevin Till <ktill@zmanda.com>
+ * common-src/security-util.c: if host is 127.0.0.1 and either
+ localhost or localhost.domain is in .amandahost, hostmatch passes.
+ * common-src/security-util.h: update check_user_amandahosts prototype
+
+2006-06-12 Jean-Louis Martineau <martineau@zmanda.com>
+ * amandad-src/amandad.c (process_writenetfd): Close the pipe if the
+ security_stream is closed.
+ * recover-src/extract_list.c: Improve message if we don't get thei
+ FEATURE line from amidxtaped.
+
+2006-06-12 Jean-Louis Martineau <martineau@zmanda.com>
+ * recover-src/amrecover.c: Read amanda-client.conf and
+ <conf>/amanda-client.conf.
+
+2006-06-12 Jean-Louis Martineau <martineau@zmanda.com>
+ * common-src/security-util.c, common-src/tapelist.c,
+ restore-src/restore.c, server-src/amcheck.c, server-src/amindexd.c,
+ server-src/amtape.c, server-src/changer.c, server-src/driver.c,
+ server-src/planner.c, server-src/taper.c,
+ server-src/taperscan.c: Fix memory leak.
+
+2006-06-12 Jean-Louis Martineau <martineau@zmanda.com>
+ * restore-src/restore.c: Fix Adding at end of list.
+
+2006-06-12 Jean-Louis Martineau <martineau@zmanda.com>
+ * server-src/taper.c (syncpipe_putstr): Don't crash if str is NULL.
+
+2006-06-09 Jean-Louis Martineau <martineau@zmanda.com>
+ * server-src/holding.c (pick_datestamp): Fix reading user input.
+
+2006-06-09 Jean-Louis Martineau <martineau@zmanda.com>
+ * recover-src/amrecover.c (sigint_handler): Call send_command only if
+ amindexd is alive.
+
+2006-06-09 Jean-Louis Martineau <martineau@zmanda.com>
+ * common-src/util.c (connect_port): ETIMEDOUT is a fatal error.
+
+2006-06-09 Jean-Louis Martineau <martineau@zmanda.com>
+ * common-src/stream.c (stream_client_internal): Get errno set
+ correctly.
+ * server-src/driver.c (handle_chunker_result): Don't assert(0) on
+ receive of a TRYAGAIN from a chunker, but set
+ chunker->result.
+ * server-src/dumper.c: Try gethostbyname("localhost") before calling
+ stream_client and log appropriate message.
+
+2006-06-09 Jean-Louis Martineau <martineau@zmanda.com>
+ * server-src/amcheck.c: Report ERROR if gethostbyname("localhost")
+ doesn't succeed.
+
+2006-06-08 Jean-Louis Martineau <martineau@zmanda.com>
+ * client-src/clientconf.c (add_client_conf): New function to map
+ normal option to their
+ -o equivalent.
+ * client-src/clientconf.h (add_client_conf): Prototype.
+ * man/xml-source/amrecover.8.xml: Document -o.
+ * recover-src/amrecover.c: Also read <config>/amanda-client.conf
+
+2006-06-08 Jean-Louis Martineau <martineau@zmanda.com>
+ * server-src/diskfile.c (parse_diskline): Only return 0 or -1.
+
+2006-06-08 Jean-Louis Martineau <martineau@zmanda.com>
+ * amandad-src/amandad.h (g_option_t): Add auth.
+ * amandad-src/amandad_util.c (init_g_options): Set auth to NULL.
+ * amandad-src/amandad_util.c (parse_g_options): Parse auth.
+ * amandad-src/amandad_util.c (free_g_options): Free auth.
+ * client-src/sendbackup.c: Get amandad_auth from command line and
+ compare with REQ packet.
+ * common-src/amfeatures.h (fe_amindexd_options_hostname,
+ fe_amindexd_options_features,
+ fe_amindexd_options_auth,
+ fe_amidxtaped_options_hostname,
+ fe_amidxtaped_options_features,
+ fe_amidxtaped_options_auth): New amfeatures.
+ * common-src/amfeatures.c (am_init_feature_set): Set new amfeatures.
+ * recover-src/amrecover.c: Send auth in OPTIONS of req packet.
+ * recover-src/extract_list.c: Send auth in OPTIONS of req packet.
+ * restore-src/amidxtaped.c: Parse amandad_auth from command line.
+ Get auth from OPTIONS line.
+ Compare them.
+ * server-src/amindexd.c: Parse amandad_auth from command line.
+ Get auth from OPTIONS line.
+ Compare them.
+
+2006-06-08 Jean-Louis Martineau <martineau@zmanda.com>
+ * common-src/util.c(connect_port): Return -2 on ECONNREFUSED error
+ from connect.
+
+2006-06-07 Jean-Louis Martineau <martineau@zmanda.com>
+ * amandad-src/amandad.c: exec the service with the auth as parameter.
+ * amandad-src/amandad.c(writebuf): Do no close fd.
+ * client-src/selfcheck.c: Read the auth for the command line and
+ compare with the option string.
+ * client-src/selfcheck.c(main): Do no close 0,1,2 fd.
+
+2006-06-07 Jean-Louis Martineau <martineau@zmanda.com>
+ * man/xml-source/amanda.8.xml(CONFIGURATION OVERWRITE): New section.
+ * man/xml-source/amadmin.8.xml, man/xml-source/amcheck.8.xml,
+ man/xml-source/amdump.8.xml, man/xml-source/amflush.8.xml,
+ man/xml-source/amgetconf.8.xml, man/xml-source/amlabel.8.xml,
+ man/xml-source/amreport.8.xml,
+ man/xml-source/amrestore.8.xml: Add -o option.
+
+2006-06-07 Jean-Louis Martineau <martineau@zmanda.com>
+ * common-src/util.c(get_conftoken): Merge from zmanda.
+
+2006-06-07 Jean-Louis Martineau <martineau@zmanda.com>
+ * common-src/util.c(get_conftoken): Remove a conftoken_ungetc.
+
+2006-06-07 Jean-Louis Martineau <martineau@zmanda.com>
+ * common-src/bsd-security.c (stream_read_callback): Merge with zmanda.
+
+2006-06-07 Jean-Louis Martineau <martineau@zmanda.com>
+ * amandad-src/amandad.c(process_writenetfd): Call security_stream_read
+ only if size > 0.
+
+2006-06-07 Jean-Louis Martineau <martineau@zmanda.com>
+ * server-src/conffile.c (lookup_interface): Fix merge error.
+
+2006-06-07 John Franks <jrfranks@zmanda.com>
+ * common-src/amanda.h:
+ Fix isnormal() replacement macro to indirectly
+ check if a floating point value is != 0.0.
+ This prevents compiler warnings.
+
+2006-06-07 John Franks <jrfranks@zmanda.com>
+ * common-src/util.c
+ Put in "/* NOTREACHED */" comments after error() calls.
+ * server-src/diskfile.c
+ Change disktype index default to yes for backward compatibility.
+
+2006-06-06 John Franks <jrfranks@zmanda.com>
+ * amandad-src/amandad.c common-src/bsd-security.c:
+ Correct fix for infinite amandad loop.
+
+2006-06-06 John Franks <jrfranks@zmanda.com>
+ * common-src/stream.c common-src/util.c:
+ Lint clean again.
+ * server-src/conffile.c:
+ Remove replicated line
+
+2006-06-06 Jean-Louis Martineau <martineau@zmanda.com>
+ * common-src/util.c (conftoken_ungetc): Return the character.
+ * common-src/util.c (get_conftoken): Merge to allow escape character.
+ * common-src/util.c (read_block): Allow STRING as IDENT.
+ * server-src/conffile.c (getconf_long, getconf_size): New function.
+ * server-src/conffile.c: Cleanup after Merge.
+
+2006-06-06 Jean-Louis Martineau <martineau@zmanda.com>
+ * server-src/amadmin.c, server-src/amcheck.c, server-src/amflush.c,
+ server-src/amlabel.c, server-src/amlogroll.c, server-src/amtrmidx.c,
+ server-src/amtrmlog.c, server-src/getconf.c,
+ server-src/reporter.c: Usage -o
+ * server-src/amflush.c, server-src/amlogroll.c, server-src/amtrmidx.c,
+ server-src/amtrmlog.c, server-src/chunker.c, server-src/driver.c,
+ server-src/dumper.c, server-src/getconf.c, server-src/planner.c,
+ server-src/reporter.c,
+ server-src/taper.c: Add call to report_bad_conf_arg.
+ * server-src/conffile.c(get_comprate, get_compress): Parse CONF_END.
+
+2006-06-06 John Franks <jrfranks@zmanda.com>
+ * configure.in:
+ Increase checking level from 1 to 2 for SUN lint.
+ * client-src/amandates.c client-src/clientconf.c
+ common-src/security-util.c recover-src/amrecover.c
+ recover-src/extract_list.c regex-src/regcomp.c server-src/amcheck.c
+ server-src/amlabel.c server-src/chunker.c server-src/conffile.c
+ server-src/conffile.h server-src/diskfile.c server-src/diskfile.h
+ server-src/driver.c server-src/holding.c server-src/reporter.c
+ server-src/tapefile.c server-src/taper.c tape-src/amdd.c:
+ Lint clean again.
+ * common-src/util.h common-src/util.c:
+ Lint clean again.
+ Add missing conftype size.
+ * common-src/bsd-security.c
+ Fix infinte loop which consumes all /tmp space and 1/2
+ the CPU time when EOF is reached on socket.
+
+2006-06-05 Paddy Sreenivasan <paddy@zmanda.com>
+ * common-src/util.c: Fix warning
+
+2006-06-05 Jean-Louis Martineau <martineau@zmanda.com>
+ * restore-src/amfetchdump.c, server-src/amcheck.c,
+ server-src/amcheckdb.sh.in, server-src/amcleanup.sh.in,
+ server-src/amdump.sh.in, server-src/amflush.c,
+ server-src/amlabel.c, server-src/amlogroll.c,
+ server-src/amtrmidx.c, server-src/amtrmlog.c,
+ server-src/chunker.c, server-src/conffile.c,
+ server-src/diskfile.c, server-src/driver.c,
+ server-src/driverio.c, server-src/dumper.c,
+ server-src/getconf.c, server-src/planner.c,
+ server-src/reporter.c, server-src/taper.c,
+ server-src/taperscan.c: Allow -o options and some memory fix.
+ * server-src/conffile.c(lookup_dumptype, lookup_tapetype,
+ lookup_interface): Use strcasecmp.
+
+2006-06-02 Jean-Louis Martineau <martineau@zmanda.com>
+ * common-src/stream.c (stream_client_internal): Use connect_portrange.
+ * common-src/util.c (connect_portrange): First, try to connect with a
+ port already used.
+ * common-src/util.c (connect_port): Try to connect with a specific port.
+ * common-src/util.h: Cleanup.
+
+2006-06-02 Jean-Louis Martineau <martineau@zmanda.com>
+ * server-src/reporter.c: Remove empty if.
+
+2006-06-02 Jean-Louis Martineau <martineau@zmanda.com>
+ * common-src/util.c (read_block): Don't read CONF_NL aftre the '{'.
+ * server-src/conffile.c(get_holdingdisk, get_tapetype, get_interface):
+ Read a CONF_NL after the call to read_block.
+ * server-src/conffile.c(read_dumptype): Read a CONF_NL if we are not
+ called from diskfile.
+ * server-src/diskfile.c: Don't loop on empty line after read_dumptype.
+
+2006-06-01 Kevin Till <ktill@zmanda.com>
+ * server-src/amcrypt-ossl.sh.in: symmetric encrypt script using openSSL.
+ Thanks to Ben Slusky.
+ * server-src/amcrypt-ossl-asym.sh.in: public-ley encrypt script using openSSL.
+ * man/xml-source/amcrypt-ossl.8.xml: man page
+ * man/xml-source/amcrypt-ossl-asym.8.xml: man page
+ * configure.in: ditto
+ * man/Makefile.am: ditto
+ * man/entities/global.entities: ditto
+ * server-src/Makefile.am: ditto
+
+2006-06-01 John Franks <jfranks@zmanda.com>
+ Eliminate Cygwin compile warnings.
+ * client-src/getfsent.c: Quiet unused parameter warnings.
+ * client-src/selfcheck.c: Quiet unused parameter warnings.
+ * common-src/security-util.h: Make hostname const char *.
+
+2006-06-01 Jean-Louis Martineau <martineau@zmanda.com>
+ * server-src/amcheck.c: holdingdisk_get_disksize() return an off_t.
+ * server-src/find.c: result should be ssize_t.
+
+2006-06-01 Jean-Louis Martineau <martineau@zmanda.com>
+ * common-src/amanda.h: Remove am64_t.
+ * client-src/clientconf.c, client-src/clientconf.h, common-src/util.c,
+ common-src/util.h, server-src/conffile.c, server-src/conffile.h:
+ Second pass of config cleanup, add function to parse -o argument.
+ * recover-src/amrecover.c: -o command argument.
+ * restore-src/restore.c: Use off_t instead of am64_t.
+ * server-src/amadmin.c: New config subcommand. -o command argument.
+ * server-src/amlabel.c: Fix memory leak.
+ * server-src/diskfile.c: Fix memory leak.
+ * server-src/diskfile.h: Rename no_hold to to_holdingdisk.
+ * server-src/driver.c: Many.
+ * server-src/planner.c: am64_t to off_t.
+
+2006-06-01 Jean-Louis Martineau <martineau@zmanda.com>
+ This is the first pass of a general rewrite of configuration file
+ parsing, It will now use array to store all options.
+
+ * client-src/clientconf.c:
+ * client-src/clientconf.h:
+ * server-src/conffile.c:
+ * server-src/conffile.h:
+ * common-src/util.c: Many new functions.
+ * common-src/util.h:
+
+ * restore-src/amidxtaped.c, server-src/amcheck.c,
+ server-src/amcleanupdisk.c, server-src/amlabel.c,
+ server-src/diskfile.c, server-src/driver.c, server-src/driverio.c,
+ server-src/find.c, server-src/holding.c, server-src/planner.c,
+ server-src/reporter.c,
+ server-src/taper.c: Use new macro to get configuration option.
+
+2006-06-01 Jean-Louis Martineau <martineau@zmanda.com>
+ * amandad-src/amandad.c, client-src/amandates.c, client-src/noop.c,
+ client-src/selfcheck.c, client-src/sendsize.c,
+ common-src/bsd-security.c, common-src/bsdtcp-security.c,
+ common-src/bsdudp-security.c, common-src/fileheader.c,
+ common-src/rsh-security.c, common-src/security-util.c,
+ common-src/security-util.h, common-src/ssh-security.c,
+ recover-src/extract_list.c, server-src/amcheck.c,
+ server-src/amindexd.c, server-src/amlogroll.c,
+ server-src/diskfile.c, server-src/driver.c, server-src/dumper.c,
+ server-src/find.c, server-src/logfile.c, server-src/planner.c,
+ server-src/reporter.c,
+ server-src/tapefile.c: Fix memory and fd leak.
+
+2006-06-01 Jean-Louis Martineau <martineau@zmanda.com>
+ * server-src/find.c (search_holding_disk): Take the datestamp from the
+ file, not the directory name, otherwise usetimestamps=no doesn't
+ work.
+
+2006-06-01 Jean-Louis Martineau <martineau@zmanda.com>
+ * common-src/stream.c (stream_server): New priv parameter if we want
+ a reserved port. Don't try to
+ get a reserved port if priv==0.
+ * common-src/stream.h (stream_server): New prototype.
+ * common-src/bsd-security.c: Call stream_server with priv==0.
+ * common-src/krb4-security.c: Call stream_server with priv==1.
+ * common-src/security-util.c: Call stream_server with priv==0.
+ * restore-src/amidxtaped.c: Call stream_server with priv==0.
+ * server-src/chunker.c: Call stream_server with priv==0.
+ * server-src/taper.c: Call stream_server with priv==0.
+
+2006-06-01 Jean-Louis Martineau <martineau@zmanda.com>
+ * server-src/diskfile.c: Return -1 if open of diskfile failed.
+ * server-src/driver.c: Change message if didn't get a DATE line.
+ * server-src/reporter.c: Ignore faillure in reading amanda.conf
+ disklist and tapelist.
+
+2006-05-29 Jean-Louis Martineau <martineau@zmanda.com>
+ * man/xml-source/amanda.8.xml: Documents service in .amandahosts.
+
+2006-05-29 Jean-Louis Martineau <martineau@zmanda.com>
+ Previous patch doesn't work because 'make -j2' will use fd 3.
+ * amandad-src/Makefile.am: Use a temporary file for output of
+ 'make listlibsrc'.
+ * changer-src/Makefile.am: Ditto.
+ * client-src/Makefile.am: Ditto.
+ * common-src/Makefile.am: Ditto.
+ * oldrecover-src/Makefile.am: Ditto.
+ * recover-src/Makefile.am: Ditto.
+ * restore-src/Makefile.am: Ditto.
+ * server-src/Makefile.am: Ditto.
+ * tape-src/Makefile.am: Ditto.
+
+2006-05-29 Jean-Louis Martineau <martineau@zmanda.com>
+ * amandad-src/Makefile.am: 'make listlibsrc' send it's ouput to fd 3.
+ * changer-src/Makefile.am: Ditto.
+ * client-src/Makefile.am: Ditto.
+ * common-src/Makefile.am: Ditto.
+ * oldrecover-src/Makefile.am: Ditto.
+ * recover-src/Makefile.am: Ditto.
+ * restore-src/Makefile.am: Ditto.
+ * server-src/Makefile.am: Ditto.
+ * tape-src/Makefile.am: Ditto.
+
+2006-05-28 Paddy Sreenivasan <paddy@zmanda.com>
+ * tape-src/tapeio.c : Fixed warnings
+ * tape-src/output-rait.c : Fixed warnings
+ * tape-src/output-null.c : Fixed warnings
+ * tape-src/output-file.c : Fiexed warnings
+ * recover-src/amrecover.c: Fixed warnings
+ * recover-src/extract_list.c : Fixed warnings
+ * server-src/amadmin.c : Fixed warnings
+ * server-src/driver.c : Fixed warnings
+ * server-src/infofile.c : Fixed warnings
+
+2006-05-26 Jean-Louis Martineau <martineau@zmanda.com>
+ * server-src/conffile.c (read_dumptype): Parse SSH_KEYS.
+
+2006-05-26 Jean-Louis Martineau <martineau@zmanda.com>
+ * common-src/security-util.c (udp_inithandle): Remove bad merge.
+ * server-src/amindexd.c: Improve error message.
+ * server-src/planner.c: Add a space in output.
+
+2006-05-26 Jean-Louis Martineau <martineau@zmanda.com>
+ * server-src/conffile.c: Set dpcur.no_hold correctly,
+ Fix for conffile program.
+
+2006-05-26 Jean-Louis Martineau <martineau@zmanda.com>
+ Allow many services to share the same tcp connection for
+ bsdtcp/ssh/rsh.
+ Add a security_close_connection to the security-api.
+ * amandad-src/amandad.c (wait_30s, exit_on_qlength): New variable to
+ control auth specific behaviour.
+ * common-src/bsd-security.c: Add sec_close_connection_none.
+ * common-src/bsdudp-security.c: Add sec_close_connection_none.
+ * common-src/krb4-security.c: Add sec_close_connection_none.
+ * common-src/krb5-security.c: Add sec_close_connection_none.
+ * common-src/security.h (security_close_connection): Prototype.
+ * common-src/security-util.h (sec_close_connection_none,
+ tcpm_close_connection): Prototype.
+ * common-src/security-util.h (struct tcp_conn): Add toclose.
+ * common-src/security-util.h (struct sec_stream): Add closed_by_me and
+ closed_by_network.
+ * common-src/security-util.c (sec_close_connection_none,
+ tcpm_close_connection): New function.
+ * common-src/security-util.c: Handle many services on one connection.
+ * common-src/bsdtcp-security.c: Handle many services on one connection.
+ * common-src/rsh-security.c: Handle many services on one connection.
+ * common-src/ssh-security.c: Handle many services on one connection.
+ * recover-src/amrecover.c: Add call security_close_connection.
+ * recover-src/extract_list.c: Add call security_close_connection.
+ * server-src/amcheck.c: Add call security_close_connection.
+ * server-src/dumper.c: Add call security_close_connection.
+
+2006-05-26 Jean-Louis Martineau <martineau@zmanda.com>
+ * common-src/security-util.c (bsd_prefix_packet): We need the username
+ of the getuid() user.
+
+2006-05-26 Jean-Louis Martineau <martineau@zmanda.com>
+ * common-src/fileheader.c: Parse datestamp on F_TAPEEND.
+ * restore-src/amrestore.c: Set read_result to the result of
+ read_file_header.
+ * restore-src/restore.c (read_file_header): Return a ssize_t.
+ Rename bytes_read by read_result.
+ Set read_result to the result of read_file_header.
+ * restore-src/restore.h (read_file_header): New prototype.
+
+2006-05-25 Jean-Louis Martineau <martineau@zmanda.com>
+ * server-src/taperscan.c: Replace bogus newvstralloc by vstrextend.
+
+2006-05-25 Jean-Louis Martineau <martineau@zmanda.com>
+ * client-src/getfsent.c (print_entry): Add prototype.
+ * common-src/token.c (main): Shut up compiler warning.
+ * server-src/infofile.c (dump_rec, dump_db): Add prototype.
+
+2006-05-25 Jean-Louis Martineau <martineau@zmanda.com>
+ * amandad-src/amandad.c, common-src/bsd-security.c,
+ common-src/bsdtcp-security.c, common-src/bsdudp-security.c,
+ common-src/event.c, common-src/krb5-security.c,
+ common-src/protocol.c, common-src/rsh-security.c,
+ common-src/security-util.c, common-src/ssh-security.c,
+ common-src/util.c, server-src/driver.c: comment debugging.
+
+2006-05-25 Jean-Louis Martineau <martineau@zmanda.com>
+ * common-src/security-util.c: typo.
+ * server-src/amcheck.c: Make sure all check are done.
+
+2006-05-25 Jean-Louis Martineau <martineau@zmanda.com>
+ Fix for program not compiled by default.
+ make bsdsecurity still not compile.
+ * common-src/bsd-security.c(bind_portrange): prototype change.
+ * common-src/Makefile.am (STANDARD_COMMON_STUFF_NOT_FILE): Add match.o.
+ * server-src/conffile.c: Many typo.
+ * tape-src/tapeio.c: Use OFF_T_FMT and SSIZE_T_FMT when needed, typo.
+
+2006-05-25 Jean-Louis Martineau <martineau@zmanda.com>
+ * common-src/fileheader.c (validate_datestamp): Works for 8 characters
+ datestamp.
+ * common-src/security-util.c (tcpm_send_token): netlength must be
+ uint32_t.
+ * common-src/security-util.c (bsd_prefix_packet): Fix typo.
+ * common-src/util.c (get_time): Don't do computation for starttime.
+ * server-src/conffile.c (read_dumptype): Do computation for starttime.
+
+2006-05-25 Jean-Louis Martineau <martineau@zmanda.com>
+ * common-src/krb5-security.c (krb5_sendpkt, krb5_stream_read_sync,
+ recv_token): Return ssize_t.
+ * common-src/krb5-security.c (krb5_accept, krb5_stream_accept,i
+ krb5_stream_auth): Shut up compiler.
+ * tape-src/output-file.c: Use SSIZE_MAX instead of SSIZE_T_MAX.
+
+2006-05-25 Jean-Louis Martineau <martineau@zmanda.com>
+ * configure.in(AM_INIT_AUTOMAKE): Fix.
+
+2006-05-25 John Franks <jrfranks@zmanda.com>
+ Pass user CFLAGS correctly to machine generated code and do not
+ enforce code quality checks on them.
+ * configure.in:
+ Put compiler code check flags into existing, but previously
+ unused, AM_CFLAGS for Makefiles to pick up. CFLAGS should
+ now only contain mandatory flags.
+
+ * recover-src/Makefile.am oldrecover-src/Makefile.am:
+ Use CFLAGS for compiling C code generated from uparse.y and uscan.l
+
+2006-05-24 John Franks <jrfranks@zmanda.com>
+ Add support for binary path names on disk and in configuration files.
+ (Allow spaces in filenames.)
+
+ Allow quoted strings for disklist entries.
+
+ Lint clean code using sun lint, splint and strict GCC warnings.
+ Type / size clean, dead code removal, portibility checks, etc.
+ Many checks are still turned off. See configure.in for lint flags used.
+
+ Increase debug output in /tmp/amanda/*debug files.
+
+ Set SO_REUSEADDR on sockets help avoid running out of ports.
+
+ * configure.in:
+ Added lint program discovery with specific targets for SUN lint and splint.
+ Check each compiler option to see if GCC supports it.
+ Enable more code quality warnings.
+ Change missing xsltproc to warning rather than error.
+ Define _GNU_SOURCES to build flags.
+ Make size_t and time_t printf format macros.
+ Check for isnormal() availability.
+ Don't install man pages if they are not built.
+ Fix man pages to not attempt build or install if
+ --without-built-manpages is set.
+
+ * Makefile.am amandad-src/Makefile.am changer-src/Makefile.am
+ client-src/Makefile.am common-src/Makefile.am
+ oldrecover-src/Makefile.am recover-src/Makefile.am
+ restore-src/Makefile.am server-src/Makefile.am tape-src/Makefile.am:
+ Add lint target.
+
+ * common-src/amanda.h common-src/dgram.c common-src/stream.c
+ common-src/util.c:
+ Keep checking for ports on all bind errors.
+ Delay and retry a few times if all ports are busy.
+ Retry bind failures after all methods fail.
+ increase bind checking timeout to 30 minutes.
+
+ * client-src/amandad.c
+ Issue wait when any child exits. (Get rid of defunct processes)
+ Stat() index file before using system command.
+ (shell is not reporting failure if index is not present)
+
+ * recover-src/extract_list.c:
+ Fix problem of 'add *' not adding directories.
+ Fix problem of freeing pointer not obtained through malloc.
+ Touch up file addition to actually use the file names
+ retrieved when adding a directory and not the directory itself.
+
+ * server-src/taper.c
+ Strenghten error recovery for broken syncpipes and writer errors.
+
+ * changer-src/chg-scsi-chio.c client-src/amandates.c
+ client-src/client_util.c client-src/findpass.c client-src/getfsent.c
+ client-src/selfcheck.c client-src/sendbackup-gnutar.c
+ client-src/sendbackup-star.c client-src/sendbackup.c
+ client-src/sendsize.c common-src/bsd-security.c common-src/file.c
+ common-src/krb5-security.c server-src/amcheck.c server-src/amindexd.c
+ server-src/diskfile.c server-src/driver.c server-src/dumper.c
+ server-src/holding.c server-src/infofile.c server-src/logfile.c
+ server-src/tapefile.c:
+ allow empty lines in input streams.
+
+ * recover-src/uparse.y
+ print message when input is garbage.
+
+ * server-src/getconf.c:
+ Define HOSTNAME_INSTANCE if it was not already defined
+ for Kerberos.
+
+ * configure.in: Make readline warning less specific. Readline is
+ used by all input from terminal now.
+
+2006-05-24 Kevin Till <ktill@@zmanda.com>
+ * client-src/sendbackup.c: ignore SIGINT
+ * common-src/ssh-security.c: add to total only when n > 0
+ * common-src/ssh-security.c: add ssh to error,
+ retry writev when EINTR, EAGAIN is seen
+ to STDOUT. exit when options is chosen in template mode.
+ * server-src/driver.c: make sure timestamp is not null
+ * amanda/configure.in: remove template.d/amanda.conf which is a dup
+ of amanda-harddisk.conf
+ * example/Makefile.am: add template.d/README
+ * amanda-harddisk.conf.in: set tapedev
+ * recover-src/amrecover.c: aclose socket before exit.
+ * recover-src/extract_list.c: ditto
+ * amanda_enterprise.spec: remove template.d/amanda.conf, add template.d/README
+ in the failure cases. <> user input field.
+ * server-src/amcheck.c: no quoted text is a warning
+ * server-src/driver.c: no need to amfree qname
+ argument. Search mtx in PATH too.
+ * example/template.d/advanced.conf.in: fix comment for autoflush
+ * example/template.d/advanced.conf.in: add usetimestamps
+ * server-src/diskfile.c: to catch unsupported compress-encryption
+ combination and abort amdump gracefully.
+ * man/xml-source/amanda.conf.5.xml: fix syntax, add
+ dumptype references.
+ * man/xml-source/amanda.8.xml: fix syntax
+ * configure.in: ditto
+ * man/Makefile.am: ditto
+ * example/amanda.conf.in: tidy up
+ * man/xml-source/amaespipe.8.xml: add uuencode as requirement
+ * man/xml-source/amcrypt.8.xml: add uuencode as requirement
+ * server-src/amcheck.c: catch dumptype misconfiguration
+ * server-src/diskfile.c: ditto
+ * server-src/driverio.c: ditto
+ * server-src/planner.c: ditto
+ * server-src/conffile.c: check includefile before calling
+ read_conffile_recursively
+ * example/amanda.conf.in: add public-key encryption dumptype example
+ * man/xml-source/amanda.8.xml: fix some formatting
+ * server-src/planner.c: adjust setuid() calling sequences so that ssh can work
+ * server-src/dumper.c: ditto
+ * configure.in: add LOW_TCPPORTRANGE for amrecover
+ * common-src/stream.c: use LOW_TCPPORTRANGE
+ * server-src/amdump.sh.in: check if config is supplied
+ * man/xml-source/amrestore.8.xml: add notes on "-f" option
+
+2006-05-24 Ian Turner <ian@zmanda.com>
+ * configure.in: Properly document --without-xsltproc as itself,
+ and not the (nonexistant) option --without-built-manpages.
+
+2006-05-16 John Franks <jrfranks@zmanda.com>
+ * amandad-src/amandad.c client-src/clientconf.c common-src/bsd-security.c
+ common-src/bsdudp-security.c common-src/dgram.c common-src/krb4-security.c
+ common-src/krb5-security.c common-src/match.c common-src/packet.c
+ common-src/security-util.c common-src/security-util.h
+ common-src/security.h common-src/util.c oldrecover-src/Makefile.am
+ oldrecover-src/set_commands.c recover-src/amrecover.c
+ recover-src/extract_list.c server-src/conffile.c server-src/driver.c
+ server-src/dumper.c server-src/planner.c server-src/reporter.c:
+ Minimal changes to get tree to compile along with some more
+ debugging output.
+
+2006-05-15 Jean-Louis Martineau <martineau@zmanda.com>
+ * server-src/amadmin.c (disklist_one): print spindle.
+
+2006-05-12 Jean-Louis Martineau <martineau@zmanda.com>
+ * commmon-src/bsd-security.c: Typo.
+
+2006-05-12 Jean-Louis Martineau <martineau@zmanda.com>
+ * common-src/Makefile.am (noinst_HEADERS): Add security-util.h.
+
+2006-05-12 Jean-Louis Martineau <martineau@zmanda.com>
+ Build a big tok_t enum for server and client config.
+ * client-src/clientconf.c: Move many things to util.c.
+ * client-src/clientconf.h: Remove extern variable.
+ * common-src/util.c: Add common part of clientconf.c and conffile.c
+ * common-src/util.h: Prototype.
+ * server-src/conffile.c: Move many things to util.c.
+ * server-src/diskfile.c(disk_parserror): Rename from parserror.
+ * server-src/taper.c: Make many variable static.
+
+2006-05-12 Jean-Louis Martineau <martineau@zmanda.com>
+ * restore-src/restore.c: Fix use of possibly NULL input.
+
+2006-05-12 Jean-Louis Martineau <martineau@zmanda.com>
+ * common-src/ssh-security.c (ssh_connect): Retrieve ssh_keys from
+ configuration.
+ * server-src/amadmin.c(disklist_one): Print ssh_keys.
+ * server-src/conffile.c(SSH_KEYS): Parse new dumptype option.
+ * server-src/conffile.h(dumptype_t): Add ssh_keys.
+ * server-src/diskfile.c(parse_diskline): Copy new field.
+ * server-src/diskfile.h(disk_t) Add ssh_keys.
+ * server-src/driverio.c(dumper_cmd): Send dp->ssh_keys in a PORT_DUMP
+ command to the dumper.
+ * server-src/dumper.c: Parse ssh_keys in a PORT_DUMP command.
+ * server-src/dumper.c(dumper_get_security_conf): Return the ssh_keys.
+ * server-src/server_util.c(amhost_get_security_conf): Return the
+ ssh_keys.
+
+2006-05-12 Jean-Louis Martineau <martineau@zmanda.com>
+ * amandad-src/amandad.c: Set allow_many_services to 0 if auth=bsdtcp.
+ * common-src/bsd-security.c: Use security-util.c.
+ * common-src/bsdtcp-security.c: New security-api.
+ * common-src/bsdudp-security.c: New secutity-api.
+ * common-src/krb4-security.c: Use security-util.c.
+ * common-src/krb5-security.c: Use security-util.c.
+ * common-src/Makefile.am (libamanda_la_SOURCES): Add bsdtcp-security.c,
+ bsdtcp-security.c
+ and security-util.c.
+ * common-src/protocol.c: Debuging cleanup.
+ * common-src/rsh-security.c Use security-util.c.
+ * common-src/security.c: Use bsdtcp_security_driver
+ and bsdudp_security_driver.
+ * common-src/security.h(accept): New prototype.
+ * common-src/security-util.c: Many common function for security-api.
+ * common-src/security-util.h: many prototype for security-api.
+ * common-src/ssh-security.c Use security-util.c.
+ * common-src/stream.c (stream_client_internal): Call connect_portrange.
+ * common-src/util.c (make_socket): Make a socket.
+ * common-src/util.c (connect_portrange): Make a socket, bind it and
+ connect.
+ * common-src/util.h (connect_portrange): Prototype.
+ * configure.in: new --with-bsdtcp-security and --with-bsdudp-security.
+
+2006-05-10 Jean-Louis Martineau <martineau@zmanda.com>
+ Patch by <amanda@inventivetechnology.at>
+ * man/xml-source/amrecover.8.xml: Document listhost command.
+
+2006-05-08 Jean-Louis Martineau <martineau@zmanda.com>
+ Patch by <amanda@inventivetechnology.at>
+ * server-src/amindexd.c: new LISTHOST command.
+ * recover-src/set_commands.c (list_host): New function.
+ * recover-src/amrecover.h (list_host): Prototype.
+ * recover-src/help.c (list_host): Print help.
+ * recover-src/uscan.l: Parse listhost command.
+ * recover-src/uparse.y: LISTHOST command.
+ * oldrecover-src/set_commands.c (list_host): New function.
+ * oldrecover-src/amrecover.h (list_host): Prototype.
+ * oldrecover-src/help.c (list_host): Print help.
+ * oldrecover-src/uscan.l: Parse listhost command.
+ * oldrecover-src/uparse.y: LISTHOST command.
+
+2006-05-08 Ian Turner <ian@zmanda.com>
+ * server-src/amcheck.c: Make it an error when the expected new
+ tape cannot be found. Thanks to Paul Bijnens
+ <paul.bijnens@xplanation.com> for the patch and to Jason L
+ Tibbitts III <tibbs@math.uh.edu> for noticing this problem.
+
+2006-05-08 Jean-Louis Martineau <martineau@zmanda.com>
+ * driverio.h (shed_s): Add est_nsize, est_csize, degr_nsize, degr_csize
+ for nativa and compressed estimate size.
+ * planner.c: Send the native and compressed estimate size to the driver.
+ * driver.c: log with L_STATS the estimate of a successful dump.
+ * reporter.c: Parse the L_STATS.
+ * reporter.c(generate_bad_estimate): New function that will put in the
+ NOTES section all bad estimate.
+
+2006-05-08 Jean-Louis Martineau <martineau@zmanda.com>
+ * configure.in (AC_CONFIG_FILES): Add oldrecover-src/Makefile.
+ * Makefile.am (RECOVER_SUBDIRS): Add oldrecover-src.
+ * oldrecover-src/amrecover.c: Copy of old recover-src/amrecover.c
+ * oldrecover-src/amrecover.h: Copy of old recover-src/amrecover.h
+ * oldrecover-src/display_commands.c: Copy of old
+ recover-src/display_commands.c
+ * oldrecover-src/extract_list.c: Copy of old recover-src/extract_list.c
+ * oldrecover-src/help.c: Copy of old recover-src/help.c
+ * oldrecover-src/Makefile.am: Copy of old recover-src/Makefile.am
+ * oldrecover-src/set_commands.c: Copy of old recover-src/set_commands.c
+ * oldrecover-src/uparse.y: Copy of old recover-src/uparse.y
+ * oldrecover-src/uscan.l: Copy of old recover-src/uscan.l
+ * recover-src/amrecover.c: Works with security-api.
+ * recover-src/amrecover.h: Works with security-api.
+ * recover-src/extract_list.c: Works with security-api.
+
+2006-05-08 Jean-Louis Martineau <martineau@zmanda.com>
+ * amandad-src/amandad.c: Fixup.
+
+2006-05-08 Jean-Louis Martineau <martineau@zmanda.com>
+ * common-src/packet.h: pkt_t.body is now a char*.
+ * common-src/packet.c (pkt_init): Return an alloced pkt.body.
+ * common-src/packet.c (pkt_cat): Increade pkt.body size if needed.
+ * common-src/protocol.c: Free allocated pkt.body.
+ * common-src/dgram.c (dgram_cat): Return int.
+ * common-src/dgram.h (dgram_cat): New prototype.
+ * common-src/krb5-security.c: Work with dynamicaly allocated packet
+ body.
+ * common-src/rsh-security.c: Work with dynamicaly allocated packet
+ body.
+ * common-src/ssh-security.c: Work with dynamicaly allocated packet
+ body.
+ * amandad-src/amandad.c: Work with dynamicaly allocated packet body.
+ * server-src/amcheck.c: Don't limit packet size.
+ * server-src/planner.c: Don't limit packet size.
+
+2006-05-08 Jean-Louis Martineau <martineau@zmanda.com>
* amandad-src/amandad.c (service_new): Apply the correct patch.
-2006-05-28 Jean-Louis Martineau <martineau@zmanda.com>
- * Amanda 2.5.0p2 released.
- * configure.in: AM_INIT_AUTOMAKE(amanda, 2.5.0p2).
- * NEWS: Changes in release 2.5.0p2.
+2006-05-08 Jean-Louis Martineau <martineau@zmanda.com>
+ * server-src/taper.c: Fix compiler warning.
+ * common-src/match.c: Many function get const parameters.
+ * common-src/amanda.h: Prototype change.
2006-05-07 Jean-Louis Martineau <martineau@zmanda.com>
- * amandad-src/amandad.c (service_new): Make sure that the 3 data[] fd
- are not in the range DATA_FD_OFFSET to
+ * amandad-src/amandad.c (service_new): Make sur that the 3 data_read[]
+ and the 3 data_write[] fd are not in the range DATA_FD_OFFSET to
DATA_FD_OFFSET+DATA_FD_COUNT-1.
+2006-05-05 Jean-Louis Martineau <martineau@zmanda.com>
+ * common-src/tapelist.c (append_to_tapelist): Remove bad amfree.
+
+2006-05-05 Nikhil Bandiwadekar <nikhil@zmanda.com>
+ * server-src/conffile.c: fix to correctly handle am64 datatype
+
2006-05-04 Jean-Louis Martineau <martineau@zmanda.com>
* server-src/taper.c: Write the slot number in the
- 'taper: wrote label' line.
+ 'taper: wrote label' line.
* server-src/amverifyrun.sh.in: Parse that line.
2006-05-02 Jean-Louis Martineau <martineau@zmanda.com>
* amstatus.pl.in: Limit characters for hostname in setup_estimate line.
-2006-04-28 Jean-Louis Martineau <martineau@zmanda.com>
- * Amanda 2.5.0p1 released.
- * configure.in: AM_INIT_AUTOMAKE(amanda, 2.5.0p1).
- * NEWS: Changes in release 2.5.0p1.
+2006-04-27 Jean-Louis Martineau <martineau@zmanda.com>
+ * common-src/rsh-security.c: Pass "amdump amindexd amidxtaped" option
+ to amandad.
+ * common-src/ssh-security.c: Ditto.
+
+2006-04-27 Jean-Louis Martineau <martineau@zmanda.com>
+ * amandad-src/amandad.c: Accept a list of services on the command line.
+
+2006-04-27 Jean-Louis Martineau <martineau@zmanda.com>
+ * common-src/tapelist.c (append_to_tapelist): Fix memory leak.
+
+2006-04-27 Jean-Louis Martineau <martineau@zmanda.com>
+ * amandad-src/amandad.c: Fix memory leak.
+ * amandad-src/amandad.h (free_g_options): Prototype.
+ * amandad-src/amandad_util.c (free_g_options): New function to free a
+ g_option_t.
+ * server-src/amcleanupdisk.c: Fix memory leak.
+ * server-src/reporter.c: Fix memory leak.
+ * server-src/tapefile.c: Fix memory leak.
+ * server-src/taperscan.c: Put message in error_message.
+
+2006-04-26 Jean-Louis Martineau <martineau@zmanda.com>
+ * server-src/amcheck.c (start_server_check): Memory leak.
+
+2006-04-26 Jean-Louis Martineau <martineau@zmanda.com>
+ * amandad-src/Makefile.am (noinst_HEADERS): Add amandad.h.
+ * client-src/Makefile.am (noinst_HEADERS): Add clientconf.h.
+
+2006-04-26 Jean-Louis Martineau <martineau@zmanda.com>
+ * man/xml-source/amanda-client.conf.5.xml: New file.
+
+2006-04-26 Jean-Louis Martineau <martineau@zmanda.com>
+ * common-src/amanda.h (check_user_ruserok, check_user_amandahosts):
+ Remove prototype.
+ * common-src/bsd-security.c: Pass the service name across check_user*
+ function and validate it from the .amandahosts file.
+
+2006-04-26 Jean-Louis Martineau <martineau@zmanda.com>
+ * restore-src/amidxtaped.c: Can be launched by amandad.
+ * server-src/Makefile.am (INCLUDES): Add -I$(top_srcdir)/amandad-src
+ * server-src/Makefile.am (amidxtaped__LDADD): Link with libamandad.
+ * restore-src/restore.c: Fix indentation.
+
+2006-04-26 Jean-Louis Martineau <martineau@zmanda.com>
+ * server-src/amindexd.c: Can be launched by amandad
+ * server-src/Makefile.am (INCLUDES): Add -I$(top_srcdir)/amandad-src
+ * server-src/Makefile.am (amindexd_LDADD): Link with libamandad.
+
+2006-04-26 Jean-Louis Martineau <martineau@zmanda.com>
+ * amandad-src/amandad.c: New file.
+ * amandad-src/amandad.h: New file.
+ * amandad-src/amandad_util.c: New file, add function init_g_options
+ parse_g_options.
+ * amandad-src/Makefile.am: New file.
+ * client-src/amandad.c: Removed file.
+ * client-src/amandad.h: Removed file.
+ * client-src/client_util.c (init_g_options, parse_g_options): Remove.
+ * client-src/client_util.h (init_g_options, parse_g_options): Remove.
+ * client-src/Makefile.am (INCLUDES): -I$(top_srcdir)/amandad-src
+ * client-src/Makefile.am (libexec_PROGRAMS): Remove amandad.
+ * client-src/Makefile.am (LDADD): Add
+ ../amandad-src/libamandad.$(LIB_EXTENSION).
+ * client-src/selfcheck.c: #include "amandad.h".
+ * client-src/sendsize.c: #include "amandad.h".
+ * configure.in (AC_CONFIG_FILES): amandad-src/Makefile.
+ * Makefile.am (SUBDIRS): amandad-src.
+
+2006-04-26 Jean-Louis Martineau <martineau@zmanda.com>
+ * docs/security-api.txt: Document security_read_sync.
+ * common-src/security.h: Typo.
+
+2006-04-26 Jean-Louis Martineau <martineau@zmanda.com>
+ * client-src/amandad.c (service_new): Pass the "amandad" argument to
+ the service.
+
+2006-04-26 Jean-Louis Martineau <martineau@zmanda.com>
+ * common-src/bsd-security.c: Allow to run many services on the same
+ client. Cleanup.
+ * common-src/rsh-security.c: Ditto.
+ * common-src/ssh-security.c: Ditto.
-2006-04-24 Ian Turner <ian@zmanda.com>
- * server-src/changer.c: Don't crash if we go to taperscan "Plan B".
+2006-04-26 Jean-Louis Martineau <martineau@zmanda.com>
+ * common-src/security.h (security_stream_read_sync): Prototype.
+ * common-src/bsd-security.c (bsd_stream_read_sync): New function.
+ * common-src/krb4-security.c (krb4_stream_read_sync): New function.
+ * common-src/krb5-security.c (krb5_stream_read_sync): New function.
+ * common-src/rsh-security.c (rsh_stream_read_sync): New function.
+ * common-src/ssh-security.c (ssh_stream_read_sync): New function.
+
+2006-04-26 Jean-Louis Martineau <martineau@zmanda.com>
+ * client-src/amandad.c: Open pipe in both direction to the services.
+ * client-src/sendbackup.c: Deal with the newer pipe.
+
+2006-04-26 Jean-Louis Martineau <martineau@zmanda.com>
+ * client-src/clientconf.c: New file to read the client configuration
+ file.
+ * client-src/clientconf.h: Header.
+ * client-src/Makefile.am: Link clientconf into libamclient.
+ * configure.in (AC_CONFIG_FILES): example/amanda-client.conf.
+ * docs/amanda-client.conf.5.txt: New documentation.
+ * docs/Makefile.am (pkgdata_DATA): amanda-client.conf.5.txt.
+ * example/amanda-client.conf.in: exemple.
+ * example/Makefile.am (noinst_DATA): amanda-client.conf.
+ * man/entities/global.entities: amclientconf.
+ * man/Makefile.am (COMMON_MAN5_PAGES): amanda-client.conf.5.
+ * man/xml-source/amanda.8.xml (SEE ALSO): amanda-client.conf(5).
+ * man/xml-source/amanda.conf.5.xml (SEE ALSO): amanda-client.conf(5).
+ * man/xml-source/amrecover.8.xml (SEE ALSO): amanda-client.conf(5).
+
+2006-04-26 K. K. George<kkg@zmanda.com>
+ * server-src/reporter.c: Fix to untaint the mailto parameter.
+ * server-src/amcheck.c: Fix to untaint the mailto parameter
+ * changer-src/chg-scsi.c: Fix to untaint the mailto parameter.
+ * changer-src/chg-scsi-chio.c: Fix to untaint the mailto parameter.
+ * common-src/util.h: Added function to check if the mailto
+ parameter is untainted
+ * common-src/util.c: Added function to check if the mailto
+ parameter is untainted
+
+2006-04-26 Jean-Louis Martineau <martineau@zmanda.com>
+ * common-src/event.c(event_wait): New function.
+ * common-src/event.h(event_wait): prototype.
+ * docs/eventapi.txt: Document event_wait.
2006-04-24 Jean-Louis Martineau <martineau@zmanda.com>
* server-src/planner.c: Fix divide by zero if runtapes==0.
+2006-04-24 K. K. George<kkg@zmanda.com>
+ * server-src/reporter.c: Fix to make the mailto parameter in
+ amanda.conf optional. Added two more commandline options
+ -i & -Maddress.
+ * server-src/amcheck.c: Fix to make the mailto parameter in
+ amanda.conf optional.
+ * man/xml-source/amreport.8.xml: Modified to document the
+ -i & -Maddress commandline parameters
+ * docs/amreport.8.txt: Modified to document the
+ -i & -Maddress commandline parameters
+ * changer-src/chg-scsi.c: Fix to make the mailto parameter in
+ amanda.conf optional.
+ * changer-src/chg-scsi-chio.c: Fix to make the mailto parameter in
+ amanda.conf optional.
+
2006-04-23 Jean-Louis Martineau <martineau@zmanda.com>
* server-src/driver.c (handle_chunker_result): make sure that
est_size > act-size.
-2006-04-23 Jean-Louis Martineau <martineau@zmanda.com>
- * server-src/chunker.c: Read the START command to set the datestamp.
- * server-src/driver.c: Send a START command to the chunker.
- * server-src/driverio.c (chunker_cmd): Add the START command.
- * server-src/server_util.c (cmdstr): Add the START command.
- * server-src/server_util.h (cmd_t): Add the START command.
+2006-04-21 Jean-Louis Martineau <martineau@zmanda.com>
+ * server-src/changer.c (changer_command): Make sure fd[0] != 1.
+
+2006-04-19 Jean-Louis Martineau <martineau@zmanda.com>
+ * restore-src/amidxtaped.c: Cleanup.
+
+2006-04-19 Ian Turner <ian@zmanda.com>
+ * tape-src/output-tape.c: Do a more thourough check to ensure
+ that we actually got a tape device, before proceeding to use
+ it.
+
+2006-04-18 Ian Turner <ian@zmanda.com>
+ * changer-src/chg-disk.sh.in: Check that the virtual device is a
+ directory with proper permissions.
+ * server-src/changer.c: Do the right thing (failure) if there is
+ a problem with the changer.
+
+2006-04-18 Ian Turner <ian@zmanda.com>
+ * recover-src/uscan.l: Accept setdate of the form
+ yyyy-MM-dd-hh-mm in addition to yyyy-MM-dd-hh-mm-ss.
+ * man/xml-source/amrecover.8.xml: Document this change.
+
+2006-04-14 Jean-Louis Martineau <martineau@zmanda.com>
+ * recover-src/help.c: Document setdate YYYY-MM-DD-HH-MM-SS format.
+ * man/xml-source/amrecover.8.xml: Ditto.
+
+2006-04-14 Jean-Louis Martineau <martineau@zmanda.com>
+ * client-src/amandad.c: Use %p to printf pointer.
2006-04-14 Jean-Louis Martineau <martineau@zmanda.com>
* server-src/amtape.c: Add update command.
+2006-04-11 Jean-Louis Martineau <martineau@zmanda.com>
+ * server-src/taper.c: log_add(L_WARNING) the output of taper_scan if
+ no valid tape are found.
+
+2006-04-11 Jean-Louis Martineau <martineau@zmanda.com>
+ * server-src/amcheck.c: Call taper_scan with
+ (..., FILE_taperscan_output_callback,outf) arguments.
+ * server-src/amtape.c: Call taper_scan with
+ (..., FILE_taperscan_output_callback,stderr) arguments.
+ * server-src/taper.c: Call taper_scan with
+ (..., CHAR_taperscan_output_callback, &error_msg) arguments.
+ * server-src/taperscan.h(FILE_taperscan_output_callback,
+ CHAR_taperscan_output_callback): Protoype.
+ * server-src/taperscan.h(taper_scan): New protoype, remove
+ error_message arg, add taperscan_output_callback and data arg.
+ * server-src/taperscan.c(FILE_taperscan_output_callback): Callback
+ that print the msg to it's arg, which is FILE*.
+ * server-src/taperscan.c(CHAR_taperscan_output_callback): Callback
+ that append the msg to it's arg, which is char*.
+ * server-src/taperscan.c(taper_scan): Fix for new arguments.
+ * server-src/taperscan.c(changer_taper_scan): Fix for new arguments.
+
+2006-04-11 Jean-Louis Martineau <martineau@zmanda.com>
+ * man/xml-source/amanda.conf.5.xml: Document amandad_path and
+ client_username dumptype option.
+
2006-04-11 Jean-Louis Martineau <martineau@zmanda.com>
* common-src/krb4-security.c: Increase timeout to 60 seconds.
* common-src/rsh-security.c: Increase timeout to 60 seconds.
* common-src/ssh-security.c: Increase timeout to 60 seconds.
+2006-04-07 Jean-Louis Martineau <martineau@zmanda.com>
+ * server-src/conffile.c: New configuration option usetimestamps.
+ * server-src/conffile.h: New configuration option usetimestamps.
+ * example/amanda.conf.in: Document new usetimestamps options.
+ * man/xml-source/amanda.conf.5.xml: Document new usetimestamps options.
+ * server-src/amflush.c: Use datestamp or timestamp depending of
+ usetimesstamps.
+ * server-src/planner.c: Use datestamp or timestamp depending of
+ usetimesstamps.
+ * server-src/driver.c: Log an ERROR if many run a day and
+ usetimestamps us set to no.
+
+2006-04-07 Ian Turner <ian@zmanda.com>
+ * server-src/changer.c: Don't crash if we go to taperscan "Plan
+ B".
+
+2006-04-07 Ian Turner <ian@zmanda.com>
+ * server-src/changer.c: Only print changer debug messages if
+ there was a problem.
+
+2006-04-07 Ian Turner <ian@zmanda.com>
+ * recover-src/amrecover.c: Print a more helpful command if mount
+ point autodetection fails.
+ * recover-src/display_commands.c: Print a more helpful message
+ if the user tries to ls without having setdisk earlier.
+
+2006-04-07 Jean-Louis Martineau <martineau@zmanda.com>
+ * server-src/amadmin.c: Fix use of datestamp as int.
+ * server-src/find.c: Ditto.
+ * server-src/reporter.c: Ditto.
+ * server-src/tapefile.c: Ditto.
+
+2006-04-07 Jean-Louis Martineau <martineau@zmanda.com>
+ * common-src/Makefile.am: Fix dependency between genversion and
+ versuff.o.
+
+2006-04-07 Jean-Louis Martineau <martineau@zmanda.com>
+ * recover-src/amrecover.c: Change initialization of server_name and
+ tape_server_name.
+
2006-04-07 Jean-Louis Martineau <martineau@zmanda.com>
* restore-src/amrestore.c: reset count_error to 0 on a restore.
+2006-04-06 Kevin Till <ktill@zmanda.com>
+ * server-src/Makefile.am: always install planner/dumper setuid-root
+ * server-src/amcheck.c: check planner/dumper for setuid-root
+ * server-src/dumper.c: drop privilege asap. Switch between bsd
+ and ssh auth is now possible with the same installation.
+ * server-src/planner.c: ditto
+
+2006-04-06 Jean-Louis Martineau <martineau@zmanda.com>
+ * server-src/taperscan.c (changer_taper_scan): Pass a pointer to the
+ changer_loadslot call.
+
+2006-04-06 Jean-Louis Martineau <martineau@zmanda.com>
+ * server-src/tapefile.c (lookup_last_reusable_tape): Fix a datestamp
+ test with an int.
+
+2006-04-06 Ian Turner <vectro@vectro.org>
+ * recover-src/amrecover.c (main): Check AMANDA_SERVER and
+ AMANDA_TAPE_SERVER environment variables before falling back
+ to compiled-in defaults. Document this new behavior. Thanks to
+ Malcolm Locke <malc@hoodee.co.uk> for the idea and patch.
+
+2006-04-06 Jean-Louis Martineau <martineau@zmanda.com>
+ * server-src/reporter.c (handle_chunk): CHUNK line always have the
+ datestamp.
+
+2006-04-05 Jean-Louis Martineau <martineau@zmanda.com>
+ * server-src/krb5-security.c: Fix for krb5_connect call in
+ open_callback.
+
+2006-04-05 Jean-Louis Martineau <martineau@zmanda.com>
+ * server-src/driver.c (start_some_dumps): Recover correctly if the
+ chunker reply with something that is not a PORT command.
+ * server-src/driver.c (dump_to_tape): remove duplicate free_serial.
+ * server-src/driverio.c: Improve debugging.
+
+2006-04-05 Jean-Louis Martineau <martineau@zmanda.com>
+ * common-src/tapelist.c(unmarshal_tapelist_str): Fix
+ "value computed is not used" compiler warning.
+
+2006-04-05 Jean-Louis Martineau <martineau@zmanda.com>
+ * common-src/bsd-security.c (bsd_connect): New datap argument.
+ * common-src/krb4-security.c (krb4_connect): New datap argument.
+ * common-src/krb5-security.c (krb5_connect): New datap argument.
+ * common-src/rsh-security.c (rsh_connect): New datap argument,
+ retrieve amanda_path and client_username from configuration.
+ * common-src/ssh-security.c (ssh_connect): New datap argument,
+ retrieve amanda_path and client_username from configuration.
+ * common-src/protocol.c: Pass new datap argument to security_connect.
+ * common-src/security.h(connect): New prototype.
+ * common-src/security.h(security_connect): Add datap to macro.
+ * server-src/amadmin.c(disklist_one): Print amandad_path and
+ client_username.
+ * server-src/conffile.c(AMANDAD_PATH, CLIENT_USERNAME): Parse new
+ dumptype option.
+ * server-src/conffile.h(dumptype_t): Add amandad_path and
+ client_username.
+ * server-src/diskfile.c(parse_diskline): Copy new field.
+ * server-src/diskfile.h(disk_t) Add amandad_path and client_username.
+ * server-src/driverio.c(dumper_cmd): Send dp->amandad_path and
+ dp->client_username in a PORT_DUMP command to the dumper.
+ * server-src/dumper.c: Parse amandad_path and client_username in a
+ PORT_DUMP command.
+ * server-src/dumper.c(dumper_get_security_conf): New function to return
+ configuration option to the security-api.
+ * server-src/dumper.c: Use dumper_get_security_conf for the callback
+ to protocol_sendreq.
+ * server-src/planner.c Use amhost_get_security_conf for the callback
+ to protocol_sendreq.
+ * server-src/amcheck.c: Use amhost_get_security_conf for the callback
+ to protocol_sendreq.
+ * server-src/server_util.c(amhost_get_security_conf): New function to
+ return configuration option to the security-api,
+ it expect an am_host_t arg.
+ * server-src/server_util.h(amhost_get_security_conf): Prototype.
+
+2006-04-05 Jean-Louis Martineau <martineau@zmanda.com>
+ * server-src/amstatus.pl.in: Remove duplicate instruction.
+
+2006-04-05 Jean-Louis Martineau <martineau@zmanda.com>
+ * server-src/amindexd.c: Remove all code that set str_buffer_size,
+ rename str_buffer_size to reply_buffer_size,
+ rename buf to reply_buffer,
+ * server-src/amindexd.c(reply, lreply_backend): Increase reply_buffer
+ size if required.
+
+2006-04-05 Jean-Louis Martineau <martineau@zmanda.com>
+ * common-src/amfeatures.h: Add fe_amrecover_timestamp amfeature.
+ * common-src/amfeatures.c (am_init_feature_set):
+ Add fe_amrecover_timestamp.
+ * server-src/amindexd.c(opaque_ls_one): New function.
+ * server-src/amindexd.c(disk_history_list,opaque_ls_one): Send only a
+ datestamp if client doesn't have fe_amrecover_timestamp.
+
+2006-04-05 Jean-Louis Martineau <martineau@zmanda.com>
+ * recover-src/uscan.l: Parse "setdate YYYY-MM-DD-HH-MM-SS".
+ * server-src/amindexd.c (cmp_date): New function to cmp datestamp with
+ timestamp, use it where needed.
+ * server-src/amindexd.c (amindexd_nicedate): Fix for timestamp.
+ * server-src/amtrmidx.c: Fix for timestamp.
+ * server-src/disk_history.h (DUMP_ITEM): Increase size of date.
+
+2006-04-05 Jean-Louis Martineau <martineau@zmanda.com>
+ * server-src/amflush.c: Send DATE line to driver, use timestamp.
+ * server-src/amindex.c (getindexfname): Increase datebuf size.
+ * server-src/amtrmlog.c: Fix bug with date_keep computation if
+ dumpcycle is INF.
+ * server-src/amtrmlog.c: rotate timestamped log file.
+ * server-src/chunker.c: Receive START cmd, use timestamp.
+ * server-src/driver.c: Receive DATE line, send START cmd to chunker,
+ use timestamp.
+ * server-src/driverio.c (startup_dump_processes): Send START cmd to
+ dumper.
+ * server-src/driverio.c (dumper_cmd, chunker_cmd): Send START command.
+ * server-src/driverio.h (startup_dump_processes): Prototype change,
+ need the timestamp.
+ * server-src/dumper.c: Receive START cmd, use timestamp.
+ * server-src/find.c (find_nicedate): Fix for timestamp.
+ * server-src/planner.c: Send DATE line to driver, use timestamp.
+ * server-src/server_util.c (cmdstr): Add START.
+ * server-src/server_util.h (cmd_t): Add START.
+ * server-src/taper.c: Get timestamp from TAPER_START command.
+
+2006-04-05 Jean-Louis Martineau <martineau@zmanda.com>
+ * server-src/amindexd.c (amindexd_nicedate): New function.
+ * server-src/find.h (struct find_result_s): Remove datestamp and
+ datestamp_aux field, only timestamp will be used.
+ * restore-src/amfetchdump.c: Convert datestamp to 'char *'.
+ * restore-src/restore.c: Convert datestamp to 'char *'.
+ * server-src/amindexd.c: Convert datestamp to 'char *'.
+ * server-src/amlabel.c: Convert datestamp to 'char *'.
+ * server-src/amtrmidx.c: Convert datestamp to 'char *'.
+ * server-src/find.c: Convert datestamp to 'char *'.
+ * server-src/reporter.c: Convert datestamp to 'char *'.
+ * server-src/tapefile.c: Convert datestamp to 'char *'.
+ * server-src/tapefile.h: Convert datestamp to 'char *'.
+ * server-src/taper.c: Convert datestamp to 'char *'.
+
+2006-04-05 Jean-Louis Martineau <martineau@zmanda.com>
+ * configure.in: AM_INIT_AUTOMAKE(amanda, 2.5.1b1).
+
2006-04-05 Jean-Louis Martineau <martineau@zmanda.com>
* server-src/driver.c: Change expression to remove overflow.
* restore-src/restore.c: Fix errors found using Coverity tools.
2006-03-09 Jean-Louis Martineau <martineau@zmanda.com>
- * server-src/holding.c: Fix John fix.
+ * server-src/holding.c: Fix errors found using Coverity tools.
2006-03-09 Jean-Louis Martineau <martineau@zmanda.com>
* server-src/driverio.c: Fix errors found using Coverity tools.
- * server-src/planner.c: Fix John fix.
+ * server-src/planner.c: Fix errors found using Coverity tools.
2006-03-09 John Franks <jrfranks@zmanda.com>
* changer-src/chg-scsi.c: Fix errors found using Coverity tools.
syntax, in favor of xx/-1.
2005-12-29 John Franks <jrfranks@zmanda.com>
- * Index: recover-src/display_commands.c
+ * recover-src/display_commands.c
Fix list deletion which did not update list root with NULL pointer.
Make free_dir_item() a non-recursive function to prevent stack bloat.
Fix list insertion code which inserts item in list initializes entry.
- * Index: recover-src/extract_list.c
+ * recover-src/extract_list.c
Fix to initialize lditem before using it...
Prevent multiple frees of cmd string.
Do not free err which is only initialized with static string pointers.
Fix typo which caused newstralloc() to free the wrong memory.
- * Index: server-src/amindexd.c
+ * server-src/amindexd.c
Fix Compiler warning of unused variable.
- * Index: server-src/taperscan.c
+ * server-src/taperscan.c
Fix Compiler warning of bogus format specifier.
2005-12-29 Kevin Till<ktill@zmanda.com>
RESTORE_SUBDIRS = restore-src
endif
if WANT_RECOVER
-RECOVER_SUBDIRS = recover-src
+RECOVER_SUBDIRS = recover-src oldrecover-src
endif
if WANT_AMPLOT
PLOT_SUBDIRS = amplot
SUBDIRS = \
config \
common-src \
+ amandad-src \
$(TAPE_SUBDIRS) \
$(CLIENT_SUBDIRS) \
$(SERVER_SUBDIRS) \
man docs example
pkgdata_DATA = \
+ ReleaseNotes \
COPYRIGHT \
COPYRIGHT-APACHE \
COPYRIGHT-REGEX
SNAPSHOT:
: SNAPSHOT file was removed, will reconfigure...
+lint:
+ (cd amandad-src; make lint)
+ (cd changer-src; make lint)
+ (cd client-src; make lint)
+ (cd common-src; make lint)
+ (cd oldrecover-src; make lint)
+ (cd recover-src; make lint)
+ (cd regex-src; make lint)
+ (cd restore-src; make lint)
+ (cd server-src; make lint)
+ (cd tape-src; make lint)
+
## Do not release the *.test.c sources. They get built on the fly and
## would contain a path from the distribution machine, which will just
## confuse the target user.
DATA = $(pkgdata_DATA)
ETAGS = etags
CTAGS = ctags
-DIST_SUBDIRS = config common-src tape-src client-src dumper-src \
- server-src changer-src restore-src recover-src amplot man docs \
- example
+DIST_SUBDIRS = config common-src amandad-src tape-src client-src \
+ dumper-src server-src changer-src restore-src recover-src \
+ oldrecover-src amplot man docs example
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
distdir = $(PACKAGE)-$(VERSION)
top_distdir = $(distdir)
AMANDA_TMPDIR = @AMANDA_TMPDIR@
AMDEP_FALSE = @AMDEP_FALSE@
AMDEP_TRUE = @AMDEP_TRUE@
+AMLINT = @AMLINT@
+AMLINTFLAGS = @AMLINTFLAGS@
AMPLOT_CAT_COMPRESS = @AMPLOT_CAT_COMPRESS@
AMPLOT_CAT_GZIP = @AMPLOT_CAT_GZIP@
AMPLOT_CAT_PACK = @AMPLOT_CAT_PACK@
AMPLOT_COMPRESS = @AMPLOT_COMPRESS@
AMTAR = @AMTAR@
+AM_CFLAGS = @AM_CFLAGS@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AWK = @AWK@
AWK_VAR_ASSIGNMENT_OPT = @AWK_VAR_ASSIGNMENT_OPT@
BINARY_OWNER = @BINARY_OWNER@
+BUILD_MAN_PAGES_FALSE = @BUILD_MAN_PAGES_FALSE@
+BUILD_MAN_PAGES_TRUE = @BUILD_MAN_PAGES_TRUE@
CAT = @CAT@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
@WANT_TAPE_TRUE@TAPE_SUBDIRS = tape-src
@WANT_SERVER_TRUE@SERVER_SUBDIRS = server-src changer-src
@WANT_RESTORE_TRUE@RESTORE_SUBDIRS = restore-src
-@WANT_RECOVER_TRUE@RECOVER_SUBDIRS = recover-src
+@WANT_RECOVER_TRUE@RECOVER_SUBDIRS = recover-src oldrecover-src
@WANT_AMPLOT_TRUE@PLOT_SUBDIRS = amplot
# order is significant, don't change it arbitrarily
SUBDIRS = \
config \
common-src \
+ amandad-src \
$(TAPE_SUBDIRS) \
$(CLIENT_SUBDIRS) \
$(SERVER_SUBDIRS) \
man docs example
pkgdata_DATA = \
+ ReleaseNotes \
COPYRIGHT \
COPYRIGHT-APACHE \
COPYRIGHT-REGEX
SNAPSHOT:
: SNAPSHOT file was removed, will reconfigure...
+lint:
+ (cd amandad-src; make lint)
+ (cd changer-src; make lint)
+ (cd client-src; make lint)
+ (cd common-src; make lint)
+ (cd oldrecover-src; make lint)
+ (cd recover-src; make lint)
+ (cd regex-src; make lint)
+ (cd restore-src; make lint)
+ (cd server-src; make lint)
+ (cd tape-src; make lint)
+
dist-hook:
find $(distdir)/. -name '*.test.c' -exec rm {} \;
# Tell versions [3.59,3.63) of GNU make to not export all variables.
+Changes in release 2.5.1
+
+ * Defects found by Coverity scan and Klocwork K7 analysis tools fixed.
+ * Works with GNU tar 1.15.91 - work with new gtar state file format.
+ * Open SSL encryption support
+ * Two new authentication methods: bsdtcp, bsdudp.
+ * Unlimited number of DLEs on a client with bsdtcp, rsh and ssh
+ authentication methods.
+ * Recovery process amrecover uses Secure API. amoldrecover command
+ (same syntax and functionality as amrecover command) is provided for
+ compatibility with old Amanda releases. amoldrecover command uses old
+ amidxtaped/amindexd protocol.
+ * Amanda debug files are separated into client/server/amandad and
+ are also classified based on Amanda configuration name.
+
+ * Amanda command changes
+ o amfetchdump -o is replaced by -O.
+ o amcheck -w option does all tests including the tape writable test.
+ Use amcheck -t -w to do only the tape writable test.
+ o -o command option to override Amanda configuration. See amanda man
+ page for details.
+ o amgetconf command doesn't write the BUGGY message when a entry
+ is not found in the configuration file.
+
+ * Amanda configuration file changes
+ o amanda.conf changes
+ + amrecover_do_fsf in amanda.conf defaults to yes
+ + amrecover_check_label in amanda.conf defaults to yes
+ + usetimestamps in amanda.conf to support multiple
+ backup runs in a calendar day.
+ + holdingdisk in amanda.conf supports new values:
+ NEVER, AUTO, REQUIRED.
+ + amandad_path, client_username and ssh_keys in
+ amanda.conf for ssh/rsh authentication.
+ o New amanda client configuration file - amanda-client.conf.
+ Different client configuration file can be used for each Amanda
+ configuration.
+ + gnutar_list-dir and amandates can be specified in
+ Amanda client configuration file - amanda-client.conf
+ o .amandahosts format changes to allow use of secure API for recovery.
+ o Amanda service entries in xinetd configuration has changed.
+
+
Changes in release 2.5.0p2
-* Fix major bug in amandad.
-* amverifyeun works.
-* amstatus works with ':' in diskname.
+* listhost subcommand in amrecover
Changes in release 2.5.0p1
* Add the 'amtape update' command.
-* Many small bug fix.
Changes in release 2.5.0
--- /dev/null
+ Release Notes for amanda-2.5.1
+
+
+usetimestamps
+
+ This new feature will record all dump with timestamp instead of datestamp,
+ it will allow to do many dump in a day and recover easily anyone of them.
+
+ If you use this features, you will not be able to downgrade to 2.5.0 or
+ earlier.
+
+ see the usetimestamps section of 'man amanda.conf'
+
+
+bsdudp/bsdtcp
+
+ These are 2 new auth, they still use bsd authentification like bsd, but
+ use less port.
+
+ bsdudp is like bsd, it use udp for connecting to client but it will use
+ only one tcp port for all data stream.
+
+ bsdtcp use tcp to connect the to client and it's the only network
+ connection use. It doesn't have the udp packet size limit, so you can
+ have an unlimited number of DLE for a single host.
+
+amrecover use the security-api
+
+ amrecover now use the security-api, You don't need to configure an
+ amindexd and an amidxtaped services in your xinetd.
+ amindexd and amidxtaped will be launched by amandad like any other services.
+ You must do modification to your xinetd configuration and .amandahosts toi
+ allow connection to amindexd and amidxtaped.
+
+new format of xinetd.d/amanda
+
+ amandad get in arguments the list of services it can launch, you must add
+ theses services in the server_args options.
+
+new format of .amandahosts
+
+ You must append to each line the services this client can launch, the
+ default is "amdump"
+
+
+See the AUTHORIZATION section of the amanda man page and the
+docs/howto-auth.txt
+
--- /dev/null
+# Makefile for Amanda client programs.
+
+INCLUDES = -I$(top_builddir)/common-src \
+ -I$(top_srcdir)/common-src
+
+LINT=@AMLINT@
+LINTFLAGS=@AMLINTFLAGS@
+
+lib_LTLIBRARIES = libamandad.la
+LIB_EXTENSION = la
+
+libexec_PROGRAMS = amandad
+
+if WANT_RUNTIME_PSEUDO_RELOC
+AM_LDFLAGS = -Wl,-enable-runtime-pseudo-reloc
+endif
+
+libamandad_la_SOURCES= amandad_util.c
+libamandad_la_LDFLAGS = -release $(VERSION)
+
+noinst_HEADERS = amandad.h
+
+###
+# Because libamanda includes routines (e.g. regex) provided by some system
+# libraries, and because of the way libtool sets up the command line, we
+# need to list libamanda twice here, first to override the system library
+# routines, and second to pick up any references in the other libraries.
+###
+
+LDADD = ../common-src/libamanda.$(LIB_EXTENSION) \
+ libamandad.$(LIB_EXTENSION) \
+ ../common-src/libamanda.$(LIB_EXTENSION)
+
+install-exec-hook:
+ @list="$(libexec_PROGRAMS) $(libexec_SCRIPTS)"; \
+ for p in $$list; do \
+ pa=$(DESTDIR)$(libexecdir)/`echo $$p|sed '$(transform)'`; \
+ echo chown $(BINARY_OWNER) $$pa; \
+ chown $(BINARY_OWNER) $$pa; \
+ echo chgrp $(SETUID_GROUP) $$pa; \
+ chgrp $(SETUID_GROUP) $$pa; \
+ done
+
+lint:
+ @ for p in $(libexec_PROGRAMS); do \
+ f="$$p.c $(libamandad_la_SOURCES)"; \
+ (cd ../common-src; make listlibsrc); \
+ f="$$f "`cat ../common-src/listlibsrc.output`; \
+ (cd ../server-src; make listlibsrc); \
+ f="$$f "`cat ../server-src/listlibsrc.output`; \
+ echo $(LINT) $$f; \
+ $(LINT) $(LINTFLAGS) $(CPPFLAGS) $(DEFS) -I. -I../config \
+ $(INCLUDES) $$f; \
+ if [ $$? -ne 0 ]; then \
+ exit 1; \
+ fi; \
+ done; \
+ exit 0
+
--- /dev/null
+# Makefile.in generated by automake 1.9.6 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+# Makefile for Amanda client programs.
+
+
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+top_builddir = ..
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+INSTALL = @INSTALL@
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+libexec_PROGRAMS = amandad$(EXEEXT)
+subdir = amandad-src
+DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \
+ $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
+ $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config/config.h
+CONFIG_CLEAN_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
+am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(libexecdir)"
+libLTLIBRARIES_INSTALL = $(INSTALL)
+LTLIBRARIES = $(lib_LTLIBRARIES)
+libamandad_la_LIBADD =
+am_libamandad_la_OBJECTS = amandad_util.lo
+libamandad_la_OBJECTS = $(am_libamandad_la_OBJECTS)
+libexecPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
+PROGRAMS = $(libexec_PROGRAMS)
+amandad_SOURCES = amandad.c
+amandad_OBJECTS = amandad.$(OBJEXT)
+amandad_LDADD = $(LDADD)
+amandad_DEPENDENCIES = ../common-src/libamanda.$(LIB_EXTENSION) \
+ libamandad.$(LIB_EXTENSION) \
+ ../common-src/libamanda.$(LIB_EXTENSION)
+DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)/config
+depcomp = $(SHELL) $(top_srcdir)/config/depcomp
+am__depfiles_maybe = depfiles
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+SOURCES = $(libamandad_la_SOURCES) amandad.c
+DIST_SOURCES = $(libamandad_la_SOURCES) amandad.c
+HEADERS = $(noinst_HEADERS)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+AMANDA_DBGDIR = @AMANDA_DBGDIR@
+AMANDA_DEBUG_DAYS = @AMANDA_DEBUG_DAYS@
+AMANDA_TMPDIR = @AMANDA_TMPDIR@
+AMDEP_FALSE = @AMDEP_FALSE@
+AMDEP_TRUE = @AMDEP_TRUE@
+AMLINT = @AMLINT@
+AMLINTFLAGS = @AMLINTFLAGS@
+AMPLOT_CAT_COMPRESS = @AMPLOT_CAT_COMPRESS@
+AMPLOT_CAT_GZIP = @AMPLOT_CAT_GZIP@
+AMPLOT_CAT_PACK = @AMPLOT_CAT_PACK@
+AMPLOT_COMPRESS = @AMPLOT_COMPRESS@
+AMTAR = @AMTAR@
+AM_CFLAGS = @AM_CFLAGS@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+AWK_VAR_ASSIGNMENT_OPT = @AWK_VAR_ASSIGNMENT_OPT@
+BINARY_OWNER = @BINARY_OWNER@
+BUILD_MAN_PAGES_FALSE = @BUILD_MAN_PAGES_FALSE@
+BUILD_MAN_PAGES_TRUE = @BUILD_MAN_PAGES_TRUE@
+CAT = @CAT@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CHIO = @CHIO@
+CHS = @CHS@
+CLIENT_LOGIN = @CLIENT_LOGIN@
+CLIENT_SCRIPTS_OPT = @CLIENT_SCRIPTS_OPT@
+COMPRESS = @COMPRESS@
+CONFIGURE_COMMAND = @CONFIGURE_COMMAND@
+CONFIG_DIR = @CONFIG_DIR@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DB_EXT = @DB_EXT@
+DD = @DD@
+DEFAULT_CHANGER_DEVICE = @DEFAULT_CHANGER_DEVICE@
+DEFAULT_CONFIG = @DEFAULT_CONFIG@
+DEFAULT_RAW_TAPE_DEVICE = @DEFAULT_RAW_TAPE_DEVICE@
+DEFAULT_SERVER = @DEFAULT_SERVER@
+DEFAULT_TAPE_DEVICE = @DEFAULT_TAPE_DEVICE@
+DEFAULT_TAPE_SERVER = @DEFAULT_TAPE_SERVER@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DOC_BUILD_DATE = @DOC_BUILD_DATE@
+DUMP = @DUMP@
+DUMPER_DIR = @DUMPER_DIR@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+GETCONF = @GETCONF@
+GNUPLOT = @GNUPLOT@
+GNUTAR = @GNUTAR@
+GNUTAR_LISTED_INCREMENTAL_DIR = @GNUTAR_LISTED_INCREMENTAL_DIR@
+GNUTAR_LISTED_INCREMENTAL_DIRX = @GNUTAR_LISTED_INCREMENTAL_DIRX@
+GREP = @GREP@
+GZIP = @GZIP@
+HAVE_XSLTPROC_FALSE = @HAVE_XSLTPROC_FALSE@
+HAVE_XSLTPROC_TRUE = @HAVE_XSLTPROC_TRUE@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIBTOOL_DEPS = @LIBTOOL_DEPS@
+LL_FMT = @LL_FMT@
+LN_S = @LN_S@
+LTALLOCA = @LTALLOCA@
+LTLIBOBJS = @LTLIBOBJS@
+MAILER = @MAILER@
+MAKEINFO = @MAKEINFO@
+MAXTAPEBLOCKSIZE = @MAXTAPEBLOCKSIZE@
+MCUTIL = @MCUTIL@
+MT = @MT@
+MTX = @MTX@
+MT_FILE_FLAG = @MT_FILE_FLAG@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PCAT = @PCAT@
+PERL = @PERL@
+PRINT = @PRINT@
+RANLIB = @RANLIB@
+READLINE_LIBS = @READLINE_LIBS@
+RESTORE = @RESTORE@
+SAMBA_CLIENT = @SAMBA_CLIENT@
+SERVICE_SUFFIX = @SERVICE_SUFFIX@
+SETUID_GROUP = @SETUID_GROUP@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SNAPSHOT_STAMP = @SNAPSHOT_STAMP@
+STRIP = @STRIP@
+USE_VERSION_SUFFIXES = @USE_VERSION_SUFFIXES@
+VDUMP = @VDUMP@
+VERSION = @VERSION@
+VERSION_COMMENT = @VERSION_COMMENT@
+VERSION_MAJOR = @VERSION_MAJOR@
+VERSION_MINOR = @VERSION_MINOR@
+VERSION_PATCH = @VERSION_PATCH@
+VERSION_SUFFIX = @VERSION_SUFFIX@
+VRESTORE = @VRESTORE@
+VXDUMP = @VXDUMP@
+VXRESTORE = @VXRESTORE@
+WANT_AMPLOT_FALSE = @WANT_AMPLOT_FALSE@
+WANT_AMPLOT_TRUE = @WANT_AMPLOT_TRUE@
+WANT_CHG_SCSI_FALSE = @WANT_CHG_SCSI_FALSE@
+WANT_CHG_SCSI_TRUE = @WANT_CHG_SCSI_TRUE@
+WANT_CHIO_SCSI_FALSE = @WANT_CHIO_SCSI_FALSE@
+WANT_CHIO_SCSI_TRUE = @WANT_CHIO_SCSI_TRUE@
+WANT_CLIENT_FALSE = @WANT_CLIENT_FALSE@
+WANT_CLIENT_TRUE = @WANT_CLIENT_TRUE@
+WANT_RECOVER_FALSE = @WANT_RECOVER_FALSE@
+WANT_RECOVER_TRUE = @WANT_RECOVER_TRUE@
+WANT_RESTORE_FALSE = @WANT_RESTORE_FALSE@
+WANT_RESTORE_TRUE = @WANT_RESTORE_TRUE@
+WANT_RUNTIME_PSEUDO_RELOC_FALSE = @WANT_RUNTIME_PSEUDO_RELOC_FALSE@
+WANT_RUNTIME_PSEUDO_RELOC_TRUE = @WANT_RUNTIME_PSEUDO_RELOC_TRUE@
+WANT_SAMBA_FALSE = @WANT_SAMBA_FALSE@
+WANT_SAMBA_TRUE = @WANT_SAMBA_TRUE@
+WANT_SERVER_FALSE = @WANT_SERVER_FALSE@
+WANT_SERVER_TRUE = @WANT_SERVER_TRUE@
+WANT_SETUID_CLIENT_FALSE = @WANT_SETUID_CLIENT_FALSE@
+WANT_SETUID_CLIENT_TRUE = @WANT_SETUID_CLIENT_TRUE@
+WANT_SSH_SECURITY_FALSE = @WANT_SSH_SECURITY_FALSE@
+WANT_SSH_SECURITY_TRUE = @WANT_SSH_SECURITY_TRUE@
+WANT_TAPE_FALSE = @WANT_TAPE_FALSE@
+WANT_TAPE_TRUE = @WANT_TAPE_TRUE@
+XFSDUMP = @XFSDUMP@
+XFSRESTORE = @XFSRESTORE@
+XSLTPROC = @XSLTPROC@
+YACC = @YACC@
+ac_c = @ac_c@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
+ac_ct_RANLIB = @ac_ct_RANLIB@
+ac_ct_STRIP = @ac_ct_STRIP@
+ac_n = @ac_n@
+am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
+am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
+am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
+am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+datadir = @datadir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+INCLUDES = -I$(top_builddir)/common-src \
+ -I$(top_srcdir)/common-src
+
+LINT = @AMLINT@
+LINTFLAGS = @AMLINTFLAGS@
+lib_LTLIBRARIES = libamandad.la
+LIB_EXTENSION = la
+@WANT_RUNTIME_PSEUDO_RELOC_TRUE@AM_LDFLAGS = -Wl,-enable-runtime-pseudo-reloc
+libamandad_la_SOURCES = amandad_util.c
+libamandad_la_LDFLAGS = -release $(VERSION)
+noinst_HEADERS = amandad.h
+
+###
+# Because libamanda includes routines (e.g. regex) provided by some system
+# libraries, and because of the way libtool sets up the command line, we
+# need to list libamanda twice here, first to override the system library
+# routines, and second to pick up any references in the other libraries.
+###
+LDADD = ../common-src/libamanda.$(LIB_EXTENSION) \
+ libamandad.$(LIB_EXTENSION) \
+ ../common-src/libamanda.$(LIB_EXTENSION)
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu amandad-src/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu amandad-src/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+install-libLTLIBRARIES: $(lib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ test -z "$(libdir)" || $(mkdir_p) "$(DESTDIR)$(libdir)"
+ @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+ if test -f $$p; then \
+ f=$(am__strip_dir) \
+ echo " $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(libdir)/$$f'"; \
+ $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(libdir)/$$f"; \
+ else :; fi; \
+ done
+
+uninstall-libLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @set -x; list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+ p=$(am__strip_dir) \
+ echo " $(LIBTOOL) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$p'"; \
+ $(LIBTOOL) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$p"; \
+ done
+
+clean-libLTLIBRARIES:
+ -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
+ @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+libamandad.la: $(libamandad_la_OBJECTS) $(libamandad_la_DEPENDENCIES)
+ $(LINK) -rpath $(libdir) $(libamandad_la_LDFLAGS) $(libamandad_la_OBJECTS) $(libamandad_la_LIBADD) $(LIBS)
+install-libexecPROGRAMS: $(libexec_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ test -z "$(libexecdir)" || $(mkdir_p) "$(DESTDIR)$(libexecdir)"
+ @list='$(libexec_PROGRAMS)'; for p in $$list; do \
+ p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
+ if test -f $$p \
+ || test -f $$p1 \
+ ; then \
+ f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \
+ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(libexecPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(libexecdir)/$$f'"; \
+ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(libexecPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(libexecdir)/$$f" || exit 1; \
+ else :; fi; \
+ done
+
+uninstall-libexecPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(libexec_PROGRAMS)'; for p in $$list; do \
+ f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \
+ echo " rm -f '$(DESTDIR)$(libexecdir)/$$f'"; \
+ rm -f "$(DESTDIR)$(libexecdir)/$$f"; \
+ done
+
+clean-libexecPROGRAMS:
+ @list='$(libexec_PROGRAMS)'; for p in $$list; do \
+ f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f $$p $$f"; \
+ rm -f $$p $$f ; \
+ done
+amandad$(EXEEXT): $(amandad_OBJECTS) $(amandad_DEPENDENCIES)
+ @rm -f amandad$(EXEEXT)
+ $(LINK) $(amandad_LDFLAGS) $(amandad_OBJECTS) $(amandad_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/amandad.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/amandad_util.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ if $(LTCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+distclean-libtool:
+ -rm -f libtool
+uninstall-info-am:
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
+ list='$(DISTFILES)'; for file in $$list; do \
+ case $$file in \
+ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
+ esac; \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+ dir="/$$dir"; \
+ $(mkdir_p) "$(distdir)$$dir"; \
+ else \
+ dir=''; \
+ fi; \
+ if test -d $$d/$$file; then \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(HEADERS)
+installdirs:
+ for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(libexecdir)"; do \
+ test -z "$$dir" || $(mkdir_p) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libLTLIBRARIES clean-libexecPROGRAMS \
+ clean-libtool mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-libtool distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-exec-am: install-libLTLIBRARIES install-libexecPROGRAMS
+ @$(NORMAL_INSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) install-exec-hook
+
+install-info: install-info-am
+
+install-man:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-info-am uninstall-libLTLIBRARIES \
+ uninstall-libexecPROGRAMS
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libLTLIBRARIES clean-libexecPROGRAMS clean-libtool ctags \
+ distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-exec install-exec-am install-exec-hook \
+ install-info install-info-am install-libLTLIBRARIES \
+ install-libexecPROGRAMS install-man install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags uninstall uninstall-am uninstall-info-am \
+ uninstall-libLTLIBRARIES uninstall-libexecPROGRAMS
+
+
+install-exec-hook:
+ @list="$(libexec_PROGRAMS) $(libexec_SCRIPTS)"; \
+ for p in $$list; do \
+ pa=$(DESTDIR)$(libexecdir)/`echo $$p|sed '$(transform)'`; \
+ echo chown $(BINARY_OWNER) $$pa; \
+ chown $(BINARY_OWNER) $$pa; \
+ echo chgrp $(SETUID_GROUP) $$pa; \
+ chgrp $(SETUID_GROUP) $$pa; \
+ done
+
+lint:
+ @ for p in $(libexec_PROGRAMS); do \
+ f="$$p.c $(libamandad_la_SOURCES)"; \
+ (cd ../common-src; make listlibsrc); \
+ f="$$f "`cat ../common-src/listlibsrc.output`; \
+ (cd ../server-src; make listlibsrc); \
+ f="$$f "`cat ../server-src/listlibsrc.output`; \
+ echo $(LINT) $$f; \
+ $(LINT) $(LINTFLAGS) $(CPPFLAGS) $(DEFS) -I. -I../config \
+ $(INCLUDES) $$f; \
+ if [ $$? -ne 0 ]; then \
+ exit 1; \
+ fi; \
+ done; \
+ exit 0
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
--- /dev/null
+/*
+ * Amanda, The Advanced Maryland Automatic Network Disk Archiver
+ * Copyright (c) 1991-1999 University of Maryland at College Park
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of U.M. not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. U.M. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: the Amanda Development Team. Its members are listed in a
+ * file named AUTHORS, in the root directory of this distribution.
+ */
+
+/*
+ * $Id: amandad.c,v 1.18 2006/08/21 20:17:09 martinea Exp $
+ *
+ * handle client-host side of Amanda network communications, including
+ * security checks, execution of the proper service, and acking the
+ * master side
+ */
+
+/*#define AMANDAD_DEBUG*/
+
+#include "amanda.h"
+#include "amandad.h"
+#include "clock.h"
+#include "event.h"
+#include "amfeatures.h"
+#include "packet.h"
+#include "version.h"
+#include "queue.h"
+#include "security.h"
+#include "stream.h"
+#include "util.h"
+
+#define REP_TIMEOUT (6*60*60) /* secs for service to reply */
+#define ACK_TIMEOUT 10 /* XXX should be configurable */
+#define MAX_REP_RETRIES 5
+
+/*
+ * These are the actions for entering the state machine
+ */
+typedef enum { A_START, A_RECVPKT, A_RECVREP, A_PENDING, A_FINISH, A_CONTINUE,
+ A_SENDNAK, A_TIMEOUT } action_t;
+
+/*
+ * This is a state in the state machine. It is a function pointer to
+ * the function that actually implements the state.
+ */
+struct active_service;
+typedef action_t (*state_t)(struct active_service *, action_t, pkt_t *);
+
+/*
+ * This structure describes an active running service.
+ *
+ * An active service is something running that we have received
+ * a request for. This structure holds info on that service, including
+ * file descriptors for data, etc, as well as the security handle
+ * for communications with the amanda server.
+ */
+struct active_service {
+ char *cmd; /* name of command we ran */
+ char *arguments; /* arguments we sent it */
+ security_handle_t *security_handle; /* remote server */
+ state_t state; /* how far this has progressed */
+ pid_t pid; /* pid of subprocess */
+ int send_partial_reply; /* send PREP packet */
+ int reqfd; /* pipe to write requests */
+ int repfd; /* pipe to read replies */
+ event_handle_t *ev_repfd; /* read event handle for repfd */
+ event_handle_t *ev_reptimeout; /* timeout for rep data */
+ pkt_t rep_pkt; /* rep packet we're sending out */
+ char *repbuf; /* buffer to read the rep into */
+ size_t bufsize; /* length of repbuf */
+ size_t repbufsize; /* length of repbuf */
+ int repretry; /* times we'll retry sending the rep */
+ /*
+ * General user streams to the process, and their equivalent
+ * network streams.
+ */
+ struct datafd_handle {
+ int fd_read; /* pipe to child process */
+ int fd_write; /* pipe to child process */
+ event_handle_t *ev_read; /* it's read event handle */
+ event_handle_t *ev_write; /* it's write event handle */
+ security_stream_t *netfd; /* stream to amanda server */
+ struct active_service *as; /* pointer back to our enclosure */
+ } data[DATA_FD_COUNT];
+ char databuf[NETWORK_BLOCK_BYTES]; /* buffer to relay netfd data in */
+ TAILQ_ENTRY(active_service) tq; /* queue handle */
+};
+
+/*
+ * Here are the services that we allow.
+ */
+static struct services {
+ char *name;
+ int active;
+} services[] = {
+ { "noop", 1 },
+ { "sendsize", 1 },
+ { "sendbackup", 1 },
+ { "selfcheck", 1 },
+ { "amindexd", 0 },
+ { "amidxtaped", 0 }
+};
+#define NSERVICES (int)(sizeof(services) / sizeof(services[0]))
+
+/*
+ * Queue of outstanding requests that we are running.
+ */
+static struct {
+ TAILQ_HEAD(, active_service) tailq;
+ int qlength;
+} serviceq = {
+ TAILQ_HEAD_INITIALIZER(serviceq.tailq), 0
+};
+
+/*
+ * Data for dbmalloc to check for memory leaks
+ */
+#ifdef USE_DBMALLOC
+static struct {
+ struct {
+ unsigned long size, hist;
+ } start, end;
+} dbmalloc_info;
+#endif
+
+static int wait_30s = 1;
+static int exit_on_qlength = 1;
+static char *auth = NULL;
+
+int main(int argc, char **argv);
+
+static int allocstream(struct active_service *, int);
+static void exit_check(void *);
+static void protocol_accept(security_handle_t *, pkt_t *);
+static void state_machine(struct active_service *, action_t, pkt_t *);
+
+static action_t s_sendack(struct active_service *, action_t, pkt_t *);
+static action_t s_repwait(struct active_service *, action_t, pkt_t *);
+static action_t s_processrep(struct active_service *, action_t, pkt_t *);
+static action_t s_sendrep(struct active_service *, action_t, pkt_t *);
+static action_t s_ackwait(struct active_service *, action_t, pkt_t *);
+
+static void repfd_recv(void *);
+static void timeout_repfd(void *);
+static void protocol_recv(void *, pkt_t *, security_status_t);
+static void process_readnetfd(void *);
+static void process_writenetfd(void *, void *, ssize_t);
+static struct active_service *service_new(security_handle_t *,
+ const char *, const char *);
+static void service_delete(struct active_service *);
+static int writebuf(struct active_service *, const void *, size_t);
+static ssize_t do_sendpkt(security_handle_t *handle, pkt_t *pkt);
+
+static void child_signal(int signal);
+
+#ifdef AMANDAD_DEBUG
+static const char *state2str(state_t);
+static const char *action2str(action_t);
+#endif
+
+/*
+ * Harvests defunct processes...
+ */
+
+static void
+child_signal(
+ int signal)
+{
+ pid_t rp;
+
+ (void)signal; /* Quite compiler warning */
+ /*
+ * Reap and child status and promptly ignore since we don't care...
+ */
+ do {
+ rp = waitpid(-1, NULL, WNOHANG);
+ } while (rp > 0);
+}
+
+int
+main(
+ int argc,
+ char ** argv)
+{
+ int i, j;
+ int have_services;
+ int in, out;
+ const security_driver_t *secdrv;
+ int no_exit = 0;
+ struct sigaction act, oact;
+ char *pgm = "amandad"; /* in case argv[0] is not set */
+#if defined(AMANDAD_DEBUG) && defined(USE_REUSEADDR)
+ const int on = 1;
+ int r;
+#endif
+
+ safe_fd(-1, 0);
+ safe_cd();
+
+ /*
+ * When called via inetd, it is not uncommon to forget to put the
+ * argv[0] value on the config line. On some systems (e.g. Solaris)
+ * this causes argv and/or argv[0] to be NULL, so we have to be
+ * careful getting our name.
+ */
+ if ((argv == NULL) || (argv[0] == NULL)) {
+ pgm = "amandad"; /* in case argv[0] is not set */
+ } else {
+ pgm = basename(argv[0]); /* Strip of leading path get debug name */
+ }
+ set_pname(pgm);
+ dbopen(DBG_SUBDIR_AMANDAD);
+
+ if(argv == NULL) {
+ error("argv == NULL\n");
+ /*NOTREACHED*/
+ }
+
+ /* Don't die when child closes pipe */
+ signal(SIGPIPE, SIG_IGN);
+
+ /* Tell me when a child exits or dies... */
+ act.sa_handler = child_signal;
+ sigemptyset(&act.sa_mask);
+ act.sa_flags = 0;
+ if(sigaction(SIGCHLD, &act, &oact) != 0) {
+ error("error setting SIGCHLD handler: %s", strerror(errno));
+ /*NOTREACHED*/
+ }
+
+#ifdef USE_DBMALLOC
+ dbmalloc_info.start.size = malloc_inuse(&dbmalloc_info.start.hist);
+#endif
+
+ erroutput_type = (ERR_INTERACTIVE|ERR_SYSLOG);
+
+#ifdef FORCE_USERID
+ /* we'd rather not run as root */
+ if (geteuid() == 0) {
+ if(client_uid == (uid_t) -1) {
+ error("error [cannot find user %s in passwd file]\n", CLIENT_LOGIN);
+ /*NOTREACHED*/
+ }
+ initgroups(CLIENT_LOGIN, client_gid);
+ setgid(client_gid);
+ setegid(client_gid);
+ seteuid(client_uid);
+ }
+#endif /* FORCE_USERID */
+
+ /*
+ * ad-hoc argument parsing
+ *
+ * We accept -auth=[authentication type]
+ * -no-exit
+#ifdef AMANDAD_DEBUG
+ * -tcp=[port]
+ * -udp=[port]
+#endif
+ * We also add a list of services that amandad can launch
+ */
+ secdrv = NULL;
+ in = 0; out = 1; /* default to stdin/stdout */
+ have_services = 0;
+ for (i = 1; i < argc; i++) {
+ /*
+ * accept -krb4 as an alias for -auth=krb4 (for compatibility)
+ */
+ if (strcmp(argv[i], "-krb4") == 0) {
+ argv[i] = "-auth=krb4";
+ /* FALLTHROUGH */
+ auth = "krb4";
+ }
+
+ /*
+ * Get a driver for a security type specified after -auth=
+ */
+ else if (strncmp(argv[i], "-auth=", strlen("-auth=")) == 0) {
+ argv[i] += strlen("-auth=");
+ secdrv = security_getdriver(argv[i]);
+ auth = argv[i];
+ if (secdrv == NULL) {
+ error("no driver for security type '%s'\n", argv[i]);
+ /*NOTREACHED*/
+ }
+ continue;
+ }
+
+ /*
+ * If -no-exit is specified, always run even after requests have
+ * been satisfied.
+ */
+ else if (strcmp(argv[i], "-no-exit") == 0) {
+ no_exit = 1;
+ continue;
+ }
+
+#ifdef AMANDAD_DEBUG
+ /*
+ * Allow us to directly bind to a udp port for debugging.
+ * This may only apply to some security types.
+ */
+ else if (strncmp(argv[i], "-udp=", strlen("-udp=")) == 0) {
+ struct sockaddr_in sin;
+
+ argv[i] += strlen("-udp=");
+ in = out = socket(AF_INET, SOCK_DGRAM, 0);
+ if (in < 0) {
+ error("can't create dgram socket: %s\n", strerror(errno));
+ /*NOTREACHED*/
+ }
+#ifdef USE_REUSEADDR
+ r = setsockopt(in, SOL_SOCKET, SO_REUSEADDR,
+ (void *)&on, (socklen_t)sizeof(on));
+ if (r < 0) {
+ dbprintf(("%s: amandad: setsockopt(SO_REUSEADDR) failed: %s\n",
+ debug_prefix(NULL),
+ strerror(errno)));
+ }
+#endif
+
+ sin.sin_family = (sa_family_t)AF_INET;
+ sin.sin_addr.s_addr = INADDR_ANY;
+ sin.sin_port = (in_port_t)htons((in_port_t)atoi(argv[i]));
+ if (bind(in, (struct sockaddr *)&sin, (socklen_t)sizeof(sin)) < 0) {
+ error("can't bind to port %d: %s\n", atoi(argv[i]),
+ strerror(errno));
+ /*NOTREACHED*/
+ }
+ }
+ /*
+ * Ditto for tcp ports.
+ */
+ else if (strncmp(argv[i], "-tcp=", strlen("-tcp=")) == 0) {
+ struct sockaddr_in sin;
+ int sock;
+ socklen_t n;
+
+ argv[i] += strlen("-tcp=");
+ sock = socket(AF_INET, SOCK_STREAM, 0);
+ if (sock < 0) {
+ error("can't create tcp socket: %s\n", strerror(errno));
+ /*NOTREACHED*/
+ }
+ n = 1;
+#ifdef USE_REUSEADDR
+ r = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
+ (void *)&on, (socklen_t)sizeof(on));
+ if (r < 0) {
+ dbprintf(("%s: amandad: setsockopt(SO_REUSEADDR) failed: %s\n",
+ debug_prefix(NULL),
+ strerror(errno)));
+ }
+#endif
+ setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
+ (void *)&n, (socklen_t)sizeof(n));
+ sin.sin_family = (sa_family_t)AF_INET;
+ sin.sin_addr.s_addr = INADDR_ANY;
+ sin.sin_port = (in_port_t)htons((in_port_t)atoi(argv[i]));
+ if (bind(sock, (struct sockaddr *)&sin, (socklen_t)sizeof(sin)) < 0) {
+ error("can't bind to port %d: %s\n", atoi(argv[i]),
+ strerror(errno));
+ /*NOTREACHED*/
+ }
+ listen(sock, 10);
+ n = (socklen_t)sizeof(sin);
+ in = out = accept(sock, (struct sockaddr *)&sin, &n);
+ }
+#endif
+ /*
+ * It must be a service name
+ */
+ else {
+ /* clear all services */
+ if(!have_services) {
+ for (j = 0; j < (int)NSERVICES; j++)
+ services[j].active = 0;
+ }
+ have_services = 1;
+
+ if(strcmp(argv[i],"amdump") == 0) {
+ services[0].active = 1;
+ services[1].active = 1;
+ services[2].active = 1;
+ services[3].active = 1;
+ }
+ else {
+ for (j = 0; j < (int)NSERVICES; j++)
+ if (strcmp(services[j].name, argv[i]) == 0)
+ break;
+ if (j == (int)NSERVICES) {
+ dbprintf(("%s: %s: invalid service\n",
+ debug_prefix_time(NULL), argv[i]));
+ exit(1);
+ }
+ services[j].active = 1;
+ }
+ }
+ }
+
+ /*
+ * If no security type specified, use BSD
+ */
+ if (secdrv == NULL) {
+ secdrv = security_getdriver("BSD");
+ auth = "bsd";
+ if (secdrv == NULL) {
+ error("no driver for default security type 'BSD'\n");
+ /*NOTREACHED*/
+ }
+ }
+
+ if(strcasecmp(auth, "rsh") == 0 ||
+ strcasecmp(auth, "ssh") == 0 ||
+ strcasecmp(auth, "bsdtcp") == 0) {
+ wait_30s = 0;
+ exit_on_qlength = 1;
+ }
+
+ /* initialize */
+
+ startclock();
+
+ dbprintf(("%s: version %s\n", get_pname(), version()));
+ for (i = 0; version_info[i] != NULL; i++) {
+ dbprintf(("%s: %s", debug_prefix(NULL), version_info[i]));
+ }
+
+ if (! (argc >= 1 && argv != NULL && argv[0] != NULL)) {
+ dbprintf(("%s: WARNING: argv[0] not defined: check inetd.conf\n",
+ debug_prefix(NULL)));
+ }
+
+ /*
+ * Schedule to call protocol_accept() when new security handles
+ * are created on stdin.
+ */
+ security_accept(secdrv, in, out, protocol_accept);
+
+ /*
+ * Schedule an event that will try to exit every 30 seconds if there
+ * are no requests outstanding.
+ */
+ if(wait_30s)
+ (void)event_register((event_id_t)30, EV_TIME, exit_check, &no_exit);
+
+ /*
+ * Call event_loop() with an arg of 0, telling it to block until all
+ * events are completed.
+ */
+ event_loop(0);
+
+ close(in);
+ close(out);
+ dbclose();
+ return(0);
+}
+
+/*
+ * This runs periodically and checks to see if we have any active services
+ * still running. If we don't, then we quit.
+ */
+static void
+exit_check(
+ void * cookie)
+{
+ int no_exit;
+
+ assert(cookie != NULL);
+ no_exit = *(int *)cookie;
+
+ /*
+ * If things are still running, then don't exit.
+ */
+ if (serviceq.qlength > 0)
+ return;
+
+ /*
+ * If the caller asked us to never exit, then we're done
+ */
+ if (no_exit)
+ return;
+
+#ifdef USE_DBMALLOC
+ dbmalloc_info.end.size = malloc_inuse(&dbmalloc_info.end.hist);
+
+ if (dbmalloc_info.start.size != dbmalloc_info.end.size) {
+ malloc_list(dbfd(), dbmalloc_info.start.hist,
+ dbmalloc_info.end.hist);
+ }
+#endif
+
+ dbclose();
+ exit(0);
+}
+
+/*
+ * Handles new incoming protocol handles. This is a callback for
+ * security_accept(), which gets called when new handles are detected.
+ */
+static void
+protocol_accept(
+ security_handle_t * handle,
+ pkt_t * pkt)
+{
+ pkt_t pkt_out;
+ struct active_service *as;
+ char *pktbody, *tok, *service, *arguments;
+ char *service_path = NULL;
+ int i;
+
+ pkt_out.body = NULL;
+
+ /*
+ * If handle is NULL, then the connection is closed.
+ */
+ if(handle == NULL) {
+ return;
+ }
+
+ /*
+ * If pkt is NULL, then there was a problem with the new connection.
+ */
+ if (pkt == NULL) {
+ dbprintf(("%s: accept error: %s\n",
+ debug_prefix_time(NULL), security_geterror(handle)));
+ pkt_init(&pkt_out, P_NAK, "ERROR %s\n", security_geterror(handle));
+ do_sendpkt(handle, &pkt_out);
+ amfree(pkt_out.body);
+ security_close(handle);
+ return;
+ }
+
+ dbprintf(("%s: accept recv %s pkt:\n<<<<<\n%s>>>>>\n",
+ debug_prefix_time(NULL), pkt_type2str(pkt->type), pkt->body));
+
+ /*
+ * If this is not a REQ packet, just forget about it.
+ */
+ if (pkt->type != P_REQ) {
+ dbprintf(("%s: received unexpected %s packet:\n<<<<<\n%s>>>>>\n\n",
+ debug_prefix_time(NULL), pkt_type2str(pkt->type), pkt->body));
+ security_close(handle);
+ return;
+ }
+
+ pktbody = service = arguments = NULL;
+ as = NULL;
+
+ /*
+ * Parse out the service and arguments
+ */
+
+ pktbody = stralloc(pkt->body);
+
+ tok = strtok(pktbody, " ");
+ if (tok == NULL)
+ goto badreq;
+ if (strcmp(tok, "SERVICE") != 0)
+ goto badreq;
+
+ tok = strtok(NULL, " \n");
+ if (tok == NULL)
+ goto badreq;
+ service = stralloc(tok);
+
+ /* we call everything else 'arguments' */
+ tok = strtok(NULL, "");
+ if (tok == NULL)
+ goto badreq;
+ arguments = stralloc(tok);
+
+ /* see if it's one we allow */
+ for (i = 0; i < (int)NSERVICES; i++)
+ if (services[i].active == 1 && strcmp(services[i].name, service) == 0)
+ break;
+ if (i == (int)NSERVICES) {
+ dbprintf(("%s: %s: invalid service\n",
+ debug_prefix_time(NULL), service));
+ pkt_init(&pkt_out, P_NAK, "ERROR %s: invalid service\n", service);
+ goto send_pkt_out;
+ }
+
+ service_path = vstralloc(libexecdir, "/", service, versionsuffix(), NULL);
+ if (access(service_path, X_OK) < 0) {
+ dbprintf(("%s: can't execute %s: %s\n",
+ debug_prefix_time(NULL), service_path, strerror(errno)));
+ pkt_init(&pkt_out, P_NAK,
+ "ERROR execute access to \"%s\" denied\n",
+ service_path);
+ goto send_pkt_out;
+ }
+
+ /* see if its already running */
+ for (as = TAILQ_FIRST(&serviceq.tailq); as != NULL;
+ as = TAILQ_NEXT(as, tq)) {
+ if (strcmp(as->cmd, service_path) == 0 &&
+ strcmp(as->arguments, arguments) == 0) {
+ dbprintf(("%s: %s %s: already running, acking req\n",
+ debug_prefix_time(NULL), service, arguments));
+ pkt_init(&pkt_out, P_ACK, "");
+ goto send_pkt_out_no_delete;
+ }
+ }
+
+ /*
+ * create a new service instance, and send the arguments down
+ * the request pipe.
+ */
+ dbprintf(("%s: creating new service: %s\n%s\n",
+ debug_prefix_time(NULL), service, arguments));
+ as = service_new(handle, service_path, arguments);
+ if (writebuf(as, arguments, strlen(arguments)) < 0) {
+ const char *errmsg = strerror(errno);
+ dbprintf(("%s: error sending arguments to %s: %s\n",
+ debug_prefix_time(NULL), service, errmsg));
+ pkt_init(&pkt_out, P_NAK, "ERROR error writing arguments to %s: %s\n",
+ service, errmsg);
+ goto send_pkt_out;
+ }
+ aclose(as->reqfd);
+
+ amfree(pktbody);
+ amfree(service);
+ amfree(service_path);
+ amfree(arguments);
+
+ /*
+ * Move to the sendack state, and start up the state
+ * machine.
+ */
+ as->state = s_sendack;
+ state_machine(as, A_START, NULL);
+ return;
+
+badreq:
+ pkt_init(&pkt_out, P_NAK, "ERROR invalid REQ\n");
+ dbprintf(("%s: received invalid %s packet:\n<<<<<\n%s>>>>>\n\n",
+ debug_prefix_time(NULL), pkt_type2str(pkt->type), pkt->body));
+
+send_pkt_out:
+ if(as)
+ service_delete(as);
+send_pkt_out_no_delete:
+ amfree(pktbody);
+ amfree(service_path);
+ amfree(service);
+ amfree(arguments);
+ do_sendpkt(handle, &pkt_out);
+ security_close(handle);
+ amfree(pkt_out.body);
+}
+
+/*
+ * Handles incoming protocol packets. Routes responses to the proper
+ * running service.
+ */
+static void
+state_machine(
+ struct active_service * as,
+ action_t action,
+ pkt_t * pkt)
+{
+ action_t retaction;
+ state_t curstate;
+ pkt_t nak;
+
+#ifdef AMANDAD_DEBUG
+ dbprintf(("%s: state_machine: %p entering\n",
+ debug_prefix_time(NULL), as));
+#endif
+ for (;;) {
+ curstate = as->state;
+#ifdef AMANDAD_DEBUG
+ dbprintf(("%s: state_machine: %p curstate=%s action=%s\n",
+ debug_prefix_time(NULL), as,
+ state2str(curstate), action2str(action)));
+#endif
+ retaction = (*curstate)(as, action, pkt);
+#ifdef AMANDAD_DEBUG
+ dbprintf(("%s: state_machine: %p curstate=%s returned %s (nextstate=%s)\n",
+ debug_prefix_time(NULL),
+ as, state2str(curstate), action2str(retaction),
+ state2str(as->state)));
+#endif
+
+ switch (retaction) {
+ /*
+ * State has queued up and is now blocking on input.
+ */
+ case A_PENDING:
+#ifdef AMANDAD_DEBUG
+ dbprintf(("%s: state_machine: %p leaving (A_PENDING)\n",
+ debug_prefix_time(NULL), as));
+#endif
+ return;
+
+ /*
+ * service has switched states. Loop.
+ */
+ case A_CONTINUE:
+ break;
+
+ /*
+ * state has determined that the packet it received was bogus.
+ * Send a nak, and return.
+ */
+ case A_SENDNAK:
+ dbprintf(("%s: received unexpected %s packet\n",
+ debug_prefix_time(NULL), pkt_type2str(pkt->type)));
+ dbprintf(("<<<<<\n%s----\n\n", pkt->body));
+ pkt_init(&nak, P_NAK, "ERROR unexpected packet type %s\n",
+ pkt_type2str(pkt->type));
+ do_sendpkt(as->security_handle, &nak);
+ amfree(nak.body);
+#ifdef AMANDAD_DEBUG
+ dbprintf(("%s: state_machine: %p leaving (A_SENDNAK)\n",
+ debug_prefix_time(NULL), as));
+#endif
+ return;
+
+ /*
+ * Service is done. Remove it and finish.
+ */
+ case A_FINISH:
+ service_delete(as);
+#ifdef AMANDAD_DEBUG
+ dbprintf(("%s: state_machine: %p leaving (A_FINISH)\n",
+ debug_prefix_time(NULL), as));
+#endif
+ return;
+
+ default:
+ assert(0);
+ break;
+ }
+ }
+ /*NOTREACHED*/
+}
+
+/*
+ * This state just sends an ack. After that, we move to the repwait
+ * state to wait for REP data to arrive from the subprocess.
+ */
+static action_t
+s_sendack(
+ struct active_service * as,
+ action_t action,
+ pkt_t * pkt)
+{
+ pkt_t ack;
+
+ (void)action; /* Quiet unused parameter warning */
+ (void)pkt; /* Quiet unused parameter warning */
+
+ pkt_init(&ack, P_ACK, "");
+ if (do_sendpkt(as->security_handle, &ack) < 0) {
+ dbprintf(("%s: error sending ACK: %s\n",
+ debug_prefix_time(NULL), security_geterror(as->security_handle)));
+ amfree(ack.body);
+ return (A_FINISH);
+ }
+ amfree(ack.body);
+
+ /*
+ * move to the repwait state
+ * Setup a listener for data on the reply fd, but also
+ * listen for packets over the wire, as the server may
+ * poll us if we take a long time.
+ * Setup a timeout that will fire if it takes too long to
+ * receive rep data.
+ */
+ as->state = s_repwait;
+ as->ev_repfd = event_register((event_id_t)as->repfd, EV_READFD, repfd_recv, as);
+ as->ev_reptimeout = event_register(REP_TIMEOUT, EV_TIME,
+ timeout_repfd, as);
+ security_recvpkt(as->security_handle, protocol_recv, as, -1);
+ return (A_PENDING);
+}
+
+/*
+ * This is the repwait state. We have responded to the initial REQ with
+ * an ACK, and we are now waiting for the process we spawned to pass us
+ * data to send in a REP.
+ */
+static action_t
+s_repwait(
+ struct active_service * as,
+ action_t action,
+ pkt_t * pkt)
+{
+ ssize_t n;
+ char *repbuf_temp;
+
+ /*
+ * We normally shouldn't receive any packets while waiting
+ * for our REP data, but in some cases we do.
+ */
+ if (action == A_RECVPKT) {
+ assert(pkt != NULL);
+ /*
+ * Another req for something that's running. Just send an ACK
+ * and go back and wait for more data.
+ */
+ if (pkt->type == P_REQ) {
+ dbprintf(("%s: received dup P_REQ packet, ACKing it\n",
+ debug_prefix_time(NULL)));
+ amfree(as->rep_pkt.body);
+ pkt_init(&as->rep_pkt, P_ACK, "");
+ do_sendpkt(as->security_handle, &as->rep_pkt);
+ return (A_PENDING);
+ }
+ /* something unexpected. Nak it */
+ return (A_SENDNAK);
+ }
+
+ if (action == A_TIMEOUT) {
+ amfree(as->rep_pkt.body);
+ pkt_init(&as->rep_pkt, P_NAK, "ERROR timeout on reply pipe\n");
+ dbprintf(("%s: %s timed out waiting for REP data\n",
+ debug_prefix_time(NULL), as->cmd));
+ do_sendpkt(as->security_handle, &as->rep_pkt);
+ return (A_FINISH);
+ }
+
+ assert(action == A_RECVREP);
+ if(as->bufsize == 0) {
+ as->bufsize = NETWORK_BLOCK_BYTES;
+ as->repbuf = alloc(as->bufsize);
+ }
+
+ do {
+ n = read(as->repfd, as->repbuf + as->repbufsize,
+ as->bufsize - as->repbufsize - 1);
+ } while ((n < 0) && ((errno == EINTR) || (errno == EAGAIN)));
+ if (n < 0) {
+ const char *errstr = strerror(errno);
+ dbprintf(("%s: read error on reply pipe: %s\n",
+ debug_prefix_time(NULL), errstr));
+ amfree(as->rep_pkt.body);
+ pkt_init(&as->rep_pkt, P_NAK, "ERROR read error on reply pipe: %s\n",
+ errstr);
+ do_sendpkt(as->security_handle, &as->rep_pkt);
+ return (A_FINISH);
+ }
+ /*
+ * If we got some data, go back and wait for more, or EOF. Nul terminate
+ * the buffer first.
+ */
+ as->repbuf[n + as->repbufsize] = '\0';
+ if (n > 0) {
+ as->repbufsize += n;
+ if(as->repbufsize >= (as->bufsize - 1)) {
+ as->bufsize *= 2;
+ repbuf_temp = alloc(as->bufsize);
+ memcpy(repbuf_temp, as->repbuf, as->repbufsize + 1);
+ amfree(as->repbuf);
+ as->repbuf = repbuf_temp;
+ }
+ else if(as->send_partial_reply) {
+ amfree(as->rep_pkt.body);
+ pkt_init(&as->rep_pkt, P_PREP, "%s", as->repbuf);
+ do_sendpkt(as->security_handle, &as->rep_pkt);
+ amfree(as->rep_pkt.body);
+ pkt_init(&as->rep_pkt, P_REP, "");
+ }
+
+ return (A_PENDING);
+ }
+
+ /*
+ * If we got 0, then we hit EOF. Process the data and release
+ * the timeout.
+ */
+ assert(n == 0);
+
+ assert(as->ev_repfd != NULL);
+ event_release(as->ev_repfd);
+ as->ev_repfd = NULL;
+
+ assert(as->ev_reptimeout != NULL);
+ event_release(as->ev_reptimeout);
+ as->ev_reptimeout = NULL;
+
+ as->state = s_processrep;
+ aclose(as->repfd);
+ return (A_CONTINUE);
+}
+
+/*
+ * After we have read in all of the rep data, we process it and send
+ * it out as a REP packet.
+ */
+static action_t
+s_processrep(
+ struct active_service * as,
+ action_t action,
+ pkt_t * pkt)
+{
+ char *tok, *repbuf;
+
+ (void)action; /* Quiet unused parameter warning */
+ (void)pkt; /* Quiet unused parameter warning */
+
+ /*
+ * Copy the rep lines into the outgoing packet.
+ *
+ * If this line is a CONNECT, translate it
+ * Format is "CONNECT <tag> <handle> <tag> <handle> etc...
+ * Example:
+ *
+ * CONNECT DATA 4 MESG 5 INDEX 6
+ *
+ * The tags are arbitrary. The handles are in the DATA_FD pool.
+ * We need to map these to security streams and pass them back
+ * to the amanda server. If the handle is -1, then we don't map.
+ */
+ repbuf = stralloc(as->repbuf);
+ amfree(as->rep_pkt.body);
+ pkt_init(&as->rep_pkt, P_REP, "");
+ tok = strtok(repbuf, " ");
+ if (tok == NULL)
+ goto error;
+ if (strcmp(tok, "CONNECT") == 0) {
+ char *line, *nextbuf;
+
+ /* Save the entire line */
+ line = strtok(NULL, "\n");
+ /* Save the buf following the line */
+ nextbuf = strtok(NULL, "");
+
+ if (line == NULL || nextbuf == NULL)
+ goto error;
+
+ pkt_cat(&as->rep_pkt, "CONNECT");
+
+ /* loop over the id/handle pairs */
+ for (;;) {
+ /* id */
+ tok = strtok(line, " ");
+ line = NULL; /* keep working from line */
+ if (tok == NULL)
+ break;
+ pkt_cat(&as->rep_pkt, " %s", tok);
+
+ /* handle */
+ tok = strtok(NULL, " \n");
+ if (tok == NULL)
+ goto error;
+ /* convert the handle into something the server can process */
+ pkt_cat(&as->rep_pkt, " %d", allocstream(as, atoi(tok)));
+ }
+ pkt_cat(&as->rep_pkt, "\n%s", nextbuf);
+ } else {
+error:
+ pkt_cat(&as->rep_pkt, "%s", as->repbuf);
+ }
+
+ /*
+ * We've setup our REP packet in as->rep_pkt. Now move to the transmission
+ * state.
+ */
+ as->state = s_sendrep;
+ as->repretry = MAX_REP_RETRIES;
+ amfree(repbuf);
+ return (A_CONTINUE);
+}
+
+/*
+ * This is the state where we send the REP we just collected from our child.
+ */
+static action_t
+s_sendrep(
+ struct active_service * as,
+ action_t action,
+ pkt_t * pkt)
+{
+ (void)action; /* Quiet unused parameter warning */
+ (void)pkt; /* Quiet unused parameter warning */
+
+ /*
+ * Transmit it and move to the ack state.
+ */
+ do_sendpkt(as->security_handle, &as->rep_pkt);
+ security_recvpkt(as->security_handle, protocol_recv, as, ACK_TIMEOUT);
+ as->state = s_ackwait;
+ return (A_PENDING);
+}
+
+/*
+ * This is the state in which we wait for the server to ACK the REP
+ * we just sent it.
+ */
+static action_t
+s_ackwait(
+ struct active_service * as,
+ action_t action,
+ pkt_t * pkt)
+{
+ struct datafd_handle *dh;
+ int npipes;
+
+ /*
+ * If we got a timeout, try again, but eventually give up.
+ */
+ if (action == A_TIMEOUT) {
+ if (--as->repretry > 0) {
+ as->state = s_sendrep;
+ return (A_CONTINUE);
+ }
+ dbprintf(("%s: timeout waiting for ACK for our REP\n",
+ debug_prefix_time(NULL)));
+ return (A_FINISH);
+ }
+#ifdef AMANDAD_DEBUG
+ dbprintf(("%s: received ACK, now opening streams\n",
+ debug_prefix_time(NULL)));
+#endif
+
+ assert(action == A_RECVPKT);
+
+ if (pkt->type == P_REQ) {
+ dbprintf(("%s: received dup P_REQ packet, resending REP\n",
+ debug_prefix_time(NULL)));
+ as->state = s_sendrep;
+ return (A_CONTINUE);
+ }
+
+ if (pkt->type != P_ACK)
+ return (A_SENDNAK);
+
+ /*
+ * Got the ack, now open the pipes
+ */
+ for (dh = &as->data[0]; dh < &as->data[DATA_FD_COUNT]; dh++) {
+ if (dh->netfd == NULL)
+ continue;
+ if (security_stream_accept(dh->netfd) < 0) {
+ dbprintf(("%s: stream %d accept failed: %s\n",
+ debug_prefix_time(NULL),
+ dh - &as->data[0], security_geterror(as->security_handle)));
+ security_stream_close(dh->netfd);
+ dh->netfd = NULL;
+ }
+ /* setup an event for reads from it */
+ dh->ev_read = event_register((event_id_t)dh->fd_read, EV_READFD,
+ process_readnetfd, dh);
+
+ security_stream_read(dh->netfd, process_writenetfd, dh);
+
+ }
+
+ /*
+ * Pipes are open, so auth them. Count them at the same time.
+ */
+ for (npipes = 0, dh = &as->data[0]; dh < &as->data[DATA_FD_COUNT]; dh++) {
+ if (dh->netfd == NULL)
+ continue;
+ if (security_stream_auth(dh->netfd) < 0) {
+ security_stream_close(dh->netfd);
+ dh->netfd = NULL;
+ event_release(dh->ev_read);
+ event_release(dh->ev_write);
+ dh->ev_read = NULL;
+ dh->ev_write = NULL;
+ } else {
+ npipes++;
+ }
+ }
+
+ /*
+ * If no pipes are open, then we're done. Otherwise, just start running.
+ * The event handlers on all of the pipes will take it from here.
+ */
+#ifdef AMANDAD_DEBUG
+ dbprintf(("%s: at end of s_ackwait, npipes is %d\n",
+ debug_prefix_time(NULL), npipes));
+#endif
+ if (npipes == 0)
+ return (A_FINISH);
+ else {
+ security_close(as->security_handle);
+ as->security_handle = NULL;
+ return (A_PENDING);
+ }
+}
+
+/*
+ * Called when a repfd has received data
+ */
+static void
+repfd_recv(
+ void * cookie)
+{
+ struct active_service *as = cookie;
+
+ assert(as != NULL);
+ assert(as->ev_repfd != NULL);
+
+ state_machine(as, A_RECVREP, NULL);
+}
+
+/*
+ * Called when a repfd has timed out
+ */
+static void
+timeout_repfd(
+ void * cookie)
+{
+ struct active_service *as = cookie;
+
+ assert(as != NULL);
+ assert(as->ev_reptimeout != NULL);
+
+ state_machine(as, A_TIMEOUT, NULL);
+}
+
+/*
+ * Called when a handle has received data
+ */
+static void
+protocol_recv(
+ void * cookie,
+ pkt_t * pkt,
+ security_status_t status)
+{
+ struct active_service *as = cookie;
+
+ assert(as != NULL);
+
+ switch (status) {
+ case S_OK:
+ dbprintf(("%s: received %s pkt:\n<<<<<\n%s>>>>>\n",
+ debug_prefix_time(NULL), pkt_type2str(pkt->type), pkt->body));
+ state_machine(as, A_RECVPKT, pkt);
+ break;
+ case S_TIMEOUT:
+ dbprintf(("%s: timeout\n", debug_prefix_time(NULL)));
+ state_machine(as, A_TIMEOUT, NULL);
+ break;
+ case S_ERROR:
+ dbprintf(("%s: receive error: %s\n",
+ debug_prefix_time(NULL), security_geterror(as->security_handle)));
+ break;
+ }
+}
+
+/*
+ * This is a generic relay function that just reads data from one of
+ * the process's pipes and passes it up the equivalent security_stream_t
+ */
+static void
+process_readnetfd(
+ void * cookie)
+{
+ pkt_t nak;
+ struct datafd_handle *dh = cookie;
+ struct active_service *as = dh->as;
+ ssize_t n;
+
+ nak.body = NULL;
+
+ do {
+ n = read(dh->fd_read, as->databuf, SIZEOF(as->databuf));
+ } while ((n < 0) && ((errno == EINTR) || (errno == EAGAIN)));
+
+ /*
+ * Process has died.
+ */
+ if (n < 0) {
+ pkt_init(&nak, P_NAK, "A ERROR data descriptor %d broken: %s\n",
+ dh->fd_read, strerror(errno));
+ goto sendnak;
+ }
+ /*
+ * Process has closed the pipe. Just remove this event handler.
+ * If all pipes are closed, shut down this service.
+ */
+ if (n == 0) {
+ event_release(dh->ev_read);
+ dh->ev_read = NULL;
+ if(dh->ev_write == NULL) {
+ security_stream_close(dh->netfd);
+ dh->netfd = NULL;
+ }
+ for (dh = &as->data[0]; dh < &as->data[DATA_FD_COUNT]; dh++) {
+ if (dh->netfd != NULL)
+ return;
+ }
+ service_delete(as);
+ return;
+ }
+ if (security_stream_write(dh->netfd, as->databuf, (size_t)n) < 0) {
+ /* stream has croaked */
+ pkt_init(&nak, P_NAK, "ERROR write error on stream %d: %s\n",
+ security_stream_id(dh->netfd),
+ security_stream_geterror(dh->netfd));
+ goto sendnak;
+ }
+ return;
+
+sendnak:
+ do_sendpkt(as->security_handle, &nak);
+ service_delete(as);
+ amfree(nak.body);
+}
+
+/*
+ * This is a generic relay function that just read data from one of
+ * the security_stream_t and passes it up the equivalent process's pipes
+ */
+static void
+process_writenetfd(
+ void * cookie,
+ void * buf,
+ ssize_t size)
+{
+ struct datafd_handle *dh;
+
+ assert(cookie != NULL);
+ dh = cookie;
+
+ if (dh->fd_write <= 0) {
+ dbprintf(("%s: process_writenetfd: dh->fd_write <= 0\n",
+ debug_prefix_time(NULL)));
+ } else if (size > 0) {
+ fullwrite(dh->fd_write, buf, (size_t)size);
+ security_stream_read(dh->netfd, process_writenetfd, dh);
+ }
+ else {
+ aclose(dh->fd_write);
+ }
+}
+
+
+/*
+ * Convert a local stream handle (DATA_FD...) into something that
+ * can be sent to the amanda server.
+ *
+ * Returns a number that should be sent to the server in the REP packet.
+ */
+static int
+allocstream(
+ struct active_service * as,
+ int handle)
+{
+ struct datafd_handle *dh;
+
+ /* if the handle is -1, then we don't bother */
+ if (handle < 0)
+ return (-1);
+
+ /* make sure the handle's kosher */
+ if (handle < DATA_FD_OFFSET || handle >= DATA_FD_OFFSET + DATA_FD_COUNT)
+ return (-1);
+
+ /* get a pointer into our handle array */
+ dh = &as->data[handle - DATA_FD_OFFSET];
+
+ /* make sure we're not already using the net handle */
+ if (dh->netfd != NULL)
+ return (-1);
+
+ /* allocate a stream from the security layer and return */
+ dh->netfd = security_stream_server(as->security_handle);
+ if (dh->netfd == NULL) {
+ dbprintf(("%s: couldn't open stream to server: %s\n",
+ debug_prefix_time(NULL), security_geterror(as->security_handle)));
+ return (-1);
+ }
+
+ /*
+ * convert the stream into a numeric id that can be sent to the
+ * remote end.
+ */
+ return (security_stream_id(dh->netfd));
+}
+
+/*
+ * Create a new service instance
+ */
+static struct active_service *
+service_new(
+ security_handle_t * security_handle,
+ const char * cmd,
+ const char * arguments)
+{
+ int i;
+ int data_read[DATA_FD_COUNT + 1][2];
+ int data_write[DATA_FD_COUNT + 1][2];
+ struct active_service *as;
+ pid_t pid;
+ int newfd;
+
+ assert(security_handle != NULL);
+ assert(cmd != NULL);
+ assert(arguments != NULL);
+
+ /* a plethora of pipes */
+ for (i = 0; i < DATA_FD_COUNT + 1; i++) {
+ if (pipe(data_read[i]) < 0) {
+ error("pipe: %s\n", strerror(errno));
+ /*NOTREACHED*/
+ }
+ if (pipe(data_write[i]) < 0) {
+ error("pipe: %s\n", strerror(errno));
+ /*NOTREACHED*/
+ }
+ }
+
+ switch(pid = fork()) {
+ case -1:
+ error("could not fork service %s: %s\n", cmd, strerror(errno));
+ /*NOTREACHED*/
+ default:
+ /*
+ * The parent. Close the far ends of our pipes and return.
+ */
+ as = alloc(SIZEOF(*as));
+ as->cmd = stralloc(cmd);
+ as->arguments = stralloc(arguments);
+ as->security_handle = security_handle;
+ as->state = NULL;
+ as->pid = pid;
+ as->send_partial_reply = 0;
+ if(strcmp(cmd+(strlen(cmd)-8), "sendsize") == 0) {
+ g_option_t *g_options;
+ char *option_str, *p;
+
+ option_str = stralloc(as->arguments+8);
+ p = strchr(option_str,'\n');
+ if(p) *p = '\0';
+
+ g_options = parse_g_options(option_str, 1);
+ if(am_has_feature(g_options->features, fe_partial_estimate)) {
+ as->send_partial_reply = 1;
+ }
+ free_g_options(g_options);
+ amfree(option_str);
+ }
+
+ /* write to the request pipe */
+ aclose(data_read[0][0]);
+ as->reqfd = data_read[0][1];
+
+ /*
+ * read from the reply pipe
+ */
+ as->repfd = data_write[0][0];
+ aclose(data_write[0][1]);
+ as->ev_repfd = NULL;
+ as->repbuf = NULL;
+ as->repbufsize = 0;
+ as->bufsize = 0;
+ as->repretry = 0;
+ as->rep_pkt.body = NULL;
+
+ /*
+ * read from the rest of the general-use pipes
+ * (netfds are opened as the client requests them)
+ */
+ for (i = 0; i < DATA_FD_COUNT; i++) {
+ aclose(data_read[i + 1][1]);
+ aclose(data_write[i + 1][0]);
+ as->data[i].fd_read = data_read[i + 1][0];
+ as->data[i].fd_write = data_write[i + 1][1];
+ as->data[i].ev_read = NULL;
+ as->data[i].ev_write = NULL;
+ as->data[i].netfd = NULL;
+ as->data[i].as = as;
+ }
+
+ /* add it to the service queue */
+ /* increment the active service count */
+ TAILQ_INSERT_TAIL(&serviceq.tailq, as, tq);
+ serviceq.qlength++;
+
+ return (as);
+ case 0:
+ /*
+ * The child. Put our pipes in their advertised locations
+ * and start up.
+ */
+#ifdef FORCE_USERID
+ seteuid((uid_t)0);
+ setuid(client_uid);
+#endif
+
+ /*
+ * The data stream is stdin in the new process
+ */
+ if (dup2(data_read[0][0], 0) < 0) {
+ error("dup %d to %d failed: %s\n", data_read[0][0], 0,
+ strerror(errno));
+ /*NOTREACHED*/
+ }
+ aclose(data_read[0][0]);
+ aclose(data_read[0][1]);
+
+ /*
+ * The reply stream is stdout
+ */
+ if (dup2(data_write[0][1], 1) < 0) {
+ error("dup %d to %d failed: %s\n", data_write[0][1], 1,
+ strerror(errno));
+ }
+ aclose(data_write[0][0]);
+ aclose(data_write[0][1]);
+
+ /*
+ * Make sure they are not open in the range DATA_FD_OFFSET to
+ * DATA_FD_OFFSET + DATA_FD_COUNT*2 - 1
+ */
+ for (i = 0; i < DATA_FD_COUNT; i++) {
+ while(data_read[i + 1][1] >= DATA_FD_OFFSET &&
+ data_read[i + 1][1] <= DATA_FD_OFFSET + DATA_FD_COUNT*2 - 1) {
+ newfd = dup(data_read[i + 1][1]);
+ if(newfd == -1)
+ error("Can't dup out off DATA_FD range");
+ data_read[i + 1][1] = newfd;
+ }
+ while(data_write[i + 1][0] >= DATA_FD_OFFSET &&
+ data_write[i + 1][0] <= DATA_FD_OFFSET + DATA_FD_COUNT*2 - 1) {
+ newfd = dup(data_write[i + 1][0]);
+ if(newfd == -1)
+ error("Can't dup out off DATA_FD range");
+ data_write[i + 1][0] = newfd;
+ }
+ }
+ for (i = 0; i < DATA_FD_COUNT; i++)
+ close(DATA_FD_OFFSET + i);
+
+ /*
+ * The rest start at the offset defined in amandad.h, and continue
+ * through the internal defined.
+ */
+ for (i = 0; i < DATA_FD_COUNT; i++) {
+ if (dup2(data_read[i + 1][1], i*2 + DATA_FD_OFFSET) < 0) {
+ error("dup %d to %d failed: %s\n", data_read[i + 1][1],
+ i + DATA_FD_OFFSET, strerror(errno));
+ }
+ aclose(data_read[i + 1][0]);
+ aclose(data_read[i + 1][1]);
+
+ if (dup2(data_write[i + 1][0], i*2 + 1 + DATA_FD_OFFSET) < 0) {
+ error("dup %d to %d failed: %s\n", data_write[i + 1][0],
+ i + DATA_FD_OFFSET, strerror(errno));
+ }
+ aclose(data_write[i + 1][0]);
+ aclose(data_write[i + 1][1]);
+ }
+
+ /* close all unneeded fd */
+ safe_fd(DATA_FD_OFFSET, DATA_FD_COUNT*2);
+ close(2);
+
+ execle(cmd, cmd, "amandad", auth, (char *)NULL, safe_env());
+ error("could not exec service %s: %s\n", cmd, strerror(errno));
+ /*NOTREACHED*/
+ }
+ return NULL;
+}
+
+/*
+ * Unallocate a service instance
+ */
+static void
+service_delete(
+ struct active_service * as)
+{
+ int i;
+ struct datafd_handle *dh;
+
+#ifdef AMANDAD_DEBUG
+ dbprintf(("%s: closing service: %s\n",
+ debug_prefix_time(NULL), (as->cmd)?as->cmd:"??UNKONWN??"));
+#endif
+
+ assert(as != NULL);
+
+ assert(as->cmd != NULL);
+ amfree(as->cmd);
+
+ assert(as->arguments != NULL);
+ amfree(as->arguments);
+
+ if (as->reqfd != -1)
+ aclose(as->reqfd);
+ if (as->repfd != -1)
+ aclose(as->repfd);
+
+ if (as->ev_repfd != NULL)
+ event_release(as->ev_repfd);
+ if (as->ev_reptimeout != NULL)
+ event_release(as->ev_reptimeout);
+
+ for (i = 0; i < DATA_FD_COUNT; i++) {
+ dh = &as->data[i];
+
+ aclose(dh->fd_read);
+ aclose(dh->fd_write);
+
+ if (dh->netfd != NULL)
+ security_stream_close(dh->netfd);
+
+ if (dh->ev_read != NULL)
+ event_release(dh->ev_read);
+ if (dh->ev_write != NULL)
+ event_release(dh->ev_write);
+ }
+
+ if (as->security_handle != NULL)
+ security_close(as->security_handle);
+
+ assert(as->pid > 0);
+ kill(as->pid, SIGTERM);
+ waitpid(as->pid, NULL, WNOHANG);
+
+ TAILQ_REMOVE(&serviceq.tailq, as, tq);
+ assert(serviceq.qlength > 0);
+ serviceq.qlength--;
+
+ amfree(as->cmd);
+ amfree(as->arguments);
+ amfree(as->repbuf);
+ amfree(as->rep_pkt.body);
+ amfree(as);
+
+ if(exit_on_qlength == 0 && serviceq.qlength == 0) {
+ dbclose();
+ exit(0);
+ }
+}
+
+/*
+ * Like 'fullwrite', but does the work in a child process so pipelines
+ * do not hang.
+ */
+static int
+writebuf(
+ struct active_service * as,
+ const void * bufp,
+ size_t size)
+{
+ pid_t pid;
+ ssize_t writesize;
+
+ switch (pid=fork()) {
+ case -1:
+ break;
+
+ default:
+ waitpid(pid, NULL, WNOHANG);
+ return 0; /* this is the parent */
+
+ case 0: /* this is the child */
+ close(as->repfd);
+ writesize = fullwrite(as->reqfd, bufp, size);
+ exit(writesize != (ssize_t)size);
+ /* NOTREACHED */
+ }
+ return -1;
+}
+
+static ssize_t
+do_sendpkt(
+ security_handle_t * handle,
+ pkt_t * pkt)
+{
+ dbprintf(("%s: sending %s pkt:\n<<<<<\n%s>>>>>\n",
+ debug_prefix_time(NULL), pkt_type2str(pkt->type), pkt->body));
+ return security_sendpkt(handle, pkt);
+}
+
+#ifdef AMANDAD_DEBUG
+/*
+ * Convert a state into a string
+ */
+static const char *
+state2str(
+ state_t state)
+{
+ static const struct {
+ state_t state;
+ const char str[13];
+ } states[] = {
+#define X(state) { state, stringize(state) }
+ X(s_sendack),
+ X(s_repwait),
+ X(s_processrep),
+ X(s_sendrep),
+ X(s_ackwait),
+#undef X
+ };
+ int i;
+
+ for (i = 0; i < (int)(sizeof(states) / sizeof(states[0])); i++)
+ if (state == states[i].state)
+ return (states[i].str);
+ return ("INVALID STATE");
+}
+
+/*
+ * Convert an action into a string
+ */
+static const char *
+action2str(
+ action_t action)
+{
+ static const struct {
+ action_t action;
+ const char str[12];
+ } actions[] = {
+#define X(action) { action, stringize(action) }
+ X(A_START),
+ X(A_RECVPKT),
+ X(A_RECVREP),
+ X(A_PENDING),
+ X(A_FINISH),
+ X(A_CONTINUE),
+ X(A_SENDNAK),
+ X(A_TIMEOUT),
+#undef X
+ };
+ int i;
+
+ for (i = 0; i < (int)(sizeof(actions) / sizeof(actions[0])); i++)
+ if (action == actions[i].action)
+ return (actions[i].str);
+ return ("UNKNOWN ACTION");
+}
+#endif /* AMANDAD_DEBUG */
--- /dev/null
+/*
+ * Amanda, The Advanced Maryland Automatic Network Disk Archiver
+ * Copyright (c) 1991-1998 University of Maryland at College Park
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of U.M. not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. U.M. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: the Amanda Development Team. Its members are listed in a
+ * file named AUTHORS, in the root directory of this distribution.
+ */
+/*
+ * $Id: amandad.h,v 1.5 2006/07/19 17:46:07 martinea Exp $
+ *
+ */
+
+#ifndef AMANDAD_UTIL_H
+#define AMANDAD_UTIL_H
+
+#include "amanda.h"
+#include "amfeatures.h"
+#include "sl.h"
+#include "util.h" /* for bstrncmp() */
+
+#define DATA_FD_COUNT 3 /* number of general-use pipes */
+#define DATA_FD_OFFSET 50
+
+typedef struct g_option_s {
+ char *str;
+ am_feature_t *features;
+ char *hostname;
+ char *auth;
+ int maxdumps;
+ char *config;
+} g_option_t;
+
+
+void init_g_options(g_option_t *g_options);
+g_option_t *parse_g_options(char *str, int verbose);
+void free_g_options(g_option_t *);
+
+#endif
--- /dev/null
+/*
+ * Amanda, The Advanced Maryland Automatic Network Disk Archiver
+ * Copyright (c) 1991-1998 University of Maryland at College Park
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of U.M. not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. U.M. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: the Amanda Development Team. Its members are listed in a
+ * file named AUTHORS, in the root directory of this distribution.
+ */
+/*
+ * $Id: amandad_util.c,v 1.5 2006/07/19 17:46:07 martinea Exp $
+ *
+ */
+
+#include "amandad.h"
+#include "util.h"
+
+#define MAXMAXDUMPS 16
+
+void
+init_g_options(
+ g_option_t * g_options)
+{
+ g_options->str = NULL;
+ g_options->features = NULL;
+ g_options->hostname = NULL;
+ g_options->auth = NULL;
+ g_options->maxdumps = 0;
+ g_options->config = NULL;
+}
+
+
+g_option_t *
+parse_g_options(
+ char * str,
+ int verbose)
+{
+ g_option_t *g_options;
+ char *p, *tok;
+ int new_maxdumps;
+
+ g_options = alloc(sizeof(g_option_t));
+ init_g_options(g_options);
+ g_options->str = stralloc(str);
+
+ p = stralloc(str);
+ tok = strtok(p,";");
+
+ while (tok != NULL) {
+ if(strncmp(tok,"features=", 9) == 0) {
+ if(g_options->features != NULL) {
+ dbprintf(("%s: multiple features option\n",
+ debug_prefix(NULL)));
+ if(verbose) {
+ printf("ERROR [multiple features option]\n");
+ }
+ }
+ if((g_options->features = am_string_to_feature(tok+9)) == NULL) {
+ dbprintf(("%s: bad features value \"%s\n",
+ debug_prefix(NULL), tok+10));
+ if(verbose) {
+ printf("ERROR [bad features value \"%s\"]\n", tok+10);
+ }
+ }
+ }
+ else if(strncmp(tok,"hostname=", 9) == 0) {
+ if(g_options->hostname != NULL) {
+ dbprintf(("%s: multiple hostname option\n",
+ debug_prefix(NULL)));
+ if(verbose) {
+ printf("ERROR [multiple hostname option]\n");
+ }
+ }
+ g_options->hostname = stralloc(tok+9);
+ }
+ else if(strncmp(tok,"auth=", 5) == 0) {
+ if(g_options->auth != NULL) {
+ dbprintf(("%s: multiple auth option\n",
+ debug_prefix(NULL)));
+ if(verbose) {
+ printf("ERROR [multiple auth option]\n");
+ }
+ }
+ g_options->auth = stralloc(tok+5);
+ }
+ else if(strncmp(tok,"maxdumps=", 9) == 0) {
+ if(g_options->maxdumps != 0) {
+ dbprintf(("%s: multiple maxdumps option\n",
+ debug_prefix(NULL)));
+ if(verbose) {
+ printf("ERROR [multiple maxdumps option]\n");
+ }
+ }
+ if(sscanf(tok+9, "%d;", &new_maxdumps) == 1) {
+ if (new_maxdumps > MAXMAXDUMPS) {
+ g_options->maxdumps = MAXMAXDUMPS;
+ }
+ else if (new_maxdumps > 0) {
+ g_options->maxdumps = new_maxdumps;
+ }
+ else {
+ dbprintf(("%s: bad maxdumps value \"%s\"\n",
+ debug_prefix(NULL), tok+9));
+ if(verbose) {
+ printf("ERROR [bad maxdumps value \"%s\"]\n",
+ tok+9);
+ }
+ }
+ }
+ else {
+ dbprintf(("%s: bad maxdumps value \"%s\"\n",
+ debug_prefix(NULL), tok+9));
+ if(verbose) {
+ printf("ERROR [bad maxdumps value \"%s\"]\n",
+ tok+9);
+ }
+ }
+ }
+ else if(strncmp(tok,"config=", 7) == 0) {
+ if(g_options->config != NULL) {
+ dbprintf(("%s: multiple config option\n",
+ debug_prefix(NULL)));
+ if(verbose) {
+ printf("ERROR [multiple config option]\n");
+ }
+ }
+ g_options->config = stralloc(tok+7);
+ if (strchr(g_options->config, '/')) {
+ amfree(g_options->config);
+ dbprintf(("%s: invalid character in config option\n",
+ debug_prefix(NULL)));
+ if(verbose) {
+ printf("ERROR [invalid character in config option]\n");
+ }
+ }
+ }
+ else {
+ dbprintf(("%s: unknown option \"%s\"\n",
+ debug_prefix(NULL), tok));
+ if(verbose) {
+ printf("ERROR [unknown option \"%s\"]\n", tok);
+ }
+ }
+ tok = strtok(NULL, ";");
+ }
+ if(g_options->features == NULL) {
+ g_options->features = am_set_default_feature_set();
+ }
+ if(g_options->maxdumps == 0) /* default */
+ g_options->maxdumps = 1;
+ amfree(p);
+ return g_options;
+}
+
+void
+free_g_options(
+ g_option_t * g_options)
+{
+ amfree(g_options->str);
+ am_release_feature_set(g_options->features);
+ amfree(g_options->hostname);
+ amfree(g_options->auth);
+ amfree(g_options->config);
+ amfree(g_options);
+}
AMANDA_TMPDIR = @AMANDA_TMPDIR@
AMDEP_FALSE = @AMDEP_FALSE@
AMDEP_TRUE = @AMDEP_TRUE@
+AMLINT = @AMLINT@
+AMLINTFLAGS = @AMLINTFLAGS@
AMPLOT_CAT_COMPRESS = @AMPLOT_CAT_COMPRESS@
AMPLOT_CAT_GZIP = @AMPLOT_CAT_GZIP@
AMPLOT_CAT_PACK = @AMPLOT_CAT_PACK@
AMPLOT_COMPRESS = @AMPLOT_COMPRESS@
AMTAR = @AMTAR@
+AM_CFLAGS = @AM_CFLAGS@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AWK = @AWK@
AWK_VAR_ASSIGNMENT_OPT = @AWK_VAR_ASSIGNMENT_OPT@
BINARY_OWNER = @BINARY_OWNER@
+BUILD_MAN_PAGES_FALSE = @BUILD_MAN_PAGES_FALSE@
+BUILD_MAN_PAGES_TRUE = @BUILD_MAN_PAGES_TRUE@
CAT = @CAT@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
-#!/bin/sh
+#!@SHELL@
# Amanda, The Advanced Maryland Automatic Network Disk Archiver
# Copyright (c) 1992-1998 University of Maryland at College Park
# All Rights Reserved.
-I$(top_srcdir)/server-src \
-I$(top_srcdir)/tape-src
+LINT=@AMLINT@
+LINTFLAGS=@AMLINTFLAGS@
+
LIB_EXTENSION = la
if WANT_CHIO_SCSI
LDADD = ../common-src/libamanda.$(LIB_EXTENSION) \
../server-src/libamserver.$(LIB_EXTENSION) \
../tape-src/libamtape.$(LIB_EXTENSION) \
- ../common-src/libamanda.$(LIB_EXTENSION)
+ ../common-src/libamanda.$(LIB_EXTENSION) \
+ $(READLINE_LIBS)
SUFFIXES = .pl .sh
-chg_scsi_SOURCES = chg-scsi.c libscsi.h scsi-defs.h \
- scsi-aix.c scsi-changer-driver.c scsi-hpux_new.c scsi-irix.c \
- scsi-linux.c scsi-solaris.c scsi-bsd.c scsi-cam.c sense.c
+chg_scsi_CSRC = chg-scsi.c scsi-aix.c scsi-changer-driver.c \
+ scsi-hpux_new.c scsi-irix.c scsi-linux.c scsi-solaris.c \
+ scsi-bsd.c scsi-cam.c sense.c
+chg_scsi_SOURCES = libscsi.h scsi-defs.h $(chg_scsi_CSRC)
-chg_scsi_chio_SOURCES = chg-scsi-chio.c scsi-hpux.c scsi-chio.c libscsi.h
+chg_scsi_chio_CSRC = chg-scsi-chio.c scsi-hpux.c scsi-chio.c
+chg_scsi_chio_SOURCES = libscsi.h $(chg_scsi_chio_CSRC)
EXTRA_DIST = scsi-proto.c
echo chgrp $(SETUID_GROUP) $$pa; \
chgrp $(SETUID_GROUP) $$pa; \
done
+
+lint:
+ @ for p in $(libexec_PROGRAMS) $(EXTRA_PROGRAMS); do \
+ f="$$p.c $(libamandad_la_SOURCES)"; \
+ (cd ../common-src; make listlibsrc); \
+ f="$$f "`cat ../common-src/listlibsrc.output`; \
+ (cd ../server-src; make listlibsrc); \
+ f="$$f "`cat ../server-src/listlibsrc.output`; \
+ (cd ../tape-src; make listlibsrc); \
+ f="$$f "`cat ../tape-src/listlibsrc.output`; \
+ echo $(LINT) $$f; \
+ $(LINT) $(LINTFLAGS) $(CPPFLAGS) $(DEFS) -I. -I../config \
+ $(INCLUDES) $$f; \
+ if [ $$? -ne 0 ]; then \
+ exit 1; \
+ fi; \
+ done; \
+ exit 0
am__installdirs = "$(DESTDIR)$(libexecdir)" "$(DESTDIR)$(libexecdir)"
libexecPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
PROGRAMS = $(libexec_PROGRAMS)
-am_chg_scsi_OBJECTS = chg-scsi.$(OBJEXT) scsi-aix.$(OBJEXT) \
+am__objects_1 = chg-scsi.$(OBJEXT) scsi-aix.$(OBJEXT) \
scsi-changer-driver.$(OBJEXT) scsi-hpux_new.$(OBJEXT) \
scsi-irix.$(OBJEXT) scsi-linux.$(OBJEXT) \
scsi-solaris.$(OBJEXT) scsi-bsd.$(OBJEXT) scsi-cam.$(OBJEXT) \
sense.$(OBJEXT)
+am_chg_scsi_OBJECTS = $(am__objects_1)
chg_scsi_OBJECTS = $(am_chg_scsi_OBJECTS)
chg_scsi_LDADD = $(LDADD)
+am__DEPENDENCIES_1 =
chg_scsi_DEPENDENCIES = ../common-src/libamanda.$(LIB_EXTENSION) \
../server-src/libamserver.$(LIB_EXTENSION) \
../tape-src/libamtape.$(LIB_EXTENSION) \
- ../common-src/libamanda.$(LIB_EXTENSION)
-am_chg_scsi_chio_OBJECTS = chg-scsi-chio.$(OBJEXT) scsi-hpux.$(OBJEXT) \
+ ../common-src/libamanda.$(LIB_EXTENSION) $(am__DEPENDENCIES_1)
+am__objects_2 = chg-scsi-chio.$(OBJEXT) scsi-hpux.$(OBJEXT) \
scsi-chio.$(OBJEXT)
+am_chg_scsi_chio_OBJECTS = $(am__objects_2)
chg_scsi_chio_OBJECTS = $(am_chg_scsi_chio_OBJECTS)
chg_scsi_chio_LDADD = $(LDADD)
chg_scsi_chio_DEPENDENCIES = ../common-src/libamanda.$(LIB_EXTENSION) \
../server-src/libamserver.$(LIB_EXTENSION) \
../tape-src/libamtape.$(LIB_EXTENSION) \
- ../common-src/libamanda.$(LIB_EXTENSION)
+ ../common-src/libamanda.$(LIB_EXTENSION) $(am__DEPENDENCIES_1)
libexecSCRIPT_INSTALL = $(INSTALL_SCRIPT)
SCRIPTS = $(libexec_SCRIPTS)
DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)/config
AMANDA_TMPDIR = @AMANDA_TMPDIR@
AMDEP_FALSE = @AMDEP_FALSE@
AMDEP_TRUE = @AMDEP_TRUE@
+AMLINT = @AMLINT@
+AMLINTFLAGS = @AMLINTFLAGS@
AMPLOT_CAT_COMPRESS = @AMPLOT_CAT_COMPRESS@
AMPLOT_CAT_GZIP = @AMPLOT_CAT_GZIP@
AMPLOT_CAT_PACK = @AMPLOT_CAT_PACK@
AMPLOT_COMPRESS = @AMPLOT_COMPRESS@
AMTAR = @AMTAR@
+AM_CFLAGS = @AM_CFLAGS@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AWK = @AWK@
AWK_VAR_ASSIGNMENT_OPT = @AWK_VAR_ASSIGNMENT_OPT@
BINARY_OWNER = @BINARY_OWNER@
+BUILD_MAN_PAGES_FALSE = @BUILD_MAN_PAGES_FALSE@
+BUILD_MAN_PAGES_TRUE = @BUILD_MAN_PAGES_TRUE@
CAT = @CAT@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
-I$(top_srcdir)/server-src \
-I$(top_srcdir)/tape-src
+LINT = @AMLINT@
+LINTFLAGS = @AMLINTFLAGS@
LIB_EXTENSION = la
@WANT_CHIO_SCSI_TRUE@CHIO_SCSI = chg-scsi-chio
@WANT_CHG_SCSI_TRUE@CHG_SCSI = chg-scsi
LDADD = ../common-src/libamanda.$(LIB_EXTENSION) \
../server-src/libamserver.$(LIB_EXTENSION) \
../tape-src/libamtape.$(LIB_EXTENSION) \
- ../common-src/libamanda.$(LIB_EXTENSION)
+ ../common-src/libamanda.$(LIB_EXTENSION) \
+ $(READLINE_LIBS)
SUFFIXES = .pl .sh
-chg_scsi_SOURCES = chg-scsi.c libscsi.h scsi-defs.h \
- scsi-aix.c scsi-changer-driver.c scsi-hpux_new.c scsi-irix.c \
- scsi-linux.c scsi-solaris.c scsi-bsd.c scsi-cam.c sense.c
+chg_scsi_CSRC = chg-scsi.c scsi-aix.c scsi-changer-driver.c \
+ scsi-hpux_new.c scsi-irix.c scsi-linux.c scsi-solaris.c \
+ scsi-bsd.c scsi-cam.c sense.c
-chg_scsi_chio_SOURCES = chg-scsi-chio.c scsi-hpux.c scsi-chio.c libscsi.h
+chg_scsi_SOURCES = libscsi.h scsi-defs.h $(chg_scsi_CSRC)
+chg_scsi_chio_CSRC = chg-scsi-chio.c scsi-hpux.c scsi-chio.c
+chg_scsi_chio_SOURCES = libscsi.h $(chg_scsi_chio_CSRC)
EXTRA_DIST = scsi-proto.c
all: all-am
echo chgrp $(SETUID_GROUP) $$pa; \
chgrp $(SETUID_GROUP) $$pa; \
done
+
+lint:
+ @ for p in $(libexec_PROGRAMS) $(EXTRA_PROGRAMS); do \
+ f="$$p.c $(libamandad_la_SOURCES)"; \
+ (cd ../common-src; make listlibsrc); \
+ f="$$f "`cat ../common-src/listlibsrc.output`; \
+ (cd ../server-src; make listlibsrc); \
+ f="$$f "`cat ../server-src/listlibsrc.output`; \
+ (cd ../tape-src; make listlibsrc); \
+ f="$$f "`cat ../tape-src/listlibsrc.output`; \
+ echo $(LINT) $$f; \
+ $(LINT) $(LINTFLAGS) $(CPPFLAGS) $(DEFS) -I. -I../config \
+ $(INCLUDES) $$f; \
+ if [ $$? -ne 0 ]; then \
+ exit 1; \
+ fi; \
+ done; \
+ exit 0
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
chomp ($tapeDevice = `$sbindir/amgetconf$SUF tapedev 2>&1`);
die "tapedev not found in amanda.conf"
- if !$tapeDevice or $tapeDevice =~ m/BUGGY/;
+ if !$tapeDevice or $tapeDevice =~ m/no such parameter/;
chomp ($changerDevice = `$sbindir/amgetconf$SUF changerdev 2>&1`);
chomp $changerDevice;
die "changerdev not found in amanda.conf"
- if !$changerDevice or $changerDevice =~ m/BUGGY/;
+ if !$changerDevice or $changerDevice =~ m/no such parameter/;
#
# Initialise a few global variables
-#!/bin/sh
+#!@SHELL@
#
# Amanda, The Advanced Maryland Automatic Network Disk Archiver
# Copyright (c) 1991-1998 University of Maryland at College Park
-#! /bin/sh
+#! @SHELL@
#
# Amanda, The Advanced Maryland Automatic Network Disk Archiver
# Copyright (c) 1991-1999 University of Maryland at College Park
expr "$1" : '[0-9][0-9]*$' > /dev/null 2>&1
}
+# Need rwx access to the virtual tape itself.
+if ! test -d $SLOTDIR; then
+ echo "Virtual-tape directory $SLOTDIR does not exist." 1>&2
+ exit 2
+fi
+if ! test -w $SLOTDIR; then
+ echo "Virtual-tape directory $SLOTDIR is not writable." 1>&2
+ exit 2
+fi
+
+
# need rwx access to directory of changer file
CHANGERFILE=`amgetconf$SUF changerfile`
CFDir=`dirname ${CHANGERFILE}`
[ -d ${CFDir} -a -r ${CFDir} -a -w ${CFDir} -a -x ${CFDir} ] ||
- { echo "$MYNAME: need 'rwx' access to '$CFDir'" ; exit 2 ; }
+ { echo "$MYNAME: need 'rwx' access to '$CFDir'" 1>&2 ; exit 2 ; }
# check or create changer metadata files
ACCESSFILE=$CHANGERFILE-access
[ -f $ACCESSFILE -a -r $ACCESSFILE -a -w $ACCESSFILE ] ||
echo 0 > $ACCESSFILE ||
- { echo "$MYNAME: could not access or create '$ACCESSFILE'" ; exit 2 ; }
+ { echo "$MYNAME: could not access or create '$ACCESSFILE'" 1>&2 ; exit 2 ; }
CLEANFILE=$CHANGERFILE-clean
[ -f $CLEANFILE -a -r $CLEANFILE -a -w $CLEANFILE ] ||
echo 0 > $CLEANFILE ||
- { echo "$MYNAME: could not access or create '$CLEANFILE'" ; exit 2 ; }
+ { echo "$MYNAME: could not access or create '$CLEANFILE'" 1>&2 ; exit 2 ; }
SLOTFILE=$CHANGERFILE-slot
[ -f $SLOTFILE -a -r $SLOTFILE -a -w $SLOTFILE ] ||
echo 0 > $SLOTFILE ||
- { echo "$MYNAME: could not access or create '$SLOTFILE'" ; exit 2 ; }
+ { echo "$MYNAME: could not access or create '$SLOTFILE'" 1>&2 ; exit 2 ; }
# read and check metadata
ACCESSCOUNT=`cat $ACCESSFILE`
LASTSLOT=`amgetconf$SUF tapecycle`
CURSLOT=0
CLEANSLOT=$LASTSLOT
+NSLOT=`expr $LASTSLOT - $FIRSTSLOT + 1`
load() {
WHICHSLOT=$1;
if [ $WHICHSLOT -ge $FIRSTSLOT -a $WHICHSLOT -le $LASTSLOT ]; then
NEWSLOT=$WHICHSLOT
else
- echo "0 illegal request"
+ echo "$WHICHSLOT illegal slot"
exit 1
fi
elif [ $WHICHSLOT = "clean" ]; then
NEWSLOT=$CLEANSLOT
else
- echo "0 illegal request"
+ echo "$WHICHSLOT illegal request"
exit 1
fi
if [ $NEWSLOT = $CURSLOT ]; then
info() {
readstatus
- echo "$CURSLOT $LASTSLOT $FIRSTSLOT"
+ echo "$CURSLOT $NSLOT 1"
exit 0
}
chomp ($tapeDevice = `$sbindir/amgetconf$SUF tapedev 2>&1`);
die "tapedev not found in amanda.conf"
- if !$tapeDevice or $tapeDevice =~ m/BUGGY/;
+ if !$tapeDevice or $tapeDevice =~ m/no such parameter/;
chomp ($changerDevice = `$sbindir/amgetconf$SUF changerdev 2>&1`);
chomp $changerDevice;
die "changerdev not found in amanda.conf"
- if !$changerDevice or $changerDevice =~ m/BUGGY/;
+ if !$changerDevice or $changerDevice =~ m/no such parameter/;
#
# Initialise a few global variables
#
$current_label = "";
-$current_slot = 0;
+#$current_slot = 0;
$max_slot = 1;
@dow = ("Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat");
-#!/bin/sh
+#!@SHELL@
# chg-juke
#
-#!/bin/sh
+#!@SHELL@
#
# Exit Status:
# 0 Alles Ok
-#!/bin/sh
+#!@SHELL@
#
# Author: Robert Dege
#
-#!/bin/sh
+#!@SHELL@
#
# Exit Status:
# 0 Alles Ok
-#! /bin/sh
+#! @SHELL@
#
# Amanda, The Advanced Maryland Automatic Network Disk Archiver
# Copyright (c) 1991-1999 University of Maryland at College Park
-#!/bin/sh
+#!@SHELL@
#
# Exit Status:
# 0 Alles Ok
-#!/bin/sh
+#!@SHELL@
# chg-rait
#
/*
- * $Id: chg-scsi-chio.c,v 1.8 2006/01/14 04:37:18 paddy_s Exp $
+ * $Id: chg-scsi-chio.c,v 1.12 2006/07/25 18:18:46 martinea Exp $
*
- * chg-scsi.c -- generic SCSI changer driver
+ * chg-scsi-chio.c -- generic SCSI changer driver
*
* This program provides a driver to control generic
* SCSI changers, no matter what platform. The host/OS
#include "amanda.h"
#include "conffile.h"
#include "libscsi.h"
+#include "scsi-defs.h"
char *tapestatfile = NULL;
/*----------------------------------------------------------------------------*/
-/* Some stuff for our own configurationfile */
-typedef struct { /* The information we can get for any drive (configuration) */
- int drivenum; /* Which drive to use in the library */
- int start; /* Which is the first slot we may use */
- int end; /* The last slot we are allowed to use */
- int cleanslot; /* Where the cleaningcartridge stays */
- char *scsitapedev; /* Where can we send raw SCSI commands to the tape */
- char *device; /* Which device is associated to the drivenum */
- char *slotfile; /* Where we should have our memory */
- char *cleanfile; /* Where we count how many cleanings we did */
- char *timefile; /* Where we count the time the tape was used*/
- char *tapestatfile;/* Where can we place some drive stats */
-}config_t;
-
-typedef struct {
- int number_of_configs; /* How many different configurations are used */
- int eject; /* Do the drives need an eject-command */
- int sleep; /* How many seconds to wait for the drive to get ready */
- int cleanmax; /* How many runs could be done with one cleaning tape */
- char *device; /* Which device is our changer */
- config_t *conf;
-}changer_t;
typedef enum{
NUMDRIVE,EJECT,SLEEP,CLEANMAX,DRIVE,START,END,CLEAN,DEVICE,STATFILE,CLEANFILE,DRIVENUM,
typedef struct {
char *word;
- int token;
+ token_t token;
} tokentable_t;
tokentable_t t_table[]={
- { "number_configs",NUMDRIVE},
- { "eject",EJECT},
- { "sleep",SLEEP},
- { "cleanmax",CLEANMAX},
- { "config",DRIVE},
- { "startuse",START},
- { "enduse",END},
- { "cleancart",CLEAN},
- { "dev",DEVICE},
- { "statfile",STATFILE},
- { "cleanfile",CLEANFILE},
- { "drivenum",DRIVENUM},
- { "changerdev",CHANGERDEV},
- { "usagecount",USAGECOUNT},
- { "scsitapedev", SCSITAPEDEV},
- { "tapestatus", TAPESTATFILE},
- { NULL,-1 }
+ { "number_configs", NUMDRIVE},
+ { "eject", EJECT},
+ { "sleep", SLEEP},
+ { "cleanmax", CLEANMAX},
+ { "config", DRIVE},
+ { "startuse", START},
+ { "enduse", END},
+ { "cleancart", CLEAN},
+ { "dev", DEVICE},
+ { "statfile", STATFILE},
+ { "cleanfile", CLEANFILE},
+ { "drivenum", DRIVENUM},
+ { "changerdev", CHANGERDEV},
+ { "usagecount", USAGECOUNT},
+ { "scsitapedev", SCSITAPEDEV},
+ { "tapestatus", TAPESTATFILE},
+ { NULL, -1 }
};
-void init_changer_struct(changer_t *chg,int number_of_config)
- /* Initialize datasructures with default values */
+changer_t *changer;
+
+void init_changer_struct(changer_t *chg, size_t number_of_config);
+void dump_changer_struct(changer_t *chg);
+void free_changer_struct(changer_t **changer);
+void parse_line(char *linebuffer,int *token,char **value);
+int read_config(char *configfile, changer_t *chg);
+int get_current_slot(char *count_file);
+void put_current_slot(char *count_file,int slot);
+void usage(char *argv[]);
+void parse_args(int argc, char *argv[],command *rval);
+int get_relative_target(int fd,int nslots,char *parameter,int loaded,
+ char *changer_file,int slot_offset,int maxslot);
+int is_positive_number(char *tmp);
+int ask_clean(char *tapedev);
+void clean_tape(int fd,char *tapedev,char *cnt_file, int drivenum,
+ int cleancart, int maxclean,char *usagetime);
+int main(int argc, char *argv[]);
+
+
+/*
+ * Initialize data structures with default values
+*/
+void
+init_changer_struct(
+ changer_t * chg,
+ size_t number_of_config)
{
int i;
-
+
+ memset(chg, 0, SIZEOF(*chg));
chg->number_of_configs = number_of_config;
chg->eject = 1;
chg->sleep = 0;
chg->cleanmax = 0;
- chg->device = NULL;
- chg->conf = malloc(sizeof(config_t)*number_of_config);
- if (chg->conf != NULL){
- for (i=0; i < number_of_config; i++){
- chg->conf[i].drivenum = 0;
- chg->conf[i].start = -1;
- chg->conf[i].end = -1;
- chg->conf[i].cleanslot = -1;
- chg->conf[i].device = NULL;
- chg->conf[i].slotfile = NULL;
- chg->conf[i].cleanfile = NULL;
- chg->conf[i].timefile = NULL;
- chg->conf[i].scsitapedev = NULL;
- chg->conf[i].tapestatfile = NULL;
- }
+ chg->device = NULL
+ chg->conf = alloc(SIZEOF(config_t) * number_of_config);
+ for (i=0; i < number_of_config; i++){
+ chg->conf[i].drivenum = 0;
+ chg->conf[i].start = -1;
+ chg->conf[i].end = -1;
+ chg->conf[i].cleanslot = -1;
+ chg->conf[i].device = NULL;
+ chg->conf[i].slotfile = NULL;
+ chg->conf[i].cleanfile = NULL;
+ chg->conf[i].timefile = NULL;
+ chg->conf[i].scsitapedev = NULL;
+ chg->conf[i].tapestatfile = NULL;
+ chg->conf[i].changerident = NULL;
+ chg->conf[i].tapeident = NULL;
}
}
-void dump_changer_struct(changer_t chg)
- /* Dump of information for debug */
+/*
+ * Dump of information for debug
+*/
+void
+dump_changer_struct(
+ changer_t * chg)
{
int i;
- dbprintf(("Number of configurations: %d\n",chg.number_of_configs));
- dbprintf(("Tapes need eject: %s\n",(chg.eject>0?"Yes":"No")));
- dbprintf(("Tapes need sleep: %d seconds\n",chg.sleep));
- dbprintf(("Cleancycles : %d\n",chg.cleanmax));
- dbprintf(("Changerdevice : %s\n",chg.device));
- for (i=0; i<chg.number_of_configs; i++){
- dbprintf(("Tapeconfig Nr: %d\n",i));
- dbprintf((" Drivenumber : %d\n",chg.conf[i].drivenum));
- dbprintf((" Startslot : %d\n",chg.conf[i].start));
- dbprintf((" Endslot : %d\n",chg.conf[i].end));
- dbprintf((" Cleanslot : %d\n",chg.conf[i].cleanslot));
- if (chg.conf[i].device != NULL)
- dbprintf((" Devicename : %s\n",chg.conf[i].device));
+ dbprintf(("Number of configurations: %d\n", chg->number_of_configs));
+ dbprintf(("Tapes need eject: %s\n", (chg->eject>0 ? "Yes" : "No")));
+ dbprintf(("Tapes need sleep: %d seconds\n", chg->sleep));
+ dbprintf(("Cleancycles : %d\n", chg->cleanmax));
+ dbprintf(("Changerdevice : %s\n", chg->device));
+ for (i = 0; i < chg->number_of_configs; i++){
+ dbprintf(("Tapeconfig Nr: %d\n", i));
+ dbprintf((" Drivenumber : %d\n", chg->conf[i].drivenum));
+ dbprintf((" Startslot : %d\n", chg->conf[i].start));
+ dbprintf((" Endslot : %d\n", chg->conf[i].end));
+ dbprintf((" Cleanslot : %d\n", chg->conf[i].cleanslot));
+ if (chg->conf[i].device != NULL)
+ dbprintf((" Devicename : %s\n", chg->conf[i].device));
else
dbprintf((" Devicename : none\n"));
- if (chg.conf[i].scsitapedev != NULL)
- dbprintf((" SCSITapedev : %s\n",chg.conf[i].scsitapedev));
+ if (chg->conf[i].scsitapedev != NULL)
+ dbprintf((" SCSITapedev : %s\n", chg->conf[i].scsitapedev));
else
dbprintf((" SCSITapedev : none\n"));
- if (chg.conf[i].tapestatfile != NULL)
- dbprintf((" statfile : %s\n", chg.conf[i].tapestatfile));
+ if (chg->conf[i].tapestatfile != NULL)
+ dbprintf((" statfile : %s\n", chg->conf[i].tapestatfile));
else
dbprintf((" statfile : none\n"));
- if (chg.conf[i].slotfile != NULL)
- dbprintf((" Slotfile : %s\n",chg.conf[i].slotfile));
+ if (chg->conf[i].slotfile != NULL)
+ dbprintf((" Slotfile : %s\n", chg->conf[i].slotfile));
else
dbprintf((" Slotfile : none\n"));
- if (chg.conf[i].cleanfile != NULL)
- dbprintf((" Cleanfile : %s\n",chg.conf[i].cleanfile));
+ if (chg->conf[i].cleanfile != NULL)
+ dbprintf((" Cleanfile : %s\n", chg->conf[i].cleanfile));
else
dbprintf((" Cleanfile : none\n"));
- if (chg.conf[i].timefile != NULL)
- dbprintf((" Usagecount : %s\n",chg.conf[i].timefile));
+ if (chg->conf[i].timefile != NULL)
+ dbprintf((" Usagecount : %s\n", chg->conf[i].timefile));
else
dbprintf((" Usagecount : none\n"));
}
}
-void free_changer_struct(changer_t *chg)
- /* Free all allocated memory */
+/*
+ * Free all allocated memory
+ */
+void
+free_changer_struct(
+changer_t **changer)
{
+ changer_t *chg;
int i;
+ assert(changer != NULL);
+ assert(*changer != NULL);
+
+ chg = *changer;
if (chg->device != NULL)
- free(chg->device);
+ amfree(chg->device);
for (i=0; i<chg->number_of_configs; i++){
if (chg->conf[i].device != NULL)
- free(chg->conf[i].device);
+ amfree(chg->conf[i].device);
if (chg->conf[i].slotfile != NULL)
- free(chg->conf[i].slotfile);
+ amfree(chg->conf[i].slotfile);
if (chg->conf[i].cleanfile != NULL)
- free(chg->conf[i].cleanfile);
+ amfree(chg->conf[i].cleanfile);
if (chg->conf[i].timefile != NULL)
- free(chg->conf[i].timefile);
+ amfree(chg->conf[i].timefile);
}
if (chg->conf != NULL)
- free(chg->conf);
+ amfree(chg->conf);
chg->conf = NULL;
chg->device = NULL;
+ amfree(*changer);
}
-void parse_line(char *linebuffer,int *token,char **value)
- /* This function parses a line, and returns the token an value */
+/*
+ * This function parses a line, and returns a token and value
+ */
+void
+parse_line(
+ char * linebuffer,
+ int * token,
+ char ** value)
{
char *tok;
int i;
return;
}
-int read_config(char *configfile, changer_t *chg)
- /* This function reads the specified configfile and fills the structure */
+/*
+ * This function reads the specified configfile and fills the structure
+*/
+int
+read_config(
+ char * configfile,
+ changer_t * chg)
{
- int numconf;
+ size_t numconf;
FILE *file;
int init_flag = 0;
int drivenum=0;
- char *linebuffer = NULL;
+ char *linebuffer;
int token;
char *value;
return (-1);
}
- amfree(linebuffer);
- while (NULL!=(linebuffer=agets(file))){
+ while (NULL != (linebuffer = agets(file))) {
+ if (linebuffer[0] == '\0') {
+ amfree(linebuffer);
+ continue;
+ }
parse_line(linebuffer,&token,&value);
if (token != -1){
if (0==init_flag) {
if (token != NUMDRIVE){
- init_changer_struct(chg,numconf);
+ init_changer_struct(chg, numconf);
} else {
numconf = atoi(value);
- init_changer_struct(chg,numconf);
+ init_changer_struct(chg, numconf);
}
init_flag=1;
}
get_pname(), count_file);
return 0;
}
- fscanf(inf,"%d",&retval);
+
+ if (fscanf(inf, "%d", &retval) != 1) {
+ fprintf(stderr, "%s: unable to read current slot file (%s)\n",
+ get_pname(), count_file);
+ retval = 0;
+ }
+
fclose(inf);
return retval;
}
void parse_args(int argc, char *argv[],command *rval)
{
int i=0;
- if ((argc<2)||(argc>3))
+ if ((argc < 2) || (argc > 3)) {
usage(argv);
+ /*NOTREACHED*/
+ }
+
while ((i<COMCOUNT)&&(strcmp(argdefs[i].str,argv[1])))
i++;
- if (i==COMCOUNT)
+ if (i == COMCOUNT) {
usage(argv);
+ /*NOTREACHED*/
+ }
rval->command_code = argdefs[i].command_code;
if (argdefs[i].takesparam) {
- if (argc<3)
+ if (argc < 3) {
usage(argv);
+ /*NOTREACHED*/
+ }
rval->parameter=argv[2];
}
else {
- if (argc>2)
+ if (argc > 2) {
usage(argv);
+ /*NOTREACHED*/
+ }
rval->parameter=0;
}
}
/* used to find actual slot number from keywords next, prev, first, etc */
-int get_relative_target(int fd,int nslots,char *parameter,int loaded,
- char *changer_file,int slot_offset,int maxslot)
+int
+get_relative_target(
+ int fd,
+ int nslots,
+ char * parameter,
+ int loaded,
+ char * changer_file,
+ int slot_offset,
+ int maxslot)
{
int current_slot,i;
+
+ (void)loaded; /* Quiet unused warning */
if (changer_file != NULL)
{
current_slot=get_current_slot(changer_file);
}
i=0;
- while((i<SLOTCOUNT)&&(strcmp(slotdefs[i].str,parameter)))
+ while((i < SLOTCOUNT) && (strcmp(slotdefs[i].str,parameter)))
i++;
switch(i) {
case SLOT_CUR:
- return current_slot;
break;
+
case SLOT_NEXT:
if (++current_slot==nslots+slot_offset)
return slot_offset;
- else
- return current_slot;
break;
+
case SLOT_PREV:
if (--current_slot<slot_offset)
return maxslot;
- else
- return current_slot;
break;
+
case SLOT_FIRST:
return slot_offset;
- break;
+
case SLOT_LAST:
return maxslot;
- break;
+
default:
printf("<none> no slot `%s'\n",parameter);
close(fd);
exit(2);
- };
+ /*NOTREACHED*/
+ }
+ return current_slot;
}
-int ask_clean(char *tapedev)
- /* This function should ask the drive if it wants to be cleaned */
+/*
+ * This function should ask the drive if it wants to be cleaned
+ */
+int
+ask_clean(
+ char * tapedev)
{
return get_clean_state(tapedev);
}
-void clean_tape(int fd,char *tapedev,char *cnt_file, int drivenum,
- int cleancart, int maxclean,char *usagetime)
- /* This function should move the cleaning cartridge into the drive */
+/*
+ * This function should move the cleaning cartridge into the drive
+ */
+void
+clean_tape(
+ int fd,
+ char * tapedev,
+ char * cnt_file,
+ int drivenum,
+ int cleancart,
+ int maxclean,
+ char * usagetime)
{
- int counter=-1;
+ int counter;
+
if (cleancart == -1 ){
return;
}
+
/* Now we should increment the counter */
if (cnt_file != NULL){
counter = get_current_slot(cnt_file);
/* Now we should inform the administrator */
char *mail_cmd;
FILE *mailf;
- mail_cmd = vstralloc(MAILER,
+ int mail_pipe_opened = 1;
+ if(getconf_seen(CNF_MAILTO) && strlen(getconf_str(CNF_MAILTO)) > 0 &&
+ validate_mailto(getconf_str(CNF_MAILTO))) {
+ mail_cmd = vstralloc(MAILER,
" -s", " \"", "AMANDA PROBLEM: PLEASE FIX", "\"",
" ", getconf_str(CNF_MAILTO),
NULL);
- if((mailf = popen(mail_cmd, "w")) == NULL){
- error("could not open pipe to \"%s\": %s",
- mail_cmd, strerror(errno));
- printf("Mail failed\n");
- return;
+ if((mailf = popen(mail_cmd, "w")) == NULL){
+ printf("Mail failed\n");
+ error("could not open pipe to \"%s\": %s",
+ mail_cmd, strerror(errno));
+ /*NOTREACHED*/
+ }
}
+ else{
+ mail_pipe_opened = 0;
+ mailf = stderr;
+ fprintf(mailf, "\nNo mail recipient specified, output redirected to stderr");
+ }
+
fprintf(mailf,"\nThe usage count of your cleaning tape in slot %d",
- cleancart);
+ cleancart);
fprintf(mailf,"\nis more than %d. (cleanmax)",maxclean);
fprintf(mailf,"\nTapedrive %s needs to be cleaned",tapedev);
fprintf(mailf,"\nPlease insert a new cleaning tape and reset");
fprintf(mailf,"\nthe countingfile %s",cnt_file);
- if(pclose(mailf) != 0)
- error("mail command failed: %s", mail_cmd);
+ if(mail_pipe_opened == 1 && pclose(mailf) != 0) {
+ error("mail command failed: %s", mail_cmd);
+ /*NOTREACHED*/
+ }
+
return;
}
}
/* ----------------------------------------------------------------------*/
-int main(int argc, char *argv[])
+int
+main(
+ int argc,
+ char * argv[])
{
- int loaded,target,oldtarget;
+ int loaded;
+ int target = -1;
+ int oldtarget;
command com; /* a little DOS joke */
- changer_t chg;
/*
* drive_num really should be something from the config file, but..
*/
int drive_num = 0;
int need_eject = 0; /* Does the drive need an eject command ? */
- int need_sleep = 0; /* How many seconds to wait for the drive to get ready */
+ unsigned need_sleep = 0; /* How many seconds to wait for the drive to get ready */
int clean_slot = -1;
int maxclean = 0;
char *clean_file=NULL;
int slot_offset;
int confnum;
- int fd, rc, slotcnt, drivecnt;
+ int fd, slotcnt, drivecnt;
int endstatus = 0;
- char *changer_dev, *tape_device;
+ char *changer_dev = NULL;
+ char *tape_device = NULL;
char *changer_file = NULL;
char *scsitapedevice = NULL;
/* Don't die when child closes pipe */
signal(SIGPIPE, SIG_IGN);
- dbopen();
+ dbopen(DBG_SUBDIR_SERVER);
parse_args(argc,argv,&com);
+ changer = alloc(SIZEOF(changer_t));
if(read_conffile(CONFFILE_NAME)) {
fprintf(stderr, "%s: could not find config file \"%s\"",
changer_dev, conffile);
tape_device = getconf_str(CNF_TAPEDEV);
/* Get the configuration parameters */
+
if (strlen(tape_device)==1){
- read_config(changer_file,&chg);
+ read_config(changer_file, changer);
confnum=atoi(tape_device);
- use_slots = chg.conf[confnum].end-chg.conf[confnum].start+1;
- slot_offset = chg.conf[confnum].start;
- drive_num = chg.conf[confnum].drivenum;
- need_eject = chg.eject;
- need_sleep = chg.sleep;
- clean_file = stralloc(chg.conf[confnum].cleanfile);
- clean_slot = chg.conf[confnum].cleanslot;
- maxclean = chg.cleanmax;
- if (NULL != chg.conf[confnum].timefile)
- time_file = stralloc(chg.conf[confnum].timefile);
- if (NULL != chg.conf[confnum].slotfile)
- changer_file = stralloc(chg.conf[confnum].slotfile);
+ use_slots = changer->conf[confnum].end-changer->conf[confnum].start+1;
+ slot_offset = changer->conf[confnum].start;
+ drive_num = changer->conf[confnum].drivenum;
+ need_eject = changer->eject;
+ need_sleep = changer->sleep;
+ clean_file = stralloc(changer->conf[confnum].cleanfile);
+ clean_slot = changer->conf[confnum].cleanslot;
+ maxclean = changer->cleanmax;
+ if (NULL != changer->conf[confnum].timefile)
+ time_file = stralloc(changer->conf[confnum].timefile);
+ if (NULL != changer->conf[confnum].slotfile)
+ changer_file = stralloc(changer->conf[confnum].slotfile);
else
changer_file = NULL;
- if (NULL != chg.conf[confnum].device)
- tape_device = stralloc(chg.conf[confnum].device);
- if (NULL != chg.device)
- changer_dev = stralloc(chg.device);
- if (NULL != chg.conf[confnum].scsitapedev)
- scsitapedevice = stralloc(chg.conf[confnum].scsitapedev);
- if (NULL != chg.conf[confnum].tapestatfile)
- tapestatfile = stralloc(chg.conf[confnum].tapestatfile);
- dump_changer_struct(chg);
+ if (NULL != changer->conf[confnum].device)
+ tape_device = stralloc(changer->conf[confnum].device);
+ if (NULL != changer->device)
+ changer_dev = stralloc(changer->device);
+ if (NULL != changer->conf[confnum].scsitapedev)
+ scsitapedevice = stralloc(changer->conf[confnum].scsitapedev);
+ if (NULL != changer->conf[confnum].tapestatfile)
+ tapestatfile = stralloc(changer->conf[confnum].tapestatfile);
+ dump_changer_struct(changer);
/* get info about the changer */
- if (-1 == (fd = OpenDevice(changer_dev, "changer_dev"))) {
+ fd = OpenDevice(INDEX_CHANGER , changer_dev,
+ "changer_dev", changer->conf[confnum].changerident);
+ if (fd == -1) {
int localerr = errno;
fprintf(stderr, "%s: open: %s: %s\n", get_pname(),
changer_dev, strerror(localerr));
scsitapedevice = stralloc(tape_device);
}
- if ((chg.conf[confnum].end == -1) || (chg.conf[confnum].start == -1)){
+ if ((changer->conf[confnum].end == -1) || (changer->conf[confnum].start == -1)){
slotcnt = get_slot_count(fd);
use_slots = slotcnt;
slot_offset = 0;
}
- free_changer_struct(&chg);
+ free_changer_struct(&changer);
} else {
/* get info about the changer */
- if (-1 == (fd = OpenDevice(changer_dev))) {
+ confnum = 0;
+ fd = OpenDevice(INDEX_CHANGER , changer_dev,
+ "changer_dev", changer->conf[confnum].changerident);
+ if (fd == -1) {
int localerr = errno;
fprintf(stderr, "%s: open: %s: %s\n", get_pname(),
changer_dev, strerror(localerr));
-#ifndef lint
-static char rcsid[] = "$Id: chg-scsi.c,v 1.44 2006/03/09 20:06:10 johnfranks Exp $";
-#endif
+static char rcsid[] = "$Id: chg-scsi.c,v 1.52 2006/07/25 18:18:46 martinea Exp $";
/*
*
*
* The device dependent part is handled by scsi-changer-driver.c
* The SCSI OS interface is handled by scsi-ostype.c
*
- * Original copyrigths:
+ * Original copyrights:
*
* This program provides a driver to control generic
* SCSI changers, no matter what platform. The host/OS
#include "config.h"
-
-
#include "amanda.h"
-
-#ifdef HAVE_DMALLOC_H
-#include <dmalloc.h>
-#endif
-
-
#include "conffile.h"
#include "libscsi.h"
#include "scsi-defs.h"
extern ElementInfo_T *pSTE; /*Storage Element */
extern ElementInfo_T *pIEE; /*Import Export Element */
extern ElementInfo_T *pDTE; /*Data Transfer Element */
-extern int MTE; /*Counter for the above element types */
-extern int STE;
-extern int IEE;
-extern int DTE;
-
-changer_t chg;
+extern size_t MTE; /*Counter for the above element types */
+extern size_t STE;
+extern size_t IEE;
+extern size_t DTE;
int do_inventory = 0; /* Set if load/unload functions thinks an inventory should be done */
int clean_slot = -1;
typedef struct {
char *word;
- int token;
+ token_t token;
} tokentable_t;
-tokentable_t t_table[]={
- { "number_configs",NUMDRIVE},
- { "autoinv", AUTOINV},
- { "eject",EJECT},
- { "sleep",SLEEP},
- { "cleanmax",CLEANMAX},
- { "config",DRIVE},
- { "startuse",START},
- { "enduse",END},
- { "cleancart",CLEAN},
- { "dev",DEVICE},
- { "statfile",STATFILE},
- { "cleanfile",CLEANFILE},
- { "drivenum",DRIVENUM},
- { "changerdev",CHANGERDEV},
- { "usagecount",USAGECOUNT},
- { "scsitapedev", SCSITAPEDEV},
- { "tapestatus", TAPESTATFILE},
- { "labelfile", LABELFILE},
- { "changerident" , CHANGERIDENT},
- { "tapeident", TAPEIDENT},
- { "emubarcode", EMUBARCODE},
- { "havebarcode", HAVEBARCODE},
- { "debuglevel", DEBUGLEVEL},
- { NULL,-1 }
+tokentable_t t_table[] = {
+ { "number_configs", NUMDRIVE},
+ { "autoinv", AUTOINV},
+ { "eject", EJECT},
+ { "sleep", SLEEP},
+ { "cleanmax", CLEANMAX},
+ { "config", DRIVE},
+ { "startuse", START},
+ { "enduse", END},
+ { "cleancart", CLEAN},
+ { "dev", DEVICE},
+ { "statfile", STATFILE},
+ { "cleanfile", CLEANFILE},
+ { "drivenum", DRIVENUM},
+ { "changerdev", CHANGERDEV},
+ { "usagecount", USAGECOUNT},
+ { "scsitapedev", SCSITAPEDEV},
+ { "tapestatus", TAPESTATFILE},
+ { "labelfile", LABELFILE},
+ { "changerident", CHANGERIDENT},
+ { "tapeident", TAPEIDENT},
+ { "emubarcode", EMUBARCODE},
+ { "havebarcode", HAVEBARCODE},
+ { "debuglevel", DEBUGLEVEL},
+ { NULL, -1 }
};
-
-void init_changer_struct(changer_t *chg,int number_of_config)
- /* Initialize datasructures with default values */
+changer_t *changer;
+int ask_clean(char *tapedev);
+int get_current_slot(char *count_file);
+int get_relative_target(int fd, int nslots, char *parameter,
+ int param_index, int loaded, char *slot_file,
+ int slot_offset, int maxslot);
+int is_positive_number(char *tmp);
+int MapBarCode(char *labelfile, MBC_T *result);
+int read_config(char *configfile, changer_t *chg);
+void clean_tape(int fd, char *tapedev, char *cnt_file, int drivenum,
+ int cleancart, int maxclean, char *usagetime);
+void dump_changer_struct(changer_t *chg);
+void free_changer_struct(changer_t **chg);
+void init_changer_struct(changer_t *chg, int number_of_config);
+void parse_line(char *linebuffer, int *token,char **value);
+void put_current_slot(char *count_file, int slot);
+void usage(char *argv[]);
+
+int main(int argc, char *argv[]);
+
+
+/* Initialize data structures with default values */
+void
+init_changer_struct(
+ changer_t *chg,
+ int number_of_config)
{
int i;
+ memset(chg, 0, SIZEOF(*chg));
chg->number_of_configs = number_of_config;
chg->eject = 1;
- chg->sleep = 0;
- chg->autoinv = 0;
- chg->cleanmax = 0;
- chg->havebarcode = 0;
- chg->emubarcode = 0;
- chg->device = NULL;
- chg->labelfile = NULL;
- chg->debuglevel = NULL;
- chg->conf = malloc(sizeof(config_t)*number_of_config);
- if (chg->conf != NULL){
- for (i=0; i < number_of_config; i++){
- chg->conf[i].drivenum = 0;
- chg->conf[i].start = -1;
- chg->conf[i].end = -1;
- chg->conf[i].cleanslot = -1;
- chg->conf[i].device = NULL;
- chg->conf[i].slotfile = NULL;
- chg->conf[i].cleanfile = NULL;
- chg->conf[i].timefile = NULL;
- chg->conf[i].scsitapedev = NULL;
- chg->conf[i].tapestatfile = NULL;
- chg->conf[i].changerident = NULL;
- chg->conf[i].tapeident = NULL;
- }
- } else {
- fprintf(stderr,"init_changer_struct malloc failed\n");
+ chg->conf = alloc(SIZEOF(config_t) * (size_t)number_of_config);
+ for (i=0; i < number_of_config; i++){
+ chg->conf[i].drivenum = 0;
+ chg->conf[i].start = -1;
+ chg->conf[i].end = -1;
+ chg->conf[i].cleanslot = -1;
+ chg->conf[i].device = NULL;
+ chg->conf[i].slotfile = NULL;
+ chg->conf[i].cleanfile = NULL;
+ chg->conf[i].timefile = NULL;
+ chg->conf[i].scsitapedev = NULL;
+ chg->conf[i].tapestatfile = NULL;
+ chg->conf[i].changerident = NULL;
+ chg->conf[i].tapeident = NULL;
}
}
-void dump_changer_struct(changer_t chg)
- /* Dump of information for debug */
+/* Dump of information for debug */
+void
+dump_changer_struct(
+ changer_t *chg)
{
int i;
- dbprintf(("Number of configurations: %d\n",chg.number_of_configs));
- dbprintf(("Tapes need eject: %s\n",(chg.eject>0?"Yes":"No")));
- dbprintf (("\traw: %d\n",chg.eject));
- dbprintf(("Inv. auto update: %s\n",(chg.autoinv>0?"Yes":"No")));
- dbprintf (("\traw: %d\n",chg.autoinv));
- dbprintf(("barcode reader : %s\n",(chg.havebarcode>0?"Yes":"No")));
- dbprintf (("\traw: %d\n",chg.havebarcode));
- dbprintf(("Emulate Barcode : %s\n",(chg.emubarcode>0?"Yes":"No")));
- dbprintf (("\traw: %d\n",chg.emubarcode));
- if (chg.debuglevel != NULL)
- dbprintf(("debug level : %s\n", chg.debuglevel));
- dbprintf(("Tapes need sleep: %d seconds\n",chg.sleep));
- dbprintf(("Cleancycles : %d\n",chg.cleanmax));
- dbprintf(("Changerdevice : %s\n",chg.device));
- if (chg.labelfile != NULL)
- dbprintf(("Labelfile : %s\n", chg.labelfile));
- for (i=0; i<chg.number_of_configs; i++){
+ dbprintf(("Number of configurations: %d\n",chg->number_of_configs));
+ dbprintf(("Tapes need eject: %s\n",(chg->eject>0?"Yes":"No")));
+ dbprintf (("\traw: %d\n",chg->eject));
+ dbprintf(("Inv. auto update: %s\n",(chg->autoinv>0?"Yes":"No")));
+ dbprintf (("\traw: %d\n",chg->autoinv));
+ dbprintf(("barcode reader : %s\n",(chg->havebarcode>0?"Yes":"No")));
+ dbprintf (("\traw: %d\n",chg->havebarcode));
+ dbprintf(("Emulate Barcode : %s\n",(chg->emubarcode>0?"Yes":"No")));
+ dbprintf (("\traw: %d\n",chg->emubarcode));
+ if (chg->debuglevel != NULL)
+ dbprintf(("debug level : %s\n", chg->debuglevel));
+ dbprintf(("Tapes need sleep: %d seconds\n",chg->sleep));
+ dbprintf(("Cleancycles : %d\n",chg->cleanmax));
+ dbprintf(("Changerdevice : %s\n",chg->device));
+ if (chg->labelfile != NULL)
+ dbprintf(("Labelfile : %s\n", chg->labelfile));
+ for (i=0; i<chg->number_of_configs; i++){
dbprintf(("Tapeconfig Nr: %d\n",i));
- dbprintf((" Drivenumber : %d\n",chg.conf[i].drivenum));
- dbprintf((" Startslot : %d\n",chg.conf[i].start));
- dbprintf((" Endslot : %d\n",chg.conf[i].end));
- dbprintf((" Cleanslot : %d\n",chg.conf[i].cleanslot));
+ dbprintf((" Drivenumber : %d\n",chg->conf[i].drivenum));
+ dbprintf((" Startslot : %d\n",chg->conf[i].start));
+ dbprintf((" Endslot : %d\n",chg->conf[i].end));
+ dbprintf((" Cleanslot : %d\n",chg->conf[i].cleanslot));
- if (chg.conf[i].device != NULL)
- dbprintf((" Devicename : %s\n",chg.conf[i].device));
+ if (chg->conf[i].device != NULL)
+ dbprintf((" Devicename : %s\n",chg->conf[i].device));
else
dbprintf((" Devicename : none\n"));
- if (chg.conf[i].changerident != NULL)
- dbprintf((" changerident : %s\n",chg.conf[i].changerident));
+ if (chg->conf[i].changerident != NULL)
+ dbprintf((" changerident : %s\n",chg->conf[i].changerident));
else
dbprintf((" changerident : none\n"));
- if (chg.conf[i].scsitapedev != NULL)
- dbprintf((" SCSITapedev : %s\n",chg.conf[i].scsitapedev));
+ if (chg->conf[i].scsitapedev != NULL)
+ dbprintf((" SCSITapedev : %s\n",chg->conf[i].scsitapedev));
else
dbprintf((" SCSITapedev : none\n"));
- if (chg.conf[i].tapeident != NULL)
- dbprintf((" tapeident : %s\n",chg.conf[i].tapeident));
+ if (chg->conf[i].tapeident != NULL)
+ dbprintf((" tapeident : %s\n",chg->conf[i].tapeident));
else
dbprintf((" tapeident : none\n"));
- if (chg.conf[i].tapestatfile != NULL)
- dbprintf((" statfile : %s\n", chg.conf[i].tapestatfile));
+ if (chg->conf[i].tapestatfile != NULL)
+ dbprintf((" statfile : %s\n", chg->conf[i].tapestatfile));
else
dbprintf((" statfile : none\n"));
- if (chg.conf[i].slotfile != NULL)
- dbprintf((" Slotfile : %s\n",chg.conf[i].slotfile));
+ if (chg->conf[i].slotfile != NULL)
+ dbprintf((" Slotfile : %s\n",chg->conf[i].slotfile));
else
dbprintf((" Slotfile : none\n"));
- if (chg.conf[i].cleanfile != NULL)
- dbprintf((" Cleanfile : %s\n",chg.conf[i].cleanfile));
+ if (chg->conf[i].cleanfile != NULL)
+ dbprintf((" Cleanfile : %s\n",chg->conf[i].cleanfile));
else
dbprintf((" Cleanfile : none\n"));
- if (chg.conf[i].timefile != NULL)
- dbprintf((" Usagecount : %s\n",chg.conf[i].timefile));
+ if (chg->conf[i].timefile != NULL)
+ dbprintf((" Usagecount : %s\n",chg->conf[i].timefile));
else
dbprintf((" Usagecount : none\n"));
}
}
-void free_changer_struct(changer_t *chg)
- /* Free all allocated memory */
+/* Free all allocated memory */
+void
+free_changer_struct(
+ changer_t **changer)
{
+ changer_t *chg;
int i;
+ chg = *changer;
if (chg->device != NULL)
- free(chg->device);
- for (i=0; i<chg->number_of_configs; i++){
+ amfree(chg->device);
+ for (i = 0; i < chg->number_of_configs; i++){
if (chg->conf[i].device != NULL)
- free(chg->conf[i].device);
+ amfree(chg->conf[i].device);
if (chg->conf[i].slotfile != NULL)
- free(chg->conf[i].slotfile);
+ amfree(chg->conf[i].slotfile);
if (chg->conf[i].cleanfile != NULL)
- free(chg->conf[i].cleanfile);
+ amfree(chg->conf[i].cleanfile);
if (chg->conf[i].timefile != NULL)
- free(chg->conf[i].timefile);
+ amfree(chg->conf[i].timefile);
}
if (chg->conf != NULL)
- free(chg->conf);
+ amfree(chg->conf);
chg->conf = NULL;
chg->device = NULL;
+ amfree(*changer);
}
-void parse_line(char *linebuffer,int *token,char **value)
- /* This function parses a line, and returns a token and value */
+/* This function parses a line, and returns a token and value */
+void
+parse_line(
+ char *linebuffer,
+ int *token,
+ char **value)
{
char *tok;
int i;
}
tok=strtok(NULL," \t\n");
}
- return;
}
-int read_config(char *configfile, changer_t *chg)
- /* This function reads the specified configfile and fills the structure */
+/* This function reads the specified configfile and fills the structure */
+int
+read_config(
+ char *configfile,
+ changer_t *chg)
{
int numconf;
FILE *file;
int init_flag = 0;
int drivenum=0;
- char *linebuffer = NULL;
+ char *linebuffer;
int token;
char *value;
char *p;
numconf = 1; /* At least one configuration is assumed */
/* If there are more, it should be the first entry in the configurationfile */
-
- if (NULL==(file=fopen(configfile,"r"))){
+ assert(chg != NULL);
+ if ((file=fopen(configfile,"r")) == NULL) {
return (-1);
}
- amfree(linebuffer);
- while ((NULL!=(linebuffer=agets(file)))) {
- parse_line(linebuffer,&token,&value);
+ while ((NULL != (linebuffer = agets(file)))) {
+ if (linebuffer[0] == '\0') {
+ amfree(linebuffer);
+ continue;
+ }
+ parse_line(linebuffer, &token, &value);
if (token != -1){
- if (0==init_flag) {
+ if (value == NULL)
+ value = "0";
+
+ if (init_flag == 0) {
if (token != NUMDRIVE){
- init_changer_struct(chg,numconf);
+ init_changer_struct(chg, numconf);
} else {
numconf = atoi(value);
- init_changer_struct(chg,numconf);
+ if (numconf < 1 || numconf > 100) {
+ fprintf(stderr,"numconf %d is bad\n", numconf);
+ numconf = 1;
+ }
+ init_changer_struct(chg, numconf);
}
init_flag=1;
}
- switch (token){
+ switch (token) {
case NUMDRIVE: if (atoi(value) != numconf)
fprintf(stderr,"Error: number_drives at wrong place, should be "\
"first in file\n");
chg->havebarcode = atoi(value);
break;
case SLEEP:
- chg->sleep = atoi(value);
+ chg->sleep = (unsigned)atoi(value);
break;
case LABELFILE:
chg->labelfile = stralloc(value);
break;
case CHANGERIDENT:
chg->conf[drivenum].changerident = stralloc(value);
+ if (drivenum < 0 || drivenum > 100) {
+ fprintf(stderr,"drivenum %d is bad\n", drivenum);
+ drivenum = 0;
+ }
p = chg->conf[drivenum].changerident;
while (*p != '\0')
{
break;
case DRIVE:
drivenum = atoi(value);
- if(drivenum >= numconf){
+ if (drivenum < 0) {
+ fprintf(stderr,"Error: drive must be >= 0\n");
+ drivenum = 0;
+ } else if (drivenum >= numconf) {
fprintf(stderr,"Error: drive must be less than number_drives\n");
+ drivenum = numconf;
}
break;
case DRIVENUM:
* we use a file to store the current slot. It is not ideal
* but it gets the job done
*/
-int get_current_slot(char *count_file)
+int
+get_current_slot(
+ char *count_file)
{
FILE *inf;
- int retval;
+ int retval = -1;
int ret; /* return value for the fscanf function */
if ((inf=fopen(count_file,"r")) == NULL) {
fprintf(stderr, "%s: unable to open (%s)\n",
get_pname(), count_file);
exit(2);
}
+
ret = fscanf(inf,"%d",&retval);
fclose(inf);
retval = -1;
}
+ if (retval < 0 || retval > 10000) {
+ retval = -1;
+ }
return retval;
}
-void put_current_slot(char *count_file,int slot)
+void
+put_current_slot(
+ char *count_file,
+ int slot)
{
FILE *inf;
+ if (!count_file)
+ return;
+
if ((inf=fopen(count_file,"w")) == NULL) {
fprintf(stderr, "%s: unable to open current slot file (%s)\n",
get_pname(), count_file);
* The passed struct MBC_T will hold the found entry in the DB
*/
-int MapBarCode(char *labelfile, MBC_T *result)
+int
+MapBarCode(
+ char *labelfile,
+ MBC_T *result)
{
FILE *fp;
int version;
LabelV2_T *plabelv2;
- int unusedpos = 0;
+ long unusedpos= 0;
int unusedrec = 0;
- int pos = 0;
- int record = 0;
- int volseen = 0;
- int loop = 1;
- int rsize = 0;
+ int record = 0;
+ int loop = 1;
+ size_t rsize;
+ long pos;
+ int rc;
DebugPrint(DEBUG_INFO,SECTION_MAP_BARCODE,"MapBarCode : Parameter\n");
DebugPrint(DEBUG_INFO,SECTION_MAP_BARCODE,"labelfile -> %s, vol -> %s, barcode -> %s, action -> %c, slot -> %d, from -> %d\n",
{
DebugPrint(DEBUG_ERROR,SECTION_MAP_BARCODE,"Got empty labelfile (NULL)\n");
ChgExit("MapBarCode", "MapBarCode name of labelfile is not set\n",FATAL);
+ /*NOTREACHED*/
}
if (access(labelfile, F_OK) == -1)
{
{
DebugPrint(DEBUG_ERROR,SECTION_MAP_BARCODE," failed\n");
ChgExit("MapBarCode", "MapBarCode, creating labelfile failed\n", FATAL);
+ /*NOTREACHED*/
}
fprintf(fp,":%d:", LABEL_DB_VERSION);
fclose(fp);
{
DebugPrint(DEBUG_ERROR,SECTION_MAP_BARCODE,"MapBarCode : failed to open %s\n", labelfile);
ChgExit("MapBarCode", "MapBarCode, opening labelfile for read/write failed\n", FATAL);
+ /*NOTREACHED*/
}
- fscanf(fp,":%d:", &version);
+ if (fscanf(fp,":%d:", &version) != 1) {
+ ChgExit("MapBarCode", "MapBarCode, DB Version unreadable.\n", FATAL);
+ /*NOTREACHED*/
+ }
DebugPrint(DEBUG_INFO,SECTION_MAP_BARCODE,"MapBarCode : DB version %d\n", version);
pos = ftell(fp);
if (version != LABEL_DB_VERSION)
{
ChgExit("MapBarCode", "MapBarCode, DB Version does not match\n", FATAL);
+ /*NOTREACHED*/
}
- if (( plabelv2 = (LabelV2_T *)malloc(sizeof(LabelV2_T))) == NULL)
+ if (( plabelv2 = (LabelV2_T *)alloc(SIZEOF(LabelV2_T))) == NULL)
{
- DebugPrint(DEBUG_ERROR,SECTION_MAP_BARCODE,"MapBarCode : malloc failed\n");
- ChgExit("MapBarCode", "MapBarCode malloc failed\n", FATAL);
+ DebugPrint(DEBUG_ERROR,SECTION_MAP_BARCODE,"MapBarCode : alloc failed\n");
+ ChgExit("MapBarCode", "MapBarCode alloc failed\n", FATAL);
+ /*NOTREACHED*/
}
- memset(plabelv2, 0, sizeof(LabelV2_T));
+ memset(plabelv2, 0, SIZEOF(LabelV2_T));
while(feof(fp) == 0 && loop == 1)
{
- rsize = fread(plabelv2, 1, sizeof(LabelV2_T), fp);
- if (rsize == sizeof(LabelV2_T))
+ rsize = fread(plabelv2, 1, SIZEOF(LabelV2_T), fp);
+ if (rsize == SIZEOF(LabelV2_T))
{
record++;
DebugPrint(DEBUG_INFO,SECTION_MAP_BARCODE,"MapBarCode : (%d) VolTag \"%s\", BarCode %s, inuse %d, slot %d, from %d, loadcount %d\n",record,
* Only dump the info
*/
case BARCODE_DUMP:
- printf("Slot -> %d, from -> %d, valid -> %d, Tag -> %s, Barcode -> %s, Loadcount %d\n",
+ printf("Slot -> %d, from -> %d, valid -> %d, Tag -> %s, Barcode -> %s, Loadcount %u\n",
plabelv2->slot,
plabelv2->from,
plabelv2->valid,
* Set all the record to invalid, used by the Inventory function
*/
case RESET_VALID:
- fseek(fp, pos, SEEK_SET);
plabelv2->valid = 0;
- fwrite(plabelv2, 1, sizeof(LabelV2_T), fp);
+ if (fseek(fp, pos, SEEK_SET) == -1) {
+ fclose(fp);
+ amfree(plabelv2);
+ return 0; /* Fail */
+ }
+ if (fwrite(plabelv2, 1, SIZEOF(LabelV2_T), fp) < SIZEOF(LabelV2_T)) {
+ fclose(fp);
+ amfree(plabelv2);
+ return 0; /* Fail */
+ }
break;
/*
* Add an entry
unusedrec = record;
}
- /*
- * Hmm whats that ?
- */
- if (strcmp(plabelv2->voltag, result->data.voltag) == 0)
- {
- volseen = record;
- }
-
/*
* OK this record matches the barcode label
* so use/update it
*/
if (strcmp(plabelv2->barcode, result->data.barcode) == 0)
{
+
DebugPrint(DEBUG_INFO,SECTION_MAP_BARCODE,"MapBarCode : update entry\n");
- fseek(fp, pos, SEEK_SET);
+ if (fseek(fp, pos, SEEK_SET) == -1) {
+ fclose(fp);
+ amfree(plabelv2);
+ return 0; /* Fail */
+ }
plabelv2->valid = 1;
plabelv2->from = result->data.from;
plabelv2->slot = result->data.slot;
plabelv2->LoadCount = plabelv2->LoadCount + result->data.LoadCount;
- strcpy(plabelv2->voltag, result->data.voltag);
- strcpy(plabelv2->barcode, result->data.barcode);
- fwrite(plabelv2, 1, sizeof(LabelV2_T), fp);
+ strncpy(plabelv2->voltag, result->data.voltag,
+ SIZEOF(plabelv2->voltag));
+ strncpy(plabelv2->barcode, result->data.barcode,
+ SIZEOF(plabelv2->barcode));
+ rc = (fwrite(plabelv2, 1, SIZEOF(LabelV2_T), fp) < SIZEOF(LabelV2_T));
fclose(fp);
- free(plabelv2);
- return(1);
+ amfree(plabelv2);
+ return(rc);
}
break;
/*
if (strcmp(plabelv2->voltag, result->data.voltag) == 0)
{
DebugPrint(DEBUG_INFO,SECTION_MAP_BARCODE,"MapBarCode FIND_SLOT : \n");
- memcpy(&(result->data), plabelv2, sizeof(LabelV2_T));
- free(plabelv2);
+ memcpy(&(result->data), plabelv2, SIZEOF(LabelV2_T));
+ amfree(plabelv2);
return(1);
}
break;
if (strcmp(plabelv2->voltag, result->data.voltag) == 0)
{
DebugPrint(DEBUG_INFO,SECTION_MAP_BARCODE,"MapBarCode UPDATE_SLOT : update entry\n");
- fseek(fp, pos, SEEK_SET);
- strcpy(plabelv2->voltag, result->data.voltag);
- strcpy(plabelv2->barcode, result->data.barcode);
+ if (fseek(fp, pos, SEEK_SET) == -1) {
+ fclose(fp);
+ amfree(plabelv2);
+ return 0; /* Fail */
+ }
+ strncpy(plabelv2->voltag, result->data.voltag,
+ SIZEOF(plabelv2->voltag));
+ strncpy(plabelv2->barcode, result->data.barcode,
+ SIZEOF(plabelv2->barcode));
plabelv2->valid = 1;
plabelv2->slot = result->data.slot;
plabelv2->from = result->data.from;
plabelv2->LoadCount = plabelv2->LoadCount + result->data.LoadCount;
- fwrite(plabelv2, 1, sizeof(LabelV2_T), fp);
+ rc = (fwrite(plabelv2, 1, SIZEOF(LabelV2_T), fp) < SIZEOF(LabelV2_T));
fclose(fp);
- free(plabelv2);
- return(1);
+ amfree(plabelv2);
+ return(rc);
}
break;
/*
DebugPrint(DEBUG_INFO,SECTION_MAP_BARCODE,"MapBarCode : VOL %s match\n", result->data.voltag);
fclose(fp);
- memcpy(&(result->data), plabelv2, sizeof(LabelV2_T));
- free(plabelv2);
+ memcpy(&(result->data), plabelv2, SIZEOF(LabelV2_T));
+ amfree(plabelv2);
return(1);
}
break;
DebugPrint(DEBUG_INFO,SECTION_MAP_BARCODE,"MapBarCode : BARCODE %s match\n", result->data.barcode);
fclose(fp);
- memcpy(&(result->data), plabelv2, sizeof(LabelV2_T));
- free(plabelv2);
+ memcpy(&(result->data), plabelv2, SIZEOF(LabelV2_T));
+ amfree(plabelv2);
return(1);
}
break;
pos = ftell(fp);
} else {
DebugPrint(DEBUG_INFO,SECTION_MAP_BARCODE,"MapBarCode : feof (%d)\n", feof(fp));
- DebugPrint(DEBUG_INFO,SECTION_MAP_BARCODE,"MapBarCode : error in read record expect %d, got %d\n",sizeof(LabelV2_T), rsize);
+ DebugPrint(DEBUG_INFO,SECTION_MAP_BARCODE,"MapBarCode : error in read record expect %d, got %d\n",SIZEOF(LabelV2_T), rsize);
loop=0;
}
}
if (unusedpos != 0)
{
DebugPrint(DEBUG_INFO,SECTION_MAP_BARCODE,"MapBarCode : reuse record %d\n", unusedrec);
- fseek(fp, unusedpos, SEEK_SET);
+ if (fseek(fp, unusedpos, SEEK_SET) == -1) {
+ fclose(fp);
+ amfree(plabelv2);
+ return 0; /* Fail */
+ }
}
/*
* Set all values to zero
*/
- memset(plabelv2, 0, sizeof(LabelV2_T));
+ memset(plabelv2, 0, SIZEOF(LabelV2_T));
- strcpy(plabelv2->voltag, result->data.voltag);
- strncpy(plabelv2->barcode, result->data.barcode, TAG_SIZE);
+ strncpy(plabelv2->voltag, result->data.voltag,
+ SIZEOF(plabelv2->voltag));
+ strncpy(plabelv2->barcode, result->data.barcode,
+ SIZEOF(plabelv2->barcode));
plabelv2->valid = 1;
plabelv2->from = result->data.from;
plabelv2->slot = result->data.slot;
- fwrite(plabelv2, 1, sizeof(LabelV2_T), fp);
+ rc = (fwrite(plabelv2, 1, SIZEOF(LabelV2_T), fp) < SIZEOF(LabelV2_T));
fclose(fp);
- free(plabelv2);
- return(1);
+ amfree(plabelv2);
+ return(rc);
}
/*
* found, so return an 0
*/
fclose(fp);
- free(plabelv2);
+ amfree(plabelv2);
return(0);
}
char *parameter;
} command;
+void parse_args(int argc, char *argv[],command *rval);
/* major command line args */
#define COMCOUNT 13
{"last",SLOT_LAST,0},
{"advance",SLOT_ADVANCE,0},
};
-#define SLOTCOUNT (sizeof(slotdefs) / sizeof(slotdefs[0]))
+#define SLOTCOUNT (int)(sizeof(slotdefs) / sizeof(slotdefs[0]))
-int is_positive_number(char *tmp) /* is the string a valid positive int? */
+/* is the string a valid positive int? */
+int
+is_positive_number(
+ char *tmp)
{
int i=0;
if ((tmp==NULL)||(tmp[0]==0))
return 0;
}
-void usage(char *argv[])
+void
+usage(
+ char *argv[])
{
int cnt;
printf("%s: Usage error.\n", argv[0]);
}
-void parse_args(int argc, char *argv[],command *rval)
+void
+parse_args(
+ int argc,
+ char *argv[],
+ command *rval)
{
- int i=0;
+ int i;
+
for (i=0; i < argc; i++)
dbprintf(("ARG [%d] : %s\n", i, argv[i]));
i = 0;
}
/* used to find actual slot number from keywords next, prev, first, etc */
-int get_relative_target(int fd,int nslots,char *parameter,int param_index,
- int loaded,char *slot_file,
- int slot_offset,int maxslot)
+int
+get_relative_target(
+ int fd,
+ int nslots,
+ char *parameter,
+ int param_index,
+ int loaded,
+ char *slot_file,
+ int slot_offset,
+ int maxslot)
{
int current_slot;
+ (void)loaded; /* Quiet unused parameter warning */
+
current_slot = get_current_slot(slot_file);
- if (current_slot > maxslot){
+ if (current_slot > maxslot) {
current_slot = slot_offset;
}
- if (current_slot < slot_offset){
+ if (current_slot < slot_offset) {
current_slot = slot_offset;
}
switch(param_index) {
case SLOT_CUR:
return current_slot;
- break;
+
case SLOT_NEXT:
case SLOT_ADVANCE:
if (++current_slot==nslots+slot_offset)
return slot_offset;
- else
- return current_slot;
- break;
+ return current_slot;
+
case SLOT_PREV:
if (--current_slot<slot_offset)
return maxslot;
- else
- return current_slot;
- break;
+ return current_slot;
+
case SLOT_FIRST:
return slot_offset;
- break;
+
case SLOT_LAST:
return maxslot;
- break;
+
default:
- printf("<none> no slot `%s'\n",parameter);
- close(fd);
- exit(2);
break;
- };
- return(-1); /* never executed */
+ }
+ printf("<none> no slot `%s'\n",parameter);
+ close(fd);
+ exit(2);
+ /*NOTREACHED*/
}
-int ask_clean(char *tapedev)
- /* This function should ask the drive if it wants to be cleaned */
+/* This function should ask the drive if it wants to be cleaned */
+int
+ask_clean(
+ char *tapedev)
{
int ret;
return ret;
}
-void clean_tape(int fd,char *tapedev,char *cnt_file, int drivenum,
- int cleancart, int maxclean,char *usagetime)
- /* This function should move the cleaning cartridge into the drive */
+/* This function should move the cleaning cartridge into the drive */
+void
+clean_tape(
+ int fd,
+ char *tapedev,
+ char *cnt_file,
+ int drivenum,
+ int cleancart,
+ int maxclean,
+ char *usagetime)
{
- int counter=-1;
+ int counter;
+
if (cleancart == -1 ){
return;
}
+
/* Now we should increment the counter */
if (cnt_file != NULL){
counter = get_current_slot(cnt_file);
counter++;
if (counter>=maxclean){
/* Now we should inform the administrator */
- char *mail_cmd;
- FILE *mailf;
- mail_cmd = vstralloc(MAILER,
+ char *mail_cmd = NULL;
+ FILE *mailf = NULL;
+ int mail_pipe_opened = 1;
+ if(getconf_seen(CNF_MAILTO) && strlen(getconf_str(CNF_MAILTO)) > 0 &&
+ validate_mailto(getconf_str(CNF_MAILTO))) {
+ mail_cmd = vstralloc(MAILER,
" -s", " \"", "AMANDA PROBLEM: PLEASE FIX", "\"",
" ", getconf_str(CNF_MAILTO),
NULL);
- if((mailf = popen(mail_cmd, "w")) == NULL){
- error("could not open pipe to \"%s\": %s",
- mail_cmd, strerror(errno));
- printf("Mail failed\n");
- return;
+ if((mailf = popen(mail_cmd, "w")) == NULL){
+ printf("Mail failed\n");
+ error("could not open pipe to \"%s\": %s",
+ mail_cmd, strerror(errno));
+ /*NOTREACHED*/
+ }
}
+ else {
+ mail_pipe_opened = 0;
+ mailf = stderr;
+ fprintf(mailf, "\nNo mail recipient specified, output redirected to stderr");
+ }
fprintf(mailf,"\nThe usage count of your cleaning tape in slot %d",
cleancart);
fprintf(mailf,"\nis more than %d. (cleanmax)",maxclean);
fprintf(mailf,"\nPlease insert a new cleaning tape and reset");
fprintf(mailf,"\nthe countingfile %s",cnt_file);
- if(pclose(mailf) != 0)
- error("mail command failed: %s", mail_cmd);
-
+ if(mail_pipe_opened == 1 && pclose(mailf) != 0) {
+ error("mail command failed: %s", mail_cmd);
+ /*NOTREACHED*/
+ }
return;
}
- put_current_slot(cnt_file,counter);
+ put_current_slot(cnt_file, counter);
}
load(fd,drivenum,cleancart);
/*
sleep(60);
if (drive_loaded(fd, drivenum))
- unload(fd,drivenum,cleancart);
- unlink(usagetime);
+ unload(fd, drivenum, cleancart);
+ if (usagetime)
+ unlink(usagetime);
}
/* ----------------------------------------------------------------------*/
-int main(int argc, char *argv[])
+int
+main(
+ int argc,
+ char *argv[])
{
- int loaded,target,oldtarget;
+ int loaded;
+ int target, oldtarget;
command com; /* a little DOS joke */
int x;
-
- MBC_T *pbarcoderes = malloc(sizeof(MBC_T));
+ MBC_T *pbarcoderes;
/*
* drive_num really should be something from the config file, but..
* for now, it is set to zero, since most of the common changers
* used by amanda only have one drive ( until someone wants to
* use an EXB60/120, or a Breece Hill Q45.. )
*/
- unsigned char emubarcode = 0;
- int drive_num = 0;
- int need_eject = 0; /* Does the drive need an eject command ? */
- int need_sleep = 0; /* How many seconds to wait for the drive to get ready */
+ unsigned char emubarcode;
+ int drive_num;
+ int need_eject; /* Does the drive need an eject command ? */
+ time_t need_sleep; /* How many seconds to wait for the drive to get ready */
- int maxclean = 0;
- char *clean_file=NULL;
- char *time_file=NULL;
+ int maxclean;
+ char *clean_file;
+ char *time_file;
/*
* For the emubarcode stuff
int slot_offset;
int confnum;
- int fd, slotcnt, drivecnt;
+ int fd;
+ int slotcnt;
+ int drivecnt;
int endstatus = 0;
- char *changer_dev = NULL;
- char *tape_device = NULL;
- char *chg_scsi_conf = NULL; /* The config file for us */
- char *slot_file = NULL; /* Where we will place the info which
+ char *changer_dev;
+ char *tape_device;
+ char *chg_scsi_conf; /* The config file for us */
+ char *slot_file; /* Where we will place the info which
* slot is loaded
*/
- char *scsitapedevice = NULL;
+ char *scsitapedevice;
int param_index = 0;
- memset(pbarcoderes, 0 , sizeof(MBC_T));
- chg.number_of_configs = 0;
- chg.eject = 0;
- chg.sleep = 0;
- chg.cleanmax = 0;
- chg.device = NULL;
- chg.labelfile = NULL;
- chg.conf = NULL;
+ changer = alloc(SIZEOF(changer_t));
+ pbarcoderes = alloc(SIZEOF(MBC_T));
+
+ memset(pbarcoderes, 0 , SIZEOF(MBC_T));
+ changer->number_of_configs = 0;
+ changer->eject = 0;
+ changer->sleep = 0;
+ changer->cleanmax = 0;
+ changer->device = NULL;
+ changer->labelfile = NULL;
+ changer->conf = NULL;
#ifdef CHG_SCSI_STANDALONE
printf("Ups standalone\n");
#else
/* Don't die when child closes pipe */
signal(SIGPIPE, SIG_IGN);
- dbopen();
+ dbopen(DBG_SUBDIR_SERVER);
- dbprintf(("chg-scsi: %s\n",rcsid));
+ dbprintf(("chg-scsi: %s\n", rcsid));
ChangerDriverVersion();
if (debug_file == NULL)
parse_args(argc,argv,&com);
- pDev = (OpenFiles_T *)malloc(sizeof(OpenFiles_T) * CHG_MAXDEV);
- memset(pDev, 0, sizeof(OpenFiles_T) * CHG_MAXDEV );
+ pDev = (OpenFiles_T *)alloc(SIZEOF(OpenFiles_T) * CHG_MAXDEV);
+ memset(pDev, 0, SIZEOF(OpenFiles_T) * CHG_MAXDEV );
switch(com.command_code)
case COM_SCAN:
ScanBus(1);
return(0);
- break;
+
case COM_GEN_CONF:
ScanBus(0);
PrintConf();
return(0);
- break;
+
default:
break;
}
if(read_conffile(CONFFILE_NAME)) {
perror(CONFFILE_NAME);
exit(1);
+ /*NOTREACHED*/
}
chg_scsi_conf = getconf_str(CNF_CHNGRFILE);
/* Attention, this will not support more than 10 tape devices 0-9 */
/* */
if (strlen(tape_device)==1){
- if (read_config(chg_scsi_conf,&chg) == -1)
+ if (read_config(chg_scsi_conf, changer) == -1)
{
fprintf(stderr, "%s open: of %s failed\n", get_pname(), chg_scsi_conf);
- return 2;
+ return (2);
}
confnum=atoi(tape_device);
- if (chg.number_of_configs == 0)
+ if (changer->number_of_configs == 0)
{
- fprintf(stderr,"%s: chg.conf[%d] == NULL\n",get_pname(), confnum);
- return(2);
+ fprintf(stderr,"%s: changer->conf[%d] == NULL\n",
+ get_pname(), confnum);
+ return (2);
+ }
+ if (confnum >= changer->number_of_configs) {
+ fprintf(stderr,"%s: Configuration %s config # out of range (%d >= %d)\n",
+ get_pname(), chg_scsi_conf,
+ confnum,
+ changer->number_of_configs);
+ return (2);
}
- use_slots = chg.conf[confnum].end-chg.conf[confnum].start+1;
- slot_offset = chg.conf[confnum].start;
- drive_num = chg.conf[confnum].drivenum;
- need_eject = chg.eject;
- need_sleep = chg.sleep;
-
- if ( NULL != chg.conf[confnum].cleanfile)
- clean_file = stralloc(chg.conf[confnum].cleanfile);
+
+ use_slots = changer->conf[confnum].end-changer->conf[confnum].start+1;
+ slot_offset = changer->conf[confnum].start;
+ drive_num = changer->conf[confnum].drivenum;
+ need_eject = changer->eject;
+ need_sleep = changer->sleep;
+
+ if ( NULL != changer->conf[confnum].cleanfile)
+ clean_file = stralloc(changer->conf[confnum].cleanfile);
else
clean_file = NULL;
- clean_slot = chg.conf[confnum].cleanslot;
- maxclean = chg.cleanmax;
- emubarcode = chg.emubarcode;
- if (NULL != chg.conf[confnum].timefile)
- time_file = stralloc(chg.conf[confnum].timefile);
+ clean_slot = changer->conf[confnum].cleanslot;
+ maxclean = changer->cleanmax;
+ emubarcode = changer->emubarcode;
+ if (NULL != changer->conf[confnum].timefile)
+ time_file = stralloc(changer->conf[confnum].timefile);
+ else
+ time_file = NULL;
- if (NULL != chg.conf[confnum].slotfile)
- slot_file = stralloc(chg.conf[confnum].slotfile);
+ if (NULL != changer->conf[confnum].slotfile)
+ slot_file = stralloc(changer->conf[confnum].slotfile);
else
slot_file = NULL;
- if (NULL != chg.conf[confnum].device)
- tape_device = stralloc(chg.conf[confnum].device);
+ if (NULL != changer->conf[confnum].device)
+ tape_device = stralloc(changer->conf[confnum].device);
+ else
+ tape_device = NULL;
- if (NULL != chg.device)
- changer_dev = stralloc(chg.device);
+ if (NULL != changer->device)
+ changer_dev = stralloc(changer->device);
+ else
+ changer_dev = NULL;
- if (NULL != chg.conf[confnum].scsitapedev)
- scsitapedevice = stralloc(chg.conf[confnum].scsitapedev);
+ if (NULL != changer->conf[confnum].scsitapedev)
+ scsitapedevice = stralloc(changer->conf[confnum].scsitapedev);
+ else
+ scsitapedevice = NULL;
- if (NULL != chg.conf[confnum].tapestatfile)
- tapestatfile = stralloc(chg.conf[confnum].tapestatfile);
- dump_changer_struct(chg);
+ if (NULL != changer->conf[confnum].tapestatfile)
+ tapestatfile = stralloc(changer->conf[confnum].tapestatfile);
+ else
+ tapestatfile = NULL;
+ dump_changer_struct(changer);
* If we can't open it fail with a message
*/
- if (OpenDevice(INDEX_CHANGER , changer_dev, "changer_dev", chg.conf[confnum].changerident) == 0)
+ if (OpenDevice(INDEX_CHANGER , changer_dev, "changer_dev", changer->conf[confnum].changerident) == 0)
{
int localerr = errno;
fprintf(stderr, "%s: open: %s: %s\n", get_pname(),
*/
if (tape_device != NULL)
{
- if (OpenDevice(INDEX_TAPE, tape_device, "tape_device", chg.conf[confnum].tapeident) == 0)
+ if (OpenDevice(INDEX_TAPE, tape_device, "tape_device", changer->conf[confnum].tapeident) == 0)
{
dbprintf(("warning open of %s: failed\n", tape_device));
}
*/
if (scsitapedevice != NULL)
{
- if (OpenDevice(INDEX_TAPECTL, scsitapedevice, "scsitapedevice", chg.conf[confnum].tapeident) == 0)
+ if (OpenDevice(INDEX_TAPECTL, scsitapedevice, "scsitapedevice", changer->conf[confnum].tapeident) == 0)
{
dbprintf(("warning open of %s: failed\n", scsitapedevice));
}
}
- if ((chg.conf[confnum].end == -1) || (chg.conf[confnum].start == -1)){
+ if ((changer->conf[confnum].end == -1) || (changer->conf[confnum].start == -1)){
slotcnt = get_slot_count(fd);
use_slots = slotcnt;
slot_offset = 0;
* we need an label file
*/
- if ( chg.emubarcode == 1 || BarCode(INDEX_CHANGER) == 1)
+ if ( changer->emubarcode == 1 || BarCode(INDEX_CHANGER) == 1)
{
- if (chg.labelfile == NULL)
+ if (changer->labelfile == NULL)
{
printf("labelfile param not set in your config\n");
return(2);
return 2;
}
- loaded = drive_loaded(fd, drive_num);
+ loaded = (int)drive_loaded(fd, drive_num);
target = -1;
switch(com.command_code) {
*/
case COM_DUMPDB:
pbarcoderes->action = BARCODE_DUMP;
- MapBarCode(chg.labelfile, pbarcoderes);
+ MapBarCode(changer->labelfile, pbarcoderes);
break;
case COM_STATUS:
- ChangerStatus(com.parameter, chg.labelfile, BarCode(fd),slot_file, changer_dev, tape_device);
+ ChangerStatus(com.parameter, changer->labelfile,
+ BarCode(fd), slot_file, changer_dev, tape_device);
break;
case COM_LABEL: /* Update BarCode/Label mapping file */
pbarcoderes->action = BARCODE_PUT;
- strcpy(pbarcoderes->data.voltag, com.parameter);
- strcpy( pbarcoderes->data.barcode, pDTE[drive_num].VolTag);
- MapBarCode(chg.labelfile, pbarcoderes);
+ strncpy(pbarcoderes->data.voltag, com.parameter,
+ SIZEOF(pbarcoderes->data.voltag));
+ strncpy(pbarcoderes->data.barcode, pDTE[drive_num].VolTag,
+ SIZEOF(pbarcoderes->data.barcode));
+ MapBarCode(changer->labelfile, pbarcoderes);
printf("0 0 0\n");
break;
(void)unload(fd, drive_num, oldtarget);
if (ask_clean(scsitapedevice))
clean_tape(fd,tape_device,clean_file,drive_num,
- clean_slot,maxclean,time_file);
+ clean_slot, maxclean, time_file);
}
- Inventory(chg.labelfile, drive_num, need_eject, 0, 0, clean_slot);
+ Inventory(changer->labelfile, drive_num, need_eject, 0, 0, clean_slot);
do_inventory = 0; /* If set on exit the labeldb will be set to invalid ..... */
break;
dbprintf(("search : look for %s\n", com.parameter));
pbarcoderes->action = BARCODE_VOL;
pbarcoderes->data.slot = -1;
- strcpy(pbarcoderes->data.voltag, com.parameter);
- if (MapBarCode(chg.labelfile, pbarcoderes) == 1)
+ strncpy(pbarcoderes->data.voltag, com.parameter,
+ SIZEOF(pbarcoderes->data.voltag));
+ if (MapBarCode(changer->labelfile, pbarcoderes) == 1)
{
/*
* If both values are unset we have an problem
if (pbarcoderes->data.barcode != NULL)
{
- for (x = 0; x < STE; x++)
+ for (x = 0; x < (int)STE; x++)
{
if (strcmp(pSTE[x].VolTag, pbarcoderes->data.barcode) == 0)
{
* If we find it check if it is in the right drive
* if we have more than one drive.
*/
- for (x = 0; x < DTE; x++)
+ for (x = 0; x < (int)DTE; x++)
{
if (strcmp(pDTE[x].VolTag, pbarcoderes->data.barcode) == 0)
{
*/
if (x == drive_num) {
oldtarget = get_current_slot(slot_file);
- printf("%d %s\n", oldtarget- slot_offset, tape_device);
+ printf("%d %s\n", oldtarget - slot_offset, tape_device);
return(0);
} else {
printf("LABEL in wrong tape Unit\n");
dbprintf(("search : look for %s\n", com.parameter));
pbarcoderes->action = FIND_SLOT;
pbarcoderes->data.slot = -1;
- strcpy(pbarcoderes->data.voltag, com.parameter);
+ strncpy(pbarcoderes->data.voltag, com.parameter,
+ SIZEOF(pbarcoderes->data.voltag));
- if (MapBarCode(chg.labelfile, pbarcoderes) == 1)
+ if (MapBarCode(changer->labelfile, pbarcoderes) == 1)
{
if (pbarcoderes->data.valid == 1)
{
endstatus = 2;
break;
} else {
- target = target+slot_offset;
+ target = target + slot_offset;
}
} else {
param_index=0;
- while((param_index<SLOTCOUNT)
- &&(strcmp(slotdefs[param_index].str,com.parameter))) {
+ while((param_index < SLOTCOUNT) &&
+ (strcmp(slotdefs[param_index].str,com.parameter))) {
param_index++;
}
target=get_relative_target(fd, use_slots,
com.parameter,param_index,
loaded,
slot_file,
- slot_offset,slot_offset+use_slots-1);
+ slot_offset,
+ (slot_offset + use_slots - 1));
}
}
(void)unload(fd, drive_num, oldtarget);
if (ask_clean(scsitapedevice))
- clean_tape(fd,tape_device,clean_file,drive_num,
- clean_slot,maxclean,time_file);
+ clean_tape(fd, tape_device, clean_file, drive_num,
+ clean_slot, maxclean, time_file);
loaded=0;
}
}
put_current_slot(slot_file, target);
if (!loaded && isempty(fd, target)) {
- printf("%d slot %d is empty\n",target-slot_offset,
- target-slot_offset);
+ printf("%d slot %d is empty\n",target - slot_offset,
+ target - slot_offset);
close(fd);
endstatus = 1;
break;
if (!loaded && param_index != SLOT_ADVANCE)
{
if (ask_clean(scsitapedevice))
- clean_tape(fd,tape_device,clean_file,drive_num,
- clean_slot,maxclean,time_file);
+ clean_tape(fd, tape_device, clean_file, drive_num,
+ clean_slot, maxclean, time_file);
if (load(fd, drive_num, target) != 0) {
- printf("%d slot %d move failed\n",target-slot_offset,
- target-slot_offset);
+ printf("%d slot %d move failed\n",target - slot_offset,
+ target - slot_offset);
close(fd);
endstatus = 2;
break;
}
}
- printf("%d %s\n", target-slot_offset, tape_device);
+ printf("%d %s\n", target - slot_offset, tape_device);
break;
case COM_INFO:
- loaded = get_current_slot(slot_file);
+ loaded = (int)get_current_slot(slot_file);
if (loaded < 0)
{
loaded = find_empty(fd, slot_offset, use_slots);
}
- loaded = loaded - slot_offset;
+ loaded = loaded - (int)slot_offset;
printf("%d %d 1", loaded, use_slots);
if (target < 0)
{
dbprintf(("COM_RESET: get_current_slot %d\n", target));
- target=find_empty(fd, slot_offset, use_slots);
+ target = find_empty(fd, slot_offset, use_slots);
dbprintf(("COM_RESET: find_empty %d\n", target));
}
if (loaded) {
if (!isempty(fd, target))
- target=find_empty(fd, slot_offset, use_slots);
+ target = find_empty(fd, slot_offset, use_slots);
if (need_eject)
{
(void)unload(fd, drive_num, target);
if (ask_clean(scsitapedevice))
- clean_tape(fd,tape_device,clean_file,drive_num,clean_slot,
- maxclean,time_file);
+ clean_tape(fd,tape_device, clean_file, drive_num, clean_slot,
+ maxclean, time_file);
}
if (isempty(fd, slot_offset)) {
}
if (load(fd, drive_num, slot_offset) != 0) {
- printf("%d slot %d move failed\n",drive_num,
- slot_offset);
+ printf("%d slot %d move failed\n",
+ drive_num, slot_offset);
close(fd);
put_current_slot(slot_file, slot_offset);
endstatus = 2;
case COM_EJECT:
if (loaded) {
- target=get_current_slot(slot_file);
+ target = get_current_slot(slot_file);
if (target < 0)
{
dbprintf(("COM_EJECT: get_current_slot %d\n", target));
(void)unload(fd, drive_num, target);
if (ask_clean(scsitapedevice))
- clean_tape(fd,tape_device,clean_file,drive_num,clean_slot,
- maxclean,time_file);
+ clean_tape(fd, tape_device, clean_file, drive_num, clean_slot,
+ maxclean, time_file);
printf("%d %s\n", target, tape_device);
} else {
printf("%d %s\n", target, "drive was not loaded");
break;
case COM_CLEAN:
if (loaded) {
- target=get_current_slot(slot_file);
+ target = get_current_slot(slot_file);
if (target < 0)
{
dbprintf(("COM_CLEAN: get_current_slot %d\n", target));
(void)unload(fd, drive_num, target);
}
- clean_tape(fd,tape_device,clean_file,drive_num,clean_slot,
- maxclean,time_file);
+ clean_tape(fd, tape_device, clean_file, drive_num, clean_slot,
+ maxclean, time_file);
printf("%s cleaned\n", tape_device);
break;
};
- /* FIX ME, should be an function to close the device */
+/* FIX ME, should be an function to close the device */
/* if (pChangerDev != NULL) */
/* close(pChangerDev->fd); */
#endif
- if (do_inventory == 1 && endstatus == 0 && chg.labelfile != NULL)
+ if (do_inventory == 1 && endstatus == 0 && changer->labelfile != NULL)
{
- if ( chg.autoinv == 1)
+ if (changer->autoinv == 1)
{
DebugPrint(DEBUG_INFO,SECTION_INFO, "Do an inventory \n");
- Inventory(chg.labelfile, drive_num , chg.eject, 0, 0, clean_slot);
+ Inventory(changer->labelfile, drive_num, changer->eject,
+ 0, 0, clean_slot);
} else {
DebugPrint(DEBUG_INFO,SECTION_INFO, "Set all entrys in DB to invalid\n");
- memset(pbarcoderes, 0 , sizeof(MBC_T));
+ memset(pbarcoderes, 0 , SIZEOF(MBC_T));
pbarcoderes->action = RESET_VALID;
- MapBarCode(chg.labelfile,pbarcoderes);
+ MapBarCode(changer->labelfile,pbarcoderes);
}
}
* tab-width: 4
* End:
*/
-
-#!/bin/sh
+#!@SHELL@
#
# Exit Status:
# 0 Alles Ok
# in amanda.conf. For example, if amanda.conf has:
#
# changerfile="/etc/amanda/Dailyset1/CHANGER"
+# or changerfile="/etc/amanda/Dailyset1/CHANGER.conf"
#
# the variables must be in "/etc/amanda/Dailyset1/CHANGER.conf".
+# The ".conf" is appended only if it's not there".
#
# If "changerfile" is a relative path, it is relative to the directory
# that contains amanda.conf. That also happens to be the directory Amanda
SUF=
fi
-DBGFILE=`amgetconf$SUF dbopen.$argv0 2>/dev/null | grep -v BUGGY`
+DBGFILE=`amgetconf$SUF dbopen.$argv0 2>/dev/null`
if [ -z "$DBGFILE" ]
then
DBGFILE=/dev/null # will try this again below
fi
-changerfile=`amgetconf$SUF changerfile 2>/dev/null | grep -v BUGGY`
+changerfile=`amgetconf$SUF changerfile 2>/dev/null`
if [ -z "$changerfile" ]; then
Exit 2 \
"<none>" \
"changerfile must be specified in amanda.conf"
fi
-tape=`amgetconf$SUF tapedev 2>/dev/null | grep -v BUGGY`
+tape=`amgetconf$SUF tapedev 2>/dev/null`
if [ -z "$tape" ]; then
Exit 2 \
"<none>" \
"<none>" \
"tapedev ($tape) may not be the null device"
fi
-TAPE=`amgetconf$SUF changerdev 2>/dev/null | grep -v BUGGY`
+TAPE=`amgetconf$SUF changerdev 2>/dev/null`
if [ -z "$TAPE" ]; then
Exit 2 \
"<none>" \
#### Set up the various config files.
-configfile=$changerfile.conf
+conf_match=`expr "$changerfile" : .\*\.conf\$`
+if [ $conf_match -ge 6 ]; then
+ configfile=$changerfile
+ changerfile=`echo $changerfile | sed 's/.conf$//g'`
+else
+ configfile=$changerfile.conf
+fi
+
cleanfile=$changerfile-clean
accessfile=$changerfile-access
slotfile=$changerfile-slot
if [ $currentslot -lt $firstslot -o $currentslot -gt $lastslot ]; then
currentslot=$firstslot # what "current" will get
fi
- set x $slot_list
- shift # get rid of the "x"
- numslots=$#
+ numslots=`expr $lastslot - $firstslot + 1`
Exit 0 "$currentslot" "$numslots 1 $reader"
return $? # in case we are internal
}
/*
- * $Id: libscsi.h,v 1.9 2000/06/25 18:48:11 ant Exp $
+ * $Id: libscsi.h,v 1.10 2006/05/25 01:47:07 johnfranks Exp $
*
* libscsi.h -- library header for routines to handle the changer
* support for chio based systems
/*
* This function gets the actual cleaning state of the drive
*/
-int get_clean_state P((char *tape));
+int get_clean_state(char *tape);
/*
* This function gets the next empty slot from the changer
* (From this slot the tape is loaded ...)
*/
-int GetCurrentSlot P((int fd, int drive));
+int GetCurrentSlot(int fd, int drive);
/*
* Eject the actual tape from the tapedrive
*/
-void eject_tape P((char *tape, int type));
+int eject_tape(char *tape, int type);
/*
* is the specified slot empty?
*/
-int isempty P((int fd, int slot));
+int isempty(int fd, int slot);
/*
* find the first empty slot
*/
-int find_empty P((int fd, int start, int count));
+int find_empty(int fd, int start, int count);
/*
* returns one if there is a tape loaded in the drive
*/
-int drive_loaded P((int fd, int drivenum));
+int drive_loaded(int fd, int drivenum);
/*
* unloads the drive, putting the tape in the specified slot
*/
-int unload P((int fd, int drive, int slot));
+int unload(int fd, int drive, int slot);
/*
* moves tape from the specified slot into the drive
*/
-int load P((int fd, int drive, int slot));
+int load(int fd, int drive, int slot);
/*
* return the number of slots in the robot
*/
-int get_slot_count P((int fd));
+int get_slot_count(int fd);
/*
* return the number of drives in the robot
*/
-int get_drive_count P((int fd));
+int get_drive_count(int fd);
#endif /* !LIBSCSI_H */
* file named AUTHORS, in the root directory of this distribution.
*/
/*
- * $Id: scsi-aix.c,v 1.22 2005/10/15 13:20:47 martinea Exp $
+ * $Id: scsi-aix.c,v 1.23 2006/05/25 01:47:07 johnfranks Exp $
*
* Interface to execute SCSI commands on an AIX System
*
#ifdef HAVE_AIX_LIKE_SCSI
+#include <scsi-defs.h>
+
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#include <scsi-defs.h>
#include <gscdds.h>
-void SCSI_OS_Version()
+void SCSI_OS_Version(void)
{
#ifndef lint
- static char rcsid[] = "$Id: scsi-aix.c,v 1.22 2005/10/15 13:20:47 martinea Exp $";
+ static char rcsid[] = "$Id: scsi-aix.c,v 1.23 2006/05/25 01:47:07 johnfranks Exp $";
DebugPrint(DEBUG_INFO, SECTION_INFO, "scsi-os-layer: %s\n",rcsid);
#endif
}
free(pDev[ip].inquiry);
return(0);
}
- } else {
- free(pDev[ip].inquiry);
- pDev[ip].inquiry = NULL;
- return(1);
}
- return(1);
+ free(pDev[ip].inquiry);
+ pDev[ip].inquiry = NULL;
+ return(1);
} else {
dbprintf(("SCSI_OpenDevice %s failed\n", pDev[ip].dev));
return(0);
int SCSI_ExecuteCommand(int DeviceFD,
Direction_T Direction,
CDB_T CDB,
- int CDB_Length,
+ size_t CDB_Length,
void *DataBuffer,
- int DataBufferLength,
- char *RequestSenseBuf,
- int RequestSenseLength)
+ size_t DataBufferLength,
+ RequestSense_T *RequestSenseBuf,
+ size_t RequestSenseLength)
{
extern OpenFiles_T *pDev;
extern FILE * debug_file;
int isbusy = 0;
int target = 3;
+ /* Basic sanity checks */
+ assert(CDB_Length <= UCHAR_MAX);
+ assert(RequestSenseLength <= UCHAR_MAX);
+
+ /* Clear buffer for cases where sense is not returned */
+ memset(RequestSenseBuf, 0, RequestSenseLength);
if (pDev[DeviceFD].avail == 0)
{
scmd.cdblen = CDB_Length;
scmd.data_buf = DataBuffer;
scmd.datalen = DataBufferLength;
- scmd.sense_buf = RequestSenseBuf;
+ scmd.sense_buf = (unsigned char *)RequestSenseBuf;
scmd.senselen = RequestSenseLength;
scmd.statusp = &sbyte;
scmd.timeval = 60;
return(SCSI_OK);
} else {
- bzero(&ds, sizeof(struct sc_iocmd));
+ bzero(&ds, SIZEOF(struct sc_iocmd));
bzero(RequestSenseBuf, RequestSenseLength);
- bzero(&ExtendedRequestSense, sizeof(ExtendedRequestSense_T));
+ bzero(&ExtendedRequestSense, SIZEOF(ExtendedRequestSense_T));
ds.flags = SC_ASYNC;
/* Timeout */
/* Sense Buffer is not available on AIX ?*/
/*
ds.req_sense_length = 255;
- ds.request_sense_ptr = (char *)RequestSense;
+ ds.request_sense_ptr = (unsigned char *)RequestSense;
*/
switch (Direction)
{
SINQ[5] = 0x80;
bcopy(SINQ, ds.scsi_cdb, 6);
ds.command_length = 6;
- ds.buffer = RequestSenseBuf;
+ ds.buffer = (unsigned char *)RequestSenseBuf;
ds.data_length = RequestSenseLength;
if (pDev[DeviceFD].devopen == 0)
Result = ioctl(pDev[DeviceFD].fd, STIOCMD, &ds);
SCSI_CloseDevice(DeviceFD);
return(SCSI_OK);
- break;
+
case SC_BUSY_STATUS:
return(SCSI_BUSY);
- break;
+
case SC_CHECK_CONDITION:
SINQ[0] = SC_COM_REQUEST_SENSE;
SINQ[1] = 0;
SINQ[5] = 0x80;
bcopy(SINQ, ds.scsi_cdb, 6);
ds.command_length = 6;
- ds.buffer = RequestSenseBuf;
- ds.data_length = RequestSenseLength;
+ ds.buffer = (unsigned char *)RequestSenseBuf;
+ ds.data_length = (unsigned char)RequestSenseLength;
if (pDev[DeviceFD].devopen == 0)
if (SCSI_OpenDevice(DeviceFD) == 0)
Result = ioctl(pDev[DeviceFD].fd, STIOCMD, &ds);
SCSI_CloseDevice(DeviceFD);
return(SCSI_CHECK);
- break;
+
default:
/*
* Makes no sense yet, may result in an endless loop
}
}
-int SCSI_Scan()
+int SCSI_Scan(void)
{
int fd;
- extern int errno;
struct sc_inquiry si;
u_char buf[255];
int target;
isbusy = 0;
}
- bzero(&si, sizeof(si));
+ bzero(&si, SIZEOF(si));
si.scsi_id = target;
si.lun_id = lun;
si.inquiry_len = 255;
printf("SCIOINQU: %s\n", strerror(errno));
} else {
dump_hex(&buf, 255, DEBUG_INFO, SECTION_SCSI);
- type = buf[0] & 0x1f;
+ type = buf[0] & 0x1lf;
buf[8+28] = 0;
- printf(stdout,"%-28s|Device Type %d\n",buf[8], type);
+ printf("%-28s|Device Type %d\n",buf[8], type);
}
if (!isbusy && ioctl(fd, SCIOSTOP, IDLUN(target, lun)) == -1)
return(1);
* file named AUTHORS, in the root directory of this distribution.
*/
/*
- * $Id: scsi-bsd.c,v 1.17 2005/10/15 13:20:47 martinea Exp $
+ * $Id: scsi-bsd.c,v 1.18 2006/05/25 01:47:07 johnfranks Exp $
*
* Interface to execute SCSI commands on an BSD System (FreeBSD)
*
void SCSI_OS_Version()
{
#ifndef lint
- static char rcsid[] = "$Id: scsi-bsd.c,v 1.17 2005/10/15 13:20:47 martinea Exp $";
+ static char rcsid[] = "$Id: scsi-bsd.c,v 1.18 2006/05/25 01:47:07 johnfranks Exp $";
DebugPrint(DEBUG_INFO, SECTION_INFO, "scsi-os-layer: %s\n",rcsid);
#endif
}
int SCSI_ExecuteCommand(int DeviceFD,
Direction_T Direction,
CDB_T CDB,
- int CDB_Length,
+ size_t CDB_Length,
void *DataBuffer,
- int DataBufferLength,
- char *pRequestSense,
- int RequestSenseLength)
+ size_t DataBufferLength,
+ RequestSense_T *pRequestSense,
+ size_t RequestSenseLength)
{
extern OpenFiles_T *pDev;
ExtendedRequestSense_T ExtendedRequestSense;
int retries = 5;
extern int errno;
+ /* Basic sanity checks */
+ assert(CDB_Length <= UCHAR_MAX);
+ assert(RequestSenseLength <= UCHAR_MAX);
+
+ /* Clear buffer for cases where sense is not returned */
+ memset(pRequestSense, 0, RequestSenseLength);
+
if (pDev[DeviceFD].avail == 0)
{
return(SCSI_ERROR);
}
- memset(&ds, 0, sizeof(scsireq_t));
+ memset(&ds, 0, SIZEOF(scsireq_t));
memset(pRequestSense, 0, RequestSenseLength);
- memset(&ExtendedRequestSense, 0 , sizeof(ExtendedRequestSense_T));
+ memset(&ExtendedRequestSense, 0 , SIZEOF(ExtendedRequestSense_T));
ds.flags = SCCMD_ESCAPE;
/* Timeout */
memcpy(pRequestSense, ds.sense, RequestSenseLength);
if (Result < 0)
{
- dbprintf(("errno : %d\n",errno));
+ dbprintf(("errno : %s\n",strerror(errno)));
return (SCSI_ERROR);
}
dbprintf(("SCSI_ExecuteCommand(BSD) %02X STATUS(%02X) \n", CDB[0], ds.retsts));
{
case SCCMD_BUSY: /* BUSY */
break;
+
case SCCMD_OK: /* GOOD */
return(SCSI_OK);
- break;
+
case SCCMD_SENSE: /* CHECK CONDITION */
return(SCSI_SENSE);
- break;
+
default:
continue;
}
if (ioctl(pDev[DeviceFD].fd , MTIOCTOP, &mtop) != 0)
{
- dbprintf(("Tape_Ioctl error ioctl %d\n",errno));
+ dbprintf(("Tape_Ioctl error ioctl %s\n",strerror(errno)));
SCSI_CloseDevice(DeviceFD);
return(-1);
}
* file named AUTHORS, in the root directory of this distribution.
*/
/*
- * $Id: scsi-cam.c,v 1.14 2005/10/15 13:20:47 martinea Exp $
+ * $Id: scsi-cam.c,v 1.15 2006/05/25 01:47:07 johnfranks Exp $
*
* Interface to execute SCSI commands on an system with cam support
* Current support is for FreeBSD 4.x
void SCSI_OS_Version()
{
#ifndef lint
- static char rcsid[] = "$Id: scsi-cam.c,v 1.14 2005/10/15 13:20:47 martinea Exp $";
+ static char rcsid[] = "$Id: scsi-cam.c,v 1.15 2006/05/25 01:47:07 johnfranks Exp $";
DebugPrint(DEBUG_INFO, SECTION_INFO, "scsi-os-layer: %s\n",rcsid);
#endif
}
return 0;
p = strtok(DeviceName, ":");
- sscanf(p,"%d", path);
+ if (sscanf(p,"%d", path) != 1) {
+ free(DeviceName);
+ ChgExit("SCSI_OpenDevice",
+ "Path conversion error. Digits expected", FATAL);
+ }
if ((p = strtok(NULL,":")) == NULL) {
free(DeviceName);
ChgExit("SCSI_OpenDevice", "target in Device Name not found", FATAL);
}
- sscanf(p,"%d", target);
+
+ if (sscanf(p,"%d", target) != 1) {
+ free(DeviceName);
+ ChgExit("SCSI_OpenDevice",
+ "Target conversion error. Digits expected", FATAL);
+ }
+
if ((p = strtok(NULL,":")) == NULL) {
free(DeviceName);
ChgExit("SCSI_OpenDevice", "lun in Device Name not found", FATAL);
}
- sscanf(p,"%d", lun);
+ if (sscanf(p,"%d", lun) != 1) {
+ free(DeviceName);
+ ChgExit("SCSI_OpenDevice",
+ "LUN conversion error. Digits expected", FATAL);
+ }
+
return 1;
}
DebugPrint(DEBUG_INFO, SECTION_SCSI,"##### STOP SCSI_OpenDevice open failed\n");
return(0);
}
- } else {
- if (parse_btl(DeviceName, &path, &target, &lun))
- pDev[ip].curdev = cam_open_btl(path, target, lun, O_RDWR, NULL);
- else
- pDev[ip].curdev = cam_open_device(DeviceName, O_RDWR);
-
- free(DeviceName);
-
- if (pDev[ip].curdev) {
- pDev[ip].devopen = 1;
- return(1);
- } else {
- return(0);
- }
}
- return(0);
+ if (parse_btl(DeviceName, &path, &target, &lun))
+ pDev[ip].curdev = cam_open_btl(path, target, lun, O_RDWR, NULL);
+ else
+ pDev[ip].curdev = cam_open_device(DeviceName, O_RDWR);
+
+ free(DeviceName);
+
+ if (pDev[ip].curdev) {
+ pDev[ip].devopen = 1;
+ return(1);
+ } else {
+ return(0);
+ }
}
int SCSI_CloseDevice(int DeviceFD)
int SCSI_ExecuteCommand(int DeviceFD,
Direction_T Direction,
CDB_T CDB,
- int CDB_Length,
+ size_t CDB_Length,
void *DataBuffer,
- int DataBufferLength,
- char *pRequestSense,
- int RequestSenseLength)
+ size_t DataBufferLength,
+ RequestSense_T *pRequestSense,
+ size_t RequestSenseLength)
{
ExtendedRequestSense_T ExtendedRequestSense;
extern OpenFiles_T *pDev;
uint32_t ccb_flags;
OpenFiles_T *pwork = NULL;
+ /* Basic sanity checks */
+ assert(CDB_Length <= UCHAR_MAX);
+ assert(RequestSenseLength <= UCHAR_MAX);
+
+ /* Clear buffer for cases where sense is not returned */
+ memset(pRequestSense, 0, RequestSenseLength);
+
if (pDev[DeviceFD].avail == 0)
{
return(SCSI_ERROR);
ccb = cam_getccb(pDev[DeviceFD].curdev);
/* Build the CCB */
- bzero(&(&ccb->ccb_h)[1], sizeof(struct ccb_scsiio));
+ bzero(&(&ccb->ccb_h)[1], SIZEOF(struct ccb_scsiio));
bcopy(&CDB[0], &ccb->csio.cdb_io.cdb_bytes, CDB_Length);
switch (Direction)
if (ioctl(pDev[DeviceFD].fd , MTIOCTOP, &mtop) != 0)
{
- dbprintf(("Tape_Ioctl error ioctl %d\n",errno));
+ dbprintf(("Tape_Ioctl error ioctl %s\n", strerror(errno)));
SCSI_CloseDevice(DeviceFD);
return(-1);
}
if (ioctl(pDev[DeviceFD].fd , MTIOCGET, &mtget) != 0)
{
- dbprintf(("Tape_Status error ioctl %d\n",errno));
+ dbprintf(("Tape_Status error ioctl %s\n", strerror(errno)));
SCSI_CloseDevice(DeviceFD);
return(-1);
}
}
}
}
+ return 0;
}
#endif
-#ifndef lint
-static char rcsid[] = "$Id: scsi-changer-driver.c,v 1.49 2006/03/16 00:20:53 paddy_s Exp $";
-#endif
+static char rcsid[] = "$Id: scsi-changer-driver.c,v 1.52 2006/07/21 00:25:50 martinea Exp $";
/*
* Interface to control a tape robot/library connected to the SCSI bus
*
#include <amanda.h>
-#ifdef HAVE_DMALLOC_H
-#include <dmalloc.h>
-#endif
-
#include "arglist.h"
/*
#ifdef HAVE_STDIO_H
#include "tapeio.h"
-extern int TapeEject(int DeviceFD);
-
extern FILE *debug_file;
+extern changer_t *changer; /* Needed for the infos about emubarcode and labelfile */
int PrintInquiry(SCSIInquiry_T *);
int GenericElementStatus(int DeviceFD, int InitStatus);
ElementInfo_T *LookupElement(int addr);
int GenericResetStatus(int DeviceFD);
int RequestSense(int, ExtendedRequestSense_T *, int );
-void dump_hex(char *, int, int, int);
-void TerminateString(char *string, int length);
+void dump_hex(u_char *, size_t, int, int);
+void TerminateString(char *string, size_t length);
void ChgExit(char *, char *, int);
int BarCode(int fd);
int LogSense(int fd);
-int SenseHandler(int fd, unsigned char flag, unsigned char SenseKey, unsigned char AdditionalSenseCode, unsigned char AdditionalSenseCodeQualifier, char *buffer);
+int SenseHandler(int fd, u_char flag, u_char SenseKey, u_char AdditionalSenseCode, u_char AdditionalSenseCodeQualifier, RequestSense_T *buffer);
+
+int SCSI_AlignElements(int DeviceFD, size_t MTE, size_t DTE, size_t STE);
-int SCSI_AlignElements(int DeviceFD, int MTE, int DTE, int STE);
+int DoNothing0(void);
+int DoNothing1(int);
+int DoNothing2(int, int);
+int DoNothing3(int, int, int);
-int DoNothing();
int GenericMove(int, int, int);
int SDXMove(int, int, int);
int CheckMove(ElementInfo_T *from, ElementInfo_T *to);
int GenericRewind(int);
-/* int GenericStatus(); */
-int GenericFree();
-int TapeStatus(); /* Is the tape loaded ? */
+/* int GenericStatus(void); */
+int GenericFree(void);
+int TapeStatus(void); /* Is the tape loaded ? */
int DLT4000Eject(char *Device, int type);
int GenericEject(char *Device, int type);
int GenericClean(char *Device); /* Does the tape need a clean */
int GenericBarCode(int DeviceFD); /* Do we have Barcode reader support */
int NoBarCode(int DeviceFD);
-int GenericSearch();
+int GenericSearch(void);
void Inventory(char *labelfile, int drive, int eject, int start, int stop, int clean);
int TreeFrogBarCode(int DeviceFD);
int EXB_BarCode(int DeviceFD);
-int GenericSenseHandler(int fd, int flags, unsigned char SenseKey, unsigned char AdditionalSenseCode, unsigned char AdditionalSenseCodeQualifier, char *);
+int GenericSenseHandler(int fd, u_char flags, u_char SenseKey, u_char AdditionalSenseCode, u_char AdditionalSenseCodeQualifier, RequestSense_T *);
ElementInfo_T *LookupElement(int address);
int eject_tape(char *tapedev, int type);
int unload(int fd, int drive, int slot);
int load(int fd, int drive, int slot);
int GetElementStatus(int DeviceFD);
+int drive_loaded(int fd, int drivenum);
/*
* Log Pages Decode
*/
-void WriteErrorCountersPage(LogParameter_T *, int);
-void ReadErrorCountersPage(LogParameter_T *, int);
-void C1553APage30(LogParameter_T *, int);
-void C1553APage37(LogParameter_T *, int);
-void EXB85058HEPage39(LogParameter_T *, int);
-void EXB85058HEPage3c(LogParameter_T *, int);
-int Decode(LogParameter_T *, int *);
-int DecodeModeSense(char *buffer, int offset, char *pstring, char block, FILE *out);
+void WriteErrorCountersPage(LogParameter_T *, size_t);
+void ReadErrorCountersPage(LogParameter_T *, size_t);
+void C1553APage30(LogParameter_T *, size_t);
+void C1553APage37(LogParameter_T *, size_t);
+void EXB85058HEPage39(LogParameter_T *, size_t);
+void EXB85058HEPage3c(LogParameter_T *, size_t);
+int Decode(LogParameter_T *, unsigned *);
+int DecodeModeSense(u_char *buffer, size_t offset, char *pstring, char block, FILE *out);
int SCSI_Run(int DeviceFD,
Direction_T Direction,
CDB_T CDB,
- int CDB_Length,
+ size_t CDB_Length,
void *DataBuffer,
- int DataBufferLength,
- char *pRequestSense,
- int RequestSenseLength);
+ size_t DataBufferLength,
+ RequestSense_T *pRequestSense,
+ size_t RequestSenseLength);
-int SCSI_Move(int DeviceFD, unsigned char chm, int from, int to);
-int SCSI_LoadUnload(int DeviceFD, RequestSense_T *pRequestSense, unsigned char byte1, unsigned char load);
+int SCSI_Move(int DeviceFD, u_char chm, int from, int to);
+int SCSI_LoadUnload(int DeviceFD, RequestSense_T *pRequestSense, u_char byte1, u_char load);
int SCSI_TestUnitReady(int, RequestSense_T *);
-int SCSI_ModeSense(int DeviceFD, char *buffer, u_char size, u_char byte1, u_char byte2);
+int SCSI_ModeSense(int DeviceFD, u_char *buffer, u_char size, u_char byte1, u_char byte2);
int SCSI_ModeSelect(int DeviceFD,
- char *buffer,
- unsigned char length,
- unsigned char save,
- unsigned char mode,
- unsigned char lun);
+ u_char *buffer,
+ u_char length,
+ u_char save,
+ u_char mode,
+ u_char lun);
int SCSI_ReadElementStatus(int DeviceFD,
- unsigned char type,
- unsigned char lun,
- unsigned char VolTag,
+ u_char type,
+ u_char lun,
+ u_char VolTag,
int StartAddress,
- int NoOfElements,
- int DescriptorSize,
- char **data);
+ size_t NoOfElements,
+ size_t DescriptorSize,
+ u_char **data);
FILE *StatFile;
+static int barcode; /* cache the result from the BarCode function */
SC_COM_T SCSICommand[] = {
{0x00,
"HP Auto Loader [C1553A]",
GenericMove,
GenericElementStatus,
- DoNothing,
+ DoNothing1,
GenericFree,
GenericEject,
GenericClean,
GenericSenseHandler},
{"EXB-85058HE-0000",
"Exabyte Tape [EXB-85058HE-0000]",
- DoNothing,
- DoNothing,
- DoNothing,
- DoNothing,
+ DoNothing3,
+ DoNothing2,
+ DoNothing1,
+ DoNothing0,
GenericEject,
GenericClean,
GenericRewind,
GenericSenseHandler},
{"DLT8000",
"DLT Tape [DLT8000]",
- DoNothing,
- DoNothing,
- DoNothing,
- DoNothing,
+ DoNothing3,
+ DoNothing2,
+ DoNothing1,
+ DoNothing0,
DLT4000Eject,
GenericClean,
GenericRewind,
GenericSenseHandler},
{"DLT7000",
"DLT Tape [DLT7000]",
- DoNothing,
- DoNothing,
- DoNothing,
- DoNothing,
+ DoNothing3,
+ DoNothing2,
+ DoNothing1,
+ DoNothing0,
DLT4000Eject,
GenericClean,
GenericRewind,
GenericSenseHandler},
{"DLT4000",
"DLT Tape [DLT4000]",
- DoNothing,
- DoNothing,
- DoNothing,
- DoNothing,
+ DoNothing3,
+ DoNothing2,
+ DoNothing1,
+ DoNothing0,
DLT4000Eject,
GenericClean,
GenericRewind,
char *SlotArgs = 0;
/* Pointer to MODE SENSE Pages */
-char *pModePage = NULL;
+u_char *pModePage = NULL;
EAAPage_T *pEAAPage = NULL;
DeviceCapabilitiesPage_T *pDeviceCapabilitiesPage = NULL;
-char *pVendorUnique = NULL;
+u_char *pVendorUnique = NULL;
/*
* New way, every element type has its on array
ElementInfo_T *pSTE = NULL; /*Storage Element */
ElementInfo_T *pIEE = NULL; /*Import Export Element */
ElementInfo_T *pDTE = NULL; /*Data Transfer Element */
-int MTE = 0; /*Counter for the above element types */
-int STE = 0;
-int IEE = 0;
-int DTE = 0;
+size_t MTE = 0; /*Counter for the above element types */
+size_t STE = 0;
+size_t IEE = 0;
+size_t DTE = 0;
char *chgscsi_datestamp = NULL; /* Result pointer for tape_rdlabel */
char *chgscsi_label = NULL; /* Result pointer for tape_rdlabel */
* Print the scsi-changer-driver version
*/
-void ChangerDriverVersion()
+void
+ChangerDriverVersion(void)
{
DebugPrint(DEBUG_ERROR, SECTION_INFO, "scsi-changer-driver: %s\n",rcsid);
SCSI_OS_Version();
* Try to generate an template which can be used as an example for the config file
*
*/
-void PrintConf()
+void
+PrintConf(void)
{
extern OpenFiles_T *pDev;
int count;
{
printf("startuse 0 # Which is the first slot to use\n");
printf(" #\n");
- printf("enduse %d # Which is the last slot to use\n", STE);
+ printf("enduse " SIZE_T_FMT " # Which is the last slot to use\n", STE);
} else {
printf("startuse ??? # Which is the first slot to use\n");
printf(" #\n");
printf(" # cleaning tape in the last slot\n");
printf(" #\n");
- cwd = getcwd(NULL, 0);
+ if ((cwd = getcwd(NULL, 0)) == NULL) {
+ cwd = "<unknown>";
+ }
printf("statfile %s/tape0-slot #\n",cwd);
printf("cleanfile %s/tape0-clean #\n", cwd);
* If an tape is loaded unload it and do initialize element status to
* get all labels if an bar code reader is installed
*/
-void Inventory(char *labelfile, int drive, int eject, int start, int stop, int clean)
+void
+Inventory(
+ char * labelfile,
+ int drive,
+ int eject,
+ int start,
+ int stop,
+ int clean)
{
extern OpenFiles_T *pDev;
- int x;
- char *result; /* Used to store the result of MapBarCode */
- int barcode; /* cache the result from the BarCode function */
+ size_t x;
static int inv_done = 0; /* Inventory function called ?, marker to disable recursion */
MBC_T *pbarcoderes; /* Here we will pass the parameter to MapBarCode and get the result */
+ (void)start; /* Quiet unused parameter warning */
+ (void)stop; /* Quiet unused parameter warning */
+
DebugPrint(DEBUG_INFO,SECTION_MAP_BARCODE, "##### START Inventory\n");
- if ((pbarcoderes = malloc(sizeof(MBC_T))) == NULL)
- {
- DebugPrint(DEBUG_ERROR, SECTION_MAP_BARCODE,"##### malloc failed (-1)\n");
- return;
- }
- memset(pbarcoderes, 0 , sizeof(MBC_T));
+ pbarcoderes = alloc(SIZEOF(MBC_T));
+ memset(pbarcoderes, 0 , SIZEOF(MBC_T));
if (inv_done != 0)
{
DebugPrint(DEBUG_INFO,SECTION_MAP_BARCODE, "##### STOP inv_done -> %d Inventory\n",inv_done);
free(pbarcoderes);
return;
+ /*NOTREACHED*/
}
inv_done = 1;
barcode = BarCode(INDEX_CHANGER);
{
if (eject)
{
- eject_tape("", eject);
+ (void)eject_tape("", eject);
}
(void)unload(INDEX_TAPE, 0, 0);
}
for (x = 0; x < STE; x++)
{
- if (x == clean)
+ if (x == (size_t)clean)
{
continue;
}
SCSI_CloseDevice(INDEX_TAPE);
- if ((result = (char *)tape_rdlabel(pDev[INDEX_TAPE].dev, &chgscsi_datestamp, &chgscsi_label)) == NULL)
+ if ((chgscsi_result = (char *)tape_rdlabel(pDev[INDEX_TAPE].dev, &chgscsi_datestamp, &chgscsi_label)) == NULL)
{
pbarcoderes->action = UPDATE_SLOT;
- strcpy(pbarcoderes->data.voltag, chgscsi_label);
+ strncpy(pbarcoderes->data.voltag, chgscsi_label,
+ SIZEOF(pbarcoderes->data.voltag));
pbarcoderes->data.slot = x;
pbarcoderes->data.from = 0;
pbarcoderes->data.LoadCount = 1;
if (BarCode(INDEX_CHANGER) == 1)
{
- strcpy(pbarcoderes->data.barcode, pDTE[drive].VolTag);
+ strncpy(pbarcoderes->data.barcode, pDTE[drive].VolTag,
+ SIZEOF(pbarcoderes->data.barcode));
MapBarCode(labelfile, pbarcoderes);
} else {
MapBarCode(labelfile, pbarcoderes);
if (eject)
{
- eject_tape("", eject);
+ (void)eject_tape("", eject);
}
(void)unload(INDEX_TAPE, drive, x);
* Check if the slot ist empty
* slot -> slot number to check
*/
-int isempty(int fd, int slot)
+int
+isempty(
+ int fd,
+ int slot)
{
extern OpenFiles_T *pDev;
DebugPrint(DEBUG_INFO,SECTION_TAPE,"##### START isempty\n");
{
DebugPrint(DEBUG_ERROR,SECTION_TAPE,"##### STOP isempty [-1]\n");
return(-1);
+ /*NOTREACHED*/
}
}
{
DebugPrint(DEBUG_INFO,SECTION_TAPE,"##### STOP isempty [1]\n");
return(1);
+ /*NOTREACHED*/
}
DebugPrint(DEBUG_INFO,SECTION_TAPE,"##### STOP isempty [0]\n");
return(0);
}
-int get_clean_state(char *tapedev)
+int
+get_clean_state(
+ char *tapedev)
{
extern OpenFiles_T *pDev;
/* Return 1 if cleaning is needed */
{
DebugPrint(DEBUG_ERROR,SECTION_TAPE,"##### STOP get_clean_state [-1]\n");
return(-1);
+ /*NOTREACHED*/
}
ret=pDev[INDEX_TAPECTL].functions->function_clean(tapedev);
DebugPrint(DEBUG_INFO,SECTION_TAPE,"##### STOP get_clean_state [%d]\n", ret);
* Type describes if we should force the SCSI eject if available
* normal eject is done with the ioctl
*/
-int eject_tape(char *tapedev, int type)
- /* This function ejects the tape from the drive */
+/* This function ejects the tape from the drive */
+
+int
+eject_tape(
+ char * tapedev,
+ int type)
{
extern OpenFiles_T *pDev;
- int ret = 0;
- extern changer_t chg; /* Needed for the infos about emubarcode and labelfile */
+ int ret;
DebugPrint(DEBUG_INFO,SECTION_TAPE,"##### START eject_tape\n");
/*
* Try to read the label
*/
- if (pDev[INDEX_TAPE].avail == 1 && (chg.emubarcode == 1 || BarCode(INDEX_CHANGER)))
+ if (pDev[INDEX_TAPE].avail == 1 && (changer->emubarcode == 1 || BarCode(INDEX_CHANGER)))
{
if (pDev[INDEX_TAPECTL].SCSI == 1 && pDev[INDEX_TAPECTL].avail) {
ret=pDev[INDEX_TAPECTL].functions->function_eject(tapedev, type);
DebugPrint(DEBUG_INFO,SECTION_TAPE,"##### STOP (SCSI)eject_tape [%d]\n", ret);
return(ret);
+ /*NOTREACHED*/
}
if (pDev[INDEX_TAPE].avail == 1)
ret=Tape_Ioctl(INDEX_TAPE, IOCTL_EJECT);
DebugPrint(DEBUG_INFO,SECTION_TAPE,"##### STOP (ioctl)eject_tape [%d]\n", ret);
return(ret);
+ /*NOTREACHED*/
}
DebugPrint(DEBUG_INFO,SECTION_TAPE,"##### STOP eject_tape [-1]\n");
/* Find an empty slot, starting at start, ending at start+count */
-int find_empty(int fd, int start, int count)
+int
+find_empty(
+ int fd,
+ int start,
+ int count)
{
extern OpenFiles_T *pDev;
- int x;
- int end;
+ size_t x;
+ size_t end;
DebugPrint(DEBUG_INFO,SECTION_ELEMENT,"###### START find_empty\n");
{
if ( pDev[fd].functions->function_status(fd , 1) != 0)
{
- DebugPrint(DEBUG_ERROR,SECTION_ELEMENT,"###### END find_empty [%d]\n", -1);
- return(-1);
+ DebugPrint(DEBUG_ERROR,SECTION_ELEMENT,
+ "###### END find_empty [-1]\n");
+ return((ssize_t)-1);
+ /*NOTREACHED*/
}
}
end = STE;
}
- DebugPrint(DEBUG_INFO,SECTION_ELEMENT,"start at %d, end at %d\n", start, end);
+ DebugPrint(DEBUG_INFO, SECTION_ELEMENT,
+ "start at " SIZE_T_FMT ", end at " SIZE_T_FMT "\n",
+ (SIZE_T_FMT_TYPE)start,
+ (SIZE_T_FMT_TYPE)end);
for (x = start; x < end; x++)
{
if (pSTE[x].status == 'E')
{
- DebugPrint(DEBUG_INFO,SECTION_ELEMENT,"###### END find_empty [%d]\n", x);
- return(x);
+ DebugPrint(DEBUG_INFO,SECTION_ELEMENT,
+ "###### END find_empty [" SIZE_T_FMT "]\n", x);
+ return((ssize_t)x);
+ /*NOTREACHED*/
}
}
- DebugPrint(DEBUG_ERROR,SECTION_ELEMENT,"###### END find_empty [%d]\n", -1);
- return(-1);
+ DebugPrint(DEBUG_ERROR,SECTION_ELEMENT,"###### END find_empty [-1]\n");
+ return((ssize_t)-1);
}
/*
* 0 -> drive is empty
* 1 -> drive is loaded
*/
-int drive_loaded(int fd, int drivenum)
+int
+drive_loaded(
+ int fd,
+ int drivenum)
{
extern OpenFiles_T *pDev;
{
DebugPrint(DEBUG_ERROR,SECTION_TAPE,"Fatal error\n");
return(-1);
+ /*NOTREACHED*/
}
}
if (pDTE[drivenum].status == 'E') {
DebugPrint(DEBUG_INFO,SECTION_TAPE,"###### STOP drive_loaded (empty)\n");
return(0);
- } else {
- DebugPrint(DEBUG_INFO,SECTION_TAPE,"###### STOP drive_loaded (not empty)\n");
- return(1);
+ /*NOTREACHED*/
}
+ DebugPrint(DEBUG_INFO,SECTION_TAPE,"###### STOP drive_loaded (not empty)\n");
+ return(1);
}
* TODO:
* Check if the MTE is empty
*/
-int unload(int fd, int drive, int slot)
+int
+unload(
+ int fd,
+ int drive,
+ int slot)
{
extern OpenFiles_T *pDev;
- int ret;
- extern changer_t chg; /* Needed for the infos about emubarcode and labelfile */
extern int do_inventory;
MBC_T *pbarcoderes;
DebugPrint(DEBUG_INFO, SECTION_TAPE,"###### START unload\n");
DebugPrint(DEBUG_INFO, SECTION_TAPE,"%-20s : fd %d, slot %d, drive %d \n", "unload", fd, slot, drive);
- if ((pbarcoderes = malloc(sizeof(MBC_T))) == NULL)
- {
- DebugPrint(DEBUG_ERROR, SECTION_TAPE,"##### malloc failed (-1)\n");
- return(-1);
- }
- memset(pbarcoderes, 0, sizeof(MBC_T));
+ pbarcoderes = alloc(SIZEOF(MBC_T));
+ memset(pbarcoderes, 0, SIZEOF(MBC_T));
/*
* If the Element Status is not valid try to
DebugPrint(DEBUG_ERROR, SECTION_TAPE,"##### STOP unload (-1)\n");
free(pbarcoderes);
return(-1);
+ /*NOTREACHED*/
}
}
DebugPrint(DEBUG_ERROR, SECTION_TAPE,"##### STOP unload (-1)\n");
free(pbarcoderes);
return(-1);
+ /*NOTREACHED*/
}
/*
DebugPrint(DEBUG_ERROR, SECTION_ELEMENT, "unload: Element Status not valid, can't find an empty slot\n");
free(pbarcoderes);
return(-1);
+ /*NOTREACHED*/
}
slot = find_empty(fd, 0, 0);
DebugPrint(DEBUG_ERROR, SECTION_ELEMENT, "unload: No Empty slot found\n");
free(pbarcoderes);
return(-1);
+ /*NOTREACHED*/
}
DebugPrint(DEBUG_INFO, SECTION_TAPE,"unload : found empty one, try to unload to slot %d\n", slot);
}
* If eject is not set we must read the label info
*/
- if (chg.eject == 0)
+ if (changer->eject == 0)
{
- if (pDev[INDEX_TAPE].avail == 1 && (chg.emubarcode == 1 || BarCode(INDEX_CHANGER)))
+ if (pDev[INDEX_TAPE].avail == 1 && (changer->emubarcode == 1 || BarCode(INDEX_CHANGER)))
{
if (pDev[INDEX_TAPECTL].SCSI == 1 && pDev[INDEX_TAPECTL].avail) {
/*
* Do the unload/move
*/
- ret = pDev[INDEX_CHANGER].functions->function_move(INDEX_CHANGER , pDTE[drive].address, pSTE[slot].address);
+ if (pDev[INDEX_CHANGER].functions->function_move(INDEX_CHANGER,
+ pDTE[drive].address, pSTE[slot].address) != 0) {
+ DebugPrint(DEBUG_ERROR, SECTION_TAPE,"##### STOP unload (-1 move failed)\n");
+ free(pbarcoderes);
+ return(-1);
+ /*NOTREACHED*/
+ }
+
/*
* Update the Status
DebugPrint(DEBUG_ERROR, SECTION_TAPE,"##### STOP unload (-1 update status failed)\n");
free(pbarcoderes);
return(-1);
+ /*NOTREACHED*/
}
/*
* if no update the vol/label mapping
* If chgscsi_label is NULL don't do it
*/
- if (chgscsi_result == NULL && chgscsi_label != NULL && chg.labelfile != NULL)
+ if (chgscsi_result == NULL && chgscsi_label != NULL && changer->labelfile != NULL)
{
/*
* OK this is only needed if we have emubarcode set
* There we need an exact inventory to get the search function working
* and returning correct results
*/
- if (BarCode(INDEX_CHANGER) == 0 && chg.emubarcode == 1)
+ if (BarCode(INDEX_CHANGER) == 0 && changer->emubarcode == 1)
{
/*
* We got something, update the db
* to where we placed the tape, if no force an inventory
*/
pbarcoderes->action = FIND_SLOT;
- strcpy(pbarcoderes->data.voltag, chgscsi_label);
- strcpy(pbarcoderes->data.barcode, pSTE[slot].VolTag );
+ strncpy(pbarcoderes->data.voltag, chgscsi_label,
+ SIZEOF(pbarcoderes->data.voltag));
+ strncpy(pbarcoderes->data.barcode, pSTE[slot].VolTag,
+ SIZEOF(pbarcoderes->data.barcode));
pbarcoderes->data.slot = 0;
pbarcoderes->data.from = 0;
pbarcoderes->data.LoadCount = 0;
- if ( MapBarCode(chg.labelfile, pbarcoderes) == 0) /* Nothing known about this, do an Inventory */
+ if ( MapBarCode(changer->labelfile, pbarcoderes) == 0) /* Nothing known about this, do an Inventory */
{
do_inventory = 1;
} else {
* return -> 0 = success
* !0 = failure
*/
-int load(int fd, int drive, int slot)
+int
+load(
+ int fd,
+ int drive,
+ int slot)
{
- extern changer_t chg; /* Needed for the infos about emubarcode and labelfile */
char *result = NULL; /* Needed for the result of tape_rdlabel */
int ret;
extern OpenFiles_T *pDev;
DebugPrint(DEBUG_INFO, SECTION_ELEMENT,"###### START load\n");
DebugPrint(DEBUG_INFO, SECTION_ELEMENT,"%-20s : fd %d, drive %d, slot %d \n", "load", fd, drive, slot);
- if ((pbarcoderes = malloc(sizeof(MBC_T))) == NULL)
- {
- DebugPrint(DEBUG_ERROR, SECTION_ELEMENT,"##### malloc failed (-1)\n");
- return(-1);
- }
- memset(pbarcoderes, 0 , sizeof(MBC_T));
+ pbarcoderes = alloc(SIZEOF(MBC_T));
+ memset(pbarcoderes, 0 , SIZEOF(MBC_T));
if (ElementStatusValid == 0)
{
DebugPrint(DEBUG_ERROR, SECTION_ELEMENT,"##### STOP load (-1 update status failed)\n");
free(pbarcoderes);
return(-1);
+ /*NOTREACHED*/
}
}
* is ge than the value we got from the ModeSense fail with an return value
* of 2
*/
- if (slot >= STE)
+ if ((size_t)slot >= STE)
{
DebugPrint(DEBUG_ERROR, SECTION_ELEMENT,"load : slot %d ge STE %d\n",slot, STE);
ChgExit("load", "slot >= STE", FATAL);
+ /*NOTREACHED*/
}
/*
* And the same for the tape drives
*/
- if (drive >= DTE)
+ if (drive >= (int)DTE)
{
DebugPrint(DEBUG_ERROR, SECTION_ELEMENT,"load : drive %d ge DTE %d\n",drive, DTE);
ChgExit("load", "drive >= DTE", FATAL);
+ /*NOTREACHED*/
}
DebugPrint(DEBUG_INFO, SECTION_ELEMENT,"load : load drive %d[%d] slot %d[%d]\n",drive,
DebugPrint(DEBUG_ERROR, SECTION_ELEMENT,"##### STOP load (-1 update status failed)\n");
free(pbarcoderes);
return(-1);
+ /*NOTREACHED*/
}
if (pSTE[slot].status == 'E')
DebugPrint(DEBUG_ERROR, SECTION_ELEMENT,"##### STOP load (-1 update status failed)\n");
free(pbarcoderes);
return(-1);
+ /*NOTREACHED*/
}
ret = pDev[fd].functions->function_move(fd, pSTE[slot].address, pDTE[drive].address);
DebugPrint(DEBUG_ERROR, SECTION_ELEMENT,"##### STOP load (-1 update status failed)\n");
free(pbarcoderes);
return(-1);
+ /*NOTREACHED*/
}
/*
* Try to read the label
* and update the label/slot database
*/
- if (pDev[INDEX_TAPE].avail == 1 && (chg.emubarcode == 1 || BarCode(INDEX_CHANGER)))
+ if (pDev[INDEX_TAPE].avail == 1 && (changer->emubarcode == 1 || BarCode(INDEX_CHANGER)))
{
if (pDev[INDEX_TAPECTL].SCSI == 1 && pDev[INDEX_TAPECTL].avail) {
* Did we get an error from tape_rdlabel
* if no update the vol/label mapping
*/
- if (result == NULL && chg.labelfile != NULL && chgscsi_label != NULL )
+ if (result == NULL && changer->labelfile != NULL && chgscsi_label != NULL )
{
/*
* We got something, update the db
* but before check if the db has as entry the slot
* to where we placed the tape, if no force an inventory
*/
- strcpy(pbarcoderes->data.voltag, chgscsi_label);
+ strncpy(pbarcoderes->data.voltag, chgscsi_label,
+ SIZEOF(pbarcoderes->data.voltag));
pbarcoderes->data.slot = 0;
pbarcoderes->data.from = 0;
pbarcoderes->data.LoadCount = 0;
* info in the DB is up to date, if no we set the do_inventory flag
*/
- if (BarCode(INDEX_CHANGER) == 1 && chg.emubarcode == 0)
+ if (BarCode(INDEX_CHANGER) == 1 && changer->emubarcode == 0)
{
pbarcoderes->action = UPDATE_SLOT;
- strcpy(pbarcoderes->data.barcode, pDTE[drive].VolTag);
+ strncpy(pbarcoderes->data.barcode, pDTE[drive].VolTag,
+ SIZEOF(pbarcoderes->data.barcode));
pbarcoderes->data.LoadCount = 1;
pbarcoderes->data.slot = slot;
- MapBarCode(chg.labelfile, pbarcoderes);
+ MapBarCode(changer->labelfile, pbarcoderes);
}
- if (BarCode(INDEX_CHANGER) == 0 && chg.emubarcode == 1)
+ if (BarCode(INDEX_CHANGER) == 0 && changer->emubarcode == 1)
{
pbarcoderes->action = FIND_SLOT;
- if (MapBarCode(chg.labelfile, pbarcoderes) == 0) /* Nothing found, do an inventory */
+ if (MapBarCode(changer->labelfile, pbarcoderes) == 0) /* Nothing found, do an inventory */
{
do_inventory = 1;
} else { /* We got something, is it correct ? */
{
DebugPrint(DEBUG_ERROR, SECTION_TAPE,"Slot DB out of sync, slot %d != map %d",slot, pbarcoderes->data.slot);
ChgExit("Load", "Label DB out of sync", FATAL);
+ /*NOTREACHED*/
} else { /* OK, so increment the load count */
pbarcoderes->action = UPDATE_SLOT;
pbarcoderes->data.LoadCount = 1;
pbarcoderes->data.slot = slot;
- MapBarCode(chg.labelfile, pbarcoderes);
+ MapBarCode(changer->labelfile, pbarcoderes);
}
}
}
- if (BarCode(INDEX_CHANGER) == 1 && chg.emubarcode == 1)
+ if (BarCode(INDEX_CHANGER) == 1 && changer->emubarcode == 1)
{
ChgExit("Load", "BarCode == 1 and emubarcode == 1", FATAL);
+ /*NOTREACHED*/
}
DebugPrint(DEBUG_INFO, SECTION_ELEMENT,"##### STOP load (%d)\n",ret);
free(pbarcoderes);
return(ret);
+ /*NOTREACHED*/
}
DebugPrint(DEBUG_INFO, SECTION_ELEMENT,"##### STOP load (%d)\n",ret);
free(pbarcoderes);
* fd -> pointer to the internal devie structure pDev
* return -> Number of slots
*/
-int get_slot_count(int fd)
+int
+get_slot_count(
+ int fd)
{
extern OpenFiles_T *pDev;
{
pDev[fd].functions->function_status(fd, 1);
}
- DebugPrint(DEBUG_INFO, SECTION_ELEMENT,"##### STOP get_slot_count (%d)\n",STE);
- return(STE);
+ DebugPrint(DEBUG_INFO, SECTION_ELEMENT,
+ "##### STOP get_slot_count (" SIZE_T_FMT ")\n",
+ (SIZE_T_FMT_TYPE)STE);
+ return((ssize_t)STE);
/*
* return the number of slots in the robot
* to the caller
*/
-
}
* fd -> pointer to the internal devie structure pDev
* return -> -1 on failure
*/
-int get_drive_count(int fd)
+int
+get_drive_count(
+ int fd)
{
extern OpenFiles_T *pDev;
DebugPrint(DEBUG_INFO, SECTION_SCSI,"###### START get_drive_count\n");
DebugPrint(DEBUG_INFO, SECTION_SCSI,"%-20s : fd %d\n", "get_drive_count", fd);
-
if (ElementStatusValid == 0)
{
if ( pDev[fd].functions->function_status(fd, 1) != 0)
DebugPrint(DEBUG_ERROR, SECTION_SCSI, "Error getting drive count\n");
DebugPrint(DEBUG_ERROR, SECTION_SCSI, "##### STOP get_drive_count (-1)\n");
return(-1);
+ /*NOTREACHED*/
}
}
- DebugPrint(DEBUG_INFO, SECTION_SCSI,"###### STOP get_drive_count (%d drives)\n",DTE);
- return(DTE);
+ DebugPrint(DEBUG_INFO, SECTION_SCSI,
+ "###### STOP get_drive_count (" SIZE_T_FMT " drives)\n",
+ (SIZE_T_FMT_TYPE)DTE);
+ return((ssize_t)DTE);
}
/*
* The OS has to decide if it is an SCSI Commands capable device
*/
-int OpenDevice(int ip , char *DeviceName, char *ConfigName, char *ident)
+int
+OpenDevice(
+ int ip,
+ char * DeviceName,
+ char * ConfigName,
+ char * ident)
{
extern OpenFiles_T *pDev;
char tmpstr[15];
ChangerCMD_T *p = (ChangerCMD_T *)&ChangerIO;
+ if (!ConfigName)
+ return 1;
+ if (!DeviceName)
+ return 1;
+
DebugPrint(DEBUG_INFO, SECTION_SCSI,"##### START OpenDevice\n");
DebugPrint(DEBUG_INFO, SECTION_SCSI,"OpenDevice : %s\n", DeviceName);
DebugPrint(DEBUG_INFO, SECTION_SCSI,"override using ident = %s, type = %s\n",p->ident, p->type);
DebugPrint(DEBUG_INFO, SECTION_SCSI,"##### STOP OpenDevice\n");
return(1);
+ /*NOTREACHED*/
}
p++;
}
ChgExit("OpenDevice", "ident not found", FATAL);
+ /*NOTREACHED*/
} else {
while(p->ident != NULL)
{
DebugPrint(DEBUG_INFO, SECTION_SCSI,"using ident = %s, type = %s\n",p->ident, p->type);
DebugPrint(DEBUG_INFO, SECTION_SCSI,"##### STOP OpenDevice\n");
return(1);
+ /*NOTREACHED*/
}
p++;
}
/* divide generic in generic_type, where type is the */
/* num returned by the inquiry command */
p = (ChangerCMD_T *)&ChangerIO;
- sprintf(&tmpstr[0],"%s_%s","generic",pDev[0].type);
+ snprintf(&tmpstr[0], SIZEOF(tmpstr), "%s_%s","generic",pDev[0].type);
while(p->ident != NULL)
{
if (strcmp(tmpstr, p->ident) == 0)
DebugPrint(DEBUG_INFO, SECTION_SCSI,"using ident = %s, type = %s\n",p->ident, p->type);
DebugPrint(DEBUG_INFO, SECTION_SCSI,"##### STOP OpenDevice\n");
return(1);
+ /*NOTREACHED*/
}
p++;
}
* This functions checks if the library has an barcode reader.
* fd -> pointer to the internal devie structure pDev
*/
-int BarCode(int fd)
+int
+BarCode(
+ int fd)
{
- int ret = 0;
+ int ret;
extern OpenFiles_T *pDev;
DebugPrint(DEBUG_INFO, SECTION_BARCODE,"##### START BarCode\n");
* wait -> time to wait for the ready status
*
*/
-int Tape_Ready(int fd, int wait_time)
+int
+Tape_Ready(
+ int fd,
+ time_t wait_time)
{
extern OpenFiles_T *pDev;
- int true = 1;
+ int done;
int ret;
- int cnt = 0;
+ time_t cnt = 0;
RequestSense_T *pRequestSense;
DebugPrint(DEBUG_INFO, SECTION_TAPE,"##### START Tape_Ready\n");
DebugPrint(DEBUG_INFO, SECTION_TAPE,"Tape_Ready : Ready after %d seconds\n",cnt);
DebugPrint(DEBUG_INFO, SECTION_TAPE,"##### STOP Tape_Ready\n");
return(0);
+ /*NOTREACHED*/
}
cnt++;
sleep(1);
DebugPrint(DEBUG_INFO, SECTION_TAPE,"Tape_Ready : not ready, stop after %d seconds\n",cnt);
DebugPrint(DEBUG_INFO, SECTION_TAPE,"##### STOP Tape_Ready\n");
return(0);
+ /*NOTREACHED*/
- } else {
- DebugPrint(DEBUG_INFO, SECTION_TAPE,"Tape_Ready : no ioctl interface, will sleep for %d seconds\n", wait_time);
- sleep(wait_time);
- DebugPrint(DEBUG_INFO, SECTION_TAPE,"##### STOP Tape_Ready\n");
- return(0);
}
+ DebugPrint(DEBUG_INFO, SECTION_TAPE,"Tape_Ready : no ioctl interface, will sleep for %d seconds\n", wait_time);
+ sleep(wait_time);
+ DebugPrint(DEBUG_INFO, SECTION_TAPE,"##### STOP Tape_Ready\n");
+ return(0);
+ /*NOTREACHED*/
}
- if ((pRequestSense = (RequestSense_T *)malloc(sizeof(RequestSense_T))) == NULL)
- {
- DebugPrint(DEBUG_INFO, SECTION_TAPE,"Tape_Ready : malloc failed\n");
- DebugPrint(DEBUG_INFO, SECTION_TAPE,"##### STOP Tape_Ready\n");
- return(-1);
- }
+ pRequestSense = alloc(SIZEOF(RequestSense_T));
/*
* Ignore errors at this point
* Wait until we get an ready condition
*/
- while (true && cnt < wait_time)
+ done = 0;
+ while (!done && (cnt < wait_time))
{
ret = SCSI_TestUnitReady(fd, pRequestSense );
switch (ret)
{
case SCSI_OK:
- true = 0;
+ done = 1;
break;
case SCSI_SENSE:
- switch (SenseHandler(fd, 0, pRequestSense->SenseKey, pRequestSense->AdditionalSenseCode, pRequestSense->AdditionalSenseCodeQualifier, (char *)pRequestSense))
+ switch (SenseHandler(fd, 0, pRequestSense->SenseKey, pRequestSense->AdditionalSenseCode, pRequestSense->AdditionalSenseCodeQualifier, pRequestSense))
{
case SENSE_NO:
DebugPrint(DEBUG_INFO, SECTION_SCSI,"TapeReady (TestUnitReady) SENSE_NO\n");
- true=0;
+ done = 1;
break;
case SENSE_TAPE_NOT_ONLINE:
DebugPrint(DEBUG_INFO, SECTION_SCSI,"TapeReady (TestUnitReady) SENSE_TAPE_NOT_ONLINE\n");
break;
case SENSE_IGNORE:
DebugPrint(DEBUG_INFO, SECTION_SCSI,"TapeReady (TestUnitReady) SENSE_IGNORE\n");
- true = 0;
+ done = 1;
break;
case SENSE_ABORT:
DebugPrint(DEBUG_ERROR, SECTION_SCSI,"TapeReady (TestUnitReady) SENSE_ABORT\n");
- free(pRequestSense);
+ amfree(pRequestSense);
return(-1);
- break;
+ /*NOTREACHED*/
case SENSE_RETRY:
DebugPrint(DEBUG_INFO, SECTION_SCSI,"TapeReady (TestUnitReady) SENSE_RETRY\n");
break;
default:
DebugPrint(DEBUG_INFO, SECTION_SCSI,"TapeReady (TestUnitReady) default (SENSE)\n");
- true=0;
+ done = 1;
break;
}
break;
DebugPrint(DEBUG_ERROR, SECTION_SCSI,"TapeReady (TestUnitReady) SCSI_ERROR\n");
free(pRequestSense);
return(-1);
- break;
+ /*NOTREACHED*/
case SCSI_BUSY:
DebugPrint(DEBUG_INFO, SECTION_SCSI,"TapeReady (TestUnitReady) SCSI_BUSY\n");
break;
cnt++;
}
+ amfree(pRequestSense);
DebugPrint(DEBUG_INFO, SECTION_TAPE,"Tape_Ready after %d sec\n", cnt);
DebugPrint(DEBUG_INFO, SECTION_TAPE,"##### STOP Tape_Ready\n");
- free(pRequestSense);
return(0);
}
-int DecodeSCSI(CDB_T CDB, char *string)
+int
+DecodeSCSI(
+ CDB_T CDB,
+ char * string)
{
SC_COM_T *pSCSICommand;
int x;
DebugPrint(DEBUG_INFO, SECTION_SCSI,"\n");
DebugPrint(DEBUG_INFO, SECTION_SCSI,"##### STOP DecodeSCSI\n");
return(0);
+ /*NOTREACHED*/
}
pSCSICommand++;
}
return(0);
}
-int DecodeModeSense(char *buffer, int offset, char *pstring, char block, FILE *out)
+int
+DecodeModeSense(
+ u_char * buffer,
+ size_t offset,
+ char * pstring,
+ char block,
+ FILE * out)
{
ReadWriteErrorRecoveryPage_T *prp;
DisconnectReconnectPage_T *pdrp;
- int length = (unsigned char)*buffer - 4 - offset;
+ size_t length = (size_t)buffer[0] - 4 - offset;
+
+ (void)pstring; /* Quiet unused parameter warning */
DebugPrint(DEBUG_INFO, SECTION_SCSI,"##### START DecodeModeSense\n");
if (block) /* Do we have an block descriptor page ?*/
{
if (out != NULL)
- fprintf(out, "DecodeModeSense : Density Code %x\n", buffer[0]);
+ fprintf(out, "DecodeModeSense : Density Code %x\n", (unsigned)buffer[0]);
buffer++;
if (out != NULL)
/* EAAPage = NULL; */
/* DeviceCapabilitiesPage = NULL; */
return(-1);
+ /*NOTREACHED*/
}
- length = length - *buffer - 2;
- buffer = buffer + *buffer + 1;
+ length = length - (size_t)*buffer - 2;
+ buffer = buffer + (size_t)*buffer + 1;
}
return(0);
}
-int DecodeSense(RequestSense_T *sense, char *pstring, FILE *out)
+int
+DecodeSense(
+ RequestSense_T * sense,
+ char * pstring,
+ FILE * out)
{
if (out == NULL)
{
return(0);
+ /*NOTREACHED*/
}
fprintf(out,"##### START DecodeSense\n");
fprintf(out,"%sSense Keys\n", pstring);
return(0);
}
-int DecodeExtSense(ExtendedRequestSense_T *sense, char *pstring, FILE *out)
+int
+DecodeExtSense(
+ ExtendedRequestSense_T * sense,
+ char * pstring,
+ FILE * out)
{
ExtendedRequestSense_T *p;
fprintf(out,"\tLog Parameter Code %02X\n", sense->LogParameterCode);
fprintf(out,"\tUnderrun/Overrun Counter %02X\n", sense->UnderrunOverrunCounter);
fprintf(out,"\tRead/Write Error Counter %d\n", V3((char *)sense->ReadWriteDataErrorCounter));
- if (sense->AdditionalSenseLength > sizeof(RequestSense_T))
+ if (sense->AdditionalSenseLength > (u_char)sizeof(RequestSense_T))
{
if (sense->PF)
fprintf(out,"\tPower Fail\n");
return(0);
}
-int PrintInquiry(SCSIInquiry_T *SCSIInquiry)
+int
+PrintInquiry(
+ SCSIInquiry_T * SCSIInquiry)
{
DebugPrint(DEBUG_INFO, SECTION_SCSI,"##### START PrintInquiry\n");
DebugPrint(DEBUG_INFO, SECTION_SCSI,"%-15s %x\n", "qualifier", SCSIInquiry->qualifier);
}
-int DoNothing()
+int
+DoNothing0(void)
+{
+ dbprintf(("##### START DoNothing\n"));
+ return(0);
+}
+
+int
+DoNothing1(
+ int unused1)
+{
+ (void)unused1; /* Quiet unused parameter warning */
+
+ dbprintf(("##### START DoNothing\n"));
+ return(0);
+}
+
+int
+DoNothing2(
+ int unused1,
+ int unused2)
+{
+ (void)unused1; /* Quiet unused parameter warning */
+ (void)unused2; /* Quiet unused parameter warning */
+
+ dbprintf(("##### START DoNothing\n"));
+ return(0);
+}
+
+int
+DoNothing3(
+ int unused1,
+ int unused2,
+ int unused3)
{
+ (void)unused1; /* Quiet unused parameter warning */
+ (void)unused2; /* Quiet unused parameter warning */
+ (void)unused3; /* Quiet unused parameter warning */
+
dbprintf(("##### START DoNothing\n"));
return(0);
}
-int GenericFree()
+int
+GenericFree(void)
{
dbprintf(("##### START GenericFree\n"));
return(0);
}
-int GenericSearch()
+int
+GenericSearch(void)
{
dbprintf(("##### START GenericSearch\n"));
return(0);
}
-int TreeFrogBarCode(int DeviceFD)
+int
+TreeFrogBarCode(
+ int DeviceFD)
{
extern OpenFiles_T *pDev;
dbprintf(("##### START TreeFrogBarCode\n"));
if (pModePage == NULL)
{
- if ((pModePage = malloc(0xff)) == NULL)
- {
- dbprintf(("TreeFrogBarCode : malloc failed\n"));
- return(-1);
- }
+ pModePage = alloc(0xff);
}
if (SCSI_ModeSense(DeviceFD, pModePage, 0xff, 0x0, 0x3f) == 0)
{
dbprintf(("TreeFrogBarCode : no pVendorUnique\n"));
return(0);
+ /*NOTREACHED*/
}
pVendor = ( ModePageTreeFrogVendorUnique_T *)pVendorUnique;
dbprintf(("TreeFrogBarCode : EBARCO %d\n", pVendor->EBARCO));
dbprintf(("TreeFrogCheckSum : CHKSUM %d\n", pVendor->CHKSUM));
- dump_hex((char *)pDev[INDEX_CHANGER].inquiry, INQUIRY_SIZE, DEBUG_INFO, SECTION_ELEMENT);
+ dump_hex((u_char *)pDev[INDEX_CHANGER].inquiry, INQUIRY_SIZE, DEBUG_INFO, SECTION_ELEMENT);
return(pVendor->EBARCO);
+ /*NOTREACHED*/
}
return(0);
}
-int EXB_BarCode(int DeviceFD)
+int
+EXB_BarCode(
+ int DeviceFD)
{
extern OpenFiles_T *pDev;
ModePageEXB120VendorUnique_T *pVendor;
- ModePageEXB120VendorUnique_T *pVendorWork = NULL;
+ ModePageEXB120VendorUnique_T *pVendorWork;
DebugPrint(DEBUG_INFO, SECTION_BARCODE,"##### START EXB_BarCode\n");
if (pModePage == NULL && LibModeSenseValid == 0)
{
- if ((pModePage = malloc(0xff)) == NULL)
- {
- DebugPrint(DEBUG_ERROR, SECTION_BARCODE,"EXB_BarCode : malloc failed\n");
- return(-1);
- }
+ pModePage = alloc(0xff);
+
if (SCSI_ModeSense(DeviceFD, pModePage, 0xff, 0x8, 0x3f) == 0)
{
DecodeModeSense(pModePage, 0, "EXB_BarCode :", 0, debug_file);
{
DebugPrint(DEBUG_INFO, SECTION_BARCODE,"EXB_BarCode : no pVendorUnique\n");
return(0);
+ /*NOTREACHED*/
}
pVendor = ( ModePageEXB120VendorUnique_T *)pVendorUnique;
DebugPrint(DEBUG_INFO, SECTION_BARCODE,"EXB_BarCode : PS %d\n", pVendor->PS);
if (pVendor->NBL == 1 && pVendor->PS == 1 )
{
- if ((pVendorWork = ( ModePageEXB120VendorUnique_T *)malloc(pVendor->ParameterListLength + 2)) == NULL)
- {
- DebugPrint(DEBUG_ERROR, SECTION_BARCODE,"EXB_BarCode : malloc failed\n");
- return(-1);
- }
+ pVendorWork = alloc((size_t)pVendor->ParameterListLength + 2);
DebugPrint(DEBUG_INFO, SECTION_BARCODE,"EXB_BarCode : setting NBL to 1\n");
- memcpy(pVendorWork, pVendor, pVendor->ParameterListLength + 2);
+ memcpy(pVendorWork, pVendor, (size_t)pVendor->ParameterListLength + 2);
pVendorWork->NBL = 0;
pVendorWork->PS = 0;
pVendorWork->RSVD0 = 0;
- if (SCSI_ModeSelect(DeviceFD, (char *)pVendorWork, pVendorWork->ParameterListLength + 2, 0, 1, 0) == 0)
+ if (SCSI_ModeSelect(DeviceFD, (u_char *)pVendorWork, (u_char)(pVendorWork->ParameterListLength + 2), 0, 1, 0) == 0)
{
DebugPrint(DEBUG_INFO, SECTION_BARCODE,"EXB_BarCode : SCSI_ModeSelect OK\n");
/* Hack !!!!!!
} else {
DebugPrint(DEBUG_INFO, SECTION_BARCODE,"EXB_BarCode : SCSI_ModeSelect failed\n");
}
- amfree(pVendorWork);
+ amfree(pVendorWork);
}
- dump_hex((char *)pDev[INDEX_CHANGER].inquiry, INQUIRY_SIZE, DEBUG_INFO, SECTION_BARCODE);
+ dump_hex((u_char *)pDev[INDEX_CHANGER].inquiry, INQUIRY_SIZE, DEBUG_INFO, SECTION_BARCODE);
DebugPrint(DEBUG_INFO, SECTION_BARCODE,"EXB_BarCode : vendor_specific[19] %x\n",
pDev[INDEX_CHANGER].inquiry->vendor_specific[19]);
}
-
return(1);
}
-int NoBarCode(int DeviceFD)
+int
+NoBarCode(
+ int DeviceFD)
{
+ (void)DeviceFD; /* Quiet unused parameter warning */
+
DebugPrint(DEBUG_INFO, SECTION_BARCODE,"##### START NoBarCode\n");
DebugPrint(DEBUG_INFO, SECTION_BARCODE,"##### STOP NoBarCode\n");
return(0);
}
-int GenericBarCode(int DeviceFD)
+int
+GenericBarCode(
+ int DeviceFD)
{
- extern changer_t chg;
+ (void)DeviceFD; /* Quiet unused parameter warning */
DebugPrint(DEBUG_INFO, SECTION_BARCODE,"##### START GenericBarCode\n");
- if ( chg.havebarcode >= 1)
+ if ( changer->havebarcode >= 1)
{
- DebugPrint(DEBUG_INFO, SECTION_BARCODE,"##### STOP GenericBarCode (havebarcode) => %d\n",chg.havebarcode);
+ DebugPrint(DEBUG_INFO, SECTION_BARCODE,"##### STOP GenericBarCode (havebarcode) => %d\n",changer->havebarcode);
return(1);
+ /*NOTREACHED*/
}
DebugPrint(DEBUG_INFO, SECTION_BARCODE,"##### STOP GenericBarCode => 0\n");
return(0);
}
-int SenseHandler(int DeviceFD, unsigned char flag, unsigned char SenseKey, unsigned char AdditionalSenseCode, unsigned char AdditionalSenseCodeQualifier, char *buffer)
+int
+SenseHandler(
+ int DeviceFD,
+ u_char flag,
+ u_char SenseKey,
+ u_char AdditionalSenseCode,
+ u_char AdditionalSenseCodeQualifier,
+ RequestSense_T * buffer)
{
extern OpenFiles_T *pDev;
int ret = 0;
* if there are more than one
* Implement the SCSI path if available
*/
-int TapeStatus()
+int
+TapeStatus(void)
{
extern OpenFiles_T *pDev;
int ret;
- int true = 1;
- int cnt = 0;
- RequestSense_T *pRequestSense = NULL;
+ int done;
+ int cnt;
+ RequestSense_T *pRequestSense;
DebugPrint(DEBUG_INFO, SECTION_TAPE,"##### START TapeStatus\n");
*/
if (pDev[INDEX_TAPECTL].SCSI == 1)
{
- if ((pRequestSense = malloc(sizeof(RequestSense_T))) == NULL)
- {
- dbprintf(("%-20s : malloc failed\n","TapeStatus"));
- return(-1);
- }
+ pRequestSense = alloc(SIZEOF(RequestSense_T));
+ memset(pRequestSense, 0, SIZEOF(RequestSense_T));
- while (true && cnt < 60)
+ for (done = 0, cnt = 0; !done && (cnt < 60); cnt++)
{
ret = SCSI_TestUnitReady(INDEX_TAPECTL, pRequestSense);
DebugPrint(DEBUG_INFO, SECTION_SCSI, "TapeStatus TestUnitReady ret %d\n",ret);
{
case SCSI_OK:
case SCSI_SENSE:
- switch (SenseHandler(INDEX_TAPECTL, 0, pRequestSense->SenseKey, pRequestSense->AdditionalSenseCode, pRequestSense->AdditionalSenseCodeQualifier, (char *)pRequestSense))
+ switch (SenseHandler(INDEX_TAPECTL, 0, pRequestSense->SenseKey, pRequestSense->AdditionalSenseCode, pRequestSense->AdditionalSenseCodeQualifier, pRequestSense))
{
case SENSE_IGNORE:
case SENSE_NO:
DebugPrint(DEBUG_INFO, SECTION_SCSI,"TapeStatus (TestUnitReady) SENSE_NO\n");
pDTE[0].status = 'F';
DebugPrint(DEBUG_INFO, SECTION_TAPE,"##### FULL\n");
- true = 0;
+ done = 1;
break;
+
case SENSE_TAPE_NOT_ONLINE:
DebugPrint(DEBUG_INFO, SECTION_SCSI,"TapeStatus (TestUnitReady) SENSE_TAPE_NOT_ONLINE\n");
pDTE[0].status = 'E';
DebugPrint(DEBUG_INFO, SECTION_TAPE,"##### EMPTY\n");
- true = 0;
+ done = 1;
break;
+
case SENSE_ABORT:
DebugPrint(DEBUG_ERROR, SECTION_SCSI,"TapeStatus (TestUnitReady) SENSE_ABORT\n");
- true = 0;
+ done = 1;
break;
+
case SENSE_RETRY:
DebugPrint(DEBUG_INFO, SECTION_SCSI,"TapeStatus (TestUnitReady) SENSE_RETRY\n");
break;
+
default:
DebugPrint(DEBUG_INFO, SECTION_SCSI,"TapeStatus (TestUnitReady) default (SENSE)\n");
break;
}
break;
+
case SCSI_ERROR:
DebugPrint(DEBUG_ERROR, SECTION_SCSI,"TapeStatus (TestUnitReady) SCSI_ERROR\n");
- true = 0;
+ done = 1;
break;
+
case SCSI_BUSY:
DebugPrint(DEBUG_INFO, SECTION_SCSI,"TapeStatus (TestUnitReady) SCSI_BUSY\n");
break;
+
case SCSI_CHECK:
DebugPrint(DEBUG_INFO, SECTION_SCSI,"TapeStatus (TestUnitReady) SCSI_CHECK\n");
break;
+
default:
DebugPrint(DEBUG_ERROR, SECTION_SCSI,"TapeStatus (TestUnitReady) unknown (%d)\n",ret);
break;
+
}
- sleep(2);
- cnt++;
+ if (!done)
+ sleep(2);
}
amfree(pRequestSense);
} else {
return(0);
}
-int DLT4000Eject(char *Device, int type)
+int
+DLT4000Eject(
+ char * Device,
+ int type)
{
extern OpenFiles_T *pDev;
ExtendedRequestSense_T *pExtendedRequestSense;
int ret;
int cnt = 0;
- int true = 1;
+ int done;
- dbprintf(("##### START DLT4000Eject\n"));
+ (void)Device; /* Quiet unused parameter warning */
- if ((pRequestSense = malloc(sizeof(RequestSense_T))) == NULL)
- {
- dbprintf(("%-20s : malloc failed\n","DLT4000Eject"));
- return(-1);
- }
+ dbprintf(("##### START DLT4000Eject\n"));
- if ((pExtendedRequestSense = malloc(sizeof(ExtendedRequestSense_T))) == NULL)
- {
- dbprintf(("%-20s : malloc failed\n","DLT4000Eject"));
- free(pRequestSense);
- return(-1);
- }
+ pRequestSense = alloc(SIZEOF(RequestSense_T));
+ pExtendedRequestSense = alloc(SIZEOF(ExtendedRequestSense_T));
if ( type > 1)
{
free(pExtendedRequestSense);
free(pRequestSense);
return(Tape_Ioctl(INDEX_TAPE, IOCTL_EJECT));
+ /*NOTREACHED*/
}
free(pExtendedRequestSense);
free(pRequestSense);
return(Tape_Ioctl(INDEX_TAPE, IOCTL_EJECT));
+ /*NOTREACHED*/
}
free(pExtendedRequestSense);
free(pRequestSense);
return(-1);
+ /*NOTREACHED*/
}
- true = 1;
- while (true && cnt < 300)
+ done = 0;
+ while (!done && cnt < 300)
{
ret = SCSI_TestUnitReady(INDEX_TAPECTL, pRequestSense);
DebugPrint(DEBUG_INFO, SECTION_SCSI, "DLT4000Eject TestUnitReady ret %d\n",ret);
switch (ret)
{
case SCSI_OK:
- true = 0;
+ done = 1;
break;
case SCSI_SENSE:
- switch (SenseHandler(INDEX_TAPECTL, 0, pRequestSense->SenseKey, pRequestSense->AdditionalSenseCode, pRequestSense->AdditionalSenseCodeQualifier, (char *)pRequestSense))
+ switch (SenseHandler(INDEX_TAPECTL, 0, pRequestSense->SenseKey, pRequestSense->AdditionalSenseCode, pRequestSense->AdditionalSenseCodeQualifier, pRequestSense))
{
case SENSE_NO:
DebugPrint(DEBUG_INFO, SECTION_SCSI,"DLT4000Eject (TestUnitReady) SENSE_NO\n");
- true = 0;
+ done = 1;
break;
case SENSE_TAPE_NOT_ONLINE:
DebugPrint(DEBUG_INFO, SECTION_SCSI,"DLT4000Eject (TestUnitReady) SENSE_TAPE_NOT_ONLINE\n");
- true = 0;
+ done = 1;
break;
case SENSE_IGNORE:
DebugPrint(DEBUG_INFO, SECTION_SCSI,"DLT4000Eject (TestUnitReady) SENSE_IGNORE\n");
- true = 0;
+ done = 1;
break;
case SENSE_ABORT:
DebugPrint(DEBUG_ERROR, SECTION_SCSI,"DLT4000Eject (TestUnitReady) SENSE_ABORT\n");
free(pExtendedRequestSense);
free(pRequestSense);
return(-1);
+ /*NOTREACHED*/
case SENSE_RETRY:
DebugPrint(DEBUG_INFO, SECTION_SCSI,"DLT4000Eject (TestUnitReady) SENSE_RETRY\n");
break;
default:
DebugPrint(DEBUG_INFO, SECTION_SCSI,"DLT4000Eject (TestUnitReady) default (SENSE)\n");
- true = 0;
+ done = 1;
break;
}
break;
free(pExtendedRequestSense);
free(pRequestSense);
return(-1);
+ /*NOTREACHED*/
case SCSI_BUSY:
DebugPrint(DEBUG_INFO, SECTION_SCSI,"DLT4000Eject (TestUnitReady) SCSI_BUSY\n");
break;
sleep(2);
}
- dbprintf(("DLT4000Eject : Ready after %d sec, true = %d\n", cnt * 2, true));
+ dbprintf(("DLT4000Eject : Ready after %d sec, done = %d\n", cnt * 2, done));
free(pExtendedRequestSense);
free(pRequestSense);
* Before unload check if there is an tape in the drive
*
*/
-int GenericEject(char *Device, int type)
+int
+GenericEject(
+ char * Device,
+ int type)
{
extern OpenFiles_T *pDev;
RequestSense_T *pRequestSense;
int ret;
int cnt = 0;
- int true = 1;
+ int done;
+
+ (void)Device; /* Quiet unused parameter warning */
+ (void)type; /* Quiet unused parameter warning */
DebugPrint(DEBUG_INFO, SECTION_TAPE, "##### START GenericEject\n");
- if ((pRequestSense = malloc(sizeof(RequestSense_T))) == NULL)
- {
- DebugPrint(DEBUG_ERROR, SECTION_TAPE, "%-20s : malloc failed\n","GenericEject");
- return(-1);
- }
+ pRequestSense = alloc(SIZEOF(RequestSense_T));
DebugPrint(DEBUG_INFO, SECTION_TAPE,"GenericEject : SCSI eject on %s = %s\n",
pDev[INDEX_TAPECTL].dev, pDev[INDEX_TAPECTL].ConfigName);
if (ret < 0) {
free(pRequestSense);
return(-1);
+ /*NOTREACHED*/
}
- true = 1;
- while (true && cnt < 300)
+ done = 0;
+ while (!done && cnt < 300)
{
ret = SCSI_TestUnitReady(INDEX_TAPECTL, pRequestSense);
DebugPrint(DEBUG_INFO, SECTION_SCSI, "GenericEject TestUnitReady ret %d\n",ret);
{
case SCSI_OK:
case SCSI_SENSE:
- switch (SenseHandler(INDEX_TAPECTL, 0, pRequestSense->SenseKey, pRequestSense->AdditionalSenseCode, pRequestSense->AdditionalSenseCodeQualifier, (char *)pRequestSense))
+ switch (SenseHandler(INDEX_TAPECTL, 0, pRequestSense->SenseKey, pRequestSense->AdditionalSenseCode, pRequestSense->AdditionalSenseCodeQualifier, pRequestSense))
{
case SENSE_NO:
DebugPrint(DEBUG_INFO, SECTION_SCSI,"GenericEject (TestUnitReady) SENSE_NO\n");
break;
case SENSE_TAPE_NOT_ONLINE:
DebugPrint(DEBUG_INFO, SECTION_SCSI,"GenericEject (TestUnitReady) SENSE_TAPE_NOT_ONLINE\n");
- true = 0;
+ done = 1;
break;
case SENSE_IGNORE:
DebugPrint(DEBUG_INFO, SECTION_SCSI,"GenericEject (TestUnitReady) SENSE_IGNORE\n");
DebugPrint(DEBUG_ERROR, SECTION_SCSI,"GenericEject (TestUnitReady) SENSE_ABORT\n");
free(pRequestSense);
return(-1);
+ /*NOTREACHED*/
case SENSE_RETRY:
DebugPrint(DEBUG_INFO, SECTION_SCSI,"GenericEject (TestUnitReady) SENSE_RETRY\n");
break;
DebugPrint(DEBUG_ERROR, SECTION_SCSI,"GenericEject (TestUnitReady) SCSI_ERROR\n");
free(pRequestSense);
return(-1);
+ /*NOTREACHED*/
case SCSI_BUSY:
DebugPrint(DEBUG_INFO, SECTION_SCSI,"GenericEject (TestUnitReady) SCSI_BUSY\n");
break;
DebugPrint(DEBUG_INFO, SECTION_TAPE,"GenericEject : Device can't understand SCSI try ioctl\n");
Tape_Ioctl(INDEX_TAPECTL, IOCTL_EJECT);
}
- DebugPrint(DEBUG_INFO, SECTION_TAPE,"GenericEject : Ready after %d sec, true = %d\n", cnt * 2, true);
+ DebugPrint(DEBUG_INFO, SECTION_TAPE,
+ "GenericEject : Ready after %d sec\n", cnt * 2);
free(pRequestSense);
return(0);
}
* -1 -> error
* 0 -> success
*/
-int GenericRewind(int DeviceFD)
+int
+GenericRewind(
+ int DeviceFD)
{
CDB_T CDB;
extern OpenFiles_T *pDev;
- RequestSense_T *pRequestSense = NULL;
+ RequestSense_T *pRequestSense;
char *errstr; /* Used by tape_rewind */
int ret;
int cnt = 0;
- int true = 1;
+ int done;
DebugPrint(DEBUG_INFO, SECTION_TAPE,"##### START GenericRewind pDEV -> %d\n",DeviceFD);
*/
if (pDev[DeviceFD].SCSI == 1)
{
- if ((pRequestSense = (RequestSense_T *)malloc(sizeof(RequestSense_T))) == NULL)
- {
- DebugPrint(DEBUG_ERROR, SECTION_TAPE,"GenericRewind : malloc failed\n");
- return(-1);
- }
+ pRequestSense = alloc(SIZEOF(RequestSense_T));
+
/*
* Before doing the rewind check if the tape is ready to accept commands
*/
- while (true == 1)
+ done = 0;
+ while (!done)
{
ret = SCSI_TestUnitReady(DeviceFD, (RequestSense_T *)pRequestSense );
DebugPrint(DEBUG_INFO, SECTION_TAPE, "GenericRewind (TestUnitReady) ret %d\n",ret);
switch (ret)
{
case SCSI_OK:
- true= 0;
+ done = 1;
break;
case SCSI_SENSE:
- switch (SenseHandler(DeviceFD, 0, pRequestSense->SenseKey, pRequestSense->AdditionalSenseCode, pRequestSense->AdditionalSenseCodeQualifier, (char *)pRequestSense))
+ switch (SenseHandler(DeviceFD, 0, pRequestSense->SenseKey, pRequestSense->AdditionalSenseCode, pRequestSense->AdditionalSenseCodeQualifier, pRequestSense))
{
case SENSE_NO:
DebugPrint(DEBUG_INFO, SECTION_SCSI,"GenericRewind (TestUnitReady) SENSE_NO\n");
- true = 0;
+ done = 1;
break;
case SENSE_TAPE_NOT_ONLINE:
DebugPrint(DEBUG_INFO, SECTION_SCSI,"GenericRewind (TestUnitReady) SENSE_TAPE_NOT_ONLINE\n");
free(pRequestSense);
return(-1);
- break;
+ /*NOTREACHED*/
case SENSE_IGNORE:
DebugPrint(DEBUG_INFO, SECTION_SCSI,"GenericRewind (TestUnitReady) SENSE_IGNORE\n");
- true = 0;
+ done = 1;
break;
case SENSE_ABORT:
DebugPrint(DEBUG_ERROR, SECTION_SCSI,"GenericRewind (TestUnitReady) SENSE_ABORT\n");
free(pRequestSense);
return(-1);
- break;
+ /*NOTREACHED*/
case SENSE_RETRY:
DebugPrint(DEBUG_INFO, SECTION_SCSI,"GenericRewind (TestUnitReady) SENSE_RETRY\n");
break;
default:
DebugPrint(DEBUG_INFO, SECTION_SCSI,"GenericRewind (TestUnitReady) default (SENSE)\n");
- true = 0;
+ done = 1;
break;
} /* switch (SenseHandler(DeviceFD, 0, pRequestSense->SenseKey.... */
break;
DebugPrint(DEBUG_ERROR, SECTION_SCSI,"GenericRewind (TestUnitReady) SCSI_ERROR\n");
free(pRequestSense);
return(-1);
- break;
+ /*NOTREACHED*/
+
case SCSI_BUSY:
DebugPrint(DEBUG_INFO, SECTION_SCSI,"GenericRewind (TestUnitReady) SCSI_BUSY\n");
break;
DebugPrint(DEBUG_ERROR, SECTION_TAPE,"##### STOP GenericRewind (-1)\n");
free(pRequestSense);
return(-1);
+ /*NOTREACHED*/
}
- } /* while true == 1 */
+ } /* while !done */
cnt = 0;
- true = 1;
CDB[0] = SC_COM_REWIND;
CDB[1] = 1;
CDB[4] = 0;
CDB[5] = 0;
- while (true)
+ done = 0;
+ while (!done)
{
ret = SCSI_Run(DeviceFD, Input, CDB, 6,
NULL, 0,
- (char *) pRequestSense,
- sizeof(RequestSense_T));
+ pRequestSense,
+ SIZEOF(RequestSense_T));
DecodeSense(pRequestSense, "GenericRewind : ", debug_file);
{
if (pRequestSense->SenseKey != UNIT_ATTENTION)
{
- true = 0;
+ done = 1;
}
}
if (ret == 0)
{
- true = 0;
+ done = 1;
}
if (ret < 0)
{
DebugPrint(DEBUG_INFO, SECTION_TAPE,"GenericRewind : failed %d\n", ret);
- true = 0;
+ done = 1;
}
}
- true = 1;
-
- while (true && cnt < 300)
+ done = 0;
+ while (!done && (cnt < 300))
{
ret = SCSI_TestUnitReady(DeviceFD, pRequestSense);
DebugPrint(DEBUG_INFO, SECTION_SCSI, "GenericRewind TestUnitReady ret %d\n",ret);
switch (ret)
{
case SCSI_OK:
- true = 0;
+ done = 1;
break;
case SCSI_SENSE:
- switch (SenseHandler(DeviceFD, 0, pRequestSense->SenseKey, pRequestSense->AdditionalSenseCode, pRequestSense->AdditionalSenseCodeQualifier, (char *)pRequestSense))
+ switch (SenseHandler(DeviceFD, 0, pRequestSense->SenseKey, pRequestSense->AdditionalSenseCode, pRequestSense->AdditionalSenseCodeQualifier, pRequestSense))
{
case SENSE_NO:
DebugPrint(DEBUG_INFO, SECTION_SCSI,"GenericRewind (TestUnitReady) SENSE_NO\n");
- true = 0;
+ done = 1;
break;
case SENSE_TAPE_NOT_ONLINE:
DebugPrint(DEBUG_INFO, SECTION_SCSI,"GenericRewind (TestUnitReady) SENSE_TAPE_NOT_ONLINE\n");
free(pRequestSense);
return(-1);
- break;
+ /*NOTREACHED*/
case SENSE_IGNORE:
DebugPrint(DEBUG_INFO, SECTION_SCSI,"GenericRewind (TestUnitReady) SENSE_IGNORE\n");
- true = 0;
+ done = 1;
break;
case SENSE_ABORT:
DebugPrint(DEBUG_ERROR, SECTION_SCSI,"GenericRewind (TestUnitReady) SENSE_ABORT\n");
free(pRequestSense);
return(-1);
- break;
+ /*NOTREACHED*/
case SENSE_RETRY:
DebugPrint(DEBUG_INFO, SECTION_SCSI,"GenericRewind (TestUnitReady) SENSE_RETRY\n");
break;
default:
DebugPrint(DEBUG_INFO, SECTION_SCSI,"GenericRewind (TestUnitReady) default (SENSE)\n");
- true = 0;
+ done = 1;
break;
}
break;
case SCSI_ERROR:
DebugPrint(DEBUG_ERROR, SECTION_SCSI,"GenericRewind (TestUnitReady) SCSI_ERROR\n");
- free(pRequestSense);
return(-1);
- break;
+ /*NOTREACHED*/
+
case SCSI_BUSY:
DebugPrint(DEBUG_INFO, SECTION_SCSI,"GenericRewind (TestUnitReady) SCSI_BUSY\n");
break;
amfree(pRequestSense);
- DebugPrint(DEBUG_INFO, SECTION_TAPE,"GenericRewind : Ready after %d sec, true = %d\n", cnt * 2, true);
+ DebugPrint(DEBUG_INFO, SECTION_TAPE,"GenericRewind : Ready after %d sec, "
+ "done = %d\n", cnt * 2, done);
DebugPrint(DEBUG_INFO, SECTION_TAPE,"##### STOP GenericRewind (0)\n");
} else {
DebugPrint(DEBUG_INFO, SECTION_TAPE,"GenericRewind : use ioctl rewind\n");
}
/* We don't retry if it fails; that is left to the vtape driver. */
if ((errstr = tape_rewind(pDev[DeviceFD].dev)) == NULL) {
- true = 0;
DebugPrint(DEBUG_INFO, SECTION_TAPE,"Rewind OK,\n", cnt);
} else {
DebugPrint(DEBUG_ERROR, SECTION_TAPE,"Rewind failed %s\n",errstr);
DebugPrint(DEBUG_INFO, SECTION_TAPE,"##### STOP GenericRewind (-1)\n");
- amfree(pRequestSense);
return(-1);
+ /*NOTREACHED*/
}
DebugPrint(DEBUG_INFO, SECTION_TAPE,"##### STOP GenericRewind (0)\n");
}
- amfree(pRequestSense);
return(0);
}
* bit set in the return of an request sense
*
*/
-int GenericClean(char * Device)
+int
+GenericClean(
+ char * Device)
{
extern OpenFiles_T *pDev;
ExtendedRequestSense_T ExtRequestSense;
int ret = 0;
+ (void)Device; /* Quiet unused parameter warning */
+
DebugPrint(DEBUG_INFO, SECTION_TAPE,"##### START GenericClean\n");
if (pDev[INDEX_TAPECTL].SCSI == 0)
{
DebugPrint(DEBUG_ERROR, SECTION_TAPE,"GenericClean : can't send SCSI commands\n");
DebugPrint(DEBUG_ERROR, SECTION_TAPE,"##### STOP GenericClean\n");
return(0);
+ /*NOTREACHED*/
}
/*
return(ret);
}
-int GenericResetStatus(int DeviceFD)
+int
+GenericResetStatus(
+ int DeviceFD)
{
CDB_T CDB;
RequestSense_T *pRequestSense;
DebugPrint(DEBUG_INFO, SECTION_ELEMENT, "##### START GenericResetStatus\n");
- if ((pRequestSense = (RequestSense_T *)malloc(sizeof(RequestSense_T))) == NULL)
- {
- DebugPrint(DEBUG_ERROR, SECTION_ELEMENT, "GenericResetStatus : malloc failed\n");
- return(-1);
- }
+ pRequestSense = alloc(SIZEOF(RequestSense_T));
while (retry)
{
ret = SCSI_Run(DeviceFD, Input, CDB, 6,
NULL, 0,
- (char *) pRequestSense,
- sizeof(RequestSense_T));
+ pRequestSense,
+ SIZEOF(RequestSense_T));
if (ret < 0)
{
/* fprintf(stderr, "%s: Request Sense[Inquiry]: %02X", */
- /* "chs", ((unsigned char *) &pRequestSense)[0]); */
- /* for (i = 1; i < sizeof(RequestSense_T); i++) */
- /* fprintf(stderr, " %02X", ((unsigned char *) &pRequestSense)[i]); */
+ /* "chs", ((u_char *) &pRequestSense)[0]); */
+ /* for (i = 1; i < SIZEOF(RequestSense_T); i++) */
+ /* fprintf(stderr, " %02X", ((u_char *) &pRequestSense)[i]); */
/* fprintf(stderr, "\n"); */
free(pRequestSense);
return(ret);
+ /*NOTREACHED*/
}
if ( ret > 0 )
{
- switch (SenseHandler(DeviceFD, 0, pRequestSense->SenseKey, pRequestSense->AdditionalSenseCode, pRequestSense->AdditionalSenseCodeQualifier, (char *)pRequestSense))
+ switch (SenseHandler(DeviceFD, 0, pRequestSense->SenseKey, pRequestSense->AdditionalSenseCode, pRequestSense->AdditionalSenseCodeQualifier, pRequestSense))
{
case SENSE_IGNORE:
free(pRequestSense);
return(0);
- break;
+ /*NOTREACHED*/
case SENSE_ABORT:
free(pRequestSense);
return(-1);
- break;
+ /*NOTREACHED*/
case SENSE_RETRY:
retry++;
if (retry < MAX_RETRIES )
DebugPrint(DEBUG_ERROR, SECTION_ELEMENT, "GenericResetStatus : return (-1)\n");
free(pRequestSense);
return(-1);
+ /*NOTREACHED*/
}
break;
default:
DebugPrint(DEBUG_ERROR, SECTION_ELEMENT, "GenericResetStatus : (default) return (-1)\n");
free(pRequestSense);
return(-1);
- break;
+ /*NOTREACHED*/
}
}
if (ret == 0)
* TODO:
* Limit recursion, may run in an infinite loop
*/
-int GenericSenseHandler(int ip, int flag, unsigned char SenseKey, unsigned char AdditionalSenseCode, unsigned char AdditionalSenseCodeQualifier, char *buffer)
+int
+GenericSenseHandler(
+ int ip,
+ u_char flag,
+ u_char SenseKey,
+ u_char AdditionalSenseCode,
+ u_char AdditionalSenseCodeQualifier,
+ RequestSense_T * pRequestSense)
{
extern OpenFiles_T *pDev;
- RequestSense_T *pRequestSense = (RequestSense_T *)buffer;
- int ret = 0;
- unsigned char *info = NULL;
+ int ret;
+ char *info = NULL;
dbprintf(("##### START GenericSenseHandler\n"));
flag, SenseKey,
AdditionalSenseCode,
AdditionalSenseCodeQualifier,
- (char **)&info);
+ &info);
dbprintf(("##### STOP GenericSenseHandler\n"));
return(ret);
* the element handling
* TODO:
*/
-int SDXMove(int DeviceFD, int from, int to)
+int
+SDXMove(
+ int DeviceFD,
+ int from,
+ int to)
{
extern OpenFiles_T *pDev;
ElementInfo_T *pfrom;
ElementInfo_T *pto;
int ret;
int tapestat;
- int moveok = 0;
+ int moveok;
int SDX_MTE = 0; /* This are parameters passed */
int SDX_STE = -1; /* to */
int SDX_DTE = -1; /* AlignElements */
DebugPrint(DEBUG_INFO, SECTION_MOVE,"SDXMove : ElementInfo for %d not found\n", from);
DebugPrint(DEBUG_INFO, SECTION_MOVE,"##### STOP SDXMove\n");
return(-1);
+ /*NOTREACHED*/
}
if ((pto = LookupElement(to)) == NULL)
DebugPrint(DEBUG_INFO, SECTION_MOVE,"SDXMove : ElementInfo for %d not found\n", to);
DebugPrint(DEBUG_INFO, SECTION_MOVE,"##### STOP SDXMove\n");
return(-1);
+ /*NOTREACHED*/
}
if (pfrom->status == 'E')
DebugPrint(DEBUG_INFO, SECTION_MOVE,"SDXMove : from %d is empty\n", from);
DebugPrint(DEBUG_INFO, SECTION_MOVE,"##### STOP SDXMove\n");
return(-1);
+ /*NOTREACHED*/
}
if (pto->status == 'F')
{
DebugPrint(DEBUG_ERROR, SECTION_MOVE,"SDXMove : no empty slot found for unload\n");
return(-1);
+ /*NOTREACHED*/
}
DebugPrint(DEBUG_INFO, SECTION_MOVE,"SDXMove : Unload to %d\n", to);
if ((pto = LookupElement(to)) == NULL)
DebugPrint(DEBUG_INFO, SECTION_MOVE, "SDXMove : ElementInfo for %d not found\n", to);
DebugPrint(DEBUG_INFO, SECTION_MOVE,"##### STOP SDXMove\n");
return(-1);
+ /*NOTREACHED*/
}
break;
case IMPORT:
{
DebugPrint(DEBUG_INFO, SECTION_MOVE,"##### STOP SDXMove\n");
return(-1);
+ /*NOTREACHED*/
}
} else {
DebugPrint(DEBUG_INFO, SECTION_MOVE,"##### Error setting STE/DTE %d/%d\n", SDX_STE, SDX_DTE);
DebugPrint(DEBUG_INFO, SECTION_MOVE,"##### STOP SDXMove\n");
return(-1);
+ /*NOTREACHED*/
}
/*
}
}
- if ( ret == 0)
+ if ((ret == 0) && moveok)
{
ret = SCSI_Move(DeviceFD, 0, from, to);
} else {
DebugPrint(DEBUG_INFO, SECTION_MOVE,"##### STOP SDXMove\n");
return(ret);
+ /*NOTREACHED*/
}
DebugPrint(DEBUG_INFO, SECTION_MOVE,"##### STOP SDXMove\n");
return(ret);
* the element handling
* TODO:
*/
-int GenericMove(int DeviceFD, int from, int to)
+int
+GenericMove(
+ int DeviceFD,
+ int from,
+ int to)
{
ElementInfo_T *pfrom;
ElementInfo_T *pto;
DebugPrint(DEBUG_INFO, SECTION_MOVE, "GenericMove : ElementInfo for %d not found\n", from);
DebugPrint(DEBUG_INFO, SECTION_MOVE,"##### STOP GenericMove\n");
return(-1);
+ /*NOTREACHED*/
}
if ((pto = LookupElement(to)) == NULL)
DebugPrint(DEBUG_INFO, SECTION_MOVE, "GenericMove : ElementInfo for %d not found\n", to);
DebugPrint(DEBUG_INFO, SECTION_MOVE,"##### STOP GenericMove\n");
return(-1);
+ /*NOTREACHED*/
}
if (pfrom->status == 'E')
DebugPrint(DEBUG_INFO, SECTION_MOVE, "GenericMove : from %d is empty\n", from);
DebugPrint(DEBUG_INFO, SECTION_MOVE,"##### STOP GenericMove\n");
return(-1);
+ /*NOTREACHED*/
}
if (pto->status == 'F')
{
DebugPrint(DEBUG_ERROR, SECTION_MOVE, "GenericMove : no empty slot found\n");
return(-1);
+ /*NOTREACHED*/
}
DebugPrint(DEBUG_INFO, SECTION_MOVE, "GenericMove : Unload to %d\n", to);
if ((pto = LookupElement(to)) == NULL)
DebugPrint(DEBUG_ERROR, SECTION_MOVE, " Ups should not happen\n");
DebugPrint(DEBUG_INFO, SECTION_MOVE,"##### STOP GenericMove\n");
return(-1);
+ /*NOTREACHED*/
}
}
* 0 => Not OK
*/
-int CheckMove(ElementInfo_T *from, ElementInfo_T *to)
+int
+CheckMove(
+ ElementInfo_T * from,
+ ElementInfo_T * to)
{
int moveok = 0;
/*
*/
-int GetCurrentSlot(int fd, int drive)
+int
+GetCurrentSlot(
+ int fd,
+ int drive)
{
extern OpenFiles_T *pDev;
- int x;
+ size_t x;
dbprintf(("##### START GetCurrentSlot\n"));
+ (void)fd; /* Quiet unused parameter warning */
+
if (pDev[0].SCSI == 0)
{
dbprintf(("GetCurrentSlot : can't send SCSI commands\n"));
return(-1);
+ /*NOTREACHED*/
}
if (ElementStatusValid == 0)
if (pDev[0].functions->function_status(0, 1) != 0)
{
return(-1);
+ /*NOTREACHED*/
}
}
{
if (pSTE[x].address == pDTE[drive].from)
return(x);
+ /*NOTREACHED*/
}
return(-1);
+ /*NOTREACHED*/
}
for (x = 0; x < STE;x++)
{
- if (pSTE[x].status == 'E')
- return(x);
+ if (pSTE[x].status == 'E') {
+ return(x);
+ /*NOTREACHED*/
+ }
}
/* Ups nothing loaded */
* If there are error conditions try to fix them
*
*/
-int GenericElementStatus(int DeviceFD, int InitStatus)
+int
+GenericElementStatus(
+ int DeviceFD,
+ int InitStatus)
{
int MTEError = 0;
int STEError = 0;
int IEEError = 0;
int DTEError = 0;
- int STEEmpty = 0;
extern OpenFiles_T *pDev;
- int error = 0; /* If set do an INIT ELEMENT STATUS */
- int x; /* The standard loop counter :-) */
- int loop = 2; /* Redo it if an error has been reset */
+ int error = 0; /* If set do an INIT ELEMENT STATUS */
+ size_t x; /* The standard loop counter :-) */
+ int retry = 2; /* Redo it if an error has been reset */
+
+ (void)InitStatus; /* Quiet unused parameter warning */
DebugPrint(DEBUG_INFO, SECTION_ELEMENT, "##### START GenericElementStatus\n");
*/
if (pModePage == NULL && LibModeSenseValid == 0)
{
- if ((pModePage = malloc(0xff)) == NULL)
- {
- DebugPrint(DEBUG_ERROR, SECTION_ELEMENT,"GenericElementStatus : malloc failed\n");
- return(-1);
- }
+ pModePage = alloc(0xff);
+
if (SCSI_ModeSense(DeviceFD, pModePage, 0xff, 0x8, 0x3f) == 0)
{
LibModeSenseValid = 1;
}
}
- if (GetElementStatus(DeviceFD) == 0 && loop > 0)
+ while ((GetElementStatus(DeviceFD) == 0) && (retry-- > 0))
{
- loop--;
for (x = 0; x < MTE; x++)
{
if (pMTE[x].ASC > 0)
{
- switch(SenseHandler(DeviceFD, 0, SENSE_CHG_ELEMENT_STATUS, pMTE[x].ASC, pMTE[x].ASCQ, (char *)&pMTE[x]))
+ switch(SenseHandler(DeviceFD, 0, SENSE_CHG_ELEMENT_STATUS, pMTE[x].ASC, pMTE[x].ASCQ, (RequestSense_T *)&pMTE[x]))
{
case SENSE_IES:
MTEError = 1;
case SENSE_ABORT:
DebugPrint(DEBUG_ERROR, SECTION_ELEMENT, "GenericElementStatus : Abort on MTE\n");
return(-1);
- break;
+ /*NOTREACHED*/
}
}
}
{
if (pIEE[x].ASC > 0)
{
- switch(SenseHandler(DeviceFD, 0, SENSE_CHG_ELEMENT_STATUS, pIEE[x].ASC, pIEE[x].ASCQ, (char *)&pIEE[x]))
+ switch(SenseHandler(DeviceFD, 0, SENSE_CHG_ELEMENT_STATUS, pIEE[x].ASC, pIEE[x].ASCQ, (RequestSense_T *)&pIEE[x]))
{
case SENSE_IES:
IEEError = 1;
case SENSE_ABORT:
DebugPrint(DEBUG_ERROR, SECTION_ELEMENT, "GenericElementStatus : Abort on IEE\n");
return(-1);
- break;
+ /*NOTREACHED*/
}
}
}
for (x = 0; x < STE; x++)
{
- /*
- * Needed for the hack to guess the tape status if an error
- * for the tape is pending
- */
- if (pSTE[x].status == 'E')
- {
- STEEmpty = 1;
- }
-
if (pSTE[x].ASC > 0)
{
- switch(SenseHandler(DeviceFD, 0, SENSE_CHG_ELEMENT_STATUS, pSTE[x].ASC, pSTE[x].ASCQ, (char *)&pSTE[x]))
+ switch(SenseHandler(DeviceFD, 0, SENSE_CHG_ELEMENT_STATUS, pSTE[x].ASC, pSTE[x].ASCQ, (RequestSense_T *)&pSTE[x]))
{
case SENSE_IES:
STEError = 1;
case SENSE_ABORT:
DebugPrint(DEBUG_ERROR, SECTION_ELEMENT, "GenericElementStatus : Abort on IES\n");
return(-1);
- break;
+ /*NOTREACHED*/
}
}
}
{
if (pDTE[x].ASC > 0)
{
- switch(SenseHandler(DeviceFD, 0, SENSE_CHG_ELEMENT_STATUS, pDTE[x].ASC, pDTE[x].ASCQ, (char *)&pDTE[x]))
+ switch(SenseHandler(DeviceFD, 0, SENSE_CHG_ELEMENT_STATUS, pDTE[x].ASC, pDTE[x].ASCQ, (RequestSense_T *)&pDTE[x]))
{
case SENSE_IES:
DTEError = 1;
case SENSE_ABORT:
DebugPrint(DEBUG_ERROR, SECTION_ELEMENT, "GenericElementStatus : Abort on DTE\n");
return(-1);
- break;
+ /*NOTREACHED*/
}
}
}
ElementStatusValid = 0;
DebugPrint(DEBUG_ERROR, SECTION_ELEMENT, "GenericElementStatus : Can't init status STEError(%d) MTEError(%d) DTEError(%d) IEEError(%d)\n", STEError, MTEError, DTEError, IEEError);
return(-1);
+ /*NOTREACHED*/
}
error = 0;
}
{
DebugPrint(DEBUG_ERROR, SECTION_ELEMENT, "GenericElementStatus : Can't init status (after loop)\n");
return(-1);
+ /*NOTREACHED*/
}
ElementStatusValid = 1;
* This is for the ADIC changer, it seems that they have an diferent
* offset in the mode sense data before the first mode page (+12)
*/
-int DLT448ElementStatus(int DeviceFD, int InitStatus)
+int
+DLT448ElementStatus(
+ int DeviceFD,
+ int InitStatus)
{
- int MTEError = 0;
- int STEError = 0;
- int IEEError = 0;
int DTEError = 0;
- int STEEmpty = 0;
extern OpenFiles_T *pDev;
int error = 0; /* If set do an INIT ELEMENT STATUS */
- int x; /* The standard loop counter :-) */
+ size_t x; /* The standard loop counter :-) */
int loop = 2; /* Redo it if an error has been reset */
+ (void)InitStatus; /* Quiet unused parameter warning */
+
DebugPrint(DEBUG_INFO, SECTION_ELEMENT, "##### START DLT448ElementStatus\n");
if (pEAAPage == NULL)
*/
if (pModePage == NULL && LibModeSenseValid == 0)
{
- if ((pModePage = malloc(0xff)) == NULL)
- {
- DebugPrint(DEBUG_ERROR, SECTION_ELEMENT,"DLT448ElementStatus : malloc failed\n");
- return(-1);
- }
+ pModePage = alloc(0xff);
+
if (SCSI_ModeSense(DeviceFD, pModePage, 0xff, 0x8, 0x3f) == 0)
{
LibModeSenseValid = 1;
}
}
- if (GetElementStatus(DeviceFD) == 0 && loop > 0)
+ while (GetElementStatus(DeviceFD) == 0 && loop-- > 0)
{
- loop--;
for (x = 0; x < MTE; x++)
{
if (pMTE[x].ASC > 0)
{
- switch(SenseHandler(DeviceFD, 0, SENSE_CHG_ELEMENT_STATUS, pMTE[x].ASC, pMTE[x].ASCQ, (char *)&pMTE[x]))
+ switch(SenseHandler(DeviceFD, 0, SENSE_CHG_ELEMENT_STATUS, pMTE[x].ASC, pMTE[x].ASCQ, (RequestSense_T *)&pMTE[x]))
{
case SENSE_IES:
- MTEError = 1;
error = 1;
break;
case SENSE_ABORT:
DebugPrint(DEBUG_ERROR, SECTION_ELEMENT, "DLT448ElementStatus : Abort on MTE\n");
return(-1);
- break;
+ /*NOTREACHED*/
}
}
}
{
if (pIEE[x].ASC > 0)
{
- switch(SenseHandler(DeviceFD, 0, SENSE_CHG_ELEMENT_STATUS, pIEE[x].ASC, pIEE[x].ASCQ, (char *)&pIEE[x]))
+ switch(SenseHandler(DeviceFD, 0, SENSE_CHG_ELEMENT_STATUS, pIEE[x].ASC, pIEE[x].ASCQ, (RequestSense_T *)&pIEE[x]))
{
case SENSE_IES:
- IEEError = 1;
error = 1;
break;
case SENSE_ABORT:
DebugPrint(DEBUG_ERROR, SECTION_ELEMENT, "DLT448ElementStatus : Abort on IEE\n");
return(-1);
- break;
+ /*NOTREACHED*/
}
}
}
* Needed for the hack to guess the tape status if an error
* for the tape is pending
*/
- if (pSTE[x].status == 'E')
- {
- STEEmpty = 1;
- }
-
if (pSTE[x].ASC > 0)
{
- switch(SenseHandler(DeviceFD, 0, SENSE_CHG_ELEMENT_STATUS, pSTE[x].ASC, pSTE[x].ASCQ, (char *)&pSTE[x]))
+ switch(SenseHandler(DeviceFD, 0, SENSE_CHG_ELEMENT_STATUS, pSTE[x].ASC, pSTE[x].ASCQ, (RequestSense_T *)&pSTE[x]))
{
case SENSE_IES:
- STEError = 1;
error = 1;
break;
case SENSE_ABORT:
DebugPrint(DEBUG_ERROR, SECTION_ELEMENT, "DLT448ElementStatus : Abort on IES\n");
return(-1);
- break;
+ /*NOTREACHED*/
}
}
}
{
if (pDTE[x].ASC > 0)
{
- switch(SenseHandler(DeviceFD, 0, SENSE_CHG_ELEMENT_STATUS, pDTE[x].ASC, pDTE[x].ASCQ, (char *)&pDTE[x]))
+ switch(SenseHandler(DeviceFD, 0, SENSE_CHG_ELEMENT_STATUS, pDTE[x].ASC, pDTE[x].ASCQ, (RequestSense_T *)&pDTE[x]))
{
case SENSE_IES:
DTEError = 1;
case SENSE_ABORT:
DebugPrint(DEBUG_ERROR, SECTION_ELEMENT, "DLT448ElementStatus : Abort on DTE\n");
return(-1);
- break;
+ /*NOTREACHED*/
}
}
}
ElementStatusValid = 0;
DebugPrint(DEBUG_ERROR, SECTION_ELEMENT, "DLT448ElementStatus : Can't init status\n");
return(-1);
+ /*NOTREACHED*/
}
error = 0;
}
{
DebugPrint(DEBUG_ERROR, SECTION_ELEMENT, "DLT448ElementStatus : Can't init status (after loop)\n");
return(-1);
+ /*NOTREACHED*/
}
ElementStatusValid = 1;
* it seemes that for the STE Elements ASC/ASCQ is not set
* on an error, only the except bit is set
*/
-int SDXElementStatus(int DeviceFD, int InitStatus)
+int
+SDXElementStatus(
+ int DeviceFD,
+ int InitStatus)
{
- int MTEError = 0;
- int STEError = 0;
- int IEEError = 0;
- int DTEError = 0;
-
int error = 0; /* If set do an INIT ELEMENT STATUS */
- int x; /* The standard loop counter :-) */
+ size_t x; /* The standard loop counter :-) */
int loop = 2; /* Redo it if an error has been reset */
+ (void)InitStatus; /* Quiet unused parameter warning */
+
DebugPrint(DEBUG_INFO, SECTION_ELEMENT, "##### START SDXElementStatus\n");
if (pEAAPage == NULL)
*/
if (pModePage == NULL && LibModeSenseValid == 0)
{
- if ((pModePage = malloc(0xff)) == NULL)
- {
- DebugPrint(DEBUG_ERROR, SECTION_ELEMENT,"SDXElementStatus : malloc failed\n");
- return(-1);
- }
+ pModePage = alloc(0xff);
+
if (SCSI_ModeSense(DeviceFD, pModePage, 0xff, 0x8, 0x3f) == 0)
{
LibModeSenseValid = 1;
}
}
- if (GetElementStatus(DeviceFD) == 0 && loop)
+ while (GetElementStatus(DeviceFD) == 0 && loop--)
{
- loop--;
error = 0;
for (x = 0; x < MTE; x++)
{
if (pMTE[x].ASC > 0)
{
- switch(SenseHandler(DeviceFD, 0, SENSE_CHG_ELEMENT_STATUS, pMTE[x].ASC, pMTE[x].ASCQ, (char *)&pMTE[x]))
+ switch(SenseHandler(DeviceFD, 0, SENSE_CHG_ELEMENT_STATUS, pMTE[x].ASC, pMTE[x].ASCQ, (RequestSense_T *)&pMTE[x]))
{
case SENSE_IES:
- MTEError = 1;
error = 1;
break;
case SENSE_ABORT:
DebugPrint(DEBUG_ERROR, SECTION_ELEMENT, "SDXElementStatus : Abort on MTE\n");
return(-1);
- break;
+ /*NOTREACHED*/
}
}
}
{
if (pIEE[x].ASC > 0)
{
- switch(SenseHandler(DeviceFD, 0, SENSE_CHG_ELEMENT_STATUS, pIEE[x].ASC, pIEE[x].ASCQ, (char *)&pIEE[x]))
+ switch(SenseHandler(DeviceFD, 0, SENSE_CHG_ELEMENT_STATUS, pIEE[x].ASC, pIEE[x].ASCQ, (RequestSense_T *)&pIEE[x]))
{
case SENSE_IES:
- IEEError = 1;
error = 1;
break;
case SENSE_ABORT:
DebugPrint(DEBUG_ERROR, SECTION_ELEMENT, "SDXElementStatus : Abort on IEE\n");
return(-1);
- break;
+ /*NOTREACHED*/
}
}
}
for (x = 0; x < STE; x++)
{
- if (pSTE[x].except != 0)
- {
- STEError = 1;
- }
-
if (pSTE[x].ASC > 0)
{
- switch(SenseHandler(DeviceFD, 0, SENSE_CHG_ELEMENT_STATUS, pSTE[x].ASC, pSTE[x].ASCQ, (char *)&pSTE[x]))
+ switch(SenseHandler(DeviceFD, 0, SENSE_CHG_ELEMENT_STATUS, pSTE[x].ASC, pSTE[x].ASCQ, (RequestSense_T *)&pSTE[x]))
{
case SENSE_IES:
- STEError = 1;
error = 1;
break;
case SENSE_ABORT:
DebugPrint(DEBUG_ERROR, SECTION_ELEMENT, "SDXElementStatus : Abort on IES\n");
return(-1);
- break;
+ /*NOTREACHED*/
}
}
}
{
if (pDTE[x].ASC > 0)
{
- switch(SenseHandler(DeviceFD, 0, SENSE_CHG_ELEMENT_STATUS, pDTE[x].ASC, pDTE[x].ASCQ, (char *)&pDTE[x]))
+ switch(SenseHandler(DeviceFD, 0, SENSE_CHG_ELEMENT_STATUS, pDTE[x].ASC, pDTE[x].ASCQ, (RequestSense_T *)&pDTE[x]))
{
case SENSE_IES:
- DTEError = 1;
/*
error = 1;
*/
case SENSE_ABORT:
DebugPrint(DEBUG_ERROR, SECTION_ELEMENT, "SDXElementStatus : Abort on DTE\n");
return(-1);
- break;
+ /*NOTREACHED*/
}
}
}
ElementStatusValid = 0;
DebugPrint(DEBUG_ERROR, SECTION_ELEMENT, "SDXElementStatus : Can't init status\n");
return(-1);
+ /*NOTREACHED*/
}
}
{
DebugPrint(DEBUG_ERROR, SECTION_ELEMENT, "SDXElementStatus : Can't init status\n");
return(-1);
+ /*NOTREACHED*/
}
ElementStatusValid = 1;
*
* TODO:
*/
-int GetElementStatus(int DeviceFD)
+int
+GetElementStatus(
+ int DeviceFD)
{
- unsigned char *DataBuffer = NULL;
- int DataBufferLength;
+ u_char *DataBuffer = NULL;
+ size_t DataBufferLength;
ElementStatusData_T *ElementStatusData;
ElementStatusPage_T *ElementStatusPage;
MediumTransportElementDescriptor_T *MediumTransportElementDescriptor;
StorageElementDescriptor_T *StorageElementDescriptor;
DataTransferElementDescriptor_T *DataTransferElementDescriptor;
ImportExportElementDescriptor_T *ImportExportElementDescriptor;
- int x = 0;
- int offset = 0;
- int length = 0; /* Length of an Element */
- int barcode = 0; /* To store the result of the BarCode function */
- int NoOfElements;
+ size_t x;
+ size_t offset;
+ size_t length; /* Length of an Element */
+ size_t NoOfElements;
DebugPrint(DEBUG_INFO, SECTION_ELEMENT,"##### START GetElementStatus\n");
/* First the Medim Transport*/
if (V2(pEAAPage->NoMediumTransportElements) > 0)
{
- free(pMTE);
MTE = V2(pEAAPage->NoMediumTransportElements) ;
- if ((pMTE = (ElementInfo_T *)malloc(sizeof(ElementInfo_T) * MTE)) == NULL)
- {
- DebugPrint(DEBUG_ERROR, SECTION_ELEMENT,"GenericElementStatus : malloc failed\n");
- return(-1);
- }
- memset(pMTE, 0, sizeof(ElementInfo_T) * MTE);
+ pMTE = alloc(SIZEOF(ElementInfo_T) * MTE);
+ memset(pMTE, 0, SIZEOF(ElementInfo_T) * MTE);
if (SCSI_ReadElementStatus(DeviceFD,
CHANGER,
0,
- barcode,
+ (u_char)barcode,
V2(pEAAPage->MediumTransportElementAddress),
- MTE+1,
- sizeof(MediumTransportElementDescriptor_T),
- (char **)&DataBuffer) != 0)
+ (MTE + (size_t)1),
+ SIZEOF(MediumTransportElementDescriptor_T),
+ &DataBuffer) != 0)
{
- free(pMTE);
- free(DataBuffer);
ChgExit("genericElementStatus","Can't read MTE status", FATAL);
+ /*NOTREACHED*/
}
- ElementStatusData = (ElementStatusData_T *)DataBuffer;
- offset = sizeof(ElementStatusData_T);
+ // ElementStatusData = (ElementStatusData_T *)DataBuffer;
+ offset = SIZEOF(ElementStatusData_T);
ElementStatusPage = (ElementStatusPage_T *)&DataBuffer[offset];
- offset = offset + sizeof(ElementStatusPage_T);
+ offset = offset + SIZEOF(ElementStatusPage_T);
length = V2(ElementStatusPage->length);
- DebugPrint(DEBUG_INFO, SECTION_ELEMENT,"MTE Length %d(%d)\n",length,sizeof(MediumTransportElementDescriptor_T));
+
+ DebugPrint(DEBUG_INFO, SECTION_ELEMENT,"MTE Length %d(%d)\n", length,
+ SIZEOF(MediumTransportElementDescriptor_T));
for (x = 0; x < MTE; x++)
{
pMTE[x].type = ElementStatusPage->type;
pMTE[x].address = V2(MediumTransportElementDescriptor->address);
pMTE[x].except = MediumTransportElementDescriptor->except;
- pMTE[x].status = (MediumTransportElementDescriptor->full > 0) ? 'F':'E';
pMTE[x].full = MediumTransportElementDescriptor->full;
+ if (MediumTransportElementDescriptor->full > 0)
+ {
+ pMTE[x].status = 'F';
+ } else {
+ pMTE[x].status = 'E';
+ }
if (length >= 5)
{
}
offset = offset + length;
}
+ free(DataBuffer);
+ DataBuffer = NULL;
}
/*
* Storage Elements
{
free(pSTE);
STE = V2(pEAAPage->NoStorageElements);
- if ((pSTE = (ElementInfo_T *)malloc(sizeof(ElementInfo_T) * STE)) == NULL)
- {
- DebugPrint(DEBUG_ERROR, SECTION_ELEMENT,"GenericElementStatus : malloc failed\n");
- free(pMTE);
- return(-1);
- }
- memset(pSTE, 0, sizeof(ElementInfo_T) * STE);
+ pSTE = alloc(SIZEOF(ElementInfo_T) * STE);
+ memset(pSTE, 0, SIZEOF(ElementInfo_T) * STE);
if (SCSI_ReadElementStatus(DeviceFD,
STORAGE,
0,
- barcode,
+ (u_char)barcode,
V2(pEAAPage->FirstStorageElementAddress),
STE,
- sizeof(StorageElementDescriptor_T),
- (char **)&DataBuffer) != 0)
+ SIZEOF(StorageElementDescriptor_T),
+ &DataBuffer) != 0)
{
- free(DataBuffer);
ChgExit("GetElementStatus", "Can't read STE status", FATAL);
+ /*NOTREACHED*/
}
+ assert(DataBuffer != NULL);
- ElementStatusData = (ElementStatusData_T *)DataBuffer;
- offset = sizeof(ElementStatusData_T);
+ // ElementStatusData = (ElementStatusData_T *)DataBuffer;
+ offset = SIZEOF(ElementStatusData_T);
ElementStatusPage = (ElementStatusPage_T *)&DataBuffer[offset];
- offset = offset + sizeof(ElementStatusPage_T);
+ offset = offset + SIZEOF(ElementStatusPage_T);
length = V2(ElementStatusPage->length);
DebugPrint(DEBUG_INFO, SECTION_ELEMENT,"STE Length %d\n",length);
pSTE[x].type = ElementStatusPage->type;
pSTE[x].address = V2(StorageElementDescriptor->address);
pSTE[x].except = StorageElementDescriptor->except;
- pSTE[x].status = (StorageElementDescriptor->full > 0) ? 'F':'E';
pSTE[x].full = StorageElementDescriptor->full;
+ if (StorageElementDescriptor->full > 0)
+ {
+ pSTE[x].status = 'F';
+ } else {
+ pSTE[x].status = 'E';
+ }
if (length >= 5)
{
offset = offset + length;
}
-
+ free(DataBuffer);
+ DataBuffer = NULL;
}
/*
* Import/Export Elements
{
free(pIEE);
IEE = V2(pEAAPage->NoImportExportElements);
- if ((pIEE = (ElementInfo_T *)malloc(sizeof(ElementInfo_T) * IEE)) == NULL)
- {
- DebugPrint(DEBUG_INFO, SECTION_ELEMENT,"GenericElementStatus : malloc failed\n");
- free(DataBuffer);
- return(-1);
- }
- memset(pIEE, 0, sizeof(ElementInfo_T) * IEE);
+ pIEE = alloc(SIZEOF(ElementInfo_T) * IEE);
+ memset(pIEE, 0, SIZEOF(ElementInfo_T) * IEE);
if (SCSI_ReadElementStatus(DeviceFD,
IMPORT,
0,
- barcode,
+ (u_char)barcode,
V2(pEAAPage->FirstImportExportElementAddress),
IEE,
- sizeof(ImportExportElementDescriptor_T),
- (char **)&DataBuffer) != 0)
+ SIZEOF(ImportExportElementDescriptor_T),
+ &DataBuffer) != 0)
{
- if (DataBuffer != 0)
- {
- free(DataBuffer);
- }
ChgExit("GetElementStatus", "Can't read IEE status", FATAL);
+ /*NOTREACHED*/
}
+ assert(DataBuffer != NULL);
- ElementStatusData = (ElementStatusData_T *)DataBuffer;
- offset = sizeof(ElementStatusData_T);
+ // ElementStatusData = (ElementStatusData_T *)DataBuffer;
+ offset = SIZEOF(ElementStatusData_T);
ElementStatusPage = (ElementStatusPage_T *)&DataBuffer[offset];
- offset = offset + sizeof(ElementStatusPage_T);
+ offset = offset + SIZEOF(ElementStatusPage_T);
length = V2(ElementStatusPage->length);
DebugPrint(DEBUG_INFO, SECTION_ELEMENT,"IEE Length %d\n",length);
pIEE[x].type = ElementStatusPage->type;
pIEE[x].address = V2(ImportExportElementDescriptor->address);
pIEE[x].except = ImportExportElementDescriptor->except;
- pIEE[x].status = (ImportExportElementDescriptor->full > 0) ? 'F':'E';
pIEE[x].full = ImportExportElementDescriptor->full;
+ if (ImportExportElementDescriptor->full > 0)
+ {
+ pIEE[x].status = 'F';
+ } else {
+ pIEE[x].status = 'E';
+ }
if (length >= 5)
{
offset = offset + length;
}
-
+ free(DataBuffer);
+ DataBuffer = NULL;
}
/*
* Data Transfer Elements
{
free(pDTE);
DTE = V2(pEAAPage->NoDataTransferElements) ;
- if ((pDTE = (ElementInfo_T *)malloc(sizeof(ElementInfo_T) * DTE)) == NULL)
- {
- DebugPrint(DEBUG_ERROR, SECTION_ELEMENT,"GenericElementStatus : malloc failed\n");
- free(DataBuffer);
- return(-1);
- }
- memset(pDTE, 0, sizeof(ElementInfo_T) * DTE);
+ pDTE = alloc(SIZEOF(ElementInfo_T) * DTE);
+ memset(pDTE, 0, SIZEOF(ElementInfo_T) * DTE);
if (SCSI_ReadElementStatus(DeviceFD,
TAPETYPE,
0,
- barcode,
+ (u_char)barcode,
V2(pEAAPage->FirstDataTransferElementAddress),
DTE,
- sizeof(DataTransferElementDescriptor_T),
- (char **)&DataBuffer) != 0)
+ SIZEOF(DataTransferElementDescriptor_T),
+ &DataBuffer) != 0)
{
- free(DataBuffer);
ChgExit("GenericElementStatus", "Can't read DTE status", FATAL);
+ /*NOTREACHED*/
}
+ assert(DataBuffer != NULL);
- ElementStatusData = (ElementStatusData_T *)DataBuffer;
- offset = sizeof(ElementStatusData_T);
+ // ElementStatusData = (ElementStatusData_T *)DataBuffer;
+ offset = SIZEOF(ElementStatusData_T);
ElementStatusPage = (ElementStatusPage_T *)&DataBuffer[offset];
- offset = offset + sizeof(ElementStatusPage_T);
+ offset = offset + SIZEOF(ElementStatusPage_T);
length = V2(ElementStatusPage->length);
DebugPrint(DEBUG_INFO, SECTION_ELEMENT,"DTE Length %d\n",length);
pDTE[x].address = V2(DataTransferElementDescriptor->address);
pDTE[x].except = DataTransferElementDescriptor->except;
pDTE[x].scsi = DataTransferElementDescriptor->scsi;
- pDTE[x].status = (DataTransferElementDescriptor->full > 0) ? 'F':'E';
pDTE[x].full = DataTransferElementDescriptor->full;
+ if (DataTransferElementDescriptor->full > 0)
+ {
+ pDTE[x].status = 'F';
+ } else {
+ pDTE[x].status = 'E';
+ }
if (length >= 5)
{
offset = offset + length;
}
+ free(DataBuffer);
+ DataBuffer = NULL;
}
} else {
/*
if (SCSI_ReadElementStatus(DeviceFD,
0,
0,
- barcode,
+ (u_char)barcode,
0,
- 0xff,
- 0x7f,
- (char **)&DataBuffer) != 0)
+ (size_t)0xff,
+ (size_t)0x7f,
+ &DataBuffer) != 0)
{
- if (DataBuffer != 0)
- {
- free(DataBuffer);
- }
ChgExit("GenericElementStatus","Can't get ElementStatus", FATAL);
+ /*NOTREACHED*/
}
+ assert(DataBuffer != NULL);
ElementStatusData = (ElementStatusData_T *)DataBuffer;
DataBufferLength = V3(ElementStatusData->count);
- offset = sizeof(ElementStatusData_T);
-
- if (DataBufferLength <= 0)
- {
- DebugPrint(DEBUG_ERROR, SECTION_ELEMENT,"DataBufferLength %d\n",DataBufferLength);
- free(DataBuffer);
- return(1);
- }
+ offset = SIZEOF(ElementStatusData_T);
while (offset < DataBufferLength)
{
ElementStatusPage = (ElementStatusPage_T *)&DataBuffer[offset];
NoOfElements = V3(ElementStatusPage->count) / V2(ElementStatusPage->length);
- offset = offset + sizeof(ElementStatusPage_T);
+ offset = offset + SIZEOF(ElementStatusPage_T);
length = V2(ElementStatusPage->length);
switch (ElementStatusPage->type)
case CHANGER:
free(pMTE);
MTE = NoOfElements;
- if ((pMTE = (ElementInfo_T *)malloc(sizeof(ElementInfo_T) * MTE)) == NULL)
- {
- DebugPrint(DEBUG_ERROR, SECTION_ELEMENT,"GenericElementStatus : malloc failed\n");
- free(DataBuffer);
- return(-1);
- }
- memset(pMTE, 0, sizeof(ElementInfo_T) * MTE);
+ pMTE = alloc(SIZEOF(ElementInfo_T) * MTE);
+ memset(pMTE, 0, SIZEOF(ElementInfo_T) * MTE);
for (x = 0; x < NoOfElements; x++)
{
pMTE[x].type = ElementStatusPage->type;
pMTE[x].address = V2(MediumTransportElementDescriptor->address);
pMTE[x].except = MediumTransportElementDescriptor->except;
- pMTE[x].status = (MediumTransportElementDescriptor->full > 0) ? 'F':'E';
pMTE[x].full = MediumTransportElementDescriptor->full;
-
+ if (MediumTransportElementDescriptor->full > 0)
+ {
+ pMTE[x].status = 'F';
+ } else {
+ pMTE[x].status = 'E';
+ }
if (length >= 5)
{
case STORAGE:
free(pSTE);
STE = NoOfElements;
- if ((pSTE = (ElementInfo_T *)malloc(sizeof(ElementInfo_T) * STE)) == NULL)
- {
- DebugPrint(DEBUG_ERROR, SECTION_ELEMENT,"GenericElementStatus : malloc failed\n");
- free(DataBuffer);
- return(-1);
- }
- memset(pSTE, 0, sizeof(ElementInfo_T) * STE);
+ pSTE = alloc(SIZEOF(ElementInfo_T) * STE);
+ memset(pSTE, 0, SIZEOF(ElementInfo_T) * STE);
for (x = 0; x < NoOfElements; x++)
{
pSTE[x].type = ElementStatusPage->type;
pSTE[x].address = V2(StorageElementDescriptor->address);
pSTE[x].except = StorageElementDescriptor->except;
- pSTE[x].status = (StorageElementDescriptor->full > 0) ? 'F':'E';
pSTE[x].full = StorageElementDescriptor->full;
+ if (StorageElementDescriptor->full > 0)
+ {
+ pSTE[x].status = 'F';
+ } else {
+ pSTE[x].status = 'E';
+ }
if (length >= 5)
{
case IMPORT:
free(pIEE);
IEE = NoOfElements;
- if ((pIEE = (ElementInfo_T *)malloc(sizeof(ElementInfo_T) * IEE)) == NULL)
- {
- DebugPrint(DEBUG_ERROR, SECTION_ELEMENT,"GenericElementStatus : malloc failed\n");
- free(DataBuffer);
- return(-1);
- }
- memset(pIEE, 0, sizeof(ElementInfo_T) * IEE);
+ pIEE = alloc(SIZEOF(ElementInfo_T) * IEE);
+ memset(pIEE, 0, SIZEOF(ElementInfo_T) * IEE);
for (x = 0; x < NoOfElements; x++)
{
pIEE[x].type = ElementStatusPage->type;
pIEE[x].address = V2(ImportExportElementDescriptor->address);
pIEE[x].except = ImportExportElementDescriptor->except;
- pIEE[x].status = (ImportExportElementDescriptor->full > 0) ? 'F':'E';
pIEE[x].full = ImportExportElementDescriptor->full;
+ if (ImportExportElementDescriptor->full > 0)
+ {
+ pIEE[x].status = 'F';
+ } else {
+ pIEE[x].status = 'E';
+ }
if (length >= 5)
{
case TAPETYPE:
free(pDTE);
DTE = NoOfElements;
- if ((pDTE = (ElementInfo_T *)malloc(sizeof(ElementInfo_T) * DTE)) == NULL)
- {
- DebugPrint(DEBUG_ERROR, SECTION_ELEMENT,"GenericElementStatus : malloc failed\n");
- free(DataBuffer);
- return(-1);
- }
- memset(pDTE, 0, sizeof(ElementInfo_T) * DTE);
+ pDTE = alloc(SIZEOF(ElementInfo_T) * DTE);
+ memset(pDTE, 0, SIZEOF(ElementInfo_T) * DTE);
for (x = 0; x < NoOfElements; x++)
{
pDTE[x].address = V2(DataTransferElementDescriptor->address);
pDTE[x].except = DataTransferElementDescriptor->except;
pDTE[x].scsi = DataTransferElementDescriptor->scsi;
- pDTE[x].status = (DataTransferElementDescriptor->full > 0) ? 'F':'E';
pDTE[x].full = DataTransferElementDescriptor->full;
+ if (DataTransferElementDescriptor->full > 0)
+ {
+ pDTE[x].status = 'F';
+ } else {
+ pDTE[x].status = 'E';
+ }
if (length >= 5)
{
break;
}
}
+ free(DataBuffer);
}
DebugPrint(DEBUG_INFO, SECTION_ELEMENT,"\n\n\tMedia Transport Elements (robot arms) :\n");
- free(DataBuffer);
return(0);
}
*
* TODO
*/
-int RequestSense(int DeviceFD, ExtendedRequestSense_T *ExtendedRequestSense, int ClearErrorCounters )
+int
+RequestSense(
+ int DeviceFD,
+ ExtendedRequestSense_T * ExtendedRequestSense,
+ int ClearErrorCounters)
{
CDB_T CDB;
int ret;
CDB[1] = 0; /* Logical Unit Number = 0, Reserved */
CDB[2] = 0; /* Reserved */
CDB[3] = 0; /* Reserved */
- CDB[4] = sizeof(ExtendedRequestSense_T); /* Allocation Length */
- CDB[5] = (ClearErrorCounters << 7) & 0x80; /* */
+ CDB[4] = (u_char)sizeof(ExtendedRequestSense_T); /* Allocation Length */
+ CDB[5] = (u_char)((ClearErrorCounters << 7) & 0x80); /* */
- memset(ExtendedRequestSense, 0, sizeof(ExtendedRequestSense_T));
+ memset(ExtendedRequestSense, 0, SIZEOF(ExtendedRequestSense_T));
ret = SCSI_Run(DeviceFD, Input, CDB, 6,
(char *) ExtendedRequestSense,
- sizeof(ExtendedRequestSense_T),
- (char *) ExtendedRequestSense, sizeof(ExtendedRequestSense_T));
+ SIZEOF(ExtendedRequestSense_T),
+ (RequestSense_T *) ExtendedRequestSense,
+ SIZEOF(ExtendedRequestSense_T));
if (ret < 0)
{
DebugPrint(DEBUG_INFO, SECTION_SCSI,"##### STOP RequestSense (%d)\n",ret);
return(ret);
+ /*NOTREACHED*/
}
if ( ret > 0)
DecodeExtSense(ExtendedRequestSense, "RequestSense : ",debug_file);
DebugPrint(DEBUG_INFO, SECTION_SCSI,"##### STOP RequestSense (%d)\n", ExtendedRequestSense->SenseKey);
return(ExtendedRequestSense->SenseKey);
+ /*NOTREACHED*/
}
- dump_hex((char *)ExtendedRequestSense , sizeof(ExtendedRequestSense_T) , DEBUG_INFO, SECTION_SCSI);
+ dump_hex((u_char *)ExtendedRequestSense ,
+ SIZEOF(ExtendedRequestSense_T),
+ DEBUG_INFO, SECTION_SCSI);
DebugPrint(DEBUG_INFO, SECTION_SCSI,"##### STOP RequestSense (0)\n");
return(0);
}
*/
-ElementInfo_T *LookupElement(int address)
+ElementInfo_T *
+LookupElement(
+ int address)
{
- int x;
+ size_t x;
dbprintf(("##### START LookupElement\n"));
{
dbprintf(("##### STOP LookupElement (DTE)\n"));
return(&pDTE[x]);
+ /*NOTREACHED*/
}
}
}
{
dbprintf(("##### STOP LookupElement (MTE)\n"));
return(&pMTE[x]);
+ /*NOTREACHED*/
}
}
}
{
dbprintf(("##### STOP LookupElement (STE)\n"));
return(&pSTE[x]);
+ /*NOTREACHED*/
}
}
}
{
dbprintf(("##### STOP LookupElement (IEE)\n"));
return(&pIEE[x]);
+ /*NOTREACHED*/
}
}
}
return(NULL);
}
+
/*
* Here comes everything what decode the log Pages
*
* Fix the result handling from TestUnitReady
*
*/
-int LogSense(DeviceFD)
+int
+LogSense(
+ int DeviceFD)
{
extern OpenFiles_T *pDev;
CDB_T CDB;
int found;
extern char *tapestatfile;
int i;
- int ParameterCode;
- unsigned int value;
- int length;
+ unsigned ParameterCode;
+ unsigned value;
+ size_t length;
int count;
- char *buffer;
- char *logpages;
- int nologpages;
- int size = 128;
+ u_char *buffer;
+ u_char *logpages;
+ size_t nologpages;
+ size_t size = 128;
+
+ (void)DeviceFD; /* Quiet unused parameter warning */
DebugPrint(DEBUG_INFO, SECTION_TAPE,"##### START LogSense\n");
if ((tapestatfile != NULL) && (pDev[INDEX_TAPECTL].SCSI == 1) &&
((StatFile = fopen(tapestatfile,"a")) != NULL))
{
- if ((pRequestSense = (RequestSense_T *)malloc(sizeof(RequestSense_T))) == NULL)
- {
- DebugPrint(DEBUG_ERROR, SECTION_TAPE,"LogSense : malloc failed\n");
- fclose(StatFile);
- return(-1);
- }
+ pRequestSense = alloc(SIZEOF(RequestSense_T));
if (GenericRewind(INDEX_TAPECTL) < 0)
{
free(pRequestSense);
fclose(StatFile);
return(0);
+ /*NOTREACHED*/
}
/*
* Try to read the tape label
}
}
- if ((buffer = (char *)malloc(size)) == NULL)
- {
- DebugPrint(DEBUG_ERROR, SECTION_TAPE,"LogSense : malloc failed\n");
- free(pRequestSense);
- fclose(StatFile);
- return(-1);
- }
+ buffer = alloc(size);
memset(buffer, 0, size);
/*
* Get the known log pages
MSB2(&CDB[7], size);
CDB[9] = 0;
- if (SCSI_Run(INDEX_TAPECTL, Input, CDB, 10,
+ if (SCSI_Run(INDEX_TAPECTL, Input, CDB, 10,
buffer,
size,
- (char *)pRequestSense,
- sizeof(RequestSense_T)) != 0)
+ pRequestSense,
+ SIZEOF(RequestSense_T)) != 0)
{
DecodeSense(pRequestSense, "LogSense : ",debug_file);
free(pRequestSense);
free(buffer);
fclose(StatFile);
return(0);
+ /*NOTREACHED*/
}
LogSenseHeader = (LogSenseHeader_T *)buffer;
nologpages = V2(LogSenseHeader->PageLength);
- if ((logpages = (char *)malloc(nologpages)) == NULL)
- {
- DebugPrint(DEBUG_ERROR, SECTION_TAPE,"LogSense : malloc failed\n");
- free(pRequestSense);
- free(buffer);
- fclose(StatFile);
- return(-1);
- }
+ logpages = alloc(nologpages);
- memcpy(logpages, buffer + sizeof(LogSenseHeader_T), nologpages);
+ memcpy(logpages, buffer + SIZEOF(LogSenseHeader_T), nologpages);
- for (count = 0; count < nologpages; count++) {
+ for (count = 0; count < (int)nologpages; count++) {
if (logpages[count] != 0 ) {
memset(buffer, 0, size);
CDB[0] = SC_COM_LOG_SENSE;
CDB[1] = 0;
- CDB[2] = 0x40 | logpages[count]; /* 0x40 for current values */
+ CDB[2] = (u_char)(0x40 | logpages[count]);/* 0x40 for current values */
CDB[3] = 0;
CDB[4] = 0;
CDB[5] = 0;
if (SCSI_Run(INDEX_TAPECTL, Input, CDB, 10,
buffer,
size,
- (char *)pRequestSense,
- sizeof(RequestSense_T)) != 0)
+ pRequestSense,
+ SIZEOF(RequestSense_T)) != 0)
{
DecodeSense(pRequestSense, "LogSense : ",debug_file);
free(pRequestSense);
free(buffer);
fclose(StatFile);
return(0);
+ /*NOTREACHED*/
}
LogSenseHeader = (LogSenseHeader_T *)buffer;
length = V2(LogSenseHeader->PageLength);
- LogParameter = (LogParameter_T *)(buffer + sizeof(LogSenseHeader_T));
+ LogParameter = (LogParameter_T *)(buffer + SIZEOF(LogSenseHeader_T));
/*
* Decode the log pages
*/
p = (struct LogPageDecode *)&DecodePages;
found = 0;
- dump_hex((char *)LogParameter, 64, DEBUG_INFO, SECTION_SCSI);
+ dump_hex((u_char *)LogParameter, 64, DEBUG_INFO, SECTION_SCSI);
while(p->ident != NULL) {
if ((strcmp(pDev[INDEX_TAPECTL].ident, p->ident) == 0 ||strcmp("*", p->ident) == 0) && p->LogPage == logpages[count]) {
if (!found) {
fprintf(StatFile, "Logpage No %d = %x\n", count ,logpages[count]);
- while ((char *)LogParameter < (buffer + length)) {
+ while ((u_char *)LogParameter < (buffer + length)) {
i = LogParameter->ParameterLength;
ParameterCode = V2(LogParameter->ParameterCode);
switch (i) {
case 1:
- value = V1((char *)LogParameter + sizeof(LogParameter_T));
+ value = V1((u_char *)LogParameter + SIZEOF(LogParameter_T));
fprintf(StatFile, "ParameterCode %02X = %u(%d)\n", ParameterCode, value, i);
break;
case 2:
- value = V2((char *)LogParameter + sizeof(LogParameter_T));
+ value = V2((u_char *)LogParameter + SIZEOF(LogParameter_T));
fprintf(StatFile, "ParameterCode %02X = %u(%d)\n", ParameterCode, value, i);
break;
case 3:
- value = V3((char *)LogParameter + sizeof(LogParameter_T));
+ value = V3((u_char *)LogParameter + SIZEOF(LogParameter_T));
fprintf(StatFile, "ParameterCode %02X = %u(%d)\n", ParameterCode, value, i);
break;
case 4:
- value = V4((char *)LogParameter + sizeof(LogParameter_T));
+ value = V4((u_char *)LogParameter + SIZEOF(LogParameter_T));
fprintf(StatFile, "ParameterCode %02X = %u(%d)\n", ParameterCode, value, i);
break;
case 5:
- value = V5((char *)LogParameter + sizeof(LogParameter_T));
+ value = V5((u_char *)LogParameter + SIZEOF(LogParameter_T));
fprintf(StatFile, "ParameterCode %02X = %u(%d)\n", ParameterCode, value, i);
break;
default:
fprintf(StatFile, "ParameterCode %02X size %d\n", ParameterCode, i);
}
- LogParameter = (LogParameter_T *)((char *)LogParameter + sizeof(LogParameter_T) + i);
+ LogParameter = (LogParameter_T *)((u_char *)LogParameter + SIZEOF(LogParameter_T) + i);
}
fprintf(StatFile, "\n");
}
CDB[8] = 0;
CDB[9] = 0;
- if (SCSI_Run(INDEX_TAPECTL, Input, CDB, 10,
+ if (SCSI_Run(INDEX_TAPECTL, Input, CDB, 10,
buffer,
size,
- (char *)pRequestSense,
- sizeof(RequestSense_T)) != 0)
+ pRequestSense,
+ SIZEOF(RequestSense_T)) != 0)
{
DecodeSense(pRequestSense, "LogSense : ",debug_file);
free(pRequestSense);
free(logpages);
+ /*@ignore@*/
free(buffer);
+ /*@end@*/
fclose(StatFile);
return(0);
+ /*NOTREACHED*/
}
free(pRequestSense);
free(logpages);
+ /*@ignore@*/
free(buffer);
+ /*@end@*/
fclose(StatFile);
}
DebugPrint(DEBUG_INFO, SECTION_TAPE,"##### STOP LogSense\n");
return(0);
}
-void WriteErrorCountersPage(LogParameter_T *buffer, int length)
+void
+WriteErrorCountersPage(
+ LogParameter_T * buffer,
+ size_t length)
{
int i;
- int value;
+ unsigned value;
LogParameter_T *LogParameter;
- int ParameterCode;
+ unsigned ParameterCode;
LogParameter = buffer;
fprintf(StatFile, "\tWrite Error Counters Page\n");
- while ((char *)LogParameter < ((char *)buffer + length)) {
+ while ((u_char *)LogParameter < ((u_char *)buffer + length)) {
i = LogParameter->ParameterLength;
ParameterCode = V2(LogParameter->ParameterCode);
} else {
fprintf(StatFile, "Error decoding Result\n");
}
- LogParameter = (LogParameter_T *)((char *)LogParameter + sizeof(LogParameter_T) + i);
+ LogParameter = (LogParameter_T *)((u_char *)LogParameter + SIZEOF(LogParameter_T) + i);
}
}
-void ReadErrorCountersPage(LogParameter_T *buffer, int length)
+void
+ReadErrorCountersPage(
+ LogParameter_T * buffer,
+ size_t length)
{
int i;
- int value;
+ unsigned value;
LogParameter_T *LogParameter;
- int ParameterCode;
+ unsigned ParameterCode;
LogParameter = buffer;
fprintf(StatFile, "\tRead Error Counters Page\n");
- while ((char *)LogParameter < ((char *)buffer + length)) {
+ while ((u_char *)LogParameter < ((u_char *)buffer + length)) {
i = LogParameter->ParameterLength;
ParameterCode = V2(LogParameter->ParameterCode);
+ value = 0;
if (Decode(LogParameter, &value) == 0) {
switch (ParameterCode) {
case 2:
} else {
fprintf(StatFile, "Error decoding Result\n");
}
- LogParameter = (LogParameter_T *)((char *)LogParameter + sizeof(LogParameter_T) + i);
+ LogParameter = (LogParameter_T *)((u_char *)LogParameter + SIZEOF(LogParameter_T) + i);
}
}
-void C1553APage30(LogParameter_T *buffer, int length)
+void
+C1553APage30(
+ LogParameter_T * buffer,
+ size_t length)
{
int i;
- int value;
+ unsigned value;
LogParameter_T *LogParameter;
- int ParameterCode;
+ unsigned ParameterCode;
LogParameter = buffer;
fprintf(StatFile, "\tData compression transfer Page\n");
- while ((char *)LogParameter < ((char *)buffer + length)) {
+ while ((u_char *)LogParameter < ((u_char *)buffer + length)) {
i = LogParameter->ParameterLength;
ParameterCode = V2(LogParameter->ParameterCode);
+ value = 0;
if (Decode(LogParameter, &value) == 0) {
switch (ParameterCode) {
default:
break;
}
}
- LogParameter = (LogParameter_T *)((char *)LogParameter + sizeof(LogParameter_T) + i);
+ LogParameter = (LogParameter_T *)((u_char *)LogParameter + SIZEOF(LogParameter_T) + i);
}
}
-void C1553APage37(LogParameter_T *buffer, int length)
+void
+C1553APage37(
+ LogParameter_T * buffer,
+ size_t length)
{
int i;
- int value;
+ unsigned value;
LogParameter_T *LogParameter;
- int ParameterCode;
+ unsigned ParameterCode;
LogParameter = buffer;
fprintf(StatFile, "\tDrive Counters Page\n");
- while ((char *)LogParameter < ((char *)buffer + length)) {
+ while ((u_char *)LogParameter < ((unsigned char *)buffer + length)) {
i = LogParameter->ParameterLength;
ParameterCode = V2(LogParameter->ParameterCode);
+ value = 0;
if (Decode(LogParameter, &value) == 0) {
switch (ParameterCode) {
case 1:
break;
}
}
- LogParameter = (LogParameter_T *)((char *)LogParameter + sizeof(LogParameter_T) + i);
+ LogParameter = (LogParameter_T *)((u_char *)LogParameter + SIZEOF(LogParameter_T) + i);
}
}
-void EXB85058HEPage39(LogParameter_T *buffer, int length)
+void
+EXB85058HEPage39(
+ LogParameter_T * buffer,
+ size_t length)
{
int i;
- int value;
+ unsigned value;
LogParameter_T *LogParameter;
- int ParameterCode;
+ unsigned ParameterCode;
LogParameter = buffer;
fprintf(StatFile, "\tData Compression Page\n");
- while ((char *)LogParameter < ((char *)buffer + length)) {
+ while ((u_char *)LogParameter < ((unsigned char *)buffer + length)) {
i = LogParameter->ParameterLength;
ParameterCode = V2(LogParameter->ParameterCode);
+ value = 0;
if (Decode(LogParameter, &value) == 0) {
switch (ParameterCode) {
case 5:
break;
}
}
- LogParameter = (LogParameter_T *)((char *)LogParameter + sizeof(LogParameter_T) + i);
+ LogParameter = (LogParameter_T *)((u_char *)LogParameter + SIZEOF(LogParameter_T) + i);
}
}
-void EXB85058HEPage3c(LogParameter_T *buffer, int length)
+void
+EXB85058HEPage3c(
+ LogParameter_T * buffer,
+ size_t length)
{
int i;
- int value;
+ unsigned value;
LogParameter_T *LogParameter;
- int ParameterCode;
+ unsigned ParameterCode;
LogParameter = buffer;
fprintf(StatFile, "\tDrive Usage Information Page\n");
- while ((char *)LogParameter < ((char *)buffer + length)) {
+ while ((u_char *)LogParameter < ((unsigned char *)buffer + length)) {
i = LogParameter->ParameterLength;
ParameterCode = V2(LogParameter->ParameterCode);
+ value = 0;
if (Decode(LogParameter, &value) == 0) {
switch (ParameterCode) {
case 1:
break;
}
}
- LogParameter = (LogParameter_T *)((char *)LogParameter + sizeof(LogParameter_T) + i);
+ LogParameter = (LogParameter_T *)((u_char *)LogParameter + SIZEOF(LogParameter_T) + i);
}
}
-int Decode(LogParameter_T *LogParameter, int *value)
+int
+Decode(
+ LogParameter_T * LogParameter,
+ unsigned * value)
{
DebugPrint(DEBUG_INFO, SECTION_SCSI,"##### START Decode\n");
DebugPrint(DEBUG_INFO, SECTION_SCSI,"Decode Parameter with length %d\n", LogParameter->ParameterLength);
+
+ *value = 0;
switch (LogParameter->ParameterLength) {
case 1:
- *value = V1((char *)LogParameter + sizeof(LogParameter_T));
+ *value = V1((u_char *)LogParameter + SIZEOF(LogParameter_T));
break;
case 2:
- *value = V2((char *)LogParameter + sizeof(LogParameter_T));
+ *value = V2((u_char *)LogParameter + SIZEOF(LogParameter_T));
break;
case 3:
- *value = V3((char *)LogParameter + sizeof(LogParameter_T));
+ *value = V3((u_char *)LogParameter + SIZEOF(LogParameter_T));
break;
case 4:
- *value = V4((char *)LogParameter + sizeof(LogParameter_T));
+ *value = V4((u_char *)LogParameter + SIZEOF(LogParameter_T));
break;
case 5:
- *value = V5((char *)LogParameter + sizeof(LogParameter_T));
+ *value = V5((u_char *)LogParameter + SIZEOF(LogParameter_T));
break;
case 6:
- *value = V6((char *)LogParameter + sizeof(LogParameter_T));
+ *value = V6((u_char *)LogParameter + SIZEOF(LogParameter_T));
break;
default:
fprintf(StatFile, "Can't decode ParameterCode %02X size %d\n",
V2(LogParameter->ParameterCode), LogParameter->ParameterLength);
DebugPrint(DEBUG_INFO, SECTION_SCSI,"##### STOP Decode (1)\n");
return(1);
+ /*NOTREACHED*/
}
DebugPrint(DEBUG_INFO, SECTION_SCSI,"Result = %d\n", *value);
DebugPrint(DEBUG_INFO, SECTION_SCSI,"##### STOP Decode(0)\n");
return(0);
}
-void DumpDev(OpenFiles_T *p, char *device)
+void
+DumpDev(
+ OpenFiles_T * p,
+ char * device)
{
if (p != NULL)
{
printf("\n");
}
-void ChangerReplay(char *option)
+void
+ChangerReplay(
+ char * option)
{
- char buffer[1024];
+ u_char buffer[1024];
FILE *ip;
- int x = 0, bufferx;
+ int x;
+ unsigned bufferx;
+
+ (void)option; /* Quiet unused parameter warning */
if ((ip=fopen("/tmp/chg-scsi-trace", "r")) == NULL)
{
exit(1);
}
- while (fscanf(ip, "%2x", &bufferx) != EOF)
+ for (x = 0; x < 1024; x++)
{
- buffer[x] = bufferx;
- x++;
+ if (fscanf(ip, "%2x", &bufferx) == EOF)
+ {
+ break;
+ /*NOTREACHED*/
+ }
+ buffer[x] = (u_char)bufferx;
+ x++;
}
DecodeModeSense(&buffer[0], 12, "DLT448ElementStatus :", 0, debug_file);
/*
* Display all Information we can get about the library....
*/
-void ChangerStatus(char *option, char * labelfile, int HasBarCode, char *changer_file, char *changer_dev, char *tape_device)
+void
+ChangerStatus(
+ char * option,
+ char * labelfile,
+ int HasBarCode,
+ char * changer_file,
+ char * changer_dev,
+ char * tape_device)
{
extern OpenFiles_T *pDev;
- int x;
+ size_t x;
FILE *out;
ExtendedRequestSense_T ExtRequestSense;
MBC_T *pbarcoderes;
ChangerCMD_T *p = (ChangerCMD_T *)&ChangerIO;
- if ((pbarcoderes = malloc(sizeof(MBC_T))) == NULL)
- {
- printf("malloc failed \n");
- return;
- }
- memset(pbarcoderes, 0, sizeof(MBC_T));
+ pbarcoderes = alloc(SIZEOF(MBC_T));
+ memset(pbarcoderes, 0, SIZEOF(MBC_T));
- if ((pModePage == NULL) && ((pModePage = (char *)malloc(0xff)) == NULL))
- {
- DebugPrint(DEBUG_ERROR, SECTION_ELEMENT,"##### malloc failed (-1)\n");
- printf("malloc failed \n");
- free(pbarcoderes);
- return;
- }
+ if (pModePage == NULL) {
+ pModePage = alloc(0xff);
+ }
if ((out = fdopen(1 , "w")) == NULL)
{
printf("Error fdopen stdout\n");
free(pbarcoderes);
return;
+ /*NOTREACHED*/
}
if (strcmp("types", option) == 0 || strcmp("all", option) == 0)
free(pbarcoderes);
fclose(out);
return;
+ /*NOTREACHED*/
}
}
/* 0123456789012345678901234567890123456789012 */
if (pMTE[x].full == 1)
{
pbarcoderes->action = BARCODE_BARCODE;
- strcpy(pbarcoderes->data.barcode, pMTE[x].VolTag);
+ strncpy(pbarcoderes->data.barcode, pMTE[x].VolTag,
+ SIZEOF(pbarcoderes->data.barcode));
if (MapBarCode(labelfile, pbarcoderes) == 0 )
{
if (pSTE[x].full == 1)
{
pbarcoderes->action = BARCODE_BARCODE;
- strcpy(pbarcoderes->data.barcode, pSTE[x].VolTag);
+ strncpy(pbarcoderes->data.barcode, pSTE[x].VolTag,
+ SIZEOF(pbarcoderes->data.barcode));
if (MapBarCode(labelfile, pbarcoderes) == 0 )
{
if (pDTE[x].full == 1)
{
pbarcoderes->action = BARCODE_BARCODE;
- strcpy(pbarcoderes->data.barcode, pDTE[x].VolTag);
+ strncpy(pbarcoderes->data.barcode, pDTE[x].VolTag,
+ SIZEOF(pbarcoderes->data.barcode));
if (MapBarCode(labelfile, pbarcoderes) == 0 )
{
if (pIEE[x].full == 1)
{
pbarcoderes->action = BARCODE_BARCODE;
- strcpy(pbarcoderes->data.barcode, pIEE[x].VolTag);
+ strncpy(pbarcoderes->data.barcode, pIEE[x].VolTag,
+ SIZEOF(pbarcoderes->data.barcode));
if (MapBarCode(labelfile, pbarcoderes) == 0 )
{
fclose(out);
}
-void dump_hex(char *p, int size, int level, int section)
+void
+dump_hex(
+ u_char * p,
+ size_t size,
+ int level,
+ int section)
{
- int row_count = 0;
- int x = 0;
+ size_t row_count = 0;
+ int x;
while (row_count < size)
{
- DebugPrint(level, section,"%02X ", (unsigned char)p[row_count]);
- if (((row_count + 1) % 16) == 0 )
+ DebugPrint(level, section,"%02X ", (u_char)p[row_count]);
+ if (((row_count + 1) % 16) == 0)
{
dbprintf((" "));
- for (x = 16; x>0;x--)
+ for (x = 16; x > 0; x--)
{
- if (isalnum((unsigned char)p[row_count - x + 1 ]))
- DebugPrint(level, section,"%c",(unsigned char)p[row_count - x + 1]);
- else
- DebugPrint(level, section,".");
- }
+ if (isalnum((u_char)p[row_count - x + 1 ]))
+ DebugPrint(level, section,"%c",(u_char)p[row_count - x + 1]);
+ else
+ DebugPrint(level, section,".");
+ }
DebugPrint(level, section,"\n");
}
row_count++;
DebugPrint(level, section,"\n");
}
-void TerminateString(char *string, int length)
+void
+TerminateString(
+ char * string,
+ size_t length)
{
- int x;
+ ssize_t x;
- for (x = length; x >= 0 && !isalnum((int)string[x]); x--)
+ for (x = (ssize_t)length; x >= 0 && !isalnum((int)string[x]); x--)
string[x] = '\0';
}
-void ChgExit(char *where, char *reason, int level)
+void
+ChgExit(
+ char * where,
+ char * reason,
+ int level)
{
+ (void)level; /* Quiet unused parameter warning */
+
dbprintf(("ChgExit in %s, reason %s\n", where, reason));
fprintf(stderr,"%s\n",reason);
exit(2);
* is ready for accepting commands, and if this is true send
* the command
*/
-int SCSI_Run(int DeviceFD,
- Direction_T Direction,
- CDB_T CDB,
- int CDB_Length,
- void *DataBuffer,
- int DataBufferLength,
- char *pRequestSense,
- int RequestSenseLength)
+int
+SCSI_Run(
+ int DeviceFD,
+ Direction_T Direction,
+ CDB_T CDB,
+ size_t CDB_Length,
+ void * DataBuffer,
+ size_t DataBufferLength,
+ RequestSense_T * pRequestSense,
+ size_t RequestSenseLength)
{
int ret = 0;
int ok = 0;
int maxtries = 0;
RequestSense_T *pRqS;
+ /* Basic sanity checks */
+ assert(CDB_Length <= UCHAR_MAX);
+ assert(RequestSenseLength <= UCHAR_MAX);
+
pRqS = (RequestSense_T *)pRequestSense;
DebugPrint(DEBUG_INFO, SECTION_SCSI, "SCSI_Run TestUnitReady\n");
ok=1;
break;
case SCSI_SENSE:
- switch (SenseHandler(DeviceFD, 0, pRqS->SenseKey, pRqS->AdditionalSenseCode, pRqS->AdditionalSenseCodeQualifier, pRequestSense))
+ switch (SenseHandler(DeviceFD, 0, pRqS->SenseKey, pRqS->AdditionalSenseCode, pRqS->AdditionalSenseCodeQualifier, pRqS))
{
case SENSE_NO:
DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_Run (TestUnitReady) SENSE_NO\n");
case SENSE_ABORT:
DebugPrint(DEBUG_ERROR, SECTION_SCSI,"SCSI_Run (TestUnitReady) SENSE_ABORT\n");
return(-1);
- break;
+ /*NOTREACHED*/
case SENSE_RETRY:
DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_Run (TestUnitReady) SENSE_RETRY\n");
break;
case SCSI_ERROR:
DebugPrint(DEBUG_ERROR, SECTION_SCSI,"SCSI_Run (TestUnitReady) SCSI_ERROR\n");
return(-1);
- break;
+ /*NOTREACHED*/
case SCSI_BUSY:
DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_Run (TestUnitReady) SCSI_BUSY\n");
break;
{
DebugPrint(DEBUG_ERROR, SECTION_SCSI,"SCSI_Run Exit %d\n",ret);
return(-1);
+ /*NOTREACHED*/
}
ok = 0;
ok=1;
break;
case SCSI_SENSE:
- switch (SenseHandler(DeviceFD, 0, pRqS->SenseKey, pRqS->AdditionalSenseCode, pRqS->AdditionalSenseCodeQualifier, pRequestSense))
+ switch (SenseHandler(DeviceFD, 0, pRqS->SenseKey, pRqS->AdditionalSenseCode, pRqS->AdditionalSenseCodeQualifier, pRqS))
{
case SENSE_NO:
DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_Run SENSE_NO\n");
case SENSE_ABORT:
DebugPrint(DEBUG_ERROR, SECTION_SCSI,"SCSI_Run SENSE_ABORT\n");
return(-1);
- break;
+ /*NOTREACHED*/
case SENSE_RETRY:
DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_Run SENSE_RETRY\n");
break;
case SCSI_ERROR:
DebugPrint(DEBUG_ERROR, SECTION_SCSI,"SCSI_Run SCSI_ERROR\n");
return(-1);
- break;
+ /*NOTREACHED*/
case SCSI_BUSY:
DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_Run SCSI_BUSY\n");
break;
if (ok == 1)
{
return(0);
- } else {
- return(-1);
+ /*NOTREACHED*/
}
+ return(-1);
}
/*
* This a vendor specific command !!!!!!
* First seen at AIT :-)
*/
-int SCSI_AlignElements(int DeviceFD, int AE_MTE, int AE_DTE, int AE_STE)
+int
+SCSI_AlignElements(
+ int DeviceFD,
+ size_t AE_MTE,
+ size_t AE_DTE,
+ size_t AE_STE)
{
RequestSense_T *pRequestSense;
int retry;
CDB_T CDB;
- int ret = -1;
+ int ret;
int i;
DebugPrint(DEBUG_INFO, SECTION_SCSI,"##### START SCSI_AlignElements\n");
- if ((pRequestSense = (RequestSense_T *)malloc(sizeof(RequestSense_T))) == NULL)
- {
- DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_AlignElements : malloc failed\n");
- return(-1);
- }
+ pRequestSense = alloc(SIZEOF(RequestSense_T));
for (retry = 0; retry < MAX_RETRIES; retry++)
{
CDB[11] = 0;
ret = SCSI_Run(DeviceFD, Input, CDB, 12,
- NULL, 0, (char *)pRequestSense, sizeof(RequestSense_T));
+ NULL, 0, pRequestSense, SIZEOF(RequestSense_T));
DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_AlignElements : SCSI_Run = %d\n", ret);
DecodeSense(pRequestSense, "SCSI_AlignElements :",debug_file);
if (ret < 0)
{
DebugPrint(DEBUG_ERROR, SECTION_SCSI,"%s: Request Sense[Inquiry]: %02X",
- "chs", ((unsigned char *) &pRequestSense)[0]);
- for (i = 1; i < sizeof(RequestSense_T); i++)
- DebugPrint(DEBUG_ERROR, SECTION_SCSI," %02X", ((unsigned char *) &pRequestSense)[i]);
+ "chs", ((u_char *) &pRequestSense)[0]);
+ for (i = 1; i < (int)sizeof(RequestSense_T); i++)
+ DebugPrint(DEBUG_ERROR, SECTION_SCSI," %02X", ((u_char *) &pRequestSense)[i]);
DebugPrint(DEBUG_ERROR, SECTION_SCSI,"\n");
return(ret);
+ /*NOTREACHED*/
}
if ( ret > 0)
{
- switch(SenseHandler(DeviceFD, 0 , pRequestSense->SenseKey, pRequestSense->AdditionalSenseCode, pRequestSense->AdditionalSenseCodeQualifier, (char *)pRequestSense))
+ switch(SenseHandler(DeviceFD, 0 , pRequestSense->SenseKey, pRequestSense->AdditionalSenseCode, pRequestSense->AdditionalSenseCodeQualifier, pRequestSense))
{
case SENSE_IGNORE:
DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_AlignElements : SENSE_IGNORE\n");
return(0);
- break;
+ /*NOTREACHED*/
case SENSE_RETRY:
DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_AlignElements : SENSE_RETRY no %d\n", retry);
break;
case SENSE_ABORT:
DebugPrint(DEBUG_ERROR, SECTION_SCSI,"SCSI_AlignElements : SENSE_ABORT\n");
return(-1);
- break;
+ /*NOTREACHED*/
case SENSE_TAPE_NOT_UNLOADED:
DebugPrint(DEBUG_ERROR, SECTION_SCSI,"SCSI_AlignElements : Tape still loaded, eject failed\n");
return(-1);
- break;
+ /*NOTREACHED*/
default:
DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_AlignElements : end %d\n", pRequestSense->SenseKey);
return(pRequestSense->SenseKey);
- break;
+ /*NOTREACHED*/
}
}
if (ret == 0)
{
DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_AlignElements : end %d\n", ret);
return(ret);
+ /*NOTREACHED*/
}
}
DebugPrint(DEBUG_ERROR, SECTION_SCSI,"SCSI_AlignElements :"
}
-int SCSI_Move(int DeviceFD, unsigned char chm, int from, int to)
+int
+SCSI_Move(
+ int DeviceFD,
+ u_char chm,
+ int from,
+ int to)
{
RequestSense_T *pRequestSense;
int retry;
DebugPrint(DEBUG_INFO, SECTION_SCSI,"##### START SCSI_Move\n");
- if ((pRequestSense = (RequestSense_T *)malloc(sizeof(RequestSense_T))) == NULL)
- {
- DebugPrint(DEBUG_ERROR, SECTION_SCSI,"SCSI_Move : malloc failed\n");
- return(-1);
- }
+ pRequestSense = alloc(SIZEOF(RequestSense_T));
for (retry = 0; (ret != 0) && (retry < MAX_RETRIES); retry++)
{
CDB[11] = 0;
ret = SCSI_Run(DeviceFD, Input, CDB, 12,
- NULL, 0, (char *)pRequestSense, sizeof(RequestSense_T));
+ NULL, 0, pRequestSense, SIZEOF(RequestSense_T));
DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_Move : SCSI_Run = %d\n", ret);
DecodeSense(pRequestSense, "SCSI_Move :",debug_file);
if (ret < 0)
{
DebugPrint(DEBUG_ERROR, SECTION_SCSI,"%s: Request Sense[Inquiry]: %02X",
- "chs", ((unsigned char *) &pRequestSense)[0]);
- for (i = 1; i < sizeof(RequestSense_T); i++)
- DebugPrint(DEBUG_ERROR, SECTION_SCSI," %02X", ((unsigned char *) &pRequestSense)[i]);
+ "chs", ((u_char *) &pRequestSense)[0]);
+ for (i = 1; i < (int)sizeof(RequestSense_T); i++)
+ DebugPrint(DEBUG_ERROR, SECTION_SCSI," %02X", ((u_char *) &pRequestSense)[i]);
DebugPrint(DEBUG_INFO, SECTION_SCSI,"\n");
return(ret);
+ /*NOTREACHED*/
}
if ( ret > 0)
{
- switch(SenseHandler(DeviceFD, 0 , pRequestSense->SenseKey, pRequestSense->AdditionalSenseCode, pRequestSense->AdditionalSenseCodeQualifier, (char *)pRequestSense))
+ switch(SenseHandler(DeviceFD, 0 , pRequestSense->SenseKey, pRequestSense->AdditionalSenseCode, pRequestSense->AdditionalSenseCodeQualifier, pRequestSense))
{
case SENSE_IGNORE:
dbprintf(("SCSI_Move : SENSE_IGNORE\n"));
return(0);
- break;
+ /*NOTREACHED*/
case SENSE_RETRY:
dbprintf(("SCSI_Move : SENSE_RETRY no %d\n", retry));
break;
case SENSE_ABORT:
dbprintf(("SCSI_Move : SENSE_ABORT\n"));
return(-1);
- break;
+ /*NOTREACHED*/
case SENSE_TAPE_NOT_UNLOADED:
dbprintf(("SCSI_Move : Tape still loaded, eject failed\n"));
return(-1);
- break;
+ /*NOTREACHED*/
default:
dbprintf(("SCSI_Move : end %d\n", pRequestSense->SenseKey));
return(pRequestSense->SenseKey);
- break;
+ /*NOTREACHED*/
}
}
}
return(ret);
}
-int SCSI_LoadUnload(int DeviceFD, RequestSense_T *pRequestSense, unsigned char byte1, unsigned char load)
+int
+SCSI_LoadUnload(
+ int DeviceFD,
+ RequestSense_T * pRequestSense,
+ u_char byte1,
+ u_char load)
{
CDB_T CDB;
int ret;
ret = SCSI_Run(DeviceFD, Input, CDB, 6,
NULL, 0,
- (char *) pRequestSense,
- sizeof(RequestSense_T));
+ pRequestSense,
+ SIZEOF(RequestSense_T));
if (ret < 0)
{
dbprintf(("SCSI_Unload : failed %d\n", ret));
return(-1);
+ /*NOTREACHED*/
}
return(ret);
}
-int SCSI_TestUnitReady(int DeviceFD, RequestSense_T *pRequestSense)
+int
+SCSI_TestUnitReady(
+ int DeviceFD,
+ RequestSense_T * pRequestSense)
{
CDB_T CDB;
int ret;
CDB[5] = 0;
ret = SCSI_ExecuteCommand(DeviceFD, Input, CDB, 6,
- NULL, 0,
- (char *) pRequestSense,
- sizeof(RequestSense_T));
+ NULL, (size_t)0,
+ pRequestSense,
+ SIZEOF(RequestSense_T));
/*
* We got an error, so let the calling function handle this
{
DebugPrint(DEBUG_INFO, SECTION_SCSI,"###### STOP SCSI_TestUnitReady (1)\n");
return(ret);
+ /*NOTREACHED*/
}
/*
{
DebugPrint(DEBUG_INFO, SECTION_SCSI,"###### STOP SCSI_TestUnitReady (1)\n");
return(0);
+ /*NOTREACHED*/
}
/*
}
-int SCSI_ModeSelect(int DeviceFD, char *buffer, unsigned char length, unsigned char save, unsigned char mode, unsigned char lun)
+int
+SCSI_ModeSelect(
+ int DeviceFD,
+ u_char * buffer,
+ u_char length,
+ u_char save,
+ u_char mode,
+ u_char lun)
{
CDB_T CDB;
RequestSense_T *pRequestSense;
int ret = -1;
- int retry = 1;
- char *sendbuf;
+ int retry;
+ u_char *sendbuf;
dbprintf(("##### START SCSI_ModeSelect\n"));
- dbprintf(("SCSI_ModeSelect start length = %d:\n", length));
- if ((pRequestSense = (RequestSense_T *)malloc(sizeof(RequestSense_T))) == NULL)
- {
- dbprintf(("SCSI_ModeSelect : malloc failed\n"));
- return(-1);
- }
-
-
- if ((sendbuf = (char *)malloc(length + 4)) == NULL)
- {
- dbprintf(("SCSI_ModeSelect : malloc failed\n"));
- free(pRequestSense);
- return(-1);
- }
-
- memset(sendbuf, 0 , length + 4);
+ dbprintf(("SCSI_ModeSelect start length = %u:\n", (unsigned)length));
+ pRequestSense = alloc(SIZEOF(RequestSense_T));
+ sendbuf = alloc((size_t)length + 4);
+ memset(sendbuf, 0 , (size_t)length + 4);
- memcpy(&sendbuf[4], buffer, length);
- dump_hex(sendbuf, length+4, DEBUG_INFO, SECTION_SCSI);
+ memcpy(&sendbuf[4], buffer, (size_t)length);
+ dump_hex(sendbuf, (size_t)length+4, DEBUG_INFO, SECTION_SCSI);
for (retry = 0; (ret != 0) && (retry < MAX_RETRIES); retry++)
{
- memset(pRequestSense, 0, sizeof(RequestSense_T));
+ memset(pRequestSense, 0, SIZEOF(RequestSense_T));
CDB[0] = SC_COM_MODE_SELECT;
- CDB[1] = ((lun << 5) & 0xF0) | ((mode << 4) & 0x10) | (save & 1);
+ CDB[1] = (u_char)(((lun << 5) & 0xF0) | ((mode << 4) & 0x10) | (save & 1));
CDB[2] = 0;
CDB[3] = 0;
- CDB[4] = length + 4;
+ CDB[4] = (u_char)(length + 4);
CDB[5] = 0;
ret = SCSI_Run(DeviceFD, Output, CDB, 6,
sendbuf,
- length + 4,
- (char *) pRequestSense,
- sizeof(RequestSense_T));
+ (size_t)length + 4,
+ pRequestSense,
+ SIZEOF(RequestSense_T));
if (ret < 0)
{
dbprintf(("SCSI_ModeSelect : ret %d\n", ret));
- free(pRequestSense);
- free(sendbuf);
- return(ret);
+ goto done;
+ /*NOTREACHED*/
}
if ( ret > 0)
switch(SenseHandler(DeviceFD, 0, pRequestSense->SenseKey,
pRequestSense->AdditionalSenseCode,
pRequestSense->AdditionalSenseCodeQualifier,
- (char *)pRequestSense))
+ pRequestSense))
{
case SENSE_IGNORE:
dbprintf(("SCSI_ModeSelect : SENSE_IGNORE\n"));
- free(pRequestSense);
- free(sendbuf);
- return(0);
- break;
+ goto done;
+ /*NOTREACHED*/
+
case SENSE_RETRY:
dbprintf(("SCSI_ModeSelect : SENSE_RETRY no %d\n", retry));
break;
+
default:
- dbprintf(("SCSI_ModeSelect : end %d\n", pRequestSense->SenseKey));
- free(pRequestSense);
- free(sendbuf);
- return(pRequestSense->SenseKey);
- break;
+ ret = pRequestSense->SenseKey;
+ goto end;
}
}
}
+end:
dbprintf(("SCSI_ModeSelect end: %d\n", ret));
+
+done:
free(pRequestSense);
free(sendbuf);
return(ret);
-int SCSI_ModeSense(int DeviceFD, char *buffer, u_char size, u_char byte1, u_char byte2)
+int
+SCSI_ModeSense(
+ int DeviceFD,
+ u_char * buffer,
+ u_char size,
+ u_char byte1,
+ u_char byte2)
{
CDB_T CDB;
RequestSense_T *pRequestSense;
DebugPrint(DEBUG_INFO, SECTION_SCSI,"##### START SCSI_ModeSense\n");
DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_ModeSense start length = %d:\n", size);
- if ((pRequestSense = (RequestSense_T *)malloc(sizeof(RequestSense_T))) == NULL)
- {
- DebugPrint(DEBUG_ERROR, SECTION_SCSI,"SCSI_ModeSense : malloc failed\n");
- return(-1);
- }
+ pRequestSense = alloc(SIZEOF(RequestSense_T));
while (ret && retry < MAX_RETRIES)
{
- memset(pRequestSense, 0, sizeof(RequestSense_T));
+ memset(pRequestSense, 0, SIZEOF(RequestSense_T));
memset(buffer, 0, size);
CDB[0] = SC_COM_MODE_SENSE;
ret = SCSI_Run(DeviceFD, Input, CDB, 6,
buffer,
size,
- (char *) pRequestSense,
- sizeof(RequestSense_T));
+ pRequestSense,
+ SIZEOF(RequestSense_T));
if (ret < 0)
{
return(ret);
+ /*NOTREACHED*/
}
if ( ret > 0)
{
- switch(SenseHandler(DeviceFD, 0, pRequestSense->SenseKey, pRequestSense->AdditionalSenseCode, pRequestSense->AdditionalSenseCodeQualifier, (char *)pRequestSense))
+ switch(SenseHandler(DeviceFD, 0, pRequestSense->SenseKey, pRequestSense->AdditionalSenseCode, pRequestSense->AdditionalSenseCodeQualifier, pRequestSense))
{
case SENSE_IGNORE:
DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_ModeSense : SENSE_IGNORE\n");
return(0);
- break;
+ /*NOTREACHED*/
case SENSE_RETRY:
DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_ModeSense : SENSE_RETRY no %d\n", retry);
break;
default:
DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_ModeSense : end %d\n", pRequestSense->SenseKey);
return(pRequestSense->SenseKey);
- break;
+ /*NOTREACHED*/
}
}
retry++;
return(ret);
}
-int SCSI_Inquiry(int DeviceFD, SCSIInquiry_T *buffer, u_char size)
+int
+SCSI_Inquiry(
+ int DeviceFD,
+ SCSIInquiry_T * buffer,
+ size_t size)
{
CDB_T CDB;
RequestSense_T *pRequestSense;
int i;
- int ret;
+ int ret = -1;
int retry = 1;
+ assert(size <= UCHAR_MAX);
+
DebugPrint(DEBUG_INFO, SECTION_SCSI, "##### START SCSI_Inquiry\n");
DebugPrint(DEBUG_INFO, SECTION_SCSI, "SCSI_Inquiry start length = %d:\n", size);
- if ((pRequestSense = (RequestSense_T *)malloc(size)) == NULL)
- {
- DebugPrint(DEBUG_ERROR, SECTION_SCSI,"SCSI_Inquiry : malloc failed\n");
- return(-1);
- }
+ pRequestSense = alloc((size_t)size);
while (retry > 0 && retry < MAX_RETRIES)
{
CDB[1] = 0;
CDB[2] = 0;
CDB[3] = 0;
- CDB[4] = size;
+ CDB[4] = (u_char)size;
CDB[5] = 0;
ret = SCSI_ExecuteCommand(DeviceFD, Input, CDB, 6,
buffer,
size,
- (char *) pRequestSense,
- sizeof(RequestSense_T));
+ pRequestSense,
+ SIZEOF(RequestSense_T));
if (ret < 0)
{
DebugPrint(DEBUG_ERROR, SECTION_SCSI,"%s: Request Sense[Inquiry]: %02X",
- "chs", ((unsigned char *) pRequestSense)[0]);
- for (i = 1; i < sizeof(RequestSense_T); i++)
- DebugPrint(DEBUG_ERROR, SECTION_SCSI," %02X", ((unsigned char *) pRequestSense)[i]);
+ "chs", ((u_char *) pRequestSense)[0]);
+ for (i = 1; i < (int)sizeof(RequestSense_T); i++)
+ DebugPrint(DEBUG_ERROR, SECTION_SCSI," %02X", ((u_char *) pRequestSense)[i]);
DebugPrint(DEBUG_ERROR, SECTION_SCSI, "\n");
- DebugPrint(DEBUG_ERROR, SECTION_SCSI, "Inquiry end: %d\n", ret);
- return(ret);
+ DebugPrint(DEBUG_ERROR, SECTION_SCSI, "Inquiry end: %d\n", ret);
+ return(ret);
+ /*NOTRACHED*/
}
if ( ret > 0)
{
- switch(SenseHandler(DeviceFD, 0, pRequestSense->SenseKey, pRequestSense->AdditionalSenseCode, pRequestSense->AdditionalSenseCodeQualifier, (char *)pRequestSense))
+ switch(SenseHandler(DeviceFD, 0, pRequestSense->SenseKey, pRequestSense->AdditionalSenseCode, pRequestSense->AdditionalSenseCodeQualifier, pRequestSense))
{
case SENSE_IGNORE:
DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_Inquiry : SENSE_IGNORE\n");
return(0);
- break;
+ /*NOTREACHED*/
case SENSE_RETRY:
DebugPrint(DEBUG_INFO, SECTION_SCSI, "SCSI_Inquiry : SENSE_RETRY no %d\n", retry);
break;
default:
DebugPrint(DEBUG_ERROR, SECTION_SCSI, "SCSI_Inquiry : end %d\n", pRequestSense->SenseKey);
return(pRequestSense->SenseKey);
- break;
+ /*NOTREACHED*/
}
}
retry++;
if (ret == 0)
{
- dump_hex((char *)buffer, size, DEBUG_INFO, SECTION_SCSI);
+ dump_hex((u_char *)buffer, size, DEBUG_INFO, SECTION_SCSI);
DebugPrint(DEBUG_INFO, SECTION_SCSI, "SCSI_Inquiry : end %d\n", ret);
return(ret);
+ /*NOTRACHED*/
}
}
* 3. do again an Read Element Status with the result from 2.
*
*/
-int SCSI_ReadElementStatus(int DeviceFD,
- unsigned char type,
- unsigned char lun,
- unsigned char VolTag,
- int StartAddress,
- int NoOfElements,
- int DescriptorSize,
- char **data)
+int
+SCSI_ReadElementStatus(
+ int DeviceFD,
+ u_char type,
+ u_char lun,
+ u_char VolTag,
+ int StartAddress,
+ size_t NoOfElements,
+ size_t DescriptorSize,
+ u_char ** data)
{
CDB_T CDB;
- int DataBufferLength;
+ size_t DataBufferLength;
ElementStatusData_T *ElementStatusData;
RequestSense_T *pRequestSense;
int retry = 1;
DebugPrint(DEBUG_INFO, SECTION_SCSI,"##### START SCSI_ReadElementStatus\n");
- if ((pRequestSense = (RequestSense_T *)malloc(sizeof(RequestSense_T))) == NULL)
- {
- DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_ReadElementStatus : malloc failed\n");
- ChgExit("SCSI_ReadElementStatus","malloc failed", FATAL);
- }
+ pRequestSense = alloc(SIZEOF(RequestSense_T));
/*
* How many elements, if <= 0 than exit with an fatal error
*/
- if (NoOfElements <= 0)
+ if (NoOfElements == 0)
{
ChgExit("SCSI_ReadElementStatus","No of Elements passed are le 0",FATAL);
+ /*NOTREACHED*/
}
- VolTag = (VolTag << 4) & 0x10;
- type = type & 0xf;
- lun = (lun << 5) & 0xe0;
-
+ VolTag = (u_char)((VolTag << 4) & 0x10);
+ type = (u_char)(type & 0xf);
+ lun = (u_char)((lun << 5) & 0xe0);
/* if DescriptorSize == 0
* try to get the allocation length for the second call
*/
if (DescriptorSize == 0)
{
- if (*data != NULL)
- {
- *data = realloc(*data, 8);
- } else {
- *data = malloc(8);
- }
-
+ *data = newalloc(*data, 8);
memset(*data, 0, 8);
-
-
while (retry > 0 && retry < MAX_RETRIES)
{
- memset(pRequestSense, 0, sizeof(RequestSense_T) );
+ memset(pRequestSense, 0, SIZEOF(RequestSense_T) );
CDB[0] = SC_COM_RES; /* READ ELEMENT STATUS */
- CDB[1] = VolTag | type | lun; /* Element Type Code , VolTag, LUN */
+ CDB[1] = (u_char)(VolTag | type | lun); /* Element Type Code , VolTag, LUN */
MSB2(&CDB[2], StartAddress); /* Starting Element Address */
MSB2(&CDB[4], NoOfElements); /* Number Of Element */
CDB[6] = 0; /* Reserved */
ret = SCSI_Run(DeviceFD, Input, CDB, 12,
*data, 8,
- (char *)pRequestSense, sizeof(RequestSense_T));
-
+ pRequestSense, SIZEOF(RequestSense_T));
DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_ReadElementStatus : (1) SCSI_Run %d\n", ret);
if (ret < 0)
DecodeSense(pRequestSense, "SCSI_ReadElementStatus :",debug_file);
DebugPrint(DEBUG_INFO, SECTION_SCSI,"##### STOP SCSI_ReadElementStatus (%d)\n",ret);
return(ret);
+ /*NOTRACHED*/
}
if ( ret > 0)
{
- switch(SenseHandler(DeviceFD, 0, pRequestSense->SenseKey, pRequestSense->AdditionalSenseCode, pRequestSense->AdditionalSenseCodeQualifier, (char *)pRequestSense))
+ switch(SenseHandler(DeviceFD, 0, pRequestSense->SenseKey, pRequestSense->AdditionalSenseCode, pRequestSense->AdditionalSenseCodeQualifier, pRequestSense))
{
case SENSE_IGNORE:
DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_ModeSense : SENSE_IGNORE\n");
default:
DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_ModeSense : end %d\n", pRequestSense->SenseKey);
return(pRequestSense->SenseKey);
- break;
+ /*NOTREACHED*/
}
}
retry++;
{
DebugPrint(DEBUG_INFO, SECTION_SCSI,"##### STOP SCSI_ReadElementStatus (%d)\n",ret);
return(ret);
+ /*NOTRACHED*/
}
ElementStatusData = (ElementStatusData_T *)*data;
}
DataBufferLength = DataBufferLength + 8;
- *data = realloc(*data, DataBufferLength);
+ *data = newalloc(*data, DataBufferLength);
memset(*data, 0, DataBufferLength);
retry = 1;
while (retry > 0 && retry < MAX_RETRIES)
{
- memset(pRequestSense, 0, sizeof(RequestSense_T) );
+ memset(pRequestSense, 0, SIZEOF(RequestSense_T) );
CDB[0] = SC_COM_RES; /* READ ELEMENT STATUS */
- CDB[1] = VolTag | type | lun; /* Element Type Code, VolTag, LUN */
+ CDB[1] = (u_char)(VolTag | type | lun); /* Element Type Code, VolTag, LUN */
MSB2(&CDB[2], StartAddress); /* Starting Element Address */
MSB2(&CDB[4], NoOfElements); /* Number Of Element */
CDB[6] = 0; /* Reserved */
ret = SCSI_Run(DeviceFD, Input, CDB, 12,
*data, DataBufferLength,
- (char *)pRequestSense, sizeof(RequestSense_T));
+ pRequestSense, SIZEOF(RequestSense_T));
DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_ReadElementStatus : (2) SCSI_Run %d\n", ret);
DecodeSense(pRequestSense, "SCSI_ReadElementStatus :",debug_file);
DebugPrint(DEBUG_INFO, SECTION_SCSI,"##### STOP SCSI_ReadElementStatus (%d)\n",ret);
return(ret);
+ /*NOTRACHED*/
}
if ( ret > 0)
{
- switch(SenseHandler(DeviceFD, 0, pRequestSense->SenseKey, pRequestSense->AdditionalSenseCode, pRequestSense->AdditionalSenseCodeQualifier, (char *)pRequestSense))
+ switch(SenseHandler(DeviceFD, 0, pRequestSense->SenseKey, pRequestSense->AdditionalSenseCode, pRequestSense->AdditionalSenseCodeQualifier, pRequestSense))
{
case SENSE_IGNORE:
DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_ModeSense : SENSE_IGNORE\n");
default:
DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_ModeSense : end %d\n", pRequestSense->SenseKey);
return(pRequestSense->SenseKey);
- break;
+ /*NOTREACHED*/
}
}
retry++;
{
DebugPrint(DEBUG_INFO, SECTION_SCSI,"##### STOP SCSI_ReadElementStatus (%d)\n",ret);
return(ret);
+ /*NOTRACHED*/
}
dump_hex(*data, DataBufferLength, DEBUG_INFO, SECTION_SCSI);
{
va_list argp;
char buf[1024];
- extern changer_t chg;
- int dlevel,dsection;
+ int dlevel;
+ int dsection = -1;
+ time_t ti = time(NULL);
- time_t ti;
-
- time(&ti);
- if (chg.debuglevel)
+ if (changer->debuglevel)
{
- sscanf(chg.debuglevel,"%d:%d", &dlevel, &dsection);
+ if (sscanf(changer->debuglevel,"%d:%d", &dlevel, &dsection) != 2) {
+ dbprintf(("Parse error: line is '%s' expected [0-9]*:[0-9]*\n",
+ changer->debuglevel));
+ dlevel=1;
+ dsection=1;
+ }
} else {
dlevel=1;
dsection=1;
}
arglist_start(argp, fmt);
- vsnprintf(buf, sizeof(buf), fmt, argp);
+ vsnprintf(buf, SIZEOF(buf), fmt, argp);
if (dlevel >= level)
{
if (section == dsection || dsection == 0)
/*
- * $Id: scsi-chio.c,v 1.13 2000/06/25 18:48:11 ant Exp $
+ * $Id: scsi-chio.c,v 1.14 2006/05/25 01:47:07 johnfranks Exp $
*
* scsi-chio.c -- library routines to handle the changer
* support for chio based systems
#include "config.h"
#include "amanda.h"
+#include "scsi-defs.h"
#if (defined(HAVE_CHIO_H) || defined(HAVE_SYS_CHIO_H)) \
&& !defined(HAVE_CAMLIB_H)
{
int ret;
+ dbprintf(("%s: CloseDevice(%s)\n", device, get_pname()));
ret = close(DeviceFD);
return ret;
/*
* Copyright (c) 1998 T.Hepper
*/
+#ifndef SCSIDEFS_H
+#define SCSIDEFS_H
+
#ifndef WORDS_BIGENDIAN
#define LITTLE_ENDIAN_BITFIELDS
#endif
#define MAX_RETRIES 100
-#define INQUIRY_SIZE sizeof(SCSIInquiry_T)
+#define INQUIRY_SIZE SIZEOF(SCSIInquiry_T)
/*
* Return values from the OS dependent part
/* macros for building scsi msb array parameter lists */
#ifndef B
-#define B(s,i) ((unsigned char)((s) >> i))
+#define B(s,i) ((unsigned char)(((s) >> (i)) & 0xff))
#endif
#ifndef B1
-#define B1(s) ((unsigned char)(s))
+#define B1(s) ((unsigned char)((s) & 0xff))
#endif
#define B2(s) B((s),8), B1(s)
#define B3(s) B((s),16), B((s),8), B1(s)
#define V6(s) (((((((((((s)[0] << 8) | (s)[1]) << 8) | (s)[2]) << 8) | (s)[3]) << 8) | (s)[4]) << 8) | (s)[5])
/* macros for converting binary into scsi msb array */
-#define MSB1(s,v) *(s)=B1(v)
-#define MSB2(s,v) *(s)=B(v,8), (s)[1]=B1(v)
-#define MSB3(s,v) *(s)=B(v,16), (s)[1]=B(v,8), (s)[2]=B1(v)
-#define MSB4(s,v) *(s)=B(v,24),(s)[1]=B(v,16), (s)[2]=B(v,8), (s)[3]=B1(v)
+#define MSB1(s,v) (s)[0]=B1(v)
+#define MSB2(s,v) (s)[0]=B(v,8), (s)[1]=B1(v)
+#define MSB3(s,v) (s)[0]=B(v,16), (s)[1]=B(v,8), (s)[2]=B1(v)
+#define MSB4(s,v) (s)[0]=B(v,24), (s)[1]=B(v,16), (s)[2]=B(v,8), (s)[3]=B1(v)
#define LABEL_DB_VERSION 2
/*----------------------------------------------------------------------------*/
/* Some stuff for our own configurationfile */
typedef struct { /* The information we can get for any drive (configuration) */
- int drivenum; /* Which drive to use in the library */
- int start; /* Which is the first slot we may use */
- int end; /* The last slot we are allowed to use */
- int cleanslot; /* Where the cleaningcartridge stays */
+ int drivenum; /* Which drive to use in the library */
+ int start; /* Which is the first slot we may use */
+ int end; /* The last slot we are allowed to use */
+ int cleanslot; /* Where the cleaningcartridge stays */
char *scsitapedev; /* Where can we send raw SCSI commands to the tape */
char *device; /* Which device is associated to the drivenum */
char *slotfile; /* Where we should have our memory */
char *cleanfile; /* Where we count how many cleanings we did */
char *timefile; /* Where we count the time the tape was used*/
char *tapestatfile;/* Where can we place some drive stats */
- char *changerident;/* Config to use foe changer control, ovverride result from inquiry */
+ char *changerident;/* Config to use for changer control, ovverride result from inquiry */
char *tapeident; /* Same as above for the tape device */
}config_t;
int havebarcode; /* Do we have an barcode reader installed */
char *debuglevel; /* How many debug info to print */
unsigned char emubarcode; /* Emulate the barcode feature, used for keeping an inventory of the lib */
- int sleep; /* How many seconds to wait for the drive to get ready */
+ time_t sleep; /* How many seconds to wait for the drive to get ready */
int cleanmax; /* How many runs could be done with one cleaning tape */
char *device; /* Which device is our changer */
char *labelfile; /* Mapping from Barcode labels to volume labels */
typedef struct {
char voltag[128]; /* Tape volume label */
char barcode[TAG_SIZE]; /* Barcode of the tape */
- unsigned int slot; /* in which slot is the tape */
- unsigned int from; /* from where it comes, needed to move
- * a tape back to the right slot from the drive
- */
+ int slot; /* in which slot is the tape */
+ int from; /* from where it comes, needed to move a tape
+ * back to the right slot from the drive
+ */
unsigned int LoadCount; /* How many times has the tape been loaded */
unsigned int RecovError; /* How many recovered errors */
int from; /* From where did it come */
char status; /* F -> Full, E -> Empty */
char VolTag[TAG_SIZE+1]; /* Label Info if Barcode reader exsist */
- int ASC; /* Additional Sense Code from read element status */
- int ASCQ; /* */
+ unsigned char ASC; /* Additional Sense Code from read element status */
+ unsigned char ASCQ; /* */
unsigned char scsi; /* if DTE, which scsi address */
PackedBit svalid : 1;
int (*function_move)(int, int, int);
int (*function_status)(int, int);
int (*function_reset_status)(int);
- int (*function_free)();
+ int (*function_free)(void);
int (*function_eject)(char *, int);
int (*function_clean)(char *);
int (*function_rewind)(int);
int (*function_barcode)(int);
- int (*function_search)();
- int (*function_error)(int, int, unsigned char, unsigned char, unsigned char, char *);
+ int (*function_search)(void);
+ int (*function_error)(int, unsigned char, unsigned char, unsigned char, unsigned char, RequestSense_T *);
} ChangerCMD_T ;
typedef struct {
typedef struct LogPageDecode {
int LogPage;
char *ident;
- void (*decode)(LogParameter_T *, int);
+ void (*decode)(LogParameter_T *, size_t);
} LogPageDecode_T;
typedef struct {
- char *ident; /* Ident as returned from the inquiry */
- char *vendor; /* Vendor as returned from the inquiry */
- int type; /* removable .... */
- int sense; /* Sense key as returned from the device */
- int asc; /* ASC as set in the sense struct */
- int ascq; /* ASCQ as set in the sense struct */
- int ret; /* What we think that we should return on this conditon */
- char text[80]; /* A short text describing this condition */
+ char *ident; /* Ident as returned from the inquiry */
+ char *vendor; /* Vendor as returned from the inquiry */
+ unsigned char type; /* removable .... */
+ unsigned char sense;/* Sense key as returned from the device */
+ unsigned char asc; /* ASC as set in the sense struct */
+ unsigned char ascq; /* ASCQ as set in the sense struct */
+ int ret; /* What we think that we should return on this conditon */
+ char text[80]; /* A short text describing this condition */
} SenseType_T;
/* ======================================================= */
-/* Funktion-Declaration */
+/* Function-Declaration */
/* ======================================================= */
-int SCSI_OpenDevice(int );
-int OpenDevice(int ,char *DeviceName, char *ConfigName, char *ident);
+int SCSI_OpenDevice(int);
+int OpenDevice(int, char *DeviceName, char *ConfigName, char *ident);
int SCSI_CloseDevice(int DeviceFD);
-int CloseDevice(int );
+int CloseDevice(char *, int);
int Tape_Eject(int);
int Tape_Status(int);
-void DumpSense();
-int Sense2Action(char *ident, unsigned char type, unsigned char ignsense, unsigned char sense, unsigned
-char asc, unsigned char ascq, char **text) ;
+void DumpSense(void);
+int Sense2Action(char *ident,
+ unsigned char type,
+ unsigned char ignsense,
+ unsigned char sense,
+ unsigned char asc,
+ unsigned char ascq,
+ char **text);
int SCSI_ExecuteCommand(int DeviceFD,
Direction_T Direction,
CDB_T CDB,
- int CDB_Length,
+ size_t CDB_Length,
void *DataBuffer,
- int DataBufferLength,
- char *RequestSense,
- int RequestSenseLength);
-
-int Tape_Ioctl( int DeviceFD, int command);
-void ChangerStatus(char * option, char * labelfile, int HasBarCode, char *changer_file, char *changer_dev, char *tape_device);
-
-int SCSI_Inquiry(int, SCSIInquiry_T *, unsigned char);
+ size_t DataBufferLength,
+ RequestSense_T *RequestSense,
+ size_t RequestSenseLength);
+
+int Tape_Ioctl(int DeviceFD, int command);
+void ChangerStatus(char * option,
+ char * labelfile,
+ int HasBarCode,
+ char *changer_file,
+ char *changer_dev,
+ char *tape_device);
+
+int SCSI_Inquiry(int, SCSIInquiry_T *, size_t);
int PrintInquiry(SCSIInquiry_T *);
int DecodeSCSI(CDB_T CDB, char *string);
-int RequestSense P((int fd, ExtendedRequestSense_T *s, int ClearErrorCounters));
-int DecodeSense P((RequestSense_T *sense, char *pstring, FILE *out));
-int DecodeExtSense P((ExtendedRequestSense_T *sense, char *pstring, FILE *out));
+int RequestSense(int fd, ExtendedRequestSense_T *s, int ClearErrorCounters);
+int DecodeSense(RequestSense_T *sense, char *pstring, FILE *out);
+int DecodeExtSense(ExtendedRequestSense_T *sense, char *pstring, FILE *out);
void ChgExit(char *, char *, int);
void ChangerReplay(char *option);
-void ChangerStatus(char * option, char * labelfile, int HasBarCode, char *changer_file, char *changer_dev, char *tape_device);
+void ChangerStatus(char *option, char *labelfile, int HasBarCode, char *changer_file, char *changer_dev, char *tape_device);
int BarCode(int fd);
int MapBarCode(char *labelfile, MBC_T *);
-int Tape_Ready(int fd, int wait_time);
+int Tape_Ready(int fd, time_t wait_time);
void Inventory(char *labelfile, int drive, int eject, int start, int stop, int clean);
-void ChangerDriverVersion();
-void PrintConf();
+void ChangerDriverVersion(void);
+void PrintConf(void);
int LogSense(int fd);
int ScanBus(int print);
void DebugPrint(int level, int section, char * fmt, ...);
int DecodeSense(RequestSense_T *sense, char *pstring, FILE *out);
-void SCSI_OS_Version();
+void SCSI_OS_Version(void);
+int get_clean_state(char *tapedev);
+int find_empty(int fd, int start, int count);
+int get_slot_count(int fd);
+int get_drive_count(int fd);
+int GetCurrentSlot(int fd, int drive);
+void DumpDev(OpenFiles_T *p, char *device);
+int isempty(int fd, int slot);
+
+#endif /* !SCSIDEFS_H */
/*
* Local variables:
* indent-tabs-mode: nil
* file named AUTHORS, in the root directory of this distribution.
*/
/*
- * $Id: scsi-hpux.c,v 1.14 2001/02/08 19:19:08 ant Exp $
+ * $Id: scsi-hpux.c,v 1.15 2006/05/25 01:47:07 johnfranks Exp $
*
* scsi-chio.c -- library routines to handle the changer
* support for chio based systems
static int get_changer_info(fd)
{
-int rc = 0;
+ int rc = 0;
if (!changer_info_init) {
rc = ioctl(fd, SIOC_ELEMENT_ADDRESSES, &changer_info);
perror(dev);
return 0;
}
- memset(buffer, 0, sizeof(buffer));
+ memset(buffer, 0, SIZEOF(buffer));
*((int *) buffer) = 0; /* length of input data */
*(((int *) buffer) + 1) = 100; /* length of output buffer */
/*
* find the first empty slot
*/
-int find_empty(int fd)
+int find_empty(int fd, int start, int count)
{
struct element_status es;
int i, rc;
int DeviceFD;
DeviceFD = open(tapedev, O_RDWR);
+ dbprintf(("%s: OpenDevice(%s) returns %d\n", get_pname(), tapedev, DeviceFD));
return(DeviceFD);
}
-int CloseDevice(int DeviceFD)
+int CloseDevice(char *device, int DeviceFD)
{
int ret;
ret = close(DeviceFD);
+ dbprintf(("%s: CloseDevice(%s) returns %d\n", get_pname(), device, ret));
return(ret);
}
* file named AUTHORS, in the root directory of this distribution.
*/
/*
- * $Id: scsi-hpux_new.c,v 1.18 2005/10/15 13:20:47 martinea Exp $
+ * $Id: scsi-hpux_new.c,v 1.19 2006/05/25 01:47:08 johnfranks Exp $
*
* Interface to execute SCSI commands on an HP-UX Workstation
*
#ifdef HAVE_SYS_IOCTL_H
#include <sys/ioctl.h>
#endif
-#ifdef HAVE_SYS_SCSI_H
-#include <sys/scsi.h>
-#endif
+#include <sys/scsi.h>
#include <sys/mtio.h>
#include <scsi-defs.h>
void SCSI_OS_Version()
{
#ifndef lint
- static char rcsid[] = "$Id: scsi-hpux_new.c,v 1.18 2005/10/15 13:20:47 martinea Exp $";
+ static char rcsid[] = "$Id: scsi-hpux_new.c,v 1.19 2006/05/25 01:47:08 johnfranks Exp $";
DebugPrint(DEBUG_INFO, SECTION_INFO, "scsi-os-layer: %s\n",rcsid);
#endif
}
free(pDev[ip].inquiry);
return(0);
}
- } else {
- close(DeviceFD);
- free(pDev[ip].inquiry);
- pDev[ip].inquiry = NULL;
- return(1);
}
- return(1);
+ close(DeviceFD);
+ free(pDev[ip].inquiry);
+ pDev[ip].inquiry = NULL;
+ return(1);
}
} else {
if ((DeviceFD = open(pDev[ip].dev, O_RDWR| O_NDELAY)) >= 0)
int SCSI_ExecuteCommand(int DeviceFD,
Direction_T Direction,
CDB_T CDB,
- int CDB_Length,
+ size_t CDB_Length,
void *DataBuffer,
- int DataBufferLength,
- char *RequestSense,
- int RequestSenseLength)
+ size_t DataBufferLength,
+ RequestSense_T *RequestSenseBuf,
+ size_t RequestSenseLength)
{
extern OpenFiles_T *pDev;
struct sctl_io sctl_io;
- extern int errno;
int Retries = 3;
int Zero = 0, Result;
+ /* Basic sanity checks */
+ assert(CDB_Length <= UCHAR_MAX);
+ assert(RequestSenseLength <= UCHAR_MAX);
+
+ /* Clear buffer for cases where sense is not returned */
+ memset(RequestSenseBuf, 0, RequestSenseLength);
+
if (pDev[DeviceFD].avail == 0)
{
return(SCSI_ERROR);
}
- memset(&sctl_io, '\0', sizeof(struct sctl_io));
+ memset(&sctl_io, '\0', SIZEOF(struct sctl_io));
sctl_io.flags = 0;
sctl_io.max_msecs = 240000;
SCSI_CloseDevice(DeviceFD);
- memcpy(RequestSense, sctl_io.sense, RequestSenseLength);
+ memcpy(RequestSenseBuf, sctl_io.sense, RequestSenseLength);
switch(sctl_io.cdb_status)
{
case S_GOOD:
return(SCSI_OK);
+
case S_CHECK_CONDITION:
return(SCSI_CHECK);
- break;
+
default:
return(SCSI_ERROR);
- break;
}
}
return(SCSI_ERROR);
mtop.mt_op = MTOFFL;
mtop.mt_count = 1;
break;
+
default:
break;
}
if (ioctl(pDev[DeviceFD].fd , MTIOCTOP, &mtop) != 0)
{
- dbprintf(("Tape_Ioctl error ioctl %d\n",errno));
+ dbprintf(("Tape_Ioctl error ioctl %s\n", strerror(errno)));
SCSI_CloseDevice(DeviceFD);
return(-1);
}
if (ioctl(pDev[DeviceFD].fd, MTIOCGET, &mtget) != 0)
{
- dbprintf(("Tape_Status error ioctl %d\n",errno));
+ dbprintf(("Tape_Status error ioctl %s\n", strerror(errno)));
SCSI_CloseDevice(DeviceFD);
return(-1);
}
* file named AUTHORS, in the root directory of this distribution.
*/
/*
- * $Id: scsi-irix.c,v 1.22 2005/10/15 13:20:47 martinea Exp $
+ * $Id: scsi-irix.c,v 1.23 2006/05/25 01:47:08 johnfranks Exp $
*
* Interface to execute SCSI commands on an SGI Workstation
*
void SCSI_OS_Version()
{
#ifndef lint
- static char rcsid[] = "$Id: scsi-irix.c,v 1.22 2005/10/15 13:20:47 martinea Exp $";
+ static char rcsid[] = "$Id: scsi-irix.c,v 1.23 2006/05/25 01:47:08 johnfranks Exp $";
DebugPrint(DEBUG_INFO, SECTION_INFO, "scsi-os-layer: %s\n",rcsid);
#endif
}
pDev[ip].avail = 0;
return(0);
}
- } else { /* inquiry failed */
- close(DeviceFD);
- free(pDev[ip].inquiry);
- pDev[ip].inquiry = NULL;
- pDev[ip].avail = 0;
- return(0);
}
-
- /*
- * Open ok, but no SCSI communication available
- */
-
- free(pDev[ip].inquiry);
- pDev[ip].inquiry = NULL;
- close(DeviceFD);
- pDev[ip].avail = 0;
- return(0);
+ /* inquiry failed or no SCSI communication available */
+ close(DeviceFD);
+ free(pDev[ip].inquiry);
+ pDev[ip].inquiry = NULL;
+ pDev[ip].avail = 0;
+ return(0);
}
} else {
if ((DeviceFD = open(pDev[ip].dev, O_RDWR | O_EXCL)) >= 0)
int SCSI_ExecuteCommand(int DeviceFD,
Direction_T Direction,
CDB_T CDB,
- int CDB_Length,
+ size_t CDB_Length,
void *DataBuffer,
- int DataBufferLength,
- char *pRequestSense,
- int RequestSenseLength)
+ size_t DataBufferLength,
+ RequestSense_T *pRequestSense,
+ size_t RequestSenseLength)
{
extern OpenFiles_T *pDev;
ExtendedRequestSense_T ExtendedRequestSense;
int Result;
int retries = 5;
+ /* Basic sanity checks */
+ assert(CDB_Length <= UCHAR_MAX);
+ assert(RequestSenseLength <= UCHAR_MAX);
+
+ /* Clear buffer for cases where sense is not returned */
+ memset(pRequestSense, 0, RequestSenseLength);
+
if (pDev[DeviceFD].avail == 0)
{
return(SCSI_ERROR);
}
- memset(&ds, 0, sizeof(struct dsreq));
+ memset(&ds, 0, SIZEOF(struct dsreq));
memset(pRequestSense, 0, RequestSenseLength);
- memset(&ExtendedRequestSense, 0 , sizeof(ExtendedRequestSense_T));
+ memset(&ExtendedRequestSense, 0 , SIZEOF(ExtendedRequestSense_T));
ds.ds_flags = DSRQ_SENSE|DSRQ_TRACE|DSRQ_PRINT;
/* Timeout */
{
case ST_BUSY: /* BUSY */
break;
+
case STA_RESERV: /* RESERV CONFLICT */
if (retries > 0)
sleep(2);
continue;
+
case ST_GOOD: /* GOOD 0x00 */
switch (RET(&ds))
{
case DSRT_SENSE:
return(SCSI_SENSE);
- break;
- case DSRT_SHORT:
- return(SCSI_OK);
- break;
- case DSRT_OK:
- default:
- return(SCSI_OK);
}
+ return(SCSI_OK);
+
case ST_CHECK: /* CHECK CONDITION 0x02 */
switch (RET(&ds))
{
case DSRT_SENSE:
return(SCSI_SENSE);
- break;
- default:
- return(SCSI_CHECK);
- break;
}
return(SCSI_CHECK);
- break;
+
case ST_COND_MET: /* INTERM/GOOD 0x10 */
default:
continue;
if (ioctl(pDev[DeviceFD].fd , MTIOCGET, &mtget) != 0)
{
- dbprintf(("Tape_Status error ioctl %d\n",errno));
+ dbprintf(("Tape_Status error ioctl %s\n",strerror(errno)));
SCSI_CloseDevice(DeviceFD);
return(-1);
}
* file named AUTHORS, in the root directory of this distribution.
*/
/*
- * $Id: scsi-linux.c,v 1.28 2006/03/09 20:06:10 johnfranks Exp $
+ * $Id: scsi-linux.c,v 1.30 2006/07/06 11:57:28 martinea Exp $
*
* Interface to execute SCSI commands on Linux
*
#include <scsi-defs.h>
+extern OpenFiles_T *pDev;
-void SCSI_OS_Version()
+void SCSI_OS_Version(void)
{
#ifndef lint
- static char rcsid[] = "$Id: scsi-linux.c,v 1.28 2006/03/09 20:06:10 johnfranks Exp $";
+ static char rcsid[] = "$Id: scsi-linux.c,v 1.30 2006/07/06 11:57:28 martinea Exp $";
DebugPrint(DEBUG_ERROR, SECTION_INFO, "scsi-os-layer: %s\n",rcsid);
#endif
}
int SCSI_CloseDevice(int DeviceFD)
{
- extern OpenFiles_T *pDev;
int ret = 0;
if (pDev[DeviceFD].devopen == 1)
#ifdef LINUX_SG
int SCSI_OpenDevice(int ip)
{
- extern OpenFiles_T *pDev;
int DeviceFD;
int i;
int timeout;
if (S_ISLNK(pstat.st_mode) == 1)
{
DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_OpenDevice : is a link, checking destination\n");
- if ((buffer = (char *)malloc(512)) == NULL)
+ if ((buffer = (char *)malloc(513)) == NULL)
{
DebugPrint(DEBUG_ERROR, SECTION_SCSI,"SCSI_OpenDevice : malloc failed\n");
return(0);
}
- memset(buffer, 0, 512);
+ memset(buffer, 0, 513);
if (( i = readlink(pDev[ip].dev, buffer, 512)) == -1)
{
if (errno == ENAMETOOLONG )
}
}
pDev[ip].inquiry = (SCSIInquiry_T *)malloc(INQUIRY_SIZE);
- if (SCSI_Inquiry(ip, pDev[ip].inquiry, INQUIRY_SIZE) == 0)
+ if (SCSI_Inquiry(ip, pDev[ip].inquiry, (u_char)INQUIRY_SIZE) == 0)
{
if (pDev[ip].inquiry->type == TYPE_TAPE || pDev[ip].inquiry->type == TYPE_CHANGER)
{
return(0);
}
-#define SCSI_OFF sizeof(struct sg_header)
+#define SCSI_OFF SIZEOF(struct sg_header)
int SCSI_ExecuteCommand(int DeviceFD,
Direction_T Direction,
CDB_T CDB,
- int CDB_Length,
+ size_t CDB_Length,
void *DataBuffer,
- int DataBufferLength,
- char *pRequestSense,
- int RequestSenseLength)
+ size_t DataBufferLength,
+ RequestSense_T *pRequestSense,
+ size_t RequestSenseLength)
{
- extern OpenFiles_T *pDev;
struct sg_header *psg_header;
char *buffer;
- int osize = 0;
- int status;
+ size_t osize = 0;
+ ssize_t status;
+
+ /* Basic sanity checks */
+ assert(CDB_Length <= UCHAR_MAX);
+ assert(RequestSenseLength <= UCHAR_MAX);
+
+ /* Clear buffer for cases where sense is not returned */
+ memset(pRequestSense, 0, RequestSenseLength);
if (pDev[DeviceFD].avail == 0)
{
psg_header->twelve_byte = 0;
}
psg_header->result = 0;
- psg_header->reply_len = SCSI_OFF + DataBufferLength;
+ psg_header->reply_len = (int)(SCSI_OFF + DataBufferLength);
switch (Direction)
{
DecodeSCSI(CDB, "SCSI_ExecuteCommand : ");
status = write(pDev[DeviceFD].fd, buffer, SCSI_OFF + CDB_Length + osize);
- if ( status < 0 || status != SCSI_OFF + CDB_Length + osize ||
- psg_header->result )
+ if ( (status < (ssize_t)0) ||
+ (status != (ssize_t)(SCSI_OFF + CDB_Length + osize)) ||
+ (psg_header->result != 0))
{
dbprintf(("SCSI_ExecuteCommand error send \n"));
SCSI_CloseDevice(DeviceFD);
memset(pRequestSense, 0, RequestSenseLength);
memcpy(pRequestSense, psg_header->sense_buffer, 16);
- if ( status < 0 || status != SCSI_OFF + DataBufferLength ||
- psg_header->result )
+ if ( (status < 0) ||
+ (status != (ssize_t)(SCSI_OFF + DataBufferLength)) ||
+ (psg_header->result != 0))
{
dbprintf(("SCSI_ExecuteCommand error read \n"));
dbprintf(("Status %d (%d) %2X\n", status, SCSI_OFF + DataBufferLength,psg_header->result ));
int SCSI_OpenDevice(int ip)
{
- extern OpenFiles_T *pDev;
int DeviceFD;
int i;
pDev[ip].SCSI = 0;
pDev[ip].inquiry = (SCSIInquiry_T *)malloc(INQUIRY_SIZE);
dbprintf(("SCSI_OpenDevice : use ioctl interface\n"));
- if (SCSI_Inquiry(ip, pDev[ip].inquiry, INQUIRY_SIZE) == 0)
+ if (SCSI_Inquiry(ip, pDev[ip].inquiry, (u_char)INQUIRY_SIZE) == 0)
{
if (pDev[ip].inquiry->type == TYPE_TAPE || pDev[ip].inquiry->type == TYPE_CHANGER)
{
int CDB_Length,
void *DataBuffer,
int DataBufferLength,
- char *pRequestSense,
+ RequestSense_T *pRequestSense,
int RequestSenseLength)
{
- extern OpenFiles_T *pDev;
unsigned char *Command;
int Zero = 0, Result;
*/
int Tape_Ioctl( int DeviceFD, int command)
{
- extern OpenFiles_T *pDev;
struct mtop mtop;
int ret = 0;
if (ioctl(pDev[DeviceFD].fd , MTIOCTOP, &mtop) != 0)
{
- dbprintf(("Tape_Ioctl error ioctl %d\n",errno));
+ dbprintf(("Tape_Ioctl error ioctl %s\n",strerror(errno)));
SCSI_CloseDevice(DeviceFD);
return(-1);
}
int Tape_Status( int DeviceFD)
{
- extern OpenFiles_T *pDev;
struct mtget mtget;
int ret = 0;
+ memset(&mtget, 0, SIZEOF(mtget));
if (pDev[DeviceFD].devopen == 0)
{
if (SCSI_OpenDevice(DeviceFD) == 0)
if (ioctl(pDev[DeviceFD].fd , MTIOCGET, &mtget) != 0)
{
- DebugPrint(DEBUG_ERROR, SECTION_TAPE,"Tape_Status error ioctl %d\n",errno);
+ DebugPrint(DEBUG_ERROR, SECTION_TAPE,"Tape_Status error ioctl %s\n",
+ strerror(errno));
SCSI_CloseDevice(DeviceFD);
return(-1);
}
{
DIR *dir;
struct dirent *dirent;
- extern OpenFiles_T *pDev;
- extern int errno;
int count = 0;
if ((dir = opendir("/dev/")) == NULL)
{
pDev[count].dev = malloc(10);
pDev[count].inqdone = 0;
- sprintf(pDev[count].dev,"/dev/%s", dirent->d_name);
+ snprintf(pDev[count].dev, SIZEOF(pDev[count].dev),
+ "/dev/%s", dirent->d_name);
if (OpenDevice(count,pDev[count].dev, "Scan", NULL ))
{
SCSI_CloseDevice(count);
/*
- * $Id: scsi-proto.c,v 1.3 1998/06/13 06:13:25 oliva Exp $
+ * $Id: scsi-proto.c,v 1.4 2006/05/25 01:47:10 johnfranks Exp $
*
* scsi-proto.c -- library routines to handle the changer
* Prototype file for customization
/*
* find the first empty slot
*/
-int find_empty(int fd)
+int find_empty( int fd, int start, int end)
{
/*
* find an empty slot to insert a tape into (if required)
* file named AUTHORS, in the root directory of this distribution.
*/
/*
- * $Id: scsi-solaris.c,v 1.25 2005/10/15 13:20:47 martinea Exp $
+ * $Id: scsi-solaris.c,v 1.26 2006/05/25 01:47:10 johnfranks Exp $
*
* Interface to execute SCSI commands on an Sun Workstation
*
void SCSI_OS_Version()
{
#ifndef lint
- static char rcsid[] = "$Id: scsi-solaris.c,v 1.25 2005/10/15 13:20:47 martinea Exp $";
+ static char rcsid[] = "$Id: scsi-solaris.c,v 1.26 2006/05/25 01:47:10 johnfranks Exp $";
DebugPrint(DEBUG_INFO, SECTION_INFO, "scsi-os-layer: %s\n",rcsid);
#endif
}
pDev[ip].devopen = 1;
pDev[ip].inquiry = (SCSIInquiry_T *)malloc(INQUIRY_SIZE);
- if (SCSI_Inquiry(ip, pDev[ip].inquiry, INQUIRY_SIZE) == 0)
+ if (SCSI_Inquiry(ip, pDev[ip].inquiry, (unsigned char)INQUIRY_SIZE) == 0)
{
if (pDev[ip].inquiry->type == TYPE_TAPE || pDev[ip].inquiry->type == TYPE_CHANGER)
{
free(pDev[ip].inquiry);
return(0);
}
- } else {
- free(pDev[ip].inquiry);
- pDev[ip].inquiry = NULL;
- return(1);
}
- return(1);
+ free(pDev[ip].inquiry);
+ pDev[ip].inquiry = NULL;
+ return(1);
} else {
dbprintf(("SCSI_OpenDevice %s failed\n", pDev[ip].dev));
return(0);
int SCSI_ExecuteCommand(int DeviceFD,
Direction_T Direction,
CDB_T CDB,
- int CDB_Length,
+ size_t CDB_Length,
void *DataBuffer,
- int DataBufferLength,
- char *pRequestSense,
- int RequestSenseLength)
+ size_t DataBufferLength,
+ RequestSense_T *RequestSense,
+ size_t RequestSenseLength)
{
extern OpenFiles_T *pDev;
extern FILE * debug_file;
int retries = 1;
extern int errno;
struct uscsi_cmd Command;
-#if 0
- ExtendedRequestSense_T pExtendedRequestSense;
-#endif
static int depth = 0;
+ /* Basic sanity checks */
+ assert(CDB_Length <= UCHAR_MAX);
+ assert(RequestSenseLength <= UCHAR_MAX);
+
+ /* Clear buffer for cases where sense is not returned */
+ memset(RequestSense, 0, RequestSenseLength);
+
if (pDev[DeviceFD].avail == 0)
{
return(SCSI_ERROR);
SCSI_CloseDevice(DeviceFD);
return SCSI_ERROR;
}
- memset(&Command, 0, sizeof(struct uscsi_cmd));
- memset(pRequestSense, 0, RequestSenseLength);
+ memset(&Command, 0, SIZEOF(struct uscsi_cmd));
+ memset(RequestSense, 0, RequestSenseLength);
switch (Direction)
{
case Input:
/* Set timeout to 5 minutes. */
Command.uscsi_timeout = 300;
Command.uscsi_cdb = (caddr_t) CDB;
- Command.uscsi_cdblen = CDB_Length;
+ Command.uscsi_cdblen = (u_char)CDB_Length;
if (DataBufferLength > 0)
{
| USCSI_WRITE | USCSI_RQENABLE;
}
- Command.uscsi_rqbuf = (caddr_t) pRequestSense;
- Command.uscsi_rqlen = RequestSenseLength;
+ Command.uscsi_rqbuf = (caddr_t)RequestSense;
+ Command.uscsi_rqlen = (u_char)RequestSenseLength;
DecodeSCSI(CDB, "SCSI_ExecuteCommand : ");
while (retries > 0)
{
ret = Command.uscsi_status;
break;
}
- dbprintf(("ioctl on %d failed, errno %d, ret %d\n",pDev[DeviceFD].fd, errno, ret));
+ dbprintf(("ioctl on %d failed, errno %s, ret %d\n",
+ pDev[DeviceFD].fd, strerror(errno), ret));
#if 0
RequestSense(DeviceFD, &pExtendedRequestSense, 0);
#endif
- DecodeSense((RequestSense_T *)pRequestSense,
- "SCSI_ExecuteCommand:", debug_file);
+ DecodeSense(RequestSense, "SCSI_ExecuteCommand:", debug_file);
retries--;
}
--depth;
SCSI_CloseDevice(DeviceFD);
- switch (ret)
- {
- default:
- DebugPrint(DEBUG_INFO, SECTION_SCSI,"ioctl ret (%d)\n",ret);
- return(SCSI_OK);
- break;
- }
+ DebugPrint(DEBUG_INFO, SECTION_SCSI,"ioctl ret (%d)\n",ret);
+ return(SCSI_OK);
}
/*
if (ioctl(pDev[DeviceFD].fd , MTIOCTOP, &mtop) != 0)
{
- dbprintf(("Tape_Ioctl error ioctl %d\n",errno));
+ dbprintf(("Tape_Ioctl error ioctl %s\n", strerror(errno)));
SCSI_CloseDevice(DeviceFD);
return(-1);
}
struct mtget mtget;
int ret = -1;
+ memset(&mtget, 0, SIZEOF(mtget));
if (pDev[DeviceFD].devopen == 0)
if (SCSI_OpenDevice(DeviceFD) == 0)
return(-1);
if (ioctl(pDev[DeviceFD].fd , MTIOCGET, &mtget) != 0)
{
- dbprintf(("Tape_Status error ioctl %d\n",errno));
+ dbprintf(("Tape_Status error ioctl %s\n", strerror(errno)));
SCSI_CloseDevice(DeviceFD);
return(-1);
}
int ScanBus(int print)
{
+ (void)print; /* Quiet unused parameter warning */
return(-1);
}
#include <string.h>
#endif
-#include "scsi-defs.h"
+#include "scsi-defs.h"
/*
Handling of Sense codes which are returned from the device
At the moment the following status us returned
* Generic one, this is used if not information is found based on the ident of the device
*/
{ "generic", "", TYPE_TAPE, SENSE_NULL, 0x0, 0x0, SENSE_NO, "No Sense"},
- { "generic", "", TYPE_TAPE, SENSE_NULL , -1, -1, SENSE_RETRY, "Default for SENSE_NULL"},
+ { "generic", "", TYPE_TAPE, SENSE_NULL , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_NULL"},
{ "generic", "", TYPE_TAPE , SENSE_RECOVERED_ERROR, 0x0, 0x0, SENSE_IGNORE, "Recovered Error"},
- { "generic", "", TYPE_TAPE, SENSE_RECOVERED_ERROR , -1, -1, SENSE_RETRY, "Default for SENSE_RECOVERED_ERROR"},
+ { "generic", "", TYPE_TAPE, SENSE_RECOVERED_ERROR , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_RECOVERED_ERROR"},
{ "generic", "", TYPE_TAPE , SENSE_NOT_READY, 0x0, 0x0, SENSE_IGNORE, "Not Ready"},
{ "generic", "", TYPE_TAPE , SENSE_NOT_READY, 0x4, 0x1, SENSE_RETRY, "The drive is not ready, but it is in the process of becoming ready"},
{ "generic", "", TYPE_TAPE , SENSE_NOT_READY, 0x3A, 0x0, SENSE_TAPE_NOT_ONLINE, "No Tape online"},
- { "generic", "", TYPE_TAPE, SENSE_NOT_READY , -1, -1, SENSE_RETRY, "Default for SENSE_NOT_READY"},
+ { "generic", "", TYPE_TAPE, SENSE_NOT_READY , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_NOT_READY"},
{ "generic", "", TYPE_TAPE , SENSE_MEDIUM_ERROR, 0x0, 0x0, SENSE_ABORT, "Medium Error"},
- { "generic", "", TYPE_TAPE, SENSE_MEDIUM_ERROR , -1, -1, SENSE_ABORT, "Default for SENSE_MEDIUM_ERROR"},
+ { "generic", "", TYPE_TAPE, SENSE_MEDIUM_ERROR , UCHAR_MAX, UCHAR_MAX, SENSE_ABORT, "Default for SENSE_MEDIUM_ERROR"},
{ "generic", "", TYPE_TAPE , SENSE_HARDWARE_ERROR, 0x0, 0x0, SENSE_ABORT, "Hardware Error"},
- { "generic", "", TYPE_TAPE, SENSE_HARDWARE_ERROR , -1, -1, SENSE_ABORT, "Default for SENSE_HARDWARE_ERROR"},
+ { "generic", "", TYPE_TAPE, SENSE_HARDWARE_ERROR , UCHAR_MAX, UCHAR_MAX, SENSE_ABORT, "Default for SENSE_HARDWARE_ERROR"},
{ "generic", "", TYPE_TAPE , SENSE_ILLEGAL_REQUEST, 0x0, 0x0, SENSE_ABORT, "Illegal Request"},
- { "generic", "", TYPE_TAPE, SENSE_ILLEGAL_REQUEST , -1, -1, SENSE_ABORT, "Default for SENSE_ILLEGAL_REQUEST"},
+ { "generic", "", TYPE_TAPE, SENSE_ILLEGAL_REQUEST , UCHAR_MAX, UCHAR_MAX, SENSE_ABORT, "Default for SENSE_ILLEGAL_REQUEST"},
{ "generic", "", TYPE_TAPE , SENSE_UNIT_ATTENTION, 0x0, 0x0, SENSE_RETRY, "Unit Attention"},
- { "generic", "", TYPE_TAPE, SENSE_UNIT_ATTENTION, -1, -1, SENSE_ABORT, "Default for SENSE_UNIT_ATTENTION"},
+ { "generic", "", TYPE_TAPE, SENSE_UNIT_ATTENTION, UCHAR_MAX, UCHAR_MAX, SENSE_ABORT, "Default for SENSE_UNIT_ATTENTION"},
- { "generic", "", TYPE_TAPE , -1, 0x0, 0x0, SENSE_ABORT, "Nothing Found"},
+ { "generic", "", TYPE_TAPE , UCHAR_MAX, 0x0, 0x0, SENSE_ABORT, "Nothing Found"},
{ "generic", "", TYPE_CHANGER, SENSE_NULL, 0x0, 0x0, SENSE_NO, "No Sense"},
- { "generic", "", TYPE_CHANGER, SENSE_NULL , -1, -1, SENSE_RETRY, "Default for SENSE_NULL"},
+ { "generic", "", TYPE_CHANGER, SENSE_NULL , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_NULL"},
{ "generic", "", TYPE_CHANGER , SENSE_RECOVERED_ERROR, 0x0, 0x0, SENSE_IGNORE, "Recovered Error"},
- { "generic", "", TYPE_CHANGER, SENSE_RECOVERED_ERROR , -1, -1, SENSE_RETRY, "Default for SENSE_RECOVERED_ERROR"},
+ { "generic", "", TYPE_CHANGER, SENSE_RECOVERED_ERROR , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_RECOVERED_ERROR"},
{ "generic", "", TYPE_CHANGER , SENSE_NOT_READY, 0x0, 0x0, SENSE_IGNORE, "Not Ready"},
{ "generic", "", TYPE_CHANGER , SENSE_NOT_READY, 0x3A, 0x0, SENSE_TAPE_NOT_ONLINE, "No Tape online"},
- { "generic", "", TYPE_CHANGER, SENSE_NOT_READY , -1, -1, SENSE_RETRY, "Default for SENSE_NOT_READY"},
+ { "generic", "", TYPE_CHANGER, SENSE_NOT_READY , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_NOT_READY"},
{ "generic", "", TYPE_CHANGER , SENSE_MEDIUM_ERROR, 0x0, 0x0, SENSE_ABORT, "Medium Error"},
- { "generic", "", TYPE_CHANGER, SENSE_MEDIUM_ERROR , -1, -1, SENSE_ABORT, "Default for SENSE_MEDIUM_ERROR"},
+ { "generic", "", TYPE_CHANGER, SENSE_MEDIUM_ERROR , UCHAR_MAX, UCHAR_MAX, SENSE_ABORT, "Default for SENSE_MEDIUM_ERROR"},
{ "generic", "", TYPE_CHANGER , SENSE_HARDWARE_ERROR, 0x0, 0x0, SENSE_ABORT, "Hardware Error"},
- { "generic", "", TYPE_CHANGER, SENSE_HARDWARE_ERROR , -1, -1, SENSE_ABORT, "Default for SENSE_HARDWARE_ERROR"},
+ { "generic", "", TYPE_CHANGER, SENSE_HARDWARE_ERROR , UCHAR_MAX, UCHAR_MAX, SENSE_ABORT, "Default for SENSE_HARDWARE_ERROR"},
{ "generic", "", TYPE_CHANGER , SENSE_ILLEGAL_REQUEST, 0x0, 0x0, SENSE_ABORT, "Illegal Request"},
- { "generic", "", TYPE_CHANGER, SENSE_ILLEGAL_REQUEST , -1, -1, SENSE_ABORT, "Default for SENSE_ILLEGAL_REQUEST"},
+ { "generic", "", TYPE_CHANGER, SENSE_ILLEGAL_REQUEST , UCHAR_MAX, UCHAR_MAX, SENSE_ABORT, "Default for SENSE_ILLEGAL_REQUEST"},
{ "generic", "", TYPE_CHANGER , SENSE_UNIT_ATTENTION, 0x0, 0x0, SENSE_RETRY, "Unit Attention"},
- { "generic", "", TYPE_CHANGER, SENSE_UNIT_ATTENTION, -1, -1, SENSE_ABORT, "Default for SENSE_UNIT_ATTENTION"},
+ { "generic", "", TYPE_CHANGER, SENSE_UNIT_ATTENTION, UCHAR_MAX, UCHAR_MAX, SENSE_ABORT, "Default for SENSE_UNIT_ATTENTION"},
- { "generic", "", TYPE_CHANGER, SENSE_CHG_ELEMENT_STATUS, -1, -1, SENSE_IGNORE, "Default for SENSE_CHG_ELEMENT_STATUS"},
+ { "generic", "", TYPE_CHANGER, SENSE_CHG_ELEMENT_STATUS, UCHAR_MAX, UCHAR_MAX, SENSE_IGNORE, "Default for SENSE_CHG_ELEMENT_STATUS"},
- { "generic", "", TYPE_CHANGER , -1, 0x0, 0x0, SENSE_ABORT, "Nothing Found"},
-/*
+ { "generic", "", TYPE_CHANGER , UCHAR_MAX, 0x0, 0x0, SENSE_ABORT, "Nothing Found"},
+/*
*
* ADIC DAT Autochanger
*
*/
{ "DAT AutoChanger", "", TYPE_CHANGER, SENSE_NULL, 0x0, 0x0, SENSE_NO, "No Sense"},
- { "DAT AutoChanger", "", TYPE_CHANGER, SENSE_NULL , -1, -1, SENSE_RETRY, "Default for SENSE_NULL"},
+ { "DAT AutoChanger", "", TYPE_CHANGER, SENSE_NULL , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_NULL"},
{ "DAT AutoChanger", "", TYPE_CHANGER , SENSE_RECOVERED_ERROR, 0x0, 0x0, SENSE_IGNORE, "Recovered Error"},
- { "DAT AutoChanger", "", TYPE_CHANGER, SENSE_RECOVERED_ERROR , -1, -1, SENSE_RETRY, "Default for SENSE_RECOVERED_ERROR"},
+ { "DAT AutoChanger", "", TYPE_CHANGER, SENSE_RECOVERED_ERROR , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_RECOVERED_ERROR"},
{ "DAT AutoChanger", "", TYPE_CHANGER , SENSE_NOT_READY, 0x0, 0x0, SENSE_IGNORE, "Not Ready"},
- { "DAT AutoChanger", "", TYPE_CHANGER, SENSE_NOT_READY , -1, -1, SENSE_RETRY, "Default for SENSE_NOT_READY"},
+ { "DAT AutoChanger", "", TYPE_CHANGER, SENSE_NOT_READY , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_NOT_READY"},
{ "DAT AutoChanger", "", TYPE_CHANGER , SENSE_MEDIUM_ERROR, 0x0, 0x0, SENSE_ABORT, "Medium Error"},
- { "DAT AutoChanger", "", TYPE_CHANGER, SENSE_MEDIUM_ERROR , -1, -1, SENSE_ABORT, "Default for SENSE_MEDIUM_ERROR"},
+ { "DAT AutoChanger", "", TYPE_CHANGER, SENSE_MEDIUM_ERROR , UCHAR_MAX, UCHAR_MAX, SENSE_ABORT, "Default for SENSE_MEDIUM_ERROR"},
{ "DAT AutoChanger", "", TYPE_CHANGER , SENSE_HARDWARE_ERROR, 0x0, 0x0, SENSE_ABORT, "Hardware Error"},
- { "DAT AutoChanger", "", TYPE_CHANGER, SENSE_HARDWARE_ERROR , -1, -1, SENSE_ABORT, "Default for SENSE_HARDWARE_ERROR"},
+ { "DAT AutoChanger", "", TYPE_CHANGER, SENSE_HARDWARE_ERROR , UCHAR_MAX, UCHAR_MAX, SENSE_ABORT, "Default for SENSE_HARDWARE_ERROR"},
{ "DAT AutoChanger", "", TYPE_CHANGER , SENSE_ILLEGAL_REQUEST, 0x0, 0x0, SENSE_ABORT, "Illegal Request"},
- { "DAT AutoChanger", "", TYPE_CHANGER, SENSE_ILLEGAL_REQUEST , -1, -1, SENSE_ABORT, "Default for SENSE_ILLEGAL_REQUEST"},
+ { "DAT AutoChanger", "", TYPE_CHANGER, SENSE_ILLEGAL_REQUEST , UCHAR_MAX, UCHAR_MAX, SENSE_ABORT, "Default for SENSE_ILLEGAL_REQUEST"},
{ "DAT AutoChanger", "", TYPE_CHANGER , SENSE_UNIT_ATTENTION, 0x0, 0x0, SENSE_RETRY, "Unit Attention"},
{ "DAT AutoChanger", "", TYPE_CHANGER , SENSE_UNIT_ATTENTION, 0x28, 0x01, SENSE_IES, "Door opend"},
- { "DAT AutoChanger", "", TYPE_CHANGER, SENSE_UNIT_ATTENTION, -1, -1, SENSE_ABORT, "Default for SENSE_UNIT_ATTENTION"},
+ { "DAT AutoChanger", "", TYPE_CHANGER, SENSE_UNIT_ATTENTION, UCHAR_MAX, UCHAR_MAX, SENSE_ABORT, "Default for SENSE_UNIT_ATTENTION"},
- { "DAT AutoChanger", "", TYPE_CHANGER, SENSE_CHG_ELEMENT_STATUS, -1, -1, SENSE_IGNORE, "Default for SENSE_CHG_ELEMENT_STATUS"},
+ { "DAT AutoChanger", "", TYPE_CHANGER, SENSE_CHG_ELEMENT_STATUS, UCHAR_MAX, UCHAR_MAX, SENSE_IGNORE, "Default for SENSE_CHG_ELEMENT_STATUS"},
- { "DAT AutoChanger", "", TYPE_CHANGER , -1, 0x0, 0x0, SENSE_ABORT, "Nothing Found"},
+ { "DAT AutoChanger", "", TYPE_CHANGER , UCHAR_MAX, 0x0, 0x0, SENSE_ABORT, "Nothing Found"},
/*
*
* L500 (for the L500 ATL library)
* */
-
+
{ "L500", "", TYPE_CHANGER, SENSE_NULL, 0x0, 0x0, SENSE_NO, "No Sense"},
- { "L500", "", TYPE_CHANGER, SENSE_NULL , -1, -1, SENSE_RETRY, "Default for SENSE_NULL"},
+ { "L500", "", TYPE_CHANGER, SENSE_NULL , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_NULL"},
{ "L500", "", TYPE_CHANGER , SENSE_RECOVERED_ERROR, 0x0, 0x0, SENSE_IGNORE, "Recovered Error"},
{ "L500", "", TYPE_CHANGER , SENSE_RECOVERED_ERROR, 0x0a, 0x0, SENSE_IGNORE, "Error Log overflow"},
{ "L500", "", TYPE_CHANGER , SENSE_RECOVERED_ERROR, 0x44, 0xc2, SENSE_IGNORE, "EEPROM Copy 2 bad"},
{ "L500", "", TYPE_CHANGER , SENSE_RECOVERED_ERROR, 0x47, 0x0, SENSE_IGNORE, "SCSI parity error"},
{ "L500", "", TYPE_CHANGER , SENSE_RECOVERED_ERROR, 0x48, 0x0, SENSE_IGNORE, "SCSI IDE message received"},
- { "L500", "", TYPE_CHANGER, SENSE_RECOVERED_ERROR , -1, -1, SENSE_RETRY, "Default for SENSE_RECOVERED_ERROR"},
+ { "L500", "", TYPE_CHANGER, SENSE_RECOVERED_ERROR , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_RECOVERED_ERROR"},
{ "L500", "", TYPE_CHANGER , SENSE_NOT_READY, 0x0, 0x0, SENSE_ABORT, "Scsi port not initialized"},
{ "L500", "", TYPE_CHANGER , SENSE_NOT_READY, 0x04, 0x01, SENSE_RETRY, "Becoming ready, scanning magazines, etc"},
{ "L500", "", TYPE_CHANGER , SENSE_NOT_READY, 0x04, 0x03, SENSE_ABORT, "Unit not ready: manual intervention required: Door Open"},
/* needed? */
{ "L500", "", TYPE_CHANGER , SENSE_NOT_READY, 0x3A, 0x0, SENSE_TAPE_NOT_ONLINE, "No Tape online"},
- { "L500", "", TYPE_CHANGER, SENSE_NOT_READY , -1, -1, SENSE_RETRY, "Default for SENSE_NOT_READY"},
+ { "L500", "", TYPE_CHANGER, SENSE_NOT_READY , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_NOT_READY"},
/* Not used by L500
{ "L500", "", TYPE_CHANGER , SENSE_MEDIUM_ERROR, 0x0, 0x0, SENSE_ABORT, "Medium Error"},
- { "L500", "", TYPE_CHANGER, SENSE_MEDIUM_ERROR , -1, -1, SENSE_ABORT, "Default for SENSE_MEDIUM_ERROR"},
+ { "L500", "", TYPE_CHANGER, SENSE_MEDIUM_ERROR , UCHAR_MAX, UCHAR_MAX, SENSE_ABORT, "Default for SENSE_MEDIUM_ERROR"},
*/
{ "L500", "", TYPE_CHANGER , SENSE_HARDWARE_ERROR, 0x0, 0x0, SENSE_ABORT, "Hardware Error"},
{ "L500", "", TYPE_CHANGER , SENSE_HARDWARE_ERROR, 0x3a, 0x80, SENSE_ABORT, "Media not present"},
{ "L500", "", TYPE_CHANGER , SENSE_HARDWARE_ERROR, 0x80, 0x83, SENSE_ABORT, "Slot empty during LOAD CARTRIDGE"},
{ "L500", "", TYPE_CHANGER , SENSE_HARDWARE_ERROR, 0x80, 0x84, SENSE_ABORT, "Cleaning Tape expired"},
{ "L500", "", TYPE_CHANGER , SENSE_HARDWARE_ERROR, 0x80, 0x85, SENSE_ABORT, "Cleaning Failed"},
- { "L500", "", TYPE_CHANGER, SENSE_HARDWARE_ERROR, -1, -1, SENSE_ABORT, "Default for SENSE_HARDWARE_ERROR"},
+ { "L500", "", TYPE_CHANGER, SENSE_HARDWARE_ERROR, UCHAR_MAX, UCHAR_MAX, SENSE_ABORT, "Default for SENSE_HARDWARE_ERROR"},
{ "L500", "", TYPE_CHANGER , SENSE_ILLEGAL_REQUEST, 0x0, 0x0, SENSE_ABORT, "Illegal Request"},
{ "L500", "", TYPE_CHANGER , SENSE_ILLEGAL_REQUEST, 0x1a, 0x0, SENSE_ABORT, "Parameter length error"},
{ "L500", "", TYPE_CHANGER , SENSE_ILLEGAL_REQUEST, 0x53, 0x01, SENSE_ABORT, "Cartridge failed to unload"},
{ "L500", "", TYPE_CHANGER , SENSE_ILLEGAL_REQUEST, 0xf1, 0x0, SENSE_ABORT, "Command unspecified"},
{ "L500", "", TYPE_CHANGER , SENSE_ILLEGAL_REQUEST, 0xf1, 0x02, SENSE_ABORT, "Unrecognized loader command"},
- { "L500", "", TYPE_CHANGER, SENSE_ILLEGAL_REQUEST , -1, -1, SENSE_ABORT, "Default for SENSE_ILLEGAL_REQUEST"},
+ { "L500", "", TYPE_CHANGER, SENSE_ILLEGAL_REQUEST , UCHAR_MAX, UCHAR_MAX, SENSE_ABORT, "Default for SENSE_ILLEGAL_REQUEST"},
{ "L500", "", TYPE_CHANGER , SENSE_UNIT_ATTENTION, 0x0, 0x0, SENSE_RETRY, "Unit Attention"},
{ "L500", "", TYPE_CHANGER , SENSE_UNIT_ATTENTION, 0x28, 0x0, SENSE_RETRY, "Not ready to Ready transition"},
{ "L500", "", TYPE_CHANGER , SENSE_UNIT_ATTENTION, 0x29, 0x0, SENSE_RETRY, "Reset occured"},
{ "L500", "", TYPE_CHANGER , SENSE_UNIT_ATTENTION, 0x2a, 0x01, SENSE_ABORT, "Mode parameters changed"},
{ "L500", "", TYPE_CHANGER , SENSE_UNIT_ATTENTION, 0x3f, 0x01, SENSE_ABORT, "Microcode has changed"},
- { "L500", "", TYPE_CHANGER, SENSE_UNIT_ATTENTION, -1, -1, SENSE_ABORT, "Default for SENSE_UNIT_ATTENTION"},
+ { "L500", "", TYPE_CHANGER, SENSE_UNIT_ATTENTION, UCHAR_MAX, UCHAR_MAX, SENSE_ABORT, "Default for SENSE_UNIT_ATTENTION"},
/* Not used by L500
- { "L500", "", TYPE_CHANGER, SENSE_CHG_ELEMENT_STATUS, -1, -1, SENSE_IGNORE, "Default for SENSE_CHG_ELEMENT_STATUS"},
+ { "L500", "", TYPE_CHANGER, SENSE_CHG_ELEMENT_STATUS, UCHAR_MAX, UCHAR_MAX, SENSE_IGNORE, "Default for SENSE_CHG_ELEMENT_STATUS"},
*/
{ "L500", "", TYPE_CHANGER, SENSE_ABORTED_COMMAND, 0x43, 0x0, SENSE_ABORT, "SCSI message error"},
{ "L500", "", TYPE_CHANGER, SENSE_ABORTED_COMMAND, 0x47, 0x0, SENSE_ABORT, "SCSI parity error"},
{ "L500", "", TYPE_CHANGER, SENSE_ABORTED_COMMAND, 0x48, 0x0, SENSE_ABORT, "SCSI IDE message received"},
{ "L500", "", TYPE_CHANGER, SENSE_ABORTED_COMMAND, 0x49, 0x0, SENSE_ABORT, "SCSI invalid message"},
{ "L500", "", TYPE_CHANGER, SENSE_ABORTED_COMMAND, 0x4e, 0x0, SENSE_ABORT, "SCSI overlapped commands"},
-
- { "L500", "", TYPE_CHANGER, SENSE_ABORTED_COMMAND, -1, -1, SENSE_ABORT, "Default for SENSE_ABORTED_COMMAND"},
- { "L500", "", TYPE_CHANGER , -1, 0x0, 0x0, SENSE_ABORT, "Nothing Found"},
+
+ { "L500", "", TYPE_CHANGER, SENSE_ABORTED_COMMAND, UCHAR_MAX, UCHAR_MAX, SENSE_ABORT, "Default for SENSE_ABORTED_COMMAND"},
+ { "L500", "", TYPE_CHANGER , UCHAR_MAX, 0x0, 0x0, SENSE_ABORT, "Nothing Found"},
/*
* HP C1553A Tape
*/
{ "C1553A", "", TYPE_TAPE, SENSE_NULL, 0x0, 0x0, SENSE_NO, "No Sense"},
- { "C1553A", "", TYPE_TAPE, SENSE_NULL , -1, -1, SENSE_RETRY, "Default for SENSE_NULL"},
+ { "C1553A", "", TYPE_TAPE, SENSE_NULL , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_NULL"},
{ "C1553A", "", TYPE_TAPE , SENSE_RECOVERED_ERROR, 0x0, 0x0, SENSE_IGNORE, "Recovered Error"},
- { "C1553A", "", TYPE_TAPE, SENSE_RECOVERED_ERROR , -1, -1, SENSE_RETRY, "Default for SENSE_RECOVERED_ERROR"},
+ { "C1553A", "", TYPE_TAPE, SENSE_RECOVERED_ERROR , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_RECOVERED_ERROR"},
{ "C1553A", "", TYPE_TAPE , SENSE_NOT_READY, 0x0, 0x0, SENSE_IGNORE, "Not Ready"},
{ "C1553A", "", TYPE_TAPE , SENSE_NOT_READY, 0x3A, 0x0, SENSE_TAPE_NOT_ONLINE, "No Tape online"},
- { "C1553A", "", TYPE_TAPE, SENSE_NOT_READY , -1, -1, SENSE_RETRY, "Default for SENSE_NOT_READY"},
+ { "C1553A", "", TYPE_TAPE, SENSE_NOT_READY , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_NOT_READY"},
{ "C1553A", "", TYPE_TAPE , SENSE_MEDIUM_ERROR, 0x0, 0x0, SENSE_ABORT, "Medium Error"},
- { "C1553A", "", TYPE_TAPE, SENSE_MEDIUM_ERROR , -1, -1, SENSE_ABORT, "Default for SENSE_MEDIUM_ERROR"},
+ { "C1553A", "", TYPE_TAPE, SENSE_MEDIUM_ERROR , UCHAR_MAX, UCHAR_MAX, SENSE_ABORT, "Default for SENSE_MEDIUM_ERROR"},
{ "C1553A", "", TYPE_TAPE , SENSE_HARDWARE_ERROR, 0x0, 0x0, SENSE_ABORT, "Hardware Error"},
- { "C1553A", "", TYPE_TAPE, SENSE_HARDWARE_ERROR , -1, -1, SENSE_ABORT, "Default for SENSE_HARDWARE_ERROR"},
+ { "C1553A", "", TYPE_TAPE, SENSE_HARDWARE_ERROR , UCHAR_MAX, UCHAR_MAX, SENSE_ABORT, "Default for SENSE_HARDWARE_ERROR"},
{ "C1553A", "", TYPE_TAPE , SENSE_ILLEGAL_REQUEST, 0x0, 0x0, SENSE_ABORT, "Illegal Request"},
- { "C1553A", "", TYPE_TAPE, SENSE_ILLEGAL_REQUEST , -1, -1, SENSE_ABORT, "Default for SENSE_ILLEGAL_REQUEST"},
+ { "C1553A", "", TYPE_TAPE, SENSE_ILLEGAL_REQUEST , UCHAR_MAX, UCHAR_MAX, SENSE_ABORT, "Default for SENSE_ILLEGAL_REQUEST"},
{ "C1553A", "", TYPE_TAPE , SENSE_UNIT_ATTENTION, 0x0, 0x0, SENSE_RETRY, "Unit Attention"},
- { "C1553A", "", TYPE_TAPE, SENSE_UNIT_ATTENTION , -1, -1, SENSE_RETRY, "Default for SENSE_UNIT_ATTENTION"},
+ { "C1553A", "", TYPE_TAPE, SENSE_UNIT_ATTENTION , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_UNIT_ATTENTION"},
- { "C1553A", "", TYPE_TAPE , -1, 0x0, 0x0, SENSE_ABORT, "Nothing Found"},
+ { "C1553A", "", TYPE_TAPE , UCHAR_MAX, 0x0, 0x0, SENSE_ABORT, "Nothing Found"},
{ "C1553A", "", TYPE_CHANGER, SENSE_NULL, 0x0, 0x0, SENSE_NO, "No Sense"},
- { "C1553A", "", TYPE_CHANGER, SENSE_NULL , -1, -1, SENSE_RETRY, "Default for SENSE_NULL"},
+ { "C1553A", "", TYPE_CHANGER, SENSE_NULL , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_NULL"},
{ "C1553A", "", TYPE_CHANGER , SENSE_RECOVERED_ERROR, 0x0, 0x0, SENSE_IGNORE, "Recovered Error"},
- { "C1553A", "", TYPE_CHANGER, SENSE_RECOVERED_ERROR , -1, -1, SENSE_RETRY, "Default for SENSE_RECOVERED_ERROR"},
+ { "C1553A", "", TYPE_CHANGER, SENSE_RECOVERED_ERROR , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_RECOVERED_ERROR"},
{ "C1553A", "", TYPE_CHANGER , SENSE_NOT_READY, 0x0, 0x0, SENSE_IGNORE, "Not Ready"},
{ "C1553A", "", TYPE_CHANGER , SENSE_NOT_READY, 0x3A, 0x0, SENSE_TAPE_NOT_ONLINE, "No Tape online"},
- { "C1553A", "", TYPE_CHANGER, SENSE_NOT_READY , -1, -1, SENSE_RETRY, "Default for SENSE_NOT_READY"},
+ { "C1553A", "", TYPE_CHANGER, SENSE_NOT_READY , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_NOT_READY"},
{ "C1553A", "", TYPE_CHANGER , SENSE_MEDIUM_ERROR, 0x0, 0x0, SENSE_ABORT, "Medium Error"},
- { "C1553A", "", TYPE_CHANGER, SENSE_MEDIUM_ERROR , -1, -1, SENSE_ABORT, "Default for SENSE_MEDIUM_ERROR"},
+ { "C1553A", "", TYPE_CHANGER, SENSE_MEDIUM_ERROR , UCHAR_MAX, UCHAR_MAX, SENSE_ABORT, "Default for SENSE_MEDIUM_ERROR"},
{ "C1553A", "", TYPE_CHANGER , SENSE_HARDWARE_ERROR, 0x0, 0x0, SENSE_ABORT, "Hardware Error"},
- { "C1553A", "", TYPE_CHANGER, SENSE_HARDWARE_ERROR , -1, -1, SENSE_ABORT, "Default for SENSE_HARDWARE_ERROR"},
+ { "C1553A", "", TYPE_CHANGER, SENSE_HARDWARE_ERROR , UCHAR_MAX, UCHAR_MAX, SENSE_ABORT, "Default for SENSE_HARDWARE_ERROR"},
{ "C1553A", "", TYPE_CHANGER , SENSE_ILLEGAL_REQUEST, 0x0, 0x0, SENSE_ABORT, "Illegal Request"},
- { "C1553A", "", TYPE_CHANGER, SENSE_ILLEGAL_REQUEST , -1, -1, SENSE_ABORT, "Default for SENSE_ILLEGAL_REQUEST"},
-
+ { "C1553A", "", TYPE_CHANGER, SENSE_ILLEGAL_REQUEST , UCHAR_MAX, UCHAR_MAX, SENSE_ABORT, "Default for SENSE_ILLEGAL_REQUEST"},
+
{ "C1553A", "", TYPE_CHANGER , SENSE_UNIT_ATTENTION, 0x0, 0x0, SENSE_RETRY, "Unit Attention"},
- { "C1553A", "", TYPE_CHANGER, SENSE_UNIT_ATTENTION , -1, -1, SENSE_RETRY, "Default for SENSE_UNIT_ATTENTION"},
-
- { "C1553A", "", TYPE_CHANGER, SENSE_CHG_ELEMENT_STATUS, -1, -1, SENSE_IGNORE, "Default for SENSE_CHG_ELEMENT_STATUS"},
+ { "C1553A", "", TYPE_CHANGER, SENSE_UNIT_ATTENTION , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_UNIT_ATTENTION"},
- { "C1553A", "", TYPE_CHANGER , -1, 0x0, 0x0, SENSE_ABORT, "Nothing Found"},
+ { "C1553A", "", TYPE_CHANGER, SENSE_CHG_ELEMENT_STATUS, UCHAR_MAX, UCHAR_MAX, SENSE_IGNORE, "Default for SENSE_CHG_ELEMENT_STATUS"},
+
+ { "C1553A", "", TYPE_CHANGER , UCHAR_MAX, 0x0, 0x0, SENSE_ABORT, "Nothing Found"},
/*
* HP C1537A Tape
*/
{ "C1537A", "", TYPE_TAPE, SENSE_NULL, 0x0, 0x0, SENSE_NO, "No Sense"},
- { "C1537A", "", TYPE_TAPE, SENSE_NULL , -1, -1, SENSE_RETRY, "Default for SENSE_NULL"},
+ { "C1537A", "", TYPE_TAPE, SENSE_NULL , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_NULL"},
{ "C1537A", "", TYPE_TAPE , SENSE_RECOVERED_ERROR, 0x0, 0x0, SENSE_IGNORE, "Recovered Error"},
- { "C1537A", "", TYPE_TAPE, SENSE_RECOVERED_ERROR , -1, -1, SENSE_RETRY, "Default for SENSE_RECOVERED_ERROR"},
+ { "C1537A", "", TYPE_TAPE, SENSE_RECOVERED_ERROR , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_RECOVERED_ERROR"},
{ "C1537A", "", TYPE_TAPE , SENSE_NOT_READY, 0x0, 0x0, SENSE_IGNORE, "Not Ready"},
{ "C1537A", "", TYPE_TAPE , SENSE_NOT_READY, 0x3A, 0x0, SENSE_TAPE_NOT_ONLINE, "No Tape online"},
{ "C1537A", "", TYPE_TAPE , SENSE_NOT_READY, 0x04, 0x0, SENSE_RETRY, "tape is being ejected"},
{ "C1537A", "", TYPE_TAPE , SENSE_NOT_READY, 0x04, 0x01, SENSE_RETRY, "tape is being loaded"},
- { "C1537A", "", TYPE_TAPE, SENSE_NOT_READY , -1, -1, SENSE_RETRY, "Default for SENSE_NOT_READY"},
+ { "C1537A", "", TYPE_TAPE, SENSE_NOT_READY , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_NOT_READY"},
{ "C1537A", "", TYPE_TAPE , SENSE_MEDIUM_ERROR, 0x0, 0x0, SENSE_ABORT, "Medium Error"},
- { "C1537A", "", TYPE_TAPE, SENSE_MEDIUM_ERROR , -1, -1, SENSE_ABORT, "Default for SENSE_MEDIUM_ERROR"},
+ { "C1537A", "", TYPE_TAPE, SENSE_MEDIUM_ERROR , UCHAR_MAX, UCHAR_MAX, SENSE_ABORT, "Default for SENSE_MEDIUM_ERROR"},
{ "C1537A", "", TYPE_TAPE , SENSE_HARDWARE_ERROR, 0x0, 0x0, SENSE_ABORT, "Hardware Error"},
- { "C1537A", "", TYPE_TAPE, SENSE_HARDWARE_ERROR , -1, -1, SENSE_ABORT, "Default for SENSE_HARDWARE_ERROR"},
+ { "C1537A", "", TYPE_TAPE, SENSE_HARDWARE_ERROR , UCHAR_MAX, UCHAR_MAX, SENSE_ABORT, "Default for SENSE_HARDWARE_ERROR"},
{ "C1537A", "", TYPE_TAPE , SENSE_ILLEGAL_REQUEST, 0x0, 0x0, SENSE_ABORT, "Illegal Request"},
- { "C1537A", "", TYPE_TAPE, SENSE_ILLEGAL_REQUEST , -1, -1, SENSE_ABORT, "Default for SENSE_ILLEGAL_REQUEST"},
-
+ { "C1537A", "", TYPE_TAPE, SENSE_ILLEGAL_REQUEST , UCHAR_MAX, UCHAR_MAX, SENSE_ABORT, "Default for SENSE_ILLEGAL_REQUEST"},
+
{ "C1537A", "", TYPE_TAPE , SENSE_UNIT_ATTENTION, 0x0, 0x0, SENSE_RETRY, "Unit Attention"},
{ "C1537A", "", TYPE_TAPE , SENSE_UNIT_ATTENTION, 0x28, 0x0, SENSE_RETRY, "Not Ready to Ready Transition"},
- { "C1537A", "", TYPE_TAPE, SENSE_UNIT_ATTENTION , -1, -1, SENSE_ABORT, "Default for SENSE_UNIT_ATTENTION"},
-
- { "C1537A", "", TYPE_TAPE, SENSE_CHG_ELEMENT_STATUS, -1, -1, SENSE_IGNORE, "Default for SENSE_CHG_ELEMENT_STATUS"},
+ { "C1537A", "", TYPE_TAPE, SENSE_UNIT_ATTENTION , UCHAR_MAX, UCHAR_MAX, SENSE_ABORT, "Default for SENSE_UNIT_ATTENTION"},
+
+ { "C1537A", "", TYPE_TAPE, SENSE_CHG_ELEMENT_STATUS, UCHAR_MAX, UCHAR_MAX, SENSE_IGNORE, "Default for SENSE_CHG_ELEMENT_STATUS"},
- { "C1537A", "", TYPE_TAPE , -1, 0x0, 0x0, SENSE_ABORT, "Nothing Found"},
+ { "C1537A", "", TYPE_TAPE , UCHAR_MAX, 0x0, 0x0, SENSE_ABORT, "Nothing Found"},
/*
* Tandberg Tape
*/
{ "TDS 1420", "", TYPE_TAPE, SENSE_NULL, 0x0, 0x0, SENSE_NO, "No Sense"},
- { "TDS 1420", "", TYPE_TAPE, SENSE_NULL , -1, -1, SENSE_RETRY, "Default for SENSE_NULL"},
+ { "TDS 1420", "", TYPE_TAPE, SENSE_NULL , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_NULL"},
{ "TDS 1420", "", TYPE_TAPE, SENSE_IES, 0x83, 0x0, SENSE_IES, "IES"},
{ "TDS 1420", "", TYPE_TAPE, SENSE_IES, 0x83, 0x1, SENSE_IES, "IES"},
{ "TDS 1420", "", TYPE_TAPE, SENSE_IES, 0x83, 0x4, SENSE_IGNORE, "IES"},
{ "TDS 1420", "", TYPE_TAPE, SENSE_RECOVERED_ERROR, 0x0, 0x0, SENSE_IGNORE, "Recovered Error"},
- { "TDS 1420", "", TYPE_TAPE, SENSE_RECOVERED_ERROR , -1, -1, SENSE_RETRY, "Default for SENSE_RECOVERED_ERROR"},
+ { "TDS 1420", "", TYPE_TAPE, SENSE_RECOVERED_ERROR , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_RECOVERED_ERROR"},
{ "TDS 1420", "", TYPE_TAPE, SENSE_NOT_READY, 0x0, 0x0, SENSE_IGNORE, "Not Ready"},
{ "TDS 1420", "", TYPE_TAPE, SENSE_NOT_READY, 0x3A, 0x0, SENSE_TAPE_NOT_ONLINE, "No Tape online"},
- { "TDS 1420", "", TYPE_TAPE, SENSE_NOT_READY , -1, -1, SENSE_RETRY, "Default for SENSE_NOT_READY"},
+ { "TDS 1420", "", TYPE_TAPE, SENSE_NOT_READY , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_NOT_READY"},
{ "TDS 1420", "", TYPE_TAPE, SENSE_MEDIUM_ERROR, 0x0, 0x0, SENSE_ABORT, "Medium Error"},
- { "TDS 1420", "", TYPE_TAPE, SENSE_MEDIUM_ERROR , -1, -1, SENSE_ABORT, "Default for SENSE_MEDIUM_ERROR"},
+ { "TDS 1420", "", TYPE_TAPE, SENSE_MEDIUM_ERROR , UCHAR_MAX, UCHAR_MAX, SENSE_ABORT, "Default for SENSE_MEDIUM_ERROR"},
{ "TDS 1420", "", TYPE_TAPE, SENSE_HARDWARE_ERROR, 0x0, 0x0, SENSE_ABORT, "Hardware Error"},
- { "TDS 1420", "", TYPE_TAPE, SENSE_HARDWARE_ERROR , -1, -1, SENSE_ABORT, "Default for SENSE_HARDWARE_ERROR"},
+ { "TDS 1420", "", TYPE_TAPE, SENSE_HARDWARE_ERROR , UCHAR_MAX, UCHAR_MAX, SENSE_ABORT, "Default for SENSE_HARDWARE_ERROR"},
{ "TDS 1420", "", TYPE_TAPE, SENSE_ILLEGAL_REQUEST, 0x0, 0x0, SENSE_ABORT, "Illegal Request"},
- { "TDS 1420", "", TYPE_TAPE, SENSE_ILLEGAL_REQUEST , -1, -1, SENSE_ABORT, "Default for SENSE_ILLEGAL_REQUEST"},
-
+ { "TDS 1420", "", TYPE_TAPE, SENSE_ILLEGAL_REQUEST , UCHAR_MAX, UCHAR_MAX, SENSE_ABORT, "Default for SENSE_ILLEGAL_REQUEST"},
+
{ "TDS 1420", "", TYPE_TAPE, SENSE_UNIT_ATTENTION, 0x0, 0x0, SENSE_RETRY, "Unit Attention"},
- { "TDS 1420", "", TYPE_TAPE, SENSE_UNIT_ATTENTION , -1, -1, SENSE_RETRY, "Default for SENSE_UNIT_ATTENTION"},
-
- { "TDS 1420", "", TYPE_TAPE, -1, 0x0, 0x0, SENSE_ABORT, "Nothing Found"},
+ { "TDS 1420", "", TYPE_TAPE, SENSE_UNIT_ATTENTION , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_UNIT_ATTENTION"},
+
+ { "TDS 1420", "", TYPE_TAPE, UCHAR_MAX, 0x0, 0x0, SENSE_ABORT, "Nothing Found"},
/*
* DLT 8000 Tape
- *
- * */
+ */
{ "DLT8000", "QUANTUM", TYPE_TAPE, SENSE_NULL, 0x0, 0x0, SENSE_NO, "No Sense"},
{ "DLT8000", "QUANTUM", TYPE_TAPE, SENSE_NULL, 0x0, 0x01, SENSE_NO, "Unexpected FM encountered"},
{ "DLT8000", "QUANTUM", TYPE_TAPE, SENSE_NULL, 0x0, 0x02, SENSE_NO, "EOM encountered"},
{ "DLT8000", "QUANTUM", TYPE_TAPE, SENSE_NULL, 0x0, 0x04, SENSE_NO, "BOM encountered"},
{ "DLT8000", "QUANTUM", TYPE_TAPE, SENSE_NULL, 0x5d, 0x00, SENSE_NO, "Failure prediction threshold exceeded"},
{ "DLT8000", "QUANTUM", TYPE_TAPE, SENSE_NULL, 0x27, 0x82, SENSE_NO, "Data safety write protect"},
- { "DLT8000", "QUANTUM", TYPE_TAPE, SENSE_NULL , -1, -1, SENSE_RETRY, "Default for SENSE_NULL"},
+ { "DLT8000", "QUANTUM", TYPE_TAPE, SENSE_NULL , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_NULL"},
{ "DLT8000", "QUANTUM", TYPE_TAPE , SENSE_RECOVERED_ERROR, 0x0, 0x0, SENSE_IGNORE, "Recovered Error"},
{ "DLT8000", "QUANTUM", TYPE_TAPE , SENSE_RECOVERED_ERROR, 0x0, 0x17, SENSE_IGNORE, "Cleaning requested"},
{ "DLT8000", "QUANTUM", TYPE_TAPE , SENSE_RECOVERED_ERROR, 0x80, 0x02, SENSE_IGNORE, "Cleaning requested"},
{ "DLT8000", "QUANTUM", TYPE_TAPE , SENSE_RECOVERED_ERROR, 0x80, 0x03, SENSE_IGNORE, "Softe error exceeds threshold"},
/* { "DLT8000", "QUANTUM", TYPE_TAPE , SENSE_RECOVERED_ERROR, 0x47, 0x0, SENSE_IGNORE, "Scsi Parity Error"}, */
- { "DLT8000", "QUANTUM", TYPE_TAPE, SENSE_RECOVERED_ERROR , -1, -1, SENSE_RETRY, "Default for SENSE_RECOVERED_ERROR"},
+ { "DLT8000", "QUANTUM", TYPE_TAPE, SENSE_RECOVERED_ERROR , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_RECOVERED_ERROR"},
{ "DLT8000", "QUANTUM", TYPE_TAPE , SENSE_NOT_READY, 0x0, 0x0, SENSE_IGNORE, "Not Ready (this shouldn't happen should it?)"},
{ "DLT8000", "QUANTUM", TYPE_TAPE , SENSE_NOT_READY, 0x4, 0x1, SENSE_RETRY, "The drive is not ready, but it is in the process of becoming ready"},
{ "DLT8000", "QUANTUM", TYPE_TAPE , SENSE_NOT_READY, 0x30,0x02, SENSE_ABORT, "Incompatible tape format"},
{ "DLT8000", "QUANTUM", TYPE_TAPE , SENSE_NOT_READY, 0x30,0x03, SENSE_ABORT, "Cleaning Cartridge in drive"},
{ "DLT8000", "QUANTUM", TYPE_TAPE , SENSE_NOT_READY, 0x3A, 0x0, SENSE_TAPE_NOT_ONLINE, "No Tape online"},
{ "DLT8000", "QUANTUM", TYPE_TAPE , SENSE_NOT_READY, 0x5a,0x01, SENSE_ABORT, "Asynchronous eject occurred"},
- { "DLT8000", "QUANTUM", TYPE_TAPE, SENSE_NOT_READY , -1, -1, SENSE_RETRY, "Default for SENSE_NOT_READY"},
+ { "DLT8000", "QUANTUM", TYPE_TAPE, SENSE_NOT_READY , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_NOT_READY"},
{ "DLT8000", "QUANTUM", TYPE_TAPE , SENSE_MEDIUM_ERROR, 0x0, 0x0, SENSE_ABORT, "Medium Error"},
- { "DLT8000", "QUANTUM", TYPE_TAPE, SENSE_MEDIUM_ERROR , -1, -1, SENSE_ABORT, "Default for SENSE_MEDIUM_ERROR"},
+ { "DLT8000", "QUANTUM", TYPE_TAPE, SENSE_MEDIUM_ERROR , UCHAR_MAX, UCHAR_MAX, SENSE_ABORT, "Default for SENSE_MEDIUM_ERROR"},
{ "DLT8000", "QUANTUM", TYPE_TAPE , SENSE_HARDWARE_ERROR, 0x0, 0x0, SENSE_ABORT, "Hardware Error"},
- { "DLT8000", "QUANTUM", TYPE_TAPE, SENSE_HARDWARE_ERROR , -1, -1, SENSE_ABORT, "Default for SENSE_HARDWARE_ERROR"},
+ { "DLT8000", "QUANTUM", TYPE_TAPE, SENSE_HARDWARE_ERROR , UCHAR_MAX, UCHAR_MAX, SENSE_ABORT, "Default for SENSE_HARDWARE_ERROR"},
{ "DLT8000", "QUANTUM", TYPE_TAPE , SENSE_ILLEGAL_REQUEST, 0x0, 0x0, SENSE_ABORT, "Illegal Request"},
- { "DLT8000", "QUANTUM", TYPE_TAPE, SENSE_ILLEGAL_REQUEST , -1, -1, SENSE_ABORT, "Default for SENSE_ILLEGAL_REQUEST"},
+ { "DLT8000", "QUANTUM", TYPE_TAPE, SENSE_ILLEGAL_REQUEST , UCHAR_MAX, UCHAR_MAX, SENSE_ABORT, "Default for SENSE_ILLEGAL_REQUEST"},
{ "DLT8000", "QUANTUM", TYPE_TAPE , SENSE_UNIT_ATTENTION, 0x0, 0x0, SENSE_RETRY, "Unit Attention"},
{ "DLT8000", "QUANTUM", TYPE_TAPE , SENSE_UNIT_ATTENTION, 0x28, 0x0, SENSE_RETRY, "Not ready to ready transition"},
- { "DLT8000", "QUANTUM", TYPE_TAPE, SENSE_UNIT_ATTENTION, -1, -1, SENSE_ABORT, "Default for SENSE_UNIT_ATTENTION"},
+ { "DLT8000", "QUANTUM", TYPE_TAPE, SENSE_UNIT_ATTENTION, UCHAR_MAX, UCHAR_MAX, SENSE_ABORT, "Default for SENSE_UNIT_ATTENTION"},
- { "DLT8000", "QUANTUM", TYPE_TAPE , -1, 0x0, 0x0, SENSE_ABORT, "Nothing Found"},
+ { "DLT8000", "QUANTUM", TYPE_TAPE , UCHAR_MAX, 0x0, 0x0, SENSE_ABORT, "Nothing Found"},
/*
* DLT 7000 Tape
{ "DLT7000", "", TYPE_TAPE, SENSE_NOT_READY, 0x4, 0x0, SENSE_RETRY, "Logical Unit not ready, no additional sense"},
{ "DLT7000", "", TYPE_TAPE, SENSE_NOT_READY, 0x4, 0x2, SENSE_TAPE_NOT_ONLINE, "Logical Unit not ready, in progress becoming ready"},
{ "DLT7000", "", TYPE_TAPE, SENSE_NOT_READY, 0x30, 0x3, SENSE_RETRY, "The tape drive is being cleaned"},
- { "DLT7000", "", TYPE_TAPE, SENSE_NOT_READY , -1, -1, SENSE_RETRY, "Default for SENSE_NOT_READY"},
+ { "DLT7000", "", TYPE_TAPE, SENSE_NOT_READY , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_NOT_READY"},
{ "DLT7000", "", TYPE_TAPE, SENSE_UNIT_ATTENTION, 0x0, 0x0, SENSE_RETRY, "Unit Attention"},
- { "DLT7000", "", TYPE_TAPE, SENSE_UNIT_ATTENTION , -1, -1, SENSE_RETRY, "Default for SENSE_UNIT_ATTENTION"},
-
+ { "DLT7000", "", TYPE_TAPE, SENSE_UNIT_ATTENTION , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_UNIT_ATTENTION"},
+
{ "DLT7000", "", TYPE_TAPE, SENSE_ILLEGAL_REQUEST, 0x0, 0x0, SENSE_ABORT, "Illegal Request"},
- { "DLT7000", "", TYPE_TAPE, SENSE_ILLEGAL_REQUEST , -1, -1, SENSE_ABORT, "Default for SENSE_ILLEGAL_REQUEST"},
-
- { "DLT7000", "", TYPE_TAPE, -1, 0x0, 0x0, SENSE_ABORT, "Nothing Found"},
+ { "DLT7000", "", TYPE_TAPE, SENSE_ILLEGAL_REQUEST , UCHAR_MAX, UCHAR_MAX, SENSE_ABORT, "Default for SENSE_ILLEGAL_REQUEST"},
+
+ { "DLT7000", "", TYPE_TAPE, UCHAR_MAX, 0x0, 0x0, SENSE_ABORT, "Nothing Found"},
/*
* DLT 4000 Tape
*/
{ "DLT4000", "", TYPE_TAPE, SENSE_NOT_READY, 0x4, 0x0, SENSE_RETRY, "Logical Unit not ready, no additional sense"},
{ "DLT4000", "", TYPE_TAPE, SENSE_NOT_READY, 0x4, 0x2, SENSE_TAPE_NOT_ONLINE, "Logical Unit not ready, in progress becoming ready"},
{ "DLT4000", "", TYPE_TAPE, SENSE_NOT_READY, 0x30, 0x3, SENSE_RETRY, "The tape drive is being cleaned"},
- { "DLT4000", "", TYPE_TAPE, SENSE_NOT_READY , -1, -1, SENSE_RETRY, "Default for SENSE_NOT_READY"},
+ { "DLT4000", "", TYPE_TAPE, SENSE_NOT_READY , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_NOT_READY"},
{ "DLT4000", "", TYPE_TAPE, SENSE_UNIT_ATTENTION, 0x0, 0x0, SENSE_RETRY, "Unit Attention"},
- { "DLT4000", "", TYPE_TAPE, SENSE_UNIT_ATTENTION , -1, -1, SENSE_RETRY, "Default for SENSE_UNIT_ATTENTION"},
-
+ { "DLT4000", "", TYPE_TAPE, SENSE_UNIT_ATTENTION , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_UNIT_ATTENTION"},
+
{ "DLT4000", "", TYPE_TAPE, SENSE_ILLEGAL_REQUEST, 0x0, 0x0, SENSE_ABORT, "Illegal Request"},
- { "DLT4000", "", TYPE_TAPE, SENSE_ILLEGAL_REQUEST , -1, -1, SENSE_ABORT, "Default for SENSE_ILLEGAL_REQUEST"},
-
- { "DLT4000", "", TYPE_TAPE, -1, 0x0, 0x0, SENSE_ABORT, "Nothing Found"},
+ { "DLT4000", "", TYPE_TAPE, SENSE_ILLEGAL_REQUEST , UCHAR_MAX, UCHAR_MAX, SENSE_ABORT, "Default for SENSE_ILLEGAL_REQUEST"},
+
+ { "DLT4000", "", TYPE_TAPE, UCHAR_MAX, 0x0, 0x0, SENSE_ABORT, "Nothing Found"},
/*
* AIT VLS DLT Library
*/
{ "VLS_DLT", "", TYPE_CHANGER, SENSE_NOT_READY, 0x4, 0x0, SENSE_RETRY, "Logical Unit not ready, no additional sense"},
{ "VLS_DLT", "", TYPE_CHANGER, SENSE_NOT_READY, 0x4, 0x2, SENSE_TAPE_NOT_ONLINE, "Logical Unit not ready, in progress becoming ready"},
{ "VLS_DLT", "", TYPE_CHANGER, SENSE_NOT_READY, 0x30, 0x3, SENSE_RETRY, "The tape drive is being cleaned"},
- { "VLS_DLT", "", TYPE_CHANGER, SENSE_NOT_READY , -1, -1, SENSE_RETRY, "Default for SENSE_NOT_READY"},
+ { "VLS_DLT", "", TYPE_CHANGER, SENSE_NOT_READY , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_NOT_READY"},
{ "VLS_DLT", "", TYPE_CHANGER, SENSE_UNIT_ATTENTION, 0x0, 0x0, SENSE_RETRY, "Unit Attention"},
- { "VLS_DLT", "", TYPE_CHANGER, SENSE_UNIT_ATTENTION , -1, -1, SENSE_RETRY, "Default for SENSE_UNIT_ATTENTION"},
-
+ { "VLS_DLT", "", TYPE_CHANGER, SENSE_UNIT_ATTENTION , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_UNIT_ATTENTION"},
+
{ "VLS_DLT", "", TYPE_CHANGER, SENSE_ILLEGAL_REQUEST, 0x0, 0x0, SENSE_ABORT, "Illegal Request"},
- { "VLS_DLT", "", TYPE_CHANGER, SENSE_ILLEGAL_REQUEST , -1, -1, SENSE_ABORT, "Default for SENSE_ILLEGAL_REQUEST"},
+ { "VLS_DLT", "", TYPE_CHANGER, SENSE_ILLEGAL_REQUEST , UCHAR_MAX, UCHAR_MAX, SENSE_ABORT, "Default for SENSE_ILLEGAL_REQUEST"},
+
+ { "VLS_DLT", "", TYPE_CHANGER, SENSE_CHG_ELEMENT_STATUS, UCHAR_MAX, UCHAR_MAX, SENSE_IGNORE, "Default for SENSE_CHG_ELEMENT_STATUS"},
- { "VLS_DLT", "", TYPE_CHANGER, SENSE_CHG_ELEMENT_STATUS, -1, -1, SENSE_IGNORE, "Default for SENSE_CHG_ELEMENT_STATUS"},
-
- { "VLS_DLT", "", TYPE_CHANGER, -1, 0x0, 0x0, SENSE_ABORT, "Nothing Found"},
+ { "VLS_DLT", "", TYPE_CHANGER, UCHAR_MAX, 0x0, 0x0, SENSE_ABORT, "Nothing Found"},
/*
* AIT VLS SDX Library
*/
{ "VLS_SDX", "", TYPE_CHANGER, SENSE_NOT_READY, 0x4, 0x0, SENSE_RETRY, "Logical Unit not ready, no additional sense"},
{ "VLS_SDX", "", TYPE_CHANGER, SENSE_NOT_READY, 0x4, 0x2, SENSE_TAPE_NOT_ONLINE, "Logical Unit not ready, in progress becoming ready"},
{ "VLS_SDX", "", TYPE_CHANGER, SENSE_NOT_READY, 0x30, 0x3, SENSE_RETRY, "The tape drive is being cleaned"},
- { "VLS_SDX", "", TYPE_CHANGER, SENSE_NOT_READY , -1, -1, SENSE_RETRY, "Default for SENSE_NOT_READY"},
+ { "VLS_SDX", "", TYPE_CHANGER, SENSE_NOT_READY , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_NOT_READY"},
{ "VLS_SDX", "", TYPE_CHANGER, SENSE_UNIT_ATTENTION, 0x0, 0x0, SENSE_RETRY, "Unit Attention"},
- { "VLS_SDX", "", TYPE_CHANGER, SENSE_UNIT_ATTENTION , -1, -1, SENSE_RETRY, "Default for SENSE_UNIT_ATTENTION"},
-
+ { "VLS_SDX", "", TYPE_CHANGER, SENSE_UNIT_ATTENTION , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_UNIT_ATTENTION"},
+
{ "VLS_SDX", "", TYPE_CHANGER, SENSE_ILLEGAL_REQUEST, 0x0, 0x0, SENSE_ABORT, "Illegal Request"},
- { "VLS_SDX", "", TYPE_CHANGER, SENSE_ILLEGAL_REQUEST , -1, -1, SENSE_ABORT, "Default for SENSE_ILLEGAL_REQUEST"},
-
- { "VLS_SDX", "", TYPE_CHANGER, SENSE_CHG_ELEMENT_STATUS, -1, -1, SENSE_IGNORE, "Default for SENSE_CHG_ELEMENT_STATUS"},
+ { "VLS_SDX", "", TYPE_CHANGER, SENSE_ILLEGAL_REQUEST , UCHAR_MAX, UCHAR_MAX, SENSE_ABORT, "Default for SENSE_ILLEGAL_REQUEST"},
+
+ { "VLS_SDX", "", TYPE_CHANGER, SENSE_CHG_ELEMENT_STATUS, UCHAR_MAX, UCHAR_MAX, SENSE_IGNORE, "Default for SENSE_CHG_ELEMENT_STATUS"},
- { "VLS_SDX", "", TYPE_CHANGER, -1, 0x0, 0x0, SENSE_ABORT, "Nothing Found"},
+ { "VLS_SDX", "", TYPE_CHANGER, UCHAR_MAX, 0x0, 0x0, SENSE_ABORT, "Nothing Found"},
/*
* Exabyte 85058 Tape
*/
{ "EXB-85058HE-0000", "", TYPE_TAPE, SENSE_NOT_READY, 0x4, 0x1, SENSE_RETRY, "Logical Unit not ready, in progress becoming ready"},
{ "EXB-85058HE-0000", "", TYPE_TAPE, SENSE_NOT_READY, 0x30, 0x3, SENSE_RETRY, "The tape drive is being cleaned"},
{ "EXB-85058HE-0000", "", TYPE_TAPE, SENSE_NOT_READY, 0x3A, 0x0, SENSE_TAPE_NOT_ONLINE, "No Tape online"},
- { "EXB-85058HE-0000", "", TYPE_TAPE, SENSE_NOT_READY , -1, -1, SENSE_RETRY, "Default for SENSE_NOT_READY"},
+ { "EXB-85058HE-0000", "", TYPE_TAPE, SENSE_NOT_READY , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_NOT_READY"},
{ "EXB-85058HE-0000", "", TYPE_TAPE, SENSE_UNIT_ATTENTION, 0x0, 0x0, SENSE_RETRY, "Unit Attention"},
- { "EXB-85058HE-0000", "", TYPE_TAPE, SENSE_UNIT_ATTENTION , -1, -1, SENSE_RETRY, "Default for SENSE_UNIT_ATTENTION"},
-
+ { "EXB-85058HE-0000", "", TYPE_TAPE, SENSE_UNIT_ATTENTION , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_UNIT_ATTENTION"},
+
{ "EXB-85058HE-0000", "", TYPE_TAPE, SENSE_ILLEGAL_REQUEST, 0x0, 0x0, SENSE_ABORT, "Illegal Request"},
- { "EXB-85058HE-0000", "", TYPE_TAPE, SENSE_ILLEGAL_REQUEST , -1, -1, SENSE_ABORT, "Default for SENSE_ILLEGAL_REQUEST"},
- { "EXB-85058HE-0000", "", TYPE_TAPE, -1, 0x0, 0x0, SENSE_ABORT, "Nothing Found"},
+ { "EXB-85058HE-0000", "", TYPE_TAPE, SENSE_ILLEGAL_REQUEST , UCHAR_MAX, UCHAR_MAX, SENSE_ABORT, "Default for SENSE_ILLEGAL_REQUEST"},
+ { "EXB-85058HE-0000", "", TYPE_TAPE, UCHAR_MAX, 0x0, 0x0, SENSE_ABORT, "Nothing Found"},
/*
* Exabyte 10e Library (Robot)
*/
{ "EXB-10e", "", TYPE_CHANGER, SENSE_NULL, 0x0, 0x0, SENSE_RETRY, "Retry, no sense"},
{ "EXB-10e", "", TYPE_CHANGER, SENSE_NULL, 0x90, 0x2, SENSE_ABORT, "Illegal Request"},
{ "EXB-10e", "", TYPE_CHANGER, SENSE_NULL , 0x90, 0x3, SENSE_IES, "IES"},
- { "EXB-10e", "", TYPE_CHANGER, SENSE_NULL , -1, -1, SENSE_RETRY, "Default for SENSE_NULL"},
+ { "EXB-10e", "", TYPE_CHANGER, SENSE_NULL , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_NULL"},
{ "EXB-10e", "", TYPE_CHANGER, SENSE_NOT_READY, 0x4, 0x0, SENSE_RETRY, "Logical Unit not ready, no additional sense"},
{ "EXB-10e", "", TYPE_CHANGER, SENSE_NOT_READY, 0x4, 0x1, SENSE_RETRY, "Logical Unit not ready, in progress becoming ready"},
{ "EXB-10e", "", TYPE_CHANGER, SENSE_NOT_READY, 0x4, 0x8E, SENSE_ABORT, "The library is in Sequential mode"},
{ "EXB-10e", "", TYPE_CHANGER, SENSE_NOT_READY, 0x30, 0x3, SENSE_RETRY, "The tape drive is being cleaned"},
{ "EXB-10e", "", TYPE_CHANGER, SENSE_NOT_READY, 0x3A, 0x0, SENSE_TAPE_NOT_ONLINE, "No Tape online"},
- { "EXB-10e", "", TYPE_CHANGER, SENSE_NOT_READY , -1, -1, SENSE_RETRY, "Default for SENSE_NOT_READY"},
- { "EXB-10e", "", TYPE_CHANGER, SENSE_NOT_READY , -1, -1, SENSE_RETRY, "Default for SENSE_NOT_READY"},
+ { "EXB-10e", "", TYPE_CHANGER, SENSE_NOT_READY , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_NOT_READY"},
+ { "EXB-10e", "", TYPE_CHANGER, SENSE_NOT_READY , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_NOT_READY"},
{ "EXB-10e", "", TYPE_CHANGER, SENSE_UNIT_ATTENTION, 0x0, 0x0, SENSE_RETRY, "Unit Attention"},
- { "EXB-10e", "", TYPE_CHANGER, SENSE_UNIT_ATTENTION , -1, -1, SENSE_RETRY, "Default for SENSE_UNIT_ATTENTION"},
-
+ { "EXB-10e", "", TYPE_CHANGER, SENSE_UNIT_ATTENTION , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_UNIT_ATTENTION"},
+
{ "EXB-10e", "", TYPE_CHANGER, SENSE_ILLEGAL_REQUEST, 0x0, 0x0, SENSE_ABORT, "Illegal Request"},
{ "EXB-10e", "", TYPE_CHANGER, SENSE_ILLEGAL_REQUEST, 0x91, 0x0, SENSE_CHM_FULL, "CHM full during reset"},
- { "EXB-10e", "", TYPE_CHANGER, SENSE_ILLEGAL_REQUEST , -1, -1, SENSE_RETRY, "Default for SENSE_ILLEGAL_REQUEST"},
-
- { "EXB-10e", "", TYPE_CHANGER, SENSE_CHG_ELEMENT_STATUS, -1, -1, SENSE_IGNORE, "Default for SENSE_CHG_ELEMENT_STATUS"},
+ { "EXB-10e", "", TYPE_CHANGER, SENSE_ILLEGAL_REQUEST , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_ILLEGAL_REQUEST"},
+
+ { "EXB-10e", "", TYPE_CHANGER, SENSE_CHG_ELEMENT_STATUS, UCHAR_MAX, UCHAR_MAX, SENSE_IGNORE, "Default for SENSE_CHG_ELEMENT_STATUS"},
- { "EXB-10e", "", TYPE_CHANGER, -1, 0x0, 0x0, SENSE_ABORT, "Nothing Found for EXB-10e"},
+ { "EXB-10e", "", TYPE_CHANGER, UCHAR_MAX, 0x0, 0x0, SENSE_ABORT, "Nothing Found for EXB-10e"},
/*
* Exabyte 210 Library (Robot)
{ "EXB-210", "", TYPE_CHANGER, SENSE_NULL, 0x0, 0x0, SENSE_RETRY, "Retry, no sense"},
{ "EXB-210", "", TYPE_CHANGER, SENSE_NULL, 0x90, 0x2, SENSE_ABORT, "Illegal Request"},
{ "EXB-210", "", TYPE_CHANGER, SENSE_NULL , 0x90, 0x3, SENSE_IES, "IES"},
- { "EXB-210", "", TYPE_CHANGER, SENSE_NULL , -1, -1, SENSE_RETRY, "Default for SENSE_NULL"},
+ { "EXB-210", "", TYPE_CHANGER, SENSE_NULL , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_NULL"},
{ "EXB-210", "", TYPE_CHANGER, SENSE_NOT_READY, 0x4, 0x0, SENSE_RETRY, "Logical Unit not ready, no additional sense"},
{ "EXB-210", "", TYPE_CHANGER, SENSE_NOT_READY, 0x4, 0x1, SENSE_RETRY, "Logical Unit not ready, in progress becoming ready"},
{ "EXB-210", "", TYPE_CHANGER, SENSE_NOT_READY, 0x4, 0x8E, SENSE_ABORT, "The library is in Sequential mode"},
{ "EXB-210", "", TYPE_CHANGER, SENSE_NOT_READY, 0x30, 0x3, SENSE_RETRY, "The tape drive is being cleaned"},
{ "EXB-210", "", TYPE_CHANGER, SENSE_NOT_READY, 0x3A, 0x0, SENSE_TAPE_NOT_ONLINE, "No Tape online"},
- { "EXB-210", "", TYPE_CHANGER, SENSE_NOT_READY , -1, -1, SENSE_RETRY, "Default for SENSE_NOT_READY"},
- { "EXB-210", "", TYPE_CHANGER, SENSE_NOT_READY , -1, -1, SENSE_RETRY, "Default for SENSE_NOT_READY"},
+ { "EXB-210", "", TYPE_CHANGER, SENSE_NOT_READY , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_NOT_READY"},
+ { "EXB-210", "", TYPE_CHANGER, SENSE_NOT_READY , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_NOT_READY"},
{ "EXB-210", "", TYPE_CHANGER, SENSE_UNIT_ATTENTION, 0x0, 0x0, SENSE_RETRY, "Unit Attention"},
- { "EXB-210", "", TYPE_CHANGER, SENSE_UNIT_ATTENTION , -1, -1, SENSE_RETRY, "Default for SENSE_UNIT_ATTENTION"},
-
+ { "EXB-210", "", TYPE_CHANGER, SENSE_UNIT_ATTENTION , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_UNIT_ATTENTION"},
+
{ "EXB-210", "", TYPE_CHANGER, SENSE_ILLEGAL_REQUEST, 0x0, 0x0, SENSE_ABORT, "Illegal Request"},
{ "EXB-210", "", TYPE_CHANGER, SENSE_ILLEGAL_REQUEST, 0x91, 0x0, SENSE_CHM_FULL, "CHM full during reset"},
{ "EXB-210", "", TYPE_CHANGER, SENSE_ILLEGAL_REQUEST, 0x21, 0x01, SENSE_ABORT, "Invalid element address"},
{ "EXB-210", "", TYPE_CHANGER, SENSE_ILLEGAL_REQUEST, 0x80, 0x04, SENSE_ABORT, "Destination magazine no installed"},
{ "EXB-210", "", TYPE_CHANGER, SENSE_ILLEGAL_REQUEST, 0x80, 0x05, SENSE_ABORT, "Source tape drive not installed"},
{ "EXB-210", "", TYPE_CHANGER, SENSE_ILLEGAL_REQUEST, 0x80, 0x06, SENSE_ABORT, "Destination tape drive not installed"},
-
- { "EXB-210", "", TYPE_CHANGER, SENSE_ILLEGAL_REQUEST , -1, -1, SENSE_RETRY, "Default for SENSE_ILLEGAL_REQUEST"},
-
+
+ { "EXB-210", "", TYPE_CHANGER, SENSE_ILLEGAL_REQUEST , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_ILLEGAL_REQUEST"},
+
{ "EXB-210", "", TYPE_CHANGER, SENSE_CHG_ELEMENT_STATUS, 0x83, 0x0, SENSE_IES, "Label questionable"},
{ "EXB-210", "", TYPE_CHANGER, SENSE_CHG_ELEMENT_STATUS, 0x83, 0x1, SENSE_IGNORE, "Cannot read bar code label"},
{ "EXB-210", "", TYPE_CHANGER, SENSE_CHG_ELEMENT_STATUS, 0x83, 0x2, SENSE_ABORT, "Cartzridge magazine not present"},
{ "EXB-210", "", TYPE_CHANGER, SENSE_CHG_ELEMENT_STATUS, 0x83, 0x8, SENSE_IGNORE, "Bar code label upside down"},
{ "EXB-210", "", TYPE_CHANGER, SENSE_CHG_ELEMENT_STATUS, 0x83, 0x9, SENSE_IGNORE, "No bar code label"},
{ "EXB-210", "", TYPE_CHANGER, SENSE_CHG_ELEMENT_STATUS, 0x83, 0xa, SENSE_IGNORE, ""},
- { "EXB-210", "", TYPE_CHANGER, SENSE_CHG_ELEMENT_STATUS, -1, -1, SENSE_IGNORE, "Default for SENSE_CHG_ELEMENT_STATUS"},
+ { "EXB-210", "", TYPE_CHANGER, SENSE_CHG_ELEMENT_STATUS, UCHAR_MAX, UCHAR_MAX, SENSE_IGNORE, "Default for SENSE_CHG_ELEMENT_STATUS"},
- { "EXB-210", "", TYPE_CHANGER, -1, 0x0, 0x0, SENSE_ABORT, "Nothing Found for EXB-10e"},
+ { "EXB-210", "", TYPE_CHANGER, UCHAR_MAX, 0x0, 0x0, SENSE_ABORT, "Nothing Found for EXB-10e"},
/*
* Exabyte 230D Library (Robot)
{ "EXB-230D", "", TYPE_CHANGER, SENSE_NULL, 0x0, 0x0, SENSE_RETRY, "Retry, no sense"},
{ "EXB-230D", "", TYPE_CHANGER, SENSE_NULL, 0x90, 0x2, SENSE_ABORT, "Illegal Request"},
{ "EXB-230D", "", TYPE_CHANGER, SENSE_NULL , 0x90, 0x3, SENSE_IES, "IES"},
- { "EXB-230D", "", TYPE_CHANGER, SENSE_NULL , -1, -1, SENSE_RETRY, "Default for SENSE_NULL"},
+ { "EXB-230D", "", TYPE_CHANGER, SENSE_NULL , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_NULL"},
{ "EXB-230D", "", TYPE_CHANGER, SENSE_NOT_READY, 0x4, 0x0, SENSE_RETRY, "Logical Unit not ready, no additional sense"},
{ "EXB-230D", "", TYPE_CHANGER, SENSE_NOT_READY, 0x4, 0x1, SENSE_RETRY, "Logical Unit not ready, in progress becoming ready"},
{ "EXB-230D", "", TYPE_CHANGER, SENSE_NOT_READY, 0x4, 0x8E, SENSE_ABORT, "The library is in Sequential mode"},
{ "EXB-230D", "", TYPE_CHANGER, SENSE_NOT_READY, 0x30, 0x3, SENSE_RETRY, "The tape drive is being cleaned"},
{ "EXB-230D", "", TYPE_CHANGER, SENSE_NOT_READY, 0x3A, 0x0, SENSE_TAPE_NOT_ONLINE, "No Tape online"},
- { "EXB-230D", "", TYPE_CHANGER, SENSE_NOT_READY , -1, -1, SENSE_RETRY, "Default for SENSE_NOT_READY"},
- { "EXB-230D", "", TYPE_CHANGER, SENSE_NOT_READY , -1, -1, SENSE_RETRY, "Default for SENSE_NOT_READY"},
+ { "EXB-230D", "", TYPE_CHANGER, SENSE_NOT_READY , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_NOT_READY"},
+ { "EXB-230D", "", TYPE_CHANGER, SENSE_NOT_READY , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_NOT_READY"},
{ "EXB-230D", "", TYPE_CHANGER, SENSE_UNIT_ATTENTION, 0x0, 0x0, SENSE_RETRY, "Unit Attention"},
- { "EXB-230D", "", TYPE_CHANGER, SENSE_UNIT_ATTENTION , -1, -1, SENSE_RETRY, "Default for SENSE_UNIT_ATTENTION"},
-
+ { "EXB-230D", "", TYPE_CHANGER, SENSE_UNIT_ATTENTION , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_UNIT_ATTENTION"},
+
{ "EXB-230D", "", TYPE_CHANGER, SENSE_ILLEGAL_REQUEST, 0x0, 0x0, SENSE_ABORT, "Illegal Request"},
{ "EXB-230D", "", TYPE_CHANGER, SENSE_ILLEGAL_REQUEST, 0x91, 0x0, SENSE_CHM_FULL, "CHM full during reset"},
- { "EXB-230D", "", TYPE_CHANGER, SENSE_ILLEGAL_REQUEST , -1, -1, SENSE_RETRY, "Default for SENSE_ILLEGAL_REQUEST"},
-
- { "EXB-230D", "", TYPE_CHANGER, SENSE_CHG_ELEMENT_STATUS, -1, -1, SENSE_IGNORE, "Default for SENSE_CHG_ELEMENT_STATUS"},
+ { "EXB-230D", "", TYPE_CHANGER, SENSE_ILLEGAL_REQUEST , UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_ILLEGAL_REQUEST"},
- { "EXB-230D", "", TYPE_CHANGER, -1, 0x0, 0x0, SENSE_ABORT, "Nothing Found for EXB-10e"},
+ { "EXB-230D", "", TYPE_CHANGER, SENSE_CHG_ELEMENT_STATUS, UCHAR_MAX, UCHAR_MAX, SENSE_IGNORE, "Default for SENSE_CHG_ELEMENT_STATUS"},
+
+ { "EXB-230D", "", TYPE_CHANGER, UCHAR_MAX, 0x0, 0x0, SENSE_ABORT, "Nothing Found for EXB-10e"},
/*
* Spectra TreeFrog library
*/
{ "215", "SPECTRA", TYPE_CHANGER, SENSE_NULL, 0x0, 0x0, SENSE_NO, "No Sense, Unit Ready"},
- { "215", "SPECTRA", TYPE_CHANGER, SENSE_NULL, -1, -1, SENSE_NO, "No Sense, Unit Ready"},
-
+ { "215", "SPECTRA", TYPE_CHANGER, SENSE_NULL, UCHAR_MAX, UCHAR_MAX, SENSE_NO, "No Sense, Unit Ready"},
+
{ "215", "SPECTRA", TYPE_CHANGER, SENSE_NOT_READY, 0x4, 0x0, SENSE_RETRY, "Unit Not Ready"},
{ "215", "SPECTRA", TYPE_CHANGER, SENSE_NOT_READY, 0x4, 0x1, SENSE_RETRY, "Unit is Becoming Ready"},
{ "215", "SPECTRA", TYPE_CHANGER, SENSE_NOT_READY, 0x4, 0x83, SENSE_ABORT, "Door is open, Robot is Disabled"},
- { "215", "SPECTRA", TYPE_CHANGER, SENSE_NOT_READY, -1, -1, SENSE_RETRY, "Default for SENSE_NOT_READY"},
-
+ { "215", "SPECTRA", TYPE_CHANGER, SENSE_NOT_READY, UCHAR_MAX, UCHAR_MAX, SENSE_RETRY, "Default for SENSE_NOT_READY"},
+
{ "215", "SPECTRA", TYPE_CHANGER, SENSE_HARDWARE_ERROR, 0x4C, 0x0, SENSE_ABORT, "Unit Failed Initialization"},
{ "215", "SPECTRA", TYPE_CHANGER, SENSE_HARDWARE_ERROR, 0x84, 0x4, SENSE_ABORT, "DRAM Memory Failure"},
{ "215", "SPECTRA", TYPE_CHANGER, SENSE_HARDWARE_ERROR, 0x84, 0x4, SENSE_ABORT, "Two ore More SCSI ID's in the library are tehe same"},
{ "215", "SPECTRA", TYPE_CHANGER, SENSE_HARDWARE_ERROR, 0x85, 0x2, SENSE_ABORT, "Long Axis Robotics Error"},
{ "215", "SPECTRA", TYPE_CHANGER, SENSE_HARDWARE_ERROR, 0x85, 0x3, SENSE_ABORT, "Short Axis Robotics Error"},
{ "215", "SPECTRA", TYPE_CHANGER, SENSE_HARDWARE_ERROR, 0x85, 0x4, SENSE_ABORT, "Ambient Light Detected"},
- { "215", "SPECTRA", TYPE_CHANGER, SENSE_HARDWARE_ERROR, -1, -1, SENSE_ABORT, "Default for SENSE_HARDWARE_ERROR"},
-
+ { "215", "SPECTRA", TYPE_CHANGER, SENSE_HARDWARE_ERROR, UCHAR_MAX, UCHAR_MAX, SENSE_ABORT, "Default for SENSE_HARDWARE_ERROR"},
+
{"215", "SPECTRA", TYPE_CHANGER, SENSE_ILLEGAL_REQUEST, 0x1A, 0x0, SENSE_ABORT, "Parameter List Length Error"},
{"215", "SPECTRA", TYPE_CHANGER, SENSE_ILLEGAL_REQUEST, 0x20, 0x0, SENSE_ABORT, "Invalid Command Code"},
{"215", "SPECTRA", TYPE_CHANGER, SENSE_ILLEGAL_REQUEST, 0x21, 0x01, SENSE_ABORT, "Invalid Element Address"},
{"215", "SPECTRA", TYPE_CHANGER, SENSE_ILLEGAL_REQUEST, 0x80, 0x18, SENSE_ABORT, "Conflict, Element is Reserved"},
{"215", "SPECTRA", TYPE_CHANGER, SENSE_ILLEGAL_REQUEST, 0x81, 0x2, SENSE_ABORT, "Library is Full of Tapes"},
{"215", "SPECTRA", TYPE_CHANGER, SENSE_ILLEGAL_REQUEST, 0x81, 0x3, SENSE_ABORT, "Grip Arm not Empty"},
- {"215", "SPECTRA", TYPE_CHANGER, SENSE_ILLEGAL_REQUEST, -1 , -1, SENSE_ABORT, "Default for SENSE_ILLEGAL_REQUEST"},
-
+ {"215", "SPECTRA", TYPE_CHANGER, SENSE_ILLEGAL_REQUEST, UCHAR_MAX , UCHAR_MAX, SENSE_ABORT, "Default for SENSE_ILLEGAL_REQUEST"},
+
{"215", "SPECTRA", TYPE_CHANGER, SENSE_UNIT_ATTENTION, 0x28, 0x0, SENSE_IES, "Inventory possible Altered"},
{"215", "SPECTRA", TYPE_CHANGER, SENSE_UNIT_ATTENTION, 0x29, 0x0, SENSE_RETRY, "A Reset Has Occured"},
{"215", "SPECTRA", TYPE_CHANGER, SENSE_UNIT_ATTENTION, 0x24, 0x1, SENSE_IGNORE, "Mode Parameter Have CHanged"},
- {"215", "SPECTRA", TYPE_CHANGER, SENSE_UNIT_ATTENTION, -1, -1, SENSE_IGNORE, "Default for SENSE_UNIT_ATTENTION"},
-
+ {"215", "SPECTRA", TYPE_CHANGER, SENSE_UNIT_ATTENTION, UCHAR_MAX, UCHAR_MAX, SENSE_IGNORE, "Default for SENSE_UNIT_ATTENTION"},
+
{"215", "SPECTRA", TYPE_CHANGER, SENSE_VENDOR_SPECIFIC, 0x83, 0x00, SENSE_ABORT, "Barcode Label is Unread"},
{"215", "SPECTRA", TYPE_CHANGER, SENSE_VENDOR_SPECIFIC, 0x83, 0x01, SENSE_ABORT, "Problem Reading Barcode"},
{"215", "SPECTRA", TYPE_CHANGER, SENSE_VENDOR_SPECIFIC, 0x83, 0x11, SENSE_ABORT, "Tape in Drive & Unmounted"},
{"215", "SPECTRA", TYPE_CHANGER, SENSE_VENDOR_SPECIFIC, 0x84, 0x03, SENSE_ABORT, "SCSI ID Same as Library's ID"},
{"215", "SPECTRA", TYPE_CHANGER, SENSE_VENDOR_SPECIFIC, 0x84, 0x08, SENSE_ABORT, "Busy Condition from Target"},
{"215", "SPECTRA", TYPE_CHANGER, SENSE_VENDOR_SPECIFIC, 0x84, 0x18, SENSE_ABORT, "SCSI Reservation Conflict"},
- {"215", "SPECTRA", TYPE_CHANGER, SENSE_VENDOR_SPECIFIC, -1, -1, SENSE_ABORT, "Default for SENSE_VENDOR_SPECIFIC"},
-
- { "215", "SPECTRA", TYPE_CHANGER, SENSE_CHG_ELEMENT_STATUS, -1, -1, SENSE_IGNORE, "Default for SENSE_CHG_ELEMENT_STATUS"},
+ {"215", "SPECTRA", TYPE_CHANGER, SENSE_VENDOR_SPECIFIC, UCHAR_MAX, UCHAR_MAX, SENSE_ABORT, "Default for SENSE_VENDOR_SPECIFIC"},
+
+ { "215", "SPECTRA", TYPE_CHANGER, SENSE_CHG_ELEMENT_STATUS, UCHAR_MAX, UCHAR_MAX, SENSE_IGNORE, "Default for SENSE_CHG_ELEMENT_STATUS"},
- { "215", "SPECTRA", TYPE_CHANGER, -1, 0x0, 0x0, SENSE_ABORT, "Nothing found for Spectra/215"},
-
- { NULL, "", 0x0, -1, 0x0, 0x0, 0x0, ""},
+ { "215", "SPECTRA", TYPE_CHANGER, UCHAR_MAX, 0x0, 0x0, SENSE_ABORT, "Nothing found for Spectra/215"},
+
+ { NULL, "", 0x0, UCHAR_MAX, 0x0, 0x0, 0x0, ""},
};
-void DumpSense()
+void
+DumpSense(void)
{
SenseType_T *pwork = (SenseType_T *)&SenseType;
- while (pwork->ident != NULL)
+ while (pwork->ident != NULL)
{
- if (pwork->sense == -1)
+ if (pwork->sense == UCHAR_MAX)
{
printf("\n");
} else {
* ASC is the ASC value returned by the scsi command
* ASCQ is the ASCQ value returned by the scsi command
* text is a pointer to store the clear text reason from the table.
- *
+ *
* TODO:
- *
+ *
*/
-int Sense2Action(char *ident,
- unsigned char type,
- unsigned char ignsense,
- unsigned char sense,
- unsigned char asc,
- unsigned char ascq,
- char **text)
+int
+Sense2Action(
+ char * ident,
+ unsigned char type,
+ unsigned char ignsense,
+ unsigned char sense,
+ unsigned char asc,
+ unsigned char ascq,
+ char ** text)
{
/*
* Decode the combination of sense key, ASC, ASCQ and return what to do with this
sense,
asc,
ascq));
-
- while (pwork->ident != NULL)
+
+ while (pwork->ident != NULL)
{
if (strcmp(pwork->ident, "generic") == 0 && pwork->type == type && generic == NULL)
{
generic = pwork;
}
-
- if (strcmp(pwork->ident, ident) == 0 && pwork->type == type)
+
+ if (strcmp((char *)pwork->ident, (char *)ident) == 0 && pwork->type == type)
{
in = 1;
} else {
if (in == 1)
{
/* End of definitions for this device */
- if (pwork->sense == -1)
+ if (pwork->sense == UCHAR_MAX)
{
- *text = (char *)stralloc(pwork->text);
+ *text = stralloc(pwork->text);
dbprintf(("Sense2Action END : no match for %s %s\n",
pwork->ident,
pwork->vendor));
return(pwork->ret);
}
-
+
if (ignsense)
{
if (pwork->asc == asc && pwork->ascq == ascq)
{
- *text = (char *)stralloc(pwork->text);
+ *text = stralloc(pwork->text);
dbprintf(("Sense2Action END(IGN) : match for %s %s return -> %d/%s\n",
pwork->ident,
pwork->vendor,
pwork->ret,
- *text));
+ *text));
return(pwork->ret);
}
pwork++;
continue;
- }
-
+ }
+
if (pwork->sense == sense)
{
/* Matching ASC/ASCQ, if yes return the defined result code */
pwork->ident,
pwork->vendor,
pwork->ret,
- *text));
+ *text));
return(pwork->ret);
}
-
+
/* End of definitions for this sense type, if yes return the default
* for this type
*/
- if ( pwork->asc == -1 && pwork->ascq == -1)
+ if ( pwork->asc == UCHAR_MAX && pwork->ascq == UCHAR_MAX)
{
*text = (char *)stralloc(pwork->text);
dbprintf(("Sense2Action END : no match for %s %s return -> %d/%s\n",
pwork->ident,
pwork->vendor,
pwork->ret,
- *text));
+ *text));
return(pwork->ret);
- }
+ }
}
}
pwork++;
}
- /*
+ /*
* Ok no match found, so lets return the values from the generic table
*/
dbprintf(("Sense2Action generic start :\n"));
- while ((generic != NULL) && generic->ident != NULL)
- {
- if (generic->sense == -1)
+ while (generic != NULL) {
+ if (generic->ident == NULL)
+ break;
+
+ if (generic->sense == UCHAR_MAX)
{
*text = (char *)stralloc(generic->text);
dbprintf(("Sense2Action generic END : match for %s %s return -> %d/%s\n",
generic->ident,
generic->vendor,
generic->ret,
- *text));
+ *text));
return(generic->ret);
}
-
+
if (ignsense)
{
if (generic->asc == asc && generic->ascq == ascq)
generic->ident,
generic->vendor,
generic->ret,
- *text));
+ *text));
return(generic->ret);
}
generic++;
continue;
- }
-
+ }
+
if (generic->sense == sense)
{
/* Matching ASC/ASCQ, if yes return the defined result code */
generic->ident,
generic->vendor,
generic->ret,
- *text));
+ *text));
return(generic->ret);
}
-
+
/* End of definitions for this sense type, if yes return the default
* for this type
*/
- if ( generic->asc == -1 && generic->ascq == -1)
+ if ( generic->asc == UCHAR_MAX && generic->ascq == UCHAR_MAX)
{
*text = (char *)stralloc(generic->text);
dbprintf(("Sense2Action generic END : no match for %s %s return -> %d/%s\n",
generic->ident,
generic->vendor,
generic->ret,
- *text));
+ *text));
return(generic->ret);
- }
+ }
generic++;
continue;
}
generic++;
- }
+ }
dbprintf(("Sense2Action END:\n"));
*text = (char *)stralloc("No match found");
# Makefile for Amanda client programs.
INCLUDES = -I$(top_builddir)/common-src \
- -I$(top_srcdir)/common-src
+ -I$(top_srcdir)/common-src \
+ -I$(top_srcdir)/amandad-src
+
+LINT=@AMLINT@
+LINTFLAGS=@AMLINTFLAGS@
lib_LTLIBRARIES = libamclient.la
LIB_EXTENSION = la
-libexec_PROGRAMS = amandad noop calcsize killpgrp rundump runtar selfcheck sendbackup sendsize versionsuffix
+libexec_PROGRAMS = noop calcsize killpgrp rundump runtar selfcheck sendbackup sendsize versionsuffix
sbin_SCRIPTS = @CLIENT_SCRIPTS_OPT@
libamclient_la_SOURCES= amandates.c getfsent.c \
unctime.c client_util.c \
- $(samba_sources)
+ clientconf.c $(samba_sources)
libamclient_la_LDFLAGS = -release $(VERSION)
###
LDADD = ../common-src/libamanda.$(LIB_EXTENSION) \
- libamclient.$(LIB_EXTENSION)
-if WANT_SERVER
-LDADD += ../tape-src/libamtape.$(LIB_EXTENSION)
-endif
-LDADD += ../common-src/libamanda.$(LIB_EXTENSION)
+ libamclient.$(LIB_EXTENSION) \
+ ../amandad-src/libamandad.$(LIB_EXTENSION) \
+ ../common-src/libamanda.$(LIB_EXTENSION)
SUFFIXES = .sh .pl
EXTRA_DIST = amhpfixdevs.sh amsinixfixdevs.sh
-sendbackup_SOURCES = sendbackup.c sendbackup.h \
+sendbackup_SOURCES = sendbackup.c sendbackup.h \
sendbackup-dump.c sendbackup-gnutar.c
-noinst_HEADERS = amandad.h amandates.h getfsent.h \
- findpass.h client_util.h
+noinst_HEADERS = amandates.h getfsent.h \
+ findpass.h client_util.h \
+ clientconf.h
install-exec-hook:
@list="$(sbin_SCRIPTS)"; \
done
endif
+lint:
+ @ for p in $(libexec_PROGRAMS); do \
+ f="$$p.c $(libamclient_la_SOURCES)"; \
+ (cd ../common-src; make listlibsrc); \
+ f="$$f "`cat ../common-src/listlibsrc.output`; \
+ echo $(LINT) $$f; \
+ $(LINT) $(LINTFLAGS) $(CPPFLAGS) $(DEFS) -I. -I../config \
+ $(INCLUDES) $$f; \
+ if [ $$? -ne 0 ]; then \
+ exit 1; \
+ fi; \
+ done; \
+ exit 0
+
getfsent_SOURCES = getfsent.test.c
%.test.c: $(srcdir)/%.c
build_triplet = @build@
host_triplet = @host@
target_triplet = @target@
-libexec_PROGRAMS = amandad$(EXEEXT) noop$(EXEEXT) calcsize$(EXEEXT) \
- killpgrp$(EXEEXT) rundump$(EXEEXT) runtar$(EXEEXT) \
- selfcheck$(EXEEXT) sendbackup$(EXEEXT) sendsize$(EXEEXT) \
- versionsuffix$(EXEEXT)
-@WANT_SERVER_TRUE@am__append_1 = ../tape-src/libamtape.$(LIB_EXTENSION)
+libexec_PROGRAMS = noop$(EXEEXT) calcsize$(EXEEXT) killpgrp$(EXEEXT) \
+ rundump$(EXEEXT) runtar$(EXEEXT) selfcheck$(EXEEXT) \
+ sendbackup$(EXEEXT) sendsize$(EXEEXT) versionsuffix$(EXEEXT)
EXTRA_PROGRAMS = $(am__EXEEXT_1)
subdir = client-src
DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \
LTLIBRARIES = $(lib_LTLIBRARIES)
libamclient_la_LIBADD =
am__libamclient_la_SOURCES_DIST = amandates.c getfsent.c unctime.c \
- client_util.c findpass.c
+ client_util.c clientconf.c findpass.c
@WANT_SAMBA_TRUE@am__objects_1 = findpass.lo
am_libamclient_la_OBJECTS = amandates.lo getfsent.lo unctime.lo \
- client_util.lo $(am__objects_1)
+ client_util.lo clientconf.lo $(am__objects_1)
libamclient_la_OBJECTS = $(am_libamclient_la_OBJECTS)
am__EXEEXT_1 = getfsent$(EXEEXT)
libexecPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
PROGRAMS = $(libexec_PROGRAMS)
-amandad_SOURCES = amandad.c
-amandad_OBJECTS = amandad.$(OBJEXT)
-amandad_LDADD = $(LDADD)
-@WANT_SERVER_TRUE@am__DEPENDENCIES_1 = \
-@WANT_SERVER_TRUE@ ../tape-src/libamtape.$(LIB_EXTENSION)
-amandad_DEPENDENCIES = ../common-src/libamanda.$(LIB_EXTENSION) \
- libamclient.$(LIB_EXTENSION) $(am__DEPENDENCIES_1) \
- ../common-src/libamanda.$(LIB_EXTENSION)
calcsize_SOURCES = calcsize.c
calcsize_OBJECTS = calcsize.$(OBJEXT)
calcsize_LDADD = $(LDADD)
calcsize_DEPENDENCIES = ../common-src/libamanda.$(LIB_EXTENSION) \
- libamclient.$(LIB_EXTENSION) $(am__DEPENDENCIES_1) \
+ libamclient.$(LIB_EXTENSION) \
+ ../amandad-src/libamandad.$(LIB_EXTENSION) \
../common-src/libamanda.$(LIB_EXTENSION)
am_getfsent_OBJECTS = getfsent.test.$(OBJEXT)
getfsent_OBJECTS = $(am_getfsent_OBJECTS)
getfsent_LDADD = $(LDADD)
getfsent_DEPENDENCIES = ../common-src/libamanda.$(LIB_EXTENSION) \
- libamclient.$(LIB_EXTENSION) $(am__DEPENDENCIES_1) \
+ libamclient.$(LIB_EXTENSION) \
+ ../amandad-src/libamandad.$(LIB_EXTENSION) \
../common-src/libamanda.$(LIB_EXTENSION)
killpgrp_SOURCES = killpgrp.c
killpgrp_OBJECTS = killpgrp.$(OBJEXT)
killpgrp_LDADD = $(LDADD)
killpgrp_DEPENDENCIES = ../common-src/libamanda.$(LIB_EXTENSION) \
- libamclient.$(LIB_EXTENSION) $(am__DEPENDENCIES_1) \
+ libamclient.$(LIB_EXTENSION) \
+ ../amandad-src/libamandad.$(LIB_EXTENSION) \
../common-src/libamanda.$(LIB_EXTENSION)
noop_SOURCES = noop.c
noop_OBJECTS = noop.$(OBJEXT)
noop_LDADD = $(LDADD)
noop_DEPENDENCIES = ../common-src/libamanda.$(LIB_EXTENSION) \
- libamclient.$(LIB_EXTENSION) $(am__DEPENDENCIES_1) \
+ libamclient.$(LIB_EXTENSION) \
+ ../amandad-src/libamandad.$(LIB_EXTENSION) \
../common-src/libamanda.$(LIB_EXTENSION)
rundump_SOURCES = rundump.c
rundump_OBJECTS = rundump.$(OBJEXT)
rundump_LDADD = $(LDADD)
rundump_DEPENDENCIES = ../common-src/libamanda.$(LIB_EXTENSION) \
- libamclient.$(LIB_EXTENSION) $(am__DEPENDENCIES_1) \
+ libamclient.$(LIB_EXTENSION) \
+ ../amandad-src/libamandad.$(LIB_EXTENSION) \
../common-src/libamanda.$(LIB_EXTENSION)
runtar_SOURCES = runtar.c
runtar_OBJECTS = runtar.$(OBJEXT)
runtar_LDADD = $(LDADD)
runtar_DEPENDENCIES = ../common-src/libamanda.$(LIB_EXTENSION) \
- libamclient.$(LIB_EXTENSION) $(am__DEPENDENCIES_1) \
+ libamclient.$(LIB_EXTENSION) \
+ ../amandad-src/libamandad.$(LIB_EXTENSION) \
../common-src/libamanda.$(LIB_EXTENSION)
selfcheck_SOURCES = selfcheck.c
selfcheck_OBJECTS = selfcheck.$(OBJEXT)
selfcheck_LDADD = $(LDADD)
selfcheck_DEPENDENCIES = ../common-src/libamanda.$(LIB_EXTENSION) \
- libamclient.$(LIB_EXTENSION) $(am__DEPENDENCIES_1) \
+ libamclient.$(LIB_EXTENSION) \
+ ../amandad-src/libamandad.$(LIB_EXTENSION) \
../common-src/libamanda.$(LIB_EXTENSION)
am_sendbackup_OBJECTS = sendbackup.$(OBJEXT) sendbackup-dump.$(OBJEXT) \
sendbackup-gnutar.$(OBJEXT)
sendbackup_OBJECTS = $(am_sendbackup_OBJECTS)
sendbackup_LDADD = $(LDADD)
sendbackup_DEPENDENCIES = ../common-src/libamanda.$(LIB_EXTENSION) \
- libamclient.$(LIB_EXTENSION) $(am__DEPENDENCIES_1) \
+ libamclient.$(LIB_EXTENSION) \
+ ../amandad-src/libamandad.$(LIB_EXTENSION) \
../common-src/libamanda.$(LIB_EXTENSION)
sendsize_SOURCES = sendsize.c
sendsize_OBJECTS = sendsize.$(OBJEXT)
sendsize_LDADD = $(LDADD)
sendsize_DEPENDENCIES = ../common-src/libamanda.$(LIB_EXTENSION) \
- libamclient.$(LIB_EXTENSION) $(am__DEPENDENCIES_1) \
+ libamclient.$(LIB_EXTENSION) \
+ ../amandad-src/libamandad.$(LIB_EXTENSION) \
../common-src/libamanda.$(LIB_EXTENSION)
versionsuffix_SOURCES = versionsuffix.c
versionsuffix_OBJECTS = versionsuffix.$(OBJEXT)
versionsuffix_LDADD = $(LDADD)
versionsuffix_DEPENDENCIES = ../common-src/libamanda.$(LIB_EXTENSION) \
- libamclient.$(LIB_EXTENSION) $(am__DEPENDENCIES_1) \
+ libamclient.$(LIB_EXTENSION) \
+ ../amandad-src/libamandad.$(LIB_EXTENSION) \
../common-src/libamanda.$(LIB_EXTENSION)
libexecSCRIPT_INSTALL = $(INSTALL_SCRIPT)
sbinSCRIPT_INSTALL = $(INSTALL_SCRIPT)
CCLD = $(CC)
LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
$(AM_LDFLAGS) $(LDFLAGS) -o $@
-SOURCES = $(libamclient_la_SOURCES) amandad.c calcsize.c \
- $(getfsent_SOURCES) killpgrp.c noop.c rundump.c runtar.c \
- selfcheck.c $(sendbackup_SOURCES) sendsize.c versionsuffix.c
-DIST_SOURCES = $(am__libamclient_la_SOURCES_DIST) amandad.c calcsize.c \
+SOURCES = $(libamclient_la_SOURCES) calcsize.c $(getfsent_SOURCES) \
+ killpgrp.c noop.c rundump.c runtar.c selfcheck.c \
+ $(sendbackup_SOURCES) sendsize.c versionsuffix.c
+DIST_SOURCES = $(am__libamclient_la_SOURCES_DIST) calcsize.c \
$(getfsent_SOURCES) killpgrp.c noop.c rundump.c runtar.c \
selfcheck.c $(sendbackup_SOURCES) sendsize.c versionsuffix.c
HEADERS = $(noinst_HEADERS)
AMANDA_TMPDIR = @AMANDA_TMPDIR@
AMDEP_FALSE = @AMDEP_FALSE@
AMDEP_TRUE = @AMDEP_TRUE@
+AMLINT = @AMLINT@
+AMLINTFLAGS = @AMLINTFLAGS@
AMPLOT_CAT_COMPRESS = @AMPLOT_CAT_COMPRESS@
AMPLOT_CAT_GZIP = @AMPLOT_CAT_GZIP@
AMPLOT_CAT_PACK = @AMPLOT_CAT_PACK@
AMPLOT_COMPRESS = @AMPLOT_COMPRESS@
AMTAR = @AMTAR@
+AM_CFLAGS = @AM_CFLAGS@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AWK = @AWK@
AWK_VAR_ASSIGNMENT_OPT = @AWK_VAR_ASSIGNMENT_OPT@
BINARY_OWNER = @BINARY_OWNER@
+BUILD_MAN_PAGES_FALSE = @BUILD_MAN_PAGES_FALSE@
+BUILD_MAN_PAGES_TRUE = @BUILD_MAN_PAGES_TRUE@
CAT = @CAT@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
target_os = @target_os@
target_vendor = @target_vendor@
INCLUDES = -I$(top_builddir)/common-src \
- -I$(top_srcdir)/common-src
+ -I$(top_srcdir)/common-src \
+ -I$(top_srcdir)/amandad-src
+LINT = @AMLINT@
+LINTFLAGS = @AMLINTFLAGS@
lib_LTLIBRARIES = libamclient.la
LIB_EXTENSION = la
sbin_SCRIPTS = @CLIENT_SCRIPTS_OPT@
@WANT_RUNTIME_PSEUDO_RELOC_TRUE@AM_LDFLAGS = -Wl,-enable-runtime-pseudo-reloc
libamclient_la_SOURCES = amandates.c getfsent.c \
unctime.c client_util.c \
- $(samba_sources)
+ clientconf.c $(samba_sources)
libamclient_la_LDFLAGS = -release $(VERSION)
# routines, and second to pick up any references in the other libraries.
###
LDADD = ../common-src/libamanda.$(LIB_EXTENSION) \
- libamclient.$(LIB_EXTENSION) $(am__append_1) \
+ libamclient.$(LIB_EXTENSION) \
+ ../amandad-src/libamandad.$(LIB_EXTENSION) \
../common-src/libamanda.$(LIB_EXTENSION)
+
SUFFIXES = .sh .pl
# these are used for testing only:
EXTRA_SCRIPTS = amhpfixdevs amsinixfixdevs
DISTCLEANFILES = $(EXTRA_SCRIPTS)
EXTRA_DIST = amhpfixdevs.sh amsinixfixdevs.sh
-sendbackup_SOURCES = sendbackup.c sendbackup.h \
+sendbackup_SOURCES = sendbackup.c sendbackup.h \
sendbackup-dump.c sendbackup-gnutar.c
-noinst_HEADERS = amandad.h amandates.h getfsent.h \
- findpass.h client_util.h
+noinst_HEADERS = amandates.h getfsent.h \
+ findpass.h client_util.h \
+ clientconf.h
getfsent_SOURCES = getfsent.test.c
all: all-am
echo " rm -f $$p $$f"; \
rm -f $$p $$f ; \
done
-amandad$(EXEEXT): $(amandad_OBJECTS) $(amandad_DEPENDENCIES)
- @rm -f amandad$(EXEEXT)
- $(LINK) $(amandad_LDFLAGS) $(amandad_OBJECTS) $(amandad_LDADD) $(LIBS)
calcsize$(EXEEXT): $(calcsize_OBJECTS) $(calcsize_DEPENDENCIES)
@rm -f calcsize$(EXEEXT)
$(LINK) $(calcsize_LDFLAGS) $(calcsize_OBJECTS) $(calcsize_LDADD) $(LIBS)
distclean-compile:
-rm -f *.tab.c
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/amandad.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/amandates.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/calcsize.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/client_util.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/clientconf.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/findpass.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getfsent.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getfsent.test.Po@am__quote@
@WANT_SETUID_CLIENT_TRUE@ fi; \
@WANT_SETUID_CLIENT_TRUE@ done
+lint:
+ @ for p in $(libexec_PROGRAMS); do \
+ f="$$p.c $(libamclient_la_SOURCES)"; \
+ (cd ../common-src; make listlibsrc); \
+ f="$$f "`cat ../common-src/listlibsrc.output`; \
+ echo $(LINT) $$f; \
+ $(LINT) $(LINTFLAGS) $(CPPFLAGS) $(DEFS) -I. -I../config \
+ $(INCLUDES) $$f; \
+ if [ $$? -ne 0 ]; then \
+ exit 1; \
+ fi; \
+ done; \
+ exit 0
+
%.test.c: $(srcdir)/%.c
echo '#define TEST' >$@
echo '#include "$<"' >>$@
+++ /dev/null
-/*
- * Amanda, The Advanced Maryland Automatic Network Disk Archiver
- * Copyright (c) 1991-1999 University of Maryland at College Park
- * All Rights Reserved.
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of U.M. not be used in advertising or
- * publicity pertaining to distribution of the software without specific,
- * written prior permission. U.M. makes no representations about the
- * suitability of this software for any purpose. It is provided "as is"
- * without express or implied warranty.
- *
- * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
- * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * Authors: the Amanda Development Team. Its members are listed in a
- * file named AUTHORS, in the root directory of this distribution.
- */
-
-/*
- * $Id: amandad.c,v 1.62.2.2 2006/05/08 11:50:16 martinea Exp $
- *
- * handle client-host side of Amanda network communications, including
- * security checks, execution of the proper service, and acking the
- * master side
- */
-
-/*#define AMANDAD_DEBUG*/
-
-#include "amanda.h"
-#include "amandad.h"
-#include "clock.h"
-#include "event.h"
-#include "amfeatures.h"
-#include "packet.h"
-#include "version.h"
-#include "queue.h"
-#include "security.h"
-#include "stream.h"
-#include "util.h"
-#include "client_util.h"
-
-#define REP_TIMEOUT (6*60*60) /* secs for service to reply */
-#define ACK_TIMEOUT 10 /* XXX should be configurable */
-#define MAX_REP_RETRIES 5
-
-/*
- * These are the actions for entering the state machine
- */
-typedef enum { A_START, A_RECVPKT, A_RECVREP, A_PENDING, A_FINISH, A_CONTINUE,
- A_SENDNAK, A_TIMEOUT } action_t;
-
-/*
- * This is a state in the state machine. It is a function pointer to
- * the function that actually implements the state.
- */
-struct active_service;
-typedef action_t (*state_t) P((struct active_service *, action_t, pkt_t *));
-
-/*
- * This structure describes an active running service.
- *
- * An active service is something running that we have received
- * a request for. This structure holds info on that service, including
- * file descriptors for data, etc, as well as the security handle
- * for communications with the amanda server.
- */
-struct active_service {
- char *cmd; /* name of command we ran */
- char *arguments; /* arguments we sent it */
- security_handle_t *security_handle; /* remote server */
- state_t state; /* how far this has progressed */
- pid_t pid; /* pid of subprocess */
- int send_partial_reply; /* send PREP packet */
- int reqfd; /* pipe to write requests */
- int repfd; /* pipe to read replies */
- event_handle_t *ev_repfd; /* read event handle for repfd */
- event_handle_t *ev_reptimeout; /* timeout for rep data */
- pkt_t rep_pkt; /* rep packet we're sending out */
- char repbuf[MAX_PACKET]; /* buffer to read the rep into */
- int repbufsize; /* length of repbuf */
- int repretry; /* times we'll retry sending the rep */
- /*
- * General user streams to the process, and their equivalent
- * network streams.
- */
- struct datafd_handle {
- int fd; /* pipe to child process */
- event_handle_t *ev_handle; /* it's read event handle */
- security_stream_t *netfd; /* stream to amanda server */
- struct active_service *as; /* pointer back to our enclosure */
- } data[DATA_FD_COUNT];
- char databuf[NETWORK_BLOCK_BYTES]; /* buffer to relay netfd data in */
- TAILQ_ENTRY(active_service) tq; /* queue handle */
-};
-
-/*
- * Here are the services that we allow.
- */
-static const char *services[] = {
- "noop",
- "sendsize",
- "sendbackup",
- "selfcheck",
-};
-#define NSERVICES (sizeof(services) / sizeof(services[0]))
-
-/*
- * Queue of outstanding requests that we are running.
- */
-static struct {
- TAILQ_HEAD(, active_service) tailq;
- int qlength;
-} serviceq = {
- TAILQ_HEAD_INITIALIZER(serviceq.tailq), 0
-};
-
-/*
- * Data for dbmalloc to check for memory leaks
- */
-#ifdef USE_DBMALLOC
-static struct {
- struct {
- unsigned long size, hist;
- } start, end;
-} dbmalloc_info;
-#endif
-
-int ack_timeout = ACK_TIMEOUT;
-
-int main P((int argc, char **argv));
-
-static int allocstream P((struct active_service *, int));
-static void exit_check P((void *));
-static void protocol_accept P((security_handle_t *, pkt_t *));
-static void state_machine P((struct active_service *, action_t, pkt_t *));
-
-static action_t s_sendack P((struct active_service *, action_t, pkt_t *));
-static action_t s_repwait P((struct active_service *, action_t, pkt_t *));
-static action_t s_processrep P((struct active_service *, action_t, pkt_t *));
-static action_t s_sendrep P((struct active_service *, action_t, pkt_t *));
-static action_t s_ackwait P((struct active_service *, action_t, pkt_t *));
-
-static void repfd_recv P((void *));
-static void timeout_repfd P((void *));
-static void protocol_recv P((void *, pkt_t *, security_status_t));
-static void process_netfd P((void *));
-static struct active_service *service_new P((security_handle_t *,
- const char *, const char *));
-static void service_delete P((struct active_service *));
-static int writebuf P((struct active_service *, const void *, size_t));
-static int do_sendpkt P((security_handle_t *handle, pkt_t *pkt));
-
-#ifdef AMANDAD_DEBUG
-static const char *state2str P((state_t));
-static const char *action2str P((action_t));
-#endif
-
-int
-main(argc, argv)
- int argc;
- char **argv;
-{
- int i, in, out;
- const security_driver_t *secdrv;
- int no_exit = 0;
- char *pgm = "amandad"; /* in case argv[0] is not set */
-
- safe_fd(-1, 0);
- safe_cd();
-
- if(argv == NULL) {
- error("argv == NULL\n");
- }
-
- /*
- * When called via inetd, it is not uncommon to forget to put the
- * argv[0] value on the config line. On some systems (e.g. Solaris)
- * this causes argv and/or argv[0] to be NULL, so we have to be
- * careful getting our name.
- */
- if (argc >= 1 && argv != NULL && argv[0] != NULL) {
- if((pgm = strrchr(argv[0], '/')) != NULL) {
- pgm++;
- } else {
- pgm = argv[0];
- }
- }
-
- set_pname(pgm);
-
- /* Don't die when child closes pipe */
- signal(SIGPIPE, SIG_IGN);
-
-#ifdef USE_DBMALLOC
- dbmalloc_info.start.size = malloc_inuse(&dbmalloc_info.start.hist);
-#endif
-
- erroutput_type = (ERR_INTERACTIVE|ERR_SYSLOG);
-
-#ifdef FORCE_USERID
- /* we'd rather not run as root */
- if (geteuid() == 0) {
- if(client_uid == (uid_t) -1) {
- error("error [cannot find user %s in passwd file]\n", CLIENT_LOGIN);
- }
- initgroups(CLIENT_LOGIN, client_gid);
- setgid(client_gid);
- setegid(client_gid);
- seteuid(client_uid);
- }
-#endif /* FORCE_USERID */
-
- /*
- * ad-hoc argument parsing
- *
- * We accept -auth=[authentication type]
- * -no-exit
-#ifdef AMANDAD_DEBUG
- * -tcp=[port]
- * -udp=[port]
-#endif
- */
- secdrv = NULL;
- in = 0; out = 1; /* default to stdin/stdout */
- for (i = 1; i < argc; i++) {
- /*
- * accept -krb4 as an alias for -auth=krb4 (for compatibility)
- */
- if (strcmp(argv[i], "-krb4") == 0) {
- argv[i] = "-auth=krb4";
- /* FALLTHROUGH */
- }
-
- /*
- * Get a driver for a security type specified after -auth=
- */
- if (strncmp(argv[i], "-auth=", strlen("-auth=")) == 0) {
- argv[i] += strlen("-auth=");
- secdrv = security_getdriver(argv[i]);
- if (secdrv == NULL)
- error("no driver for security type '%s'", argv[i]);
- continue;
- }
-
- /*
- * If -no-exit is specified, always run even after requests have
- * been satisfied.
- */
- if (strcmp(argv[i], "-no-exit") == 0) {
- no_exit = 1;
- continue;
- }
-
-#ifdef AMANDAD_DEBUG
- /*
- * Allow us to directly bind to a udp port for debugging.
- * This may only apply to some security types.
- */
- if (strncmp(argv[i], "-udp=", strlen("-udp=")) == 0) {
- struct sockaddr_in sin;
-
- argv[i] += strlen("-udp=");
- in = out = socket(AF_INET, SOCK_DGRAM, 0);
- if (in < 0)
- error("can't create dgram socket: %s\n", strerror(errno));
- sin.sin_family = AF_INET;
- sin.sin_addr.s_addr = INADDR_ANY;
- sin.sin_port = htons(atoi(argv[i]));
- if (bind(in, (struct sockaddr *)&sin, sizeof(sin)) < 0)
- error("can't bind to port %d: %s\n", atoi(argv[i]),
- strerror(errno));
- }
- /*
- * Ditto for tcp ports.
- */
- if (strncmp(argv[i], "-tcp=", strlen("-tcp=")) == 0) {
- struct sockaddr_in sin;
- int sock, n;
-
- argv[i] += strlen("-tcp=");
- sock = socket(AF_INET, SOCK_STREAM, 0);
- if (sock < 0)
- error("can't create tcp socket: %s\n", strerror(errno));
- n = 1;
- setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void *)&n, sizeof(n));
- sin.sin_family = AF_INET;
- sin.sin_addr.s_addr = INADDR_ANY;
- sin.sin_port = htons(atoi(argv[i]));
- if (bind(sock, (struct sockaddr *)&sin, sizeof(sin)) < 0)
- error("can't bind to port %d: %s\n", atoi(argv[i]),
- strerror(errno));
- listen(sock, 10);
- n = sizeof(sin);
- in = out = accept(sock, (struct sockaddr *)&sin, &n);
- }
-#endif
- }
-
- /*
- * If no security type specified, use BSD
- */
- if (secdrv == NULL) {
- secdrv = security_getdriver("BSD");
- if (secdrv == NULL)
- error("no driver for default security type 'BSD'");
- }
-
- /* initialize */
-
- dbopen();
- {
- /* this lameness is for error() */
- int db_fd = dbfd();
- if(db_fd != -1) {
- dup2(db_fd, 2);
- }
- }
-
- startclock();
-
- dbprintf(("%s: version %s\n", get_pname(), version()));
- for (i = 0; version_info[i] != NULL; i++) {
- dbprintf(("%s: %s", debug_prefix(NULL), version_info[i]));
- }
-
- if (! (argc >= 1 && argv != NULL && argv[0] != NULL)) {
- dbprintf(("%s: WARNING: argv[0] not defined: check inetd.conf\n",
- debug_prefix(NULL)));
- }
-
- /*
- * Schedule to call protocol_accept() when new security handles
- * are created on stdin.
- */
- security_accept(secdrv, in, out, protocol_accept);
-
- /*
- * Schedule an event that will try to exit every 30 seconds if there
- * are no requests outstanding.
- */
- (void)event_register(30, EV_TIME, exit_check, &no_exit);
-
- /*
- * Call event_loop() with an arg of 0, telling it to block until all
- * events are completed.
- */
- event_loop(0);
-
- /* NOTREACHED */
- exit(1); /* appease gcc/lint */
-}
-
-/*
- * This runs periodically and checks to see if we have any active services
- * still running. If we don't, then we quit.
- */
-static void
-exit_check(cookie)
- void *cookie;
-{
- int no_exit;
-
- assert(cookie != NULL);
- no_exit = *(int *)cookie;
-
- /*
- * If things are still running, then don't exit.
- */
- if (serviceq.qlength > 0)
- return;
-
- /*
- * If the caller asked us to never exit, then we're done
- */
- if (no_exit)
- return;
-
-#ifdef USE_DBMALLOC
- dbmalloc_info.end.size = malloc_inuse(&dbmalloc_info.end.hist);
-
- if (dbmalloc_info.start.size != dbmalloc_info.end.size) {
- malloc_list(dbfd(), dbmalloc_info.start.hist,
- dbmalloc_info.end.hist);
- }
-#endif
-
- dbclose();
- exit(0);
-}
-
-/*
- * Handles new incoming protocol handles. This is a callback for
- * security_accept(), which gets called when new handles are detected.
- */
-static void
-protocol_accept(handle, pkt)
- security_handle_t *handle;
- pkt_t *pkt;
-{
- pkt_t pkt_out;
- struct active_service *as;
- char *pktbody, *tok, *service, *arguments;
- int i;
-
- /*
- * If pkt is NULL, then there was a problem with the new connection.
- */
- if (pkt == NULL) {
- dbprintf(("%s: accept error: %s\n",
- debug_prefix_time(NULL), security_geterror(handle)));
- pkt_init(&pkt_out, P_NAK, "ERROR %s\n", security_geterror(handle));
- do_sendpkt(handle, &pkt_out);
- security_close(handle);
- return;
- }
-
- dbprintf(("%s: accept recv %s pkt:\n<<<<<\n%s>>>>>\n",
- debug_prefix_time(NULL), pkt_type2str(pkt->type), pkt->body));
-
- /*
- * If this is not a REQ packet, just forget about it.
- */
- if (pkt->type != P_REQ) {
- dbprintf(("%s: received unexpected %s packet:\n<<<<<\n%s>>>>>\n\n",
- debug_prefix_time(NULL), pkt_type2str(pkt->type), pkt->body));
- security_close(handle);
- return;
- }
-
- pktbody = service = arguments = NULL;
- as = NULL;
-
- /*
- * Parse out the service and arguments
- */
-
- pktbody = stralloc(pkt->body);
-
- tok = strtok(pktbody, " ");
- if (tok == NULL)
- goto badreq;
- if (strcmp(tok, "SERVICE") != 0)
- goto badreq;
-
- tok = strtok(NULL, " \n");
- if (tok == NULL)
- goto badreq;
- service = stralloc(tok);
-
- /* we call everything else 'arguments' */
- tok = strtok(NULL, "");
- if (tok == NULL)
- goto badreq;
- arguments = stralloc(tok);
-
- /* see if it's one we allow */
- for (i = 0; i < NSERVICES; i++)
- if (strcmp(services[i], service) == 0)
- break;
- if (i == NSERVICES) {
- dbprintf(("%s: %s: invalid service\n",
- debug_prefix_time(NULL), service));
- pkt_init(&pkt_out, P_NAK, "ERROR %s: invalid service\n", service);
- goto send_pkt_out;
- }
-
- service = newvstralloc(service,
- libexecdir, "/", service, versionsuffix(),
- NULL);
- if (access(service, X_OK) < 0) {
- dbprintf(("%s: can't execute %s: %s\n",
- debug_prefix_time(NULL), service, strerror(errno)));
- pkt_init(&pkt_out, P_NAK, "ERROR execute access to \"%s\" denied\n",
- service);
- goto send_pkt_out;
- }
-
- /* see if its already running */
- for (as = TAILQ_FIRST(&serviceq.tailq); as != NULL;
- as = TAILQ_NEXT(as, tq)) {
- if (strcmp(as->cmd, service) == 0 &&
- strcmp(as->arguments, arguments) == 0) {
- dbprintf(("%s: %s %s: already running, acking req\n",
- debug_prefix_time(NULL), service, arguments));
- pkt_init(&pkt_out, P_ACK, "");
- goto send_pkt_out;
- }
- }
-
- /*
- * create a new service instance, and send the arguments down
- * the request pipe.
- */
- dbprintf(("%s: creating new service: %s\n%s\n",
- debug_prefix_time(NULL), service, arguments));
- as = service_new(handle, service, arguments);
- if (writebuf(as, arguments, strlen(arguments)) < 0) {
- const char *errmsg = strerror(errno);
- dbprintf(("%s: error sending arguments to %s: %s\n",
- debug_prefix_time(NULL), service, errmsg));
- pkt_init(&pkt_out, P_NAK, "ERROR error writing arguments to %s: %s\n",
- service, errmsg);
- goto send_pkt_out;
- }
- aclose(as->reqfd);
-
- amfree(pktbody);
- amfree(service);
- amfree(arguments);
-
- /*
- * Move to the sendack state, and start up the state
- * machine.
- */
- as->state = s_sendack;
- state_machine(as, A_START, NULL);
- return;
-
-badreq:
- pkt_init(&pkt_out, P_NAK, "ERROR invalid REQ\n");
- dbprintf(("%s: received invalid %s packet:\n<<<<<\n%s>>>>>\n\n",
- debug_prefix_time(NULL), pkt_type2str(pkt->type), pkt->body));
-
-send_pkt_out:
- amfree(pktbody);
- amfree(service);
- amfree(arguments);
- if(as) service_delete(as);
- do_sendpkt(handle, &pkt_out);
- security_close(handle);
-}
-
-/*
- * Handles incoming protocol packets. Routes responses to the proper
- * running service.
- */
-static void
-state_machine(as, action, pkt)
- struct active_service *as;
- action_t action;
- pkt_t *pkt;
-{
- action_t retaction;
- state_t curstate;
- pkt_t nak;
-
-#ifdef AMANDAD_DEBUG
- dbprintf(("%s: state_machine: %X entering\n",
- debug_prefix_time(NULL), (unsigned int)as));
-#endif
- for (;;) {
- curstate = as->state;
-#ifdef AMANDAD_DEBUG
- dbprintf(("%s: state_machine: %X curstate=%s action=%s\n",
- debug_prefix_time(NULL), (unsigned int)as,
- state2str(curstate), action2str(action)));
-#endif
- retaction = (*curstate)(as, action, pkt);
-#ifdef AMANDAD_DEBUG
- dbprintf(("%s: state_machine: %X curstate=%s returned %s (nextstate=%s)\n",
- debug_prefix_time(NULL),
- (unsigned int)as, state2str(curstate), action2str(retaction),
- state2str(as->state)));
-#endif
-
- switch (retaction) {
- /*
- * State has queued up and is now blocking on input.
- */
- case A_PENDING:
-#ifdef AMANDAD_DEBUG
- dbprintf(("%s: state_machine: %X leaving (A_PENDING)\n",
- debug_prefix_time(NULL), (unsigned int)as));
-#endif
- return;
-
- /*
- * service has switched states. Loop.
- */
- case A_CONTINUE:
- break;
-
- /*
- * state has determined that the packet it received was bogus.
- * Send a nak, and return.
- */
- case A_SENDNAK:
- dbprintf(("%s: received unexpected %s packet\n",
- debug_prefix_time(NULL), pkt_type2str(pkt->type)));
- dbprintf(("<<<<<\n%s----\n\n", pkt->body));
- pkt_init(&nak, P_NAK, "ERROR unexpected packet type %s\n",
- pkt_type2str(pkt->type));
- do_sendpkt(as->security_handle, &nak);
-#ifdef AMANDAD_DEBUG
- dbprintf(("%s: state_machine: %X leaving (A_SENDNAK)\n",
- debug_prefix_time(NULL), (unsigned int)as));
-#endif
- return;
-
- /*
- * Service is done. Remove it and finish.
- */
- case A_FINISH:
- service_delete(as);
-#ifdef AMANDAD_DEBUG
- dbprintf(("%s: state_machine: %X leaving (A_FINISH)\n",
- debug_prefix_time(NULL), (unsigned int)as));
-#endif
- return;
-
- default:
- assert(0);
- break;
- }
- }
- /* NOTREACHED */
-}
-
-/*
- * This state just sends an ack. After that, we move to the repwait
- * state to wait for REP data to arrive from the subprocess.
- */
-static action_t
-s_sendack(as, action, pkt)
- struct active_service *as;
- action_t action;
- pkt_t *pkt;
-{
- pkt_t ack;
-
- pkt_init(&ack, P_ACK, "");
- if (do_sendpkt(as->security_handle, &ack) < 0) {
- dbprintf(("%s: error sending ACK: %s\n",
- debug_prefix_time(NULL), security_geterror(as->security_handle)));
- return (A_FINISH);
- }
-
- /*
- * move to the repwait state
- * Setup a listener for data on the reply fd, but also
- * listen for packets over the wire, as the server may
- * poll us if we take a long time.
- * Setup a timeout that will fire if it takes too long to
- * receive rep data.
- */
- as->state = s_repwait;
- as->ev_repfd = event_register(as->repfd, EV_READFD, repfd_recv, as);
- as->ev_reptimeout = event_register(REP_TIMEOUT, EV_TIME,
- timeout_repfd, as);
- security_recvpkt(as->security_handle, protocol_recv, as, -1);
- return (A_PENDING);
-}
-
-/*
- * This is the repwait state. We have responded to the initial REQ with
- * an ACK, and we are now waiting for the process we spawned to pass us
- * data to send in a REP.
- */
-static action_t
-s_repwait(as, action, pkt)
- struct active_service *as;
- action_t action;
- pkt_t *pkt;
-{
- int n;
-
- /*
- * We normally shouldn't receive any packets while waiting
- * for our REP data, but in some cases we do.
- */
- if (action == A_RECVPKT) {
- assert(pkt != NULL);
- /*
- * Another req for something that's running. Just send an ACK
- * and go back and wait for more data.
- */
- if (pkt->type == P_REQ) {
- dbprintf(("%s: received dup P_REQ packet, ACKing it\n",
- debug_prefix_time(NULL)));
- pkt_init(&as->rep_pkt, P_ACK, "");
- do_sendpkt(as->security_handle, &as->rep_pkt);
- return (A_PENDING);
- }
- /* something unexpected. Nak it */
- return (A_SENDNAK);
- }
-
- if (action == A_TIMEOUT) {
- pkt_init(&as->rep_pkt, P_NAK, "ERROR timeout on reply pipe\n");
- dbprintf(("%s: %s timed out waiting for REP data\n",
- debug_prefix_time(NULL), as->cmd));
- do_sendpkt(as->security_handle, &as->rep_pkt);
- return (A_FINISH);
- }
-
- assert(action == A_RECVREP);
-
- /*
- * If the read fails, consider the process dead, and remove it.
- * Always save room for nul termination.
- */
- if (as->repbufsize + 1 >= sizeof(as->repbuf)) {
- dbprintf(("%s: more than %d bytes in reply\n",
- debug_prefix_time(NULL), sizeof(as->repbuf)));
- dbprintf(("%s: reply so far:\n%s\n", debug_prefix(NULL), as->repbuf));
- pkt_init(&as->rep_pkt, P_NAK, "ERROR more than %d bytes in reply\n",
- sizeof(as->repbuf));
- do_sendpkt(as->security_handle, &as->rep_pkt);
- return (A_FINISH);
- }
- do {
- n = read(as->repfd, as->repbuf + as->repbufsize,
- sizeof(as->repbuf) - as->repbufsize - 1);
- } while ((n < 0) && ((errno == EINTR) || (errno == EAGAIN)));
- if (n < 0) {
- const char *errstr = strerror(errno);
- dbprintf(("%s: read error on reply pipe: %s\n",
- debug_prefix_time(NULL), errstr));
- pkt_init(&as->rep_pkt, P_NAK, "ERROR read error on reply pipe: %s\n",
- errstr);
- do_sendpkt(as->security_handle, &as->rep_pkt);
- return (A_FINISH);
- }
- /*
- * If we got some data, go back and wait for more, or EOF. Nul terminate
- * the buffer first.
- */
- as->repbuf[n + as->repbufsize] = '\0';
- if (n > 0) {
- as->repbufsize += n;
- if(as->send_partial_reply) {
- pkt_init(&as->rep_pkt, P_PREP, "%s", as->repbuf);
- do_sendpkt(as->security_handle, &as->rep_pkt);
- pkt_init(&as->rep_pkt, P_REP, "");
- }
-
- return (A_PENDING);
- }
-
- /*
- * If we got 0, then we hit EOF. Process the data and release
- * the timeout.
- */
- assert(n == 0);
-
- assert(as->ev_repfd != NULL);
- event_release(as->ev_repfd);
- as->ev_repfd = NULL;
-
- assert(as->ev_reptimeout != NULL);
- event_release(as->ev_reptimeout);
- as->ev_reptimeout = NULL;
-
- as->state = s_processrep;
- aclose(as->repfd);
- return (A_CONTINUE);
-}
-
-/*
- * After we have read in all of the rep data, we process it and send
- * it out as a REP packet.
- */
-static action_t
-s_processrep(as, action, pkt)
- struct active_service *as;
- action_t action;
- pkt_t *pkt;
-{
- char *tok, *repbuf;
-
- /*
- * Copy the rep lines into the outgoing packet.
- *
- * If this line is a CONNECT, translate it
- * Format is "CONNECT <tag> <handle> <tag> <handle> etc...
- * Example:
- *
- * CONNECT DATA 4 MESG 5 INDEX 6
- *
- * The tags are arbitrary. The handles are in the DATA_FD pool.
- * We need to map these to security streams and pass them back
- * to the amanda server. If the handle is -1, then we don't map.
- */
- repbuf = stralloc(as->repbuf);
- pkt_init(&as->rep_pkt, P_REP, "");
- tok = strtok(repbuf, " ");
- if (tok == NULL)
- goto error;
- if (strcmp(tok, "CONNECT") == 0) {
- char *line, *nextbuf;
-
- /* Save the entire line */
- line = strtok(NULL, "\n");
- /* Save the buf following the line */
- nextbuf = strtok(NULL, "");
-
- if (line == NULL || nextbuf == NULL)
- goto error;
-
- pkt_cat(&as->rep_pkt, "CONNECT");
-
- /* loop over the id/handle pairs */
- for (;;) {
- /* id */
- tok = strtok(line, " ");
- line = NULL; /* keep working from line */
- if (tok == NULL)
- break;
- pkt_cat(&as->rep_pkt, " %s", tok);
-
- /* handle */
- tok = strtok(NULL, " \n");
- if (tok == NULL)
- goto error;
- /* convert the handle into something the server can process */
- pkt_cat(&as->rep_pkt, " %d", allocstream(as, atoi(tok)));
- }
- pkt_cat(&as->rep_pkt, "\n%s", nextbuf);
- } else {
-error:
- pkt_cat(&as->rep_pkt, "%s", as->repbuf);
- }
-
- /*
- * We've setup our REP packet in as->rep_pkt. Now move to the transmission
- * state.
- */
- as->state = s_sendrep;
- as->repretry = MAX_REP_RETRIES;
- amfree(repbuf);
- return (A_CONTINUE);
-}
-
-/*
- * This is the state where we send the REP we just collected from our child.
- */
-static action_t
-s_sendrep(as, action, pkt)
- struct active_service *as;
- action_t action;
- pkt_t *pkt;
-{
-
- /*
- * Transmit it and move to the ack state.
- */
- do_sendpkt(as->security_handle, &as->rep_pkt);
- security_recvpkt(as->security_handle, protocol_recv, as, ACK_TIMEOUT);
- as->state = s_ackwait;
- return (A_PENDING);
-}
-
-/*
- * This is the state in which we wait for the server to ACK the REP
- * we just sent it.
- */
-static action_t
-s_ackwait(as, action, pkt)
- struct active_service *as;
- action_t action;
- pkt_t *pkt;
-{
- struct datafd_handle *dh;
- int npipes;
-
- /*
- * If we got a timeout, try again, but eventually give up.
- */
- if (action == A_TIMEOUT) {
- if (--as->repretry > 0) {
- as->state = s_sendrep;
- return (A_CONTINUE);
- }
- dbprintf(("%s: timeout waiting for ACK for our REP\n",
- debug_prefix_time(NULL)));
- return (A_FINISH);
- }
-#ifdef AMANDAD_DEBUG
- dbprintf(("%s: received ACK, now opening streams\n",
- debug_prefix_time(NULL)));
-#endif
-
- assert(action == A_RECVPKT);
- if (pkt->type != P_ACK)
- return (A_SENDNAK);
-
- /*
- * Got the ack, now open the pipes
- */
- for (dh = &as->data[0]; dh < &as->data[DATA_FD_COUNT]; dh++) {
- if (dh->netfd == NULL)
- continue;
- if (security_stream_accept(dh->netfd) < 0) {
- dbprintf(("%s: stream %d accept failed: %s\n",
- debug_prefix_time(NULL),
- dh - &as->data[0], security_geterror(as->security_handle)));
- security_stream_close(dh->netfd);
- dh->netfd = NULL;
- }
- /* setup an event for reads from it */
- dh->ev_handle = event_register(dh->fd, EV_READFD, process_netfd, dh);
- }
-
- /*
- * Pipes are open, so auth them. Count them at the same time.
- */
- for (npipes = 0, dh = &as->data[0]; dh < &as->data[DATA_FD_COUNT]; dh++) {
- if (dh->netfd == NULL)
- continue;
- if (security_stream_auth(dh->netfd) < 0) {
- security_stream_close(dh->netfd);
- dh->netfd = NULL;
- event_release(dh->ev_handle);
- dh->ev_handle = NULL;
- } else {
- npipes++;
- }
- }
-
- /*
- * If no pipes are open, then we're done. Otherwise, just start running.
- * The event handlers on all of the pipes will take it from here.
- */
-#ifdef AMANDAD_DEBUG
- dbprintf(("%s: at end of s_ackwait, npipes is %d\n",
- debug_prefix_time(NULL), npipes));
-#endif
- if (npipes == 0)
- return (A_FINISH);
- else {
- security_close(as->security_handle);
- as->security_handle = NULL;
- return (A_PENDING);
- }
-}
-
-/*
- * Called when a repfd has received data
- */
-static void
-repfd_recv(cookie)
- void *cookie;
-{
- struct active_service *as = cookie;
-
- assert(as != NULL);
- assert(as->ev_repfd != NULL);
-
- state_machine(as, A_RECVREP, NULL);
-}
-
-/*
- * Called when a repfd has timed out
- */
-static void
-timeout_repfd(cookie)
- void *cookie;
-{
- struct active_service *as = cookie;
-
- assert(as != NULL);
- assert(as->ev_reptimeout != NULL);
-
- state_machine(as, A_TIMEOUT, NULL);
-}
-
-/*
- * Called when a handle has received data
- */
-static void
-protocol_recv(cookie, pkt, status)
- void *cookie;
- pkt_t *pkt;
- security_status_t status;
-{
- struct active_service *as = cookie;
-
- assert(as != NULL);
-
- switch (status) {
- case S_OK:
- dbprintf(("%s: received %s pkt:\n<<<<<\n%s>>>>>\n",
- debug_prefix_time(NULL), pkt_type2str(pkt->type), pkt->body));
- state_machine(as, A_RECVPKT, pkt);
- break;
- case S_TIMEOUT:
- dbprintf(("%s: timeout\n", debug_prefix_time(NULL)));
- state_machine(as, A_TIMEOUT, NULL);
- break;
- case S_ERROR:
- dbprintf(("%s: receive error: %s\n",
- debug_prefix_time(NULL), security_geterror(as->security_handle)));
- break;
- }
-}
-
-/*
- * This is a generic relay function that just reads data from one of
- * the process's pipes and passes it up the equivalent security_stream_t
- */
-static void
-process_netfd(cookie)
- void *cookie;
-{
- pkt_t nak;
- struct datafd_handle *dh = cookie;
- struct active_service *as = dh->as;
- int n;
-
- do {
- n = read(dh->fd, as->databuf, sizeof(as->databuf));
- } while ((n < 0) && ((errno == EINTR) || (errno == EAGAIN)));
-
- /*
- * Process has died.
- */
- if (n < 0) {
- pkt_init(&nak, P_NAK, "ERROR data descriptor %d broken: %s\n",
- dh->fd, strerror(errno));
- goto sendnak;
- }
- /*
- * Process has closed the pipe. Just remove this event handler.
- * If all pipes are closed, shut down this service.
- */
- if (n == 0) {
- event_release(dh->ev_handle);
- dh->ev_handle = NULL;
- security_stream_close(dh->netfd);
- dh->netfd = NULL;
- for (dh = &as->data[0]; dh < &as->data[DATA_FD_COUNT]; dh++) {
- if (dh->netfd != NULL)
- return;
- }
- service_delete(as);
- return;
- }
- if (security_stream_write(dh->netfd, as->databuf, n) < 0) {
- /* stream has croaked */
- pkt_init(&nak, P_NAK, "ERROR write error on stream %d: %s\n",
- security_stream_id(dh->netfd),
- security_stream_geterror(dh->netfd));
- goto sendnak;
- }
- return;
-
-sendnak:
- do_sendpkt(as->security_handle, &nak);
- service_delete(as);
-}
-
-
-/*
- * Convert a local stream handle (DATA_FD...) into something that
- * can be sent to the amanda server.
- *
- * Returns a number that should be sent to the server in the REP packet.
- */
-static int
-allocstream(as, handle)
- struct active_service *as;
- int handle;
-{
- struct datafd_handle *dh;
-
- /* if the handle is -1, then we don't bother */
- if (handle < 0)
- return (-1);
-
- /* make sure the handle's kosher */
- if (handle < DATA_FD_OFFSET || handle >= DATA_FD_OFFSET + DATA_FD_COUNT)
- return (-1);
-
- /* get a pointer into our handle array */
- dh = &as->data[handle - DATA_FD_OFFSET];
-
- /* make sure we're not already using the net handle */
- if (dh->netfd != NULL)
- return (-1);
-
- /* allocate a stream from the security layer and return */
- dh->netfd = security_stream_server(as->security_handle);
- if (dh->netfd == NULL) {
- dbprintf(("%s: couldn't open stream to server: %s\n",
- debug_prefix_time(NULL), security_geterror(as->security_handle)));
- return (-1);
- }
-
- /*
- * convert the stream into a numeric id that can be sent to the
- * remote end.
- */
- return (security_stream_id(dh->netfd));
-}
-
-/*
- * Create a new service instance
- */
-static struct active_service *
-service_new(security_handle, cmd, arguments)
- security_handle_t *security_handle;
- const char *cmd, *arguments;
-{
- int data[DATA_FD_COUNT + 2][2], i;
- struct active_service *as;
- pid_t pid;
- int newfd;
-
- assert(security_handle != NULL);
- assert(cmd != NULL);
- assert(arguments != NULL);
-
- /* a plethora of pipes */
- for (i = 0; i < DATA_FD_COUNT + 2; i++)
- if (pipe(data[i]) < 0)
- error("pipe: %s", strerror(errno));
-
- switch(pid = fork()) {
- case -1:
- error("could not fork service %s: %s", cmd, strerror(errno));
- default:
- /*
- * The parent. Close the far ends of our pipes and return.
- */
- as = alloc(sizeof(*as));
- as->cmd = stralloc(cmd);
- as->arguments = stralloc(arguments);
- as->security_handle = security_handle;
- as->state = NULL;
- as->pid = pid;
- as->send_partial_reply = 0;
- if(strcmp(cmd+(strlen(cmd)-8), "sendsize") == 0) {
- g_option_t *g_options;
- char *option_str, *p;
-
- option_str = stralloc(as->arguments+8);
- p = strchr(option_str,'\n');
- if(p) *p = '\0';
-
- g_options = parse_g_options(option_str, 1);
- if(am_has_feature(g_options->features, fe_partial_estimate)) {
- as->send_partial_reply = 1;
- }
- amfree(g_options);
- amfree(option_str);
- }
-
- /* write to the request pipe */
- aclose(data[0][0]);
- as->reqfd = data[0][1];
-
- /*
- * read from the reply pipe
- */
- as->repfd = data[1][0];
- aclose(data[1][1]);
- as->ev_repfd = NULL;
- as->repbufsize = 0;
- as->repretry = 0;
-
- /*
- * read from the rest of the general-use pipes
- * (netfds are opened as the client requests them)
- */
- for (i = 0; i < DATA_FD_COUNT; i++) {
- aclose(data[i + 2][1]);
- as->data[i].fd = data[i + 2][0];
- as->data[i].ev_handle = NULL;
- as->data[i].netfd = NULL;
- as->data[i].as = as;
- }
-
- /* add it to the service queue */
- /* increment the active service count */
- TAILQ_INSERT_TAIL(&serviceq.tailq, as, tq);
- serviceq.qlength++;
-
- return (as);
- case 0:
- /*
- * The child. Put our pipes in their advertised locations
- * and start up.
- */
-#ifdef FORCE_USERID
- seteuid((uid_t)0);
- setuid(client_uid);
-#endif
-
- /*
- * The data stream is stdin in the new process
- */
- if (dup2(data[0][0], 0) < 0) {
- error("dup %d to %d failed: %s\n", data[0][0], 0,
- strerror(errno));
- }
- aclose(data[0][0]);
- aclose(data[0][1]);
-
- /*
- * The reply stream is stdout
- */
- if (dup2(data[1][1], 1) < 0) {
- error("dup %d to %d failed: %s\n", data[1][1], 1,
- strerror(errno));
- }
- aclose(data[1][0]);
- aclose(data[1][1]);
-
- /*
- * The rest start at the offset defined in amandad.h, and continue
- * through the internal defined.
- */
- for (i = 0; i < DATA_FD_COUNT; i++)
- aclose(data[i + 2][0]);
-
- /*
- * Make sure they are not open in the range DATA_FD_OFFSET to
- * DATA_FD_OFFSET + DATA_FD_COUNT - 1
- */
- for (i = 0; i < DATA_FD_COUNT; i++) {
- while(data[i + 2][1] >= DATA_FD_OFFSET &&
- data[i + 2][1] <= DATA_FD_OFFSET + DATA_FD_COUNT - 1) {
- newfd = dup(data[i + 2][1]);
- if(newfd == -1)
- error("Can't dup out off DATA_FD range");
- data[i + 2][1] = newfd;
- }
- }
- for (i = 0; i < DATA_FD_COUNT; i++)
- close(DATA_FD_OFFSET + i);
-
- for (i = 0; i < DATA_FD_COUNT; i++) {
- if (dup2(data[i + 2][1], i + DATA_FD_OFFSET) < 0) {
- error("dup %d to %d failed: %s\n", data[i + 2][1],
- i + DATA_FD_OFFSET, strerror(errno));
- }
- aclose(data[i + 2][1]);
- }
-
- execle(cmd, cmd, NULL, safe_env());
- error("could not exec service %s: %s", cmd, strerror(errno));
- }
- /* NOTREACHED */
- return NULL;
-}
-
-/*
- * Unallocate a service instance
- */
-static void
-service_delete(as)
- struct active_service *as;
-{
- int i;
- struct datafd_handle *dh;
-
-#ifdef AMANDAD_DEBUG
- dbprintf(("%s: closing service: %s\n",
- debug_prefix_time(NULL), (as->cmd)?as->cmd:"??UNKONWN??"));
-#endif
-
- assert(as != NULL);
-
- assert(as->cmd != NULL);
- amfree(as->cmd);
-
- assert(as->arguments != NULL);
- amfree(as->arguments);
-
- if (as->reqfd != -1)
- aclose(as->reqfd);
- if (as->repfd != -1)
- aclose(as->repfd);
-
- if (as->ev_repfd != NULL)
- event_release(as->ev_repfd);
- if (as->ev_reptimeout != NULL)
- event_release(as->ev_reptimeout);
-
- for (i = 0; i < DATA_FD_COUNT; i++) {
- dh = &as->data[i];
-
- aclose(dh->fd);
-
- if (dh->netfd != NULL)
- security_stream_close(dh->netfd);
-
- if (dh->ev_handle != NULL)
- event_release(dh->ev_handle);
- }
-
- if (as->security_handle != NULL)
- security_close(as->security_handle);
-
- assert(as->pid > 0);
- kill(as->pid, SIGTERM);
- waitpid(as->pid, NULL, WNOHANG);
-
- TAILQ_REMOVE(&serviceq.tailq, as, tq);
- assert(serviceq.qlength > 0);
- serviceq.qlength--;
-
- amfree(as);
-}
-
-/*
- * Like 'fullwrite', but does the work in a child process so pipelines
- * do not hang.
- */
-static int
-writebuf(as, bufp, size)
- struct active_service *as;
- const void *bufp;
- size_t size;
-{
- int pid;
-
- switch (pid=fork()) {
- case -1:
- return -1;
-
- default:
- waitpid(pid, NULL, WNOHANG);
- return 0; /* this is the parent */
-
- case 0:
- break; /* this is the child */
- }
- aclose (as->repfd); /* make sure we are not a reader */
- exit (fullwrite(as->reqfd, bufp, size) != size);
-}
-
-static int
-do_sendpkt(handle, pkt)
- security_handle_t *handle;
- pkt_t *pkt;
-{
- dbprintf(("%s: sending %s pkt:\n<<<<<\n%s>>>>>\n",
- debug_prefix_time(NULL), pkt_type2str(pkt->type), pkt->body));
- return security_sendpkt(handle, pkt);
-}
-
-#ifdef AMANDAD_DEBUG
-/*
- * Convert a state into a string
- */
-static const char *
-state2str(state)
- state_t state;
-{
- static const struct {
- state_t state;
- const char str[13];
- } states[] = {
-#define X(state) { state, stringize(state) }
- X(s_sendack),
- X(s_repwait),
- X(s_processrep),
- X(s_sendrep),
- X(s_ackwait),
-#undef X
- };
- int i;
-
- for (i = 0; i < sizeof(states) / sizeof(states[0]); i++)
- if (state == states[i].state)
- return (states[i].str);
- return ("INVALID STATE");
-}
-
-/*
- * Convert an action into a string
- */
-static const char *
-action2str(action)
- action_t action;
-{
- static const struct {
- action_t action;
- const char str[12];
- } actions[] = {
-#define X(action) { action, stringize(action) }
- X(A_START),
- X(A_RECVPKT),
- X(A_RECVREP),
- X(A_PENDING),
- X(A_FINISH),
- X(A_CONTINUE),
- X(A_SENDNAK),
- X(A_TIMEOUT),
-#undef X
- };
- int i;
-
- for (i = 0; i < sizeof(actions) / sizeof(actions[0]); i++)
- if (action == actions[i].action)
- return (actions[i].str);
- return ("UNKNOWN ACTION");
-}
-#endif /* AMANDAD_DEBUG */
+++ /dev/null
-/*
- * Amanda, The Advanced Maryland Automatic Network Disk Archiver
- * Copyright (c) 1999 University of Maryland at College Park
- * All Rights Reserved.
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of U.M. not be used in advertising or
- * publicity pertaining to distribution of the software without specific,
- * written prior permission. U.M. makes no representations about the
- * suitability of this software for any purpose. It is provided "as is"
- * without express or implied warranty.
- *
- * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
- * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * Authors: the Amanda Development Team. Its members are listed in a
- * file named AUTHORS, in the root directory of this distribution.
- */
-/*
- * $Id: amandad.h,v 1.2 1999/04/16 05:12:39 kashmir Exp $
- */
-#ifndef AMANDAD_H
-#define AMANDAD_H
-
-/*
- * General-use pipes inherited by sendbackup that are connected to the
- * data, mesg, index, etc connections on the server. amandad sets these
- * up before calling sendbackup, and will relay data sent on them
- * back to the server.
- */
-#define DATA_FD_COUNT 3 /* number of general-use pipes */
-#define DATA_FD_OFFSET 50 /* fd at which they start */
-
-#endif /* AMANDAD_H */
* file named AUTHORS, in the root directory of this distribution.
*/
/*
- * $Id: amandates.c,v 1.16 2003/10/22 17:43:20 martinea Exp $
+ * $Id: amandates.c,v 1.21 2006/07/25 18:35:21 martinea Exp $
*
* manage amandates file, that mimics /etc/dumpdates, but stores
* GNUTAR dates
#include "amanda.h"
#include "getfsent.h"
+#include "util.h"
#include "amandates.h"
static amandates_t *amandates_list = NULL;
static FILE *amdf = NULL;
static int updated, readonly;
-static void import_dumpdates P((amandates_t *));
-static void enter_record P((char *, int , time_t));
-static amandates_t *lookup P((char *name, int import));
-
-int start_amandates(open_readwrite)
-int open_readwrite;
+static char *g_amandates_file = NULL;
+static void import_dumpdates(amandates_t *);
+static void enter_record(char *, int , time_t);
+static amandates_t *lookup(char *name, int import);
+
+int
+start_amandates(
+ char *amandates_file,
+ int open_readwrite)
{
- int rc, level;
- long ldate;
- char *line = NULL, *name = NULL;
+ int rc, level = 0;
+ long ldate = 0L;
+ char *line;
+ char *name;
char *s;
int ch;
+ char *qname;
+
+ if (amandates_file == NULL)
+ return 0;
/* clean up from previous invocation */
finish_amandates();
if(amandates_list != NULL)
free_amandates();
+ amfree(g_amandates_file);
/* initialize state */
readonly = !open_readwrite;
amdf = NULL;
amandates_list = NULL;
-
+ g_amandates_file = stralloc(amandates_file);
/* open the file */
- if (access(AMANDATES_FILE,F_OK))
+ if (access(amandates_file,F_OK))
/* not yet existing */
- if ( (rc = open(AMANDATES_FILE,(O_CREAT|O_RDWR),0644)) != -1 )
+ if ( (rc = open(amandates_file,(O_CREAT|O_RDWR),0644)) != -1 )
/* open/create successfull */
aclose(rc);
if(open_readwrite)
- amdf = fopen(AMANDATES_FILE, "r+");
+ amdf = fopen(amandates_file, "r+");
else
- amdf = fopen(AMANDATES_FILE, "r");
+ amdf = fopen(amandates_file, "r");
/* create it if we need to */
if(amdf == NULL && (errno == EINTR || errno == ENOENT) && open_readwrite)
- amdf = fopen(AMANDATES_FILE, "w");
+ amdf = fopen(amandates_file, "w");
if(amdf == NULL)
return 0;
if(open_readwrite)
- rc = amflock(fileno(amdf), "amandates");
+ rc = amflock(fileno(amdf), amandates_file);
else
- rc = amroflock(fileno(amdf), "amandates");
+ rc = amroflock(fileno(amdf), amandates_file);
- if(rc == -1)
- error("could not lock %s: %s", AMANDATES_FILE, strerror(errno));
+ if(rc == -1) {
+ error("could not lock %s: %s", amandates_file, strerror(errno));
+ /*NOTREACHED*/
+ }
for(; (line = agets(amdf)) != NULL; free(line)) {
+ if (line[0] == '\0')
+ continue;
s = line;
ch = *s++;
if(ch == '\0') {
continue; /* no name field */
}
- name = s - 1;
- skip_non_whitespace(s, ch);
+ qname = s - 1;
+ skip_quoted_string(s, ch);
s[-1] = '\0'; /* terminate the name */
+ name = unquote_string(qname);
skip_whitespace(s, ch);
if(ch == '\0' || sscanf(s - 1, "%d %ld", &level, &ldate) != 2) {
+ amfree(name);
continue; /* no more fields */
}
if(level < 0 || level >= DUMP_LEVELS) {
+ amfree(name);
continue;
}
enter_record(name, level, (time_t) ldate);
+ amfree(name);
}
- if(ferror(amdf))
- error("reading %s: %s", AMANDATES_FILE, strerror(errno));
+ if(ferror(amdf)) {
+ error("reading %s: %s", amandates_file, strerror(errno));
+ /*NOTREACHED*/
+ }
updated = 0; /* reset updated flag */
return 1;
}
-void finish_amandates()
+void
+finish_amandates(void)
{
amandates_t *amdp;
int level;
+ char *qname;
if(amdf == NULL)
return;
if(updated) {
- if(readonly)
+ if(readonly) {
error("updated amandates after opening readonly");
+ /*NOTREACHED*/
+ }
rewind(amdf);
for(amdp = amandates_list; amdp != NULL; amdp = amdp->next) {
for(level = 0; level < DUMP_LEVELS; level++) {
if(amdp->dates[level] == EPOCH) continue;
+ qname = quote_string(amdp->name);
fprintf(amdf, "%s %d %ld\n",
- amdp->name, level, (long) amdp->dates[level]);
+ qname, level, (long) amdp->dates[level]);
+ amfree(qname);
}
}
}
- if(amfunlock(fileno(amdf), "amandates") == -1)
- error("could not unlock %s: %s", AMANDATES_FILE, strerror(errno));
- if (fclose(amdf) == EOF)
- error("error [closing %s: %s]", AMANDATES_FILE, strerror(errno));
+ if(amfunlock(fileno(amdf), g_amandates_file) == -1) {
+ error("could not unlock %s: %s", g_amandates_file, strerror(errno));
+ /*NOTREACHED*/
+ }
+ if (fclose(amdf) == EOF) {
+ error("error [closing %s: %s]", g_amandates_file, strerror(errno));
+ /*NOTREACHED*/
+ }
amdf = NULL;
}
-void free_amandates()
+void
+free_amandates(void)
{
amandates_t *amdp, *nextp;
amandates_list = NULL;
}
-static amandates_t *lookup(name, import)
-char *name;
-int import;
+static amandates_t *
+lookup(
+ char * name,
+ int import)
{
- amandates_t *prevp, *amdp, *newp;
+ amandates_t *prevp, *amdp;
int rc, level;
+ (void)import; /* Quiet unused parameter warning */
rc = 0;
- for(prevp=NULL,amdp=amandates_list;amdp!=NULL;prevp=amdp,amdp=amdp->next)
- if((rc = strcmp(name, amdp->name)) <= 0)
+ prevp = NULL;
+ amdp = amandates_list;
+ while (amdp != NULL) {
+ if ((rc = strcmp(name, amdp->name)) <= 0)
break;
-
- if(amdp && rc == 0)
- return amdp;
-
- newp = alloc(sizeof(amandates_t));
- newp->name = stralloc(name);
- for(level = 0; level < DUMP_LEVELS; level++)
- newp->dates[level] = EPOCH;
- newp->next = amdp;
- if(prevp) prevp->next = newp;
- else amandates_list = newp;
-
- import_dumpdates(newp);
-
- return newp;
+ prevp = amdp;
+ amdp = amdp->next;
+ }
+ if (!(amdp && (rc == 0))) {
+ amandates_t *newp = alloc(SIZEOF(amandates_t));
+ newp->name = stralloc(name);
+ for (level = 0; level < DUMP_LEVELS; level++)
+ newp->dates[level] = EPOCH;
+ newp->next = amdp;
+ if (prevp != NULL) {
+#ifndef __lint /* Remove complaint about NULL pointer assignment */
+ prevp->next = newp;
+#else
+ (void)prevp;
+#endif
+ } else {
+ amandates_list = newp;
+ }
+ import_dumpdates(newp);
+ return newp;
+ }
+ return amdp;
}
-amandates_t *amandates_lookup(name)
-char *name;
+amandates_t *
+amandates_lookup(
+ char * name)
{
return lookup(name, 1);
}
-static void enter_record(name, level, dumpdate)
-char *name;
-int level;
-time_t dumpdate;
+static void
+enter_record(
+ char * name,
+ int level,
+ time_t dumpdate)
{
amandates_t *amdp;
+ char *qname;
amdp = lookup(name, 0);
if(level < 0 || level >= DUMP_LEVELS || dumpdate < amdp->dates[level]) {
+ qname = quote_string(name);
/* this is not allowed, but we can ignore it */
dbprintf(("amandates botch: %s lev %d: new dumpdate %ld old %ld\n",
- name, level, (long) dumpdate, (long) amdp->dates[level]));
+ qname, level, (long) dumpdate, (long) amdp->dates[level]));
+ amfree(qname);
return;
}
}
-void amandates_updateone(name, level, dumpdate)
-char *name;
-int level;
-time_t dumpdate;
+void
+amandates_updateone(
+ char * name,
+ int level,
+ time_t dumpdate)
{
amandates_t *amdp;
+ char *qname;
assert(!readonly);
if(level < 0 || level >= DUMP_LEVELS || dumpdate < amdp->dates[level]) {
/* this is not allowed, but we can ignore it */
+ qname = quote_string(name);
dbprintf(("amandates updateone: %s lev %d: new dumpdate %ld old %ld",
name, level, (long) dumpdate, (long) amdp->dates[level]));
+ amfree(qname);
return;
}
/* -------------------------- */
-static void import_dumpdates(amdp)
-amandates_t *amdp;
+static void
+import_dumpdates(
+ amandates_t * amdp)
{
- char *devname = NULL, *line = NULL, *fname = NULL;
- int level;
+ char *devname;
+ char *line;
+ char *fname;
+ int level = 0;
time_t dumpdate;
FILE *dumpdf;
char *s;
}
for(; (line = agets(dumpdf)) != NULL; free(line)) {
+ if (line[0] == '\0')
+ continue;
s = line;
ch = *s++;
* file named AUTHORS, in the root directory of this distribution.
*/
/*
- * $Id: amandates.h,v 1.3 1998/07/04 00:18:10 oliva Exp $
+ * $Id: amandates.h,v 1.5 2006/07/25 18:35:21 martinea Exp $
*
* interface for amandates file
*/
time_t dates[DUMP_LEVELS]; /* dump dates */
} amandates_t;
-int start_amandates P((int open_readwrite));
-void finish_amandates P((void));
-void free_amandates P((void));
-amandates_t *amandates_lookup P((char *name));
-void amandates_updateone P((char *name, int level, time_t dumpdate));
+int start_amandates (char *amandates_file, int open_readwrite);
+void finish_amandates (void);
+void free_amandates (void);
+amandates_t *amandates_lookup (char *name);
+void amandates_updateone (char *name, int level, time_t dumpdate);
#endif /* ! AMANDATES_H */
* file named AUTHORS, in the root directory of this distribution.
*/
/*
- * $Id: calcsize.c,v 1.37 2006/03/29 15:45:08 martinea Exp $
+ * $Id: calcsize.c,v 1.44 2006/07/25 18:27:56 martinea Exp $
*
* traverse directory tree to get backup size estimates
+ *
+ * argv[0] is the calcsize program name
+ * argv[1] is the config name or NOCONFIG
*/
#include "amanda.h"
#include "statfs.h"
+#include "version.h"
#include "sl.h"
+#include "util.h"
#define ROUND(n,x) ((x) + (n) - 1 - (((x) + (n) - 1) % (n)))
/*
-static unsigned long round_function(n, x)
-unsigned long n, x;
+static off_t
+round_function(n, x)
+ off_t n,
+ off_t x)
{
unsigned long remainder = x % n;
if (remainder)
- x += n-remainder;
+ x += n - remainder;
return x;
}
*/
-#define ST_BLOCKS(s) ((((s).st_blocks * 512) <= (s).st_size) ? (s).st_blocks+1 : ((s).st_size / 512 + (((s).st_size % 512) ? 1 : 0)))
+#define ST_BLOCKS(s) \
+ (((((off_t)(s).st_blocks * (off_t)512) <= (s).st_size)) ? \
+ ((off_t)(s).st_blocks + (off_t)1) : \
+ ((s).st_size / (off_t)512 + \
+ (off_t)((((s).st_size % (off_t)512) != (off_t)0) ? \
+ (off_t)1 : (off_t)0)))
#define FILETYPES (S_IFREG|S_IFLNK|S_IFDIR)
int max_inode;
int total_dirs;
int total_files;
- long total_size;
- long total_size_name;
+ off_t total_size;
+ off_t total_size_name;
} dumpstats[MAXDUMPS];
time_t dumpdate[MAXDUMPS];
int dumplevel[MAXDUMPS];
int ndumps;
-void (*add_file_name) P((int, char *));
-void (*add_file) P((int, struct stat *));
-long (*final_size) P((int, char *));
+void (*add_file_name)(int, char *);
+void (*add_file)(int, struct stat *);
+off_t (*final_size)(int, char *);
+
+int main(int, char **);
+void traverse_dirs(char *, char *);
-int main P((int, char **));
-void traverse_dirs P((char *, char *));
+void add_file_name_dump(int, char *);
+void add_file_dump(int, struct stat *);
+off_t final_size_dump(int, char *);
-void add_file_name_dump P((int, char *));
-void add_file_dump P((int, struct stat *));
-long final_size_dump P((int, char *));
+void add_file_name_star(int, char *);
+void add_file_star(int, struct stat *);
+off_t final_size_star(int, char *);
-void add_file_name_gnutar P((int, char *));
-void add_file_gnutar P((int, struct stat *));
-long final_size_gnutar P((int, char *));
+void add_file_name_gnutar(int, char *);
+void add_file_gnutar(int, struct stat *);
+off_t final_size_gnutar(int, char *);
-void add_file_name_unknown P((int, char *));
-void add_file_unknown P((int, struct stat *));
-long final_size_unknown P((int, char *));
+void add_file_name_unknown(int, char *);
+void add_file_unknown(int, struct stat *);
+off_t final_size_unknown(int, char *);
-sl_t *calc_load_file P((char *filename));
-int calc_check_exclude P((char *filename));
+sl_t *calc_load_file(char *filename);
+int calc_check_exclude(char *filename);
+int use_star_excl = 0;
int use_gtar_excl = 0;
sl_t *include_sl=NULL, *exclude_sl=NULL;
-int main(argc, argv)
-int argc;
-char **argv;
+int
+main(
+ int argc,
+ char ** argv)
{
#ifdef TEST
/* standalone test to ckeck wether the calculated file size is ok */
struct stat finfo;
int i;
- unsigned long dump_total=0, gtar_total=0;
+ off_t dump_total = (off_t)0;
+ off_t gtar_total = (off_t)0;
char *d;
int l, w;
set_pname("calcsize");
+ dbopen(NULL);
+
/* Don't die when child closes pipe */
signal(SIGPIPE, SIG_IGN);
continue;
}
printf("%s: st_size=%lu", argv[i],(unsigned long)finfo.st_size);
- printf(": blocks=%lu\n", (unsigned long)ST_BLOCKS(finfo));
- dump_total += (ST_BLOCKS(finfo) + 1)/2 + 1;
- gtar_total += ROUND(4,(ST_BLOCKS(finfo) + 1));
+ printf(": blocks=%llu\n", ST_BLOCKS(finfo));
+ dump_total += (ST_BLOCKS(finfo) + (off_t)1) / (off_t)2 + (off_t)1;
+ gtar_total += ROUND(4,(ST_BLOCKS(finfo) + (off_t)1));
}
printf(" gtar dump\n");
printf("total %-9lu %-9lu\n",gtar_total,dump_total);
return 0;
#else
int i;
- char *dirname=NULL, *amname=NULL, *filename=NULL;
+ char *dirname=NULL, *amname=NULL, *filename=NULL, *qfilename = NULL;
unsigned long malloc_hist_1, malloc_size_1;
unsigned long malloc_hist_2, malloc_size_2;
set_pname("calcsize");
+ dbopen(DBG_SUBDIR_CLIENT);
+ dbprintf(("%s: version %s\n", debug_prefix(NULL), version()));
+
malloc_size_1 = malloc_inuse(&malloc_hist_1);
#if 0
/* need at least program, amname, and directory name */
- if(argc < 3) {
- error("Usage: %s [DUMP|GNUTAR] name dir [-X exclude-file] [-I include-file] [level date]*",
+ if(argc < 4) {
+ error("Usage: %s config [DUMP|GNUTAR] name dir [-X exclude-file] [-I include-file] [level date]*",
get_pname());
- return 1;
+ /*NOTREACHED*/
+ }
+
+ dbprintf(("config: %s\n", *argv));
+ if (strcmp(*argv, "NOCONFIG") != 0) {
+ dbrename(*argv, DBG_SUBDIR_CLIENT);
}
+ argc--;
+ argv++;
/* parse backup program name */
if(strcmp(*argv, "DUMP") == 0) {
#if !defined(DUMP) && !defined(XFSDUMP)
error("dump not available on this system");
- return 1;
+ /*NOTREACHED*/
#else
add_file_name = add_file_name_dump;
add_file = add_file_dump;
else if(strcmp(*argv, "GNUTAR") == 0) {
#ifndef GNUTAR
error("gnutar not available on this system");
- return 1;
+ /*NOTREACHED*/
#else
add_file_name = add_file_name_gnutar;
add_file = add_file_gnutar;
if (argc > 0) {
amname = *argv;
argc--, argv++;
- } else
+ } else {
error("missing <name>");
+ /*NOTREACHED*/
+ }
/* the toplevel directory name to search from */
if (argc > 0) {
dirname = *argv;
argc--, argv++;
- } else
+ } else {
error("missing <dir>");
+ /*NOTREACHED*/
+ }
if ((argc > 1) && strcmp(*argv,"-X") == 0) {
argv++;
- if (!use_gtar_excl) {
+ if (!(use_gtar_excl || use_star_excl)) {
error("exclusion specification not supported");
- return 1;
+ /*NOTREACHED*/
}
filename = stralloc(*argv);
+ qfilename = quote_string(filename);
if (access(filename, R_OK) != 0) {
- fprintf(stderr,"Cannot open exclude file %s\n",filename);
- use_gtar_excl = 0;
+ fprintf(stderr,"Cannot open exclude file %s\n", qfilename);
+ use_gtar_excl = use_star_excl = 0;
} else {
- exclude_sl = calc_load_file(filename);
+ exclude_sl = calc_load_file(filename);
+ if (!exclude_sl) {
+ fprintf(stderr,"Cannot open exclude file %s: %s\n", qfilename,
+ strerror(errno));
+ use_gtar_excl = use_star_excl = 0;
+ }
}
+ amfree(qfilename);
amfree(filename);
argc -= 2;
argv++;
- } else
- use_gtar_excl = 0;
+ } else {
+ use_gtar_excl = use_star_excl = 0;
+ }
if ((argc > 1) && strcmp(*argv,"-I") == 0) {
argv++;
filename = stralloc(*argv);
+ qfilename = quote_string(filename);
if (access(filename, R_OK) != 0) {
- fprintf(stderr,"Cannot open include file %s\n",filename);
- use_gtar_excl = 0;
+ fprintf(stderr,"Cannot open include file %s\n", qfilename);
+ use_gtar_excl = use_star_excl = 0;
} else {
- include_sl = calc_load_file(filename);
+ include_sl = calc_load_file(filename);
+ if (!include_sl) {
+ fprintf(stderr,"Cannot open include file %s: %s\n", qfilename,
+ strerror(errno));
+ use_gtar_excl = use_star_excl = 0;
+ }
}
+ amfree(qfilename);
amfree(filename);
argc -= 2;
argv++;
}
}
- if(argc)
+ if(argc) {
error("leftover arg \"%s\", expected <level> and <date>", *argv);
+ /*NOTREACHED*/
+ }
if(is_empty_sl(include_sl)) {
traverse_dirs(dirname,".");
amflock(1, "size");
- lseek(1, (off_t)0, SEEK_END);
+ if (fseek(stderr, 0L, SEEK_END) < 0) {
+ dbprintf(("calcsize: warning - seek failed: %s\n",
+ strerror(errno)));
+ }
- fprintf(stderr, "%s %d SIZE %ld\n",
- amname, dumplevel[i], final_size(i, dirname));
- fflush(stdout);
+ dbprintf(("calcsize: %s %d SIZE " OFF_T_FMT "\n",
+ amname, dumplevel[i],
+ (OFF_T_FMT_TYPE)final_size(i, dirname)));
+ fprintf(stderr, "%s %d SIZE " OFF_T_FMT "\n",
+ amname, dumplevel[i],
+ (OFF_T_FMT_TYPE)final_size(i, dirname));
+ fflush(stderr);
amfunlock(1, "size");
}
*/
#if !defined(HAVE_BASENAME) && defined(BUILTIN_EXCLUDE_SUPPORT)
-static char *basename P((char *));
-static char *basename(file)
-char *file;
+static char *
+basename(
+ char * file)
{
char *cp;
}
#endif
-void push_name P((char *str));
-char *pop_name P((void));
+void push_name(char *str);
+char *pop_name(void);
-void traverse_dirs(parent_dir, include)
-char *parent_dir;
-char *include;
+void
+traverse_dirs(
+ char * parent_dir,
+ char * include)
{
DIR *d;
struct dirent *f;
struct stat finfo;
char *dirname, *newname = NULL;
char *newbase = NULL;
- dev_t parent_dev = 0;
+ dev_t parent_dev = (dev_t)0;
int i;
- int l;
- int parent_len;
- int has_exclude = !is_empty_sl(exclude_sl) && use_gtar_excl;
+ size_t l;
+ size_t parent_len;
+ int has_exclude;
char *aparent;
- if(parent_dir == NULL || include == NULL) return;
+ if(parent_dir == NULL || include == NULL)
+ return;
+ has_exclude = !is_empty_sl(exclude_sl) && (use_gtar_excl || use_star_excl);
aparent = vstralloc(parent_dir, "/", include, NULL);
if(stat(parent_dir, &finfo) != -1)
push_name(aparent);
- for(dirname = pop_name(); dirname; free(dirname), dirname = pop_name()) {
+ for(; (dirname = pop_name()) != NULL; free(dirname)) {
if(has_exclude && calc_check_exclude(dirname+parent_len+1)) {
continue;
}
int is_excluded = -1;
for(i = 0; i < ndumps; i++) {
add_file_name(i, newname);
- if(is_file && finfo.st_ctime >= dumpdate[i]) {
+ if(is_file && (time_t)finfo.st_ctime >= dumpdate[i]) {
if(has_exclude) {
if(is_excluded == -1)
amfree(aparent);
}
-void push_name(str)
-char *str;
+void
+push_name(
+ char * str)
{
Name *newp;
- newp = alloc(sizeof(*newp));
+ newp = alloc(SIZEOF(*newp));
newp->str = stralloc(str);
newp->next = name_stack;
name_stack = newp;
}
-char *pop_name()
+char *
+pop_name(void)
{
Name *newp = name_stack;
char *str;
* requirements for files with holes, nor the dumping of directories that
* are not themselves modified.
*/
-void add_file_name_dump(level, name)
-int level;
-char *name;
+void
+add_file_name_dump(
+ int level,
+ char * name)
{
+ (void)level; /* Quiet unused parameter warning */
+ (void)name; /* Quiet unused parameter warning */
+
return;
}
-void add_file_dump(level, sp)
-int level;
-struct stat *sp;
+void
+add_file_dump(
+ int level,
+ struct stat * sp)
{
/* keep the size in kbytes, rounded up, plus a 1k header block */
if((sp->st_mode & S_IFMT) == S_IFREG || (sp->st_mode & S_IFMT) == S_IFDIR)
- dumpstats[level].total_size += (ST_BLOCKS(*sp) + 1)/2 + 1;
+ dumpstats[level].total_size +=
+ (ST_BLOCKS(*sp) + (off_t)1) / (off_t)2 + (off_t)1;
}
-long final_size_dump(level, topdir)
-int level;
-char *topdir;
+off_t
+final_size_dump(
+ int level,
+ char * topdir)
{
generic_fs_stats_t stats;
- int mapsize;
+ off_t mapsize;
char *s;
/* calculate the map sizes */
s = stralloc2(topdir, "/.");
if(get_fs_stats(s, &stats) == -1) {
error("statfs %s: %s", s, strerror(errno));
+ /*NOTREACHED*/
}
amfree(s);
- mapsize = (stats.files + 7) / 8; /* in bytes */
- mapsize = (mapsize + 1023) / 1024; /* in kbytes */
+ mapsize = (stats.files + (off_t)7) / (off_t)8; /* in bytes */
+ mapsize = (mapsize + (off_t)1023) / (off_t)1024; /* in kbytes */
/* the dump contains three maps plus the files */
- return 3*mapsize + dumpstats[level].total_size;
+ return (mapsize * (off_t)3) + dumpstats[level].total_size;
}
/*
*
* As with DUMP, we only need a reasonable estimate, not an exact figure.
*/
-void add_file_name_gnutar(level, name)
-int level;
-char *name;
+void
+add_file_name_gnutar(
+ int level,
+ char * name)
{
-/* dumpstats[level].total_size_name += strlen(name) + 64;*/
- dumpstats[level].total_size += 1;
+ (void)name; /* Quiet unused parameter warning */
+
+/* dumpstats[level].total_size_name += strlen(name) + 64;*/
+ dumpstats[level].total_size += (off_t)1;
}
-void add_file_gnutar(level, sp)
-int level;
-struct stat *sp;
+void
+add_file_gnutar(
+ int level,
+ struct stat * sp)
{
/* the header takes one additional block */
dumpstats[level].total_size += ST_BLOCKS(*sp);
}
-long final_size_gnutar(level, topdir)
-int level;
-char *topdir;
+off_t
+final_size_gnutar(
+ int level,
+ char * topdir)
{
+ (void)topdir; /* Quiet unused parameter warning */
+
/* divide by two to get kbytes, rounded up */
/* + 4 blocks for security */
- return (dumpstats[level].total_size + 5 + (dumpstats[level].total_size_name/512)) / 2;
+ return (dumpstats[level].total_size + (off_t)5 +
+ (dumpstats[level].total_size_name/(off_t)512)) / (off_t)2;
}
/*
* Here we'll just add up the file sizes and output that.
*/
-void add_file_name_unknown(level, name)
-int level;
-char *name;
+void
+add_file_name_unknown(
+ int level,
+ char * name)
{
+ (void)level; /* Quiet unused parameter warning */
+ (void)name; /* Quiet unused parameter warning */
+
return;
}
-void add_file_unknown(level, sp)
-int level;
-struct stat *sp;
+void
+add_file_unknown(
+ int level,
+ struct stat * sp)
{
/* just add up the block counts */
if((sp->st_mode & S_IFMT) == S_IFREG || (sp->st_mode & S_IFMT) == S_IFDIR)
dumpstats[level].total_size += ST_BLOCKS(*sp);
}
-long final_size_unknown(level, topdir)
-int level;
-char *topdir;
+off_t
+final_size_unknown(
+ int level,
+ char * topdir)
{
+ (void)topdir; /* Quiet unused parameter warning */
+
/* divide by two to get kbytes, rounded up */
- return (dumpstats[level].total_size + 1) / 2;
+ return (dumpstats[level].total_size + (off_t)1) / (off_t)2;
}
/*
* =========================================================================
*/
-sl_t *calc_load_file(filename)
-char *filename;
+sl_t *
+calc_load_file(
+ char * filename)
{
char pattern[1025];
- sl_t *sl_list = new_sl();
+ sl_t *sl_list;
FILE *file = fopen(filename, "r");
+ if (!file) {
+ return NULL;
+ }
+
+ sl_list = new_sl();
+
while(fgets(pattern, 1025, file)) {
if(strlen(pattern)>0 && pattern[strlen(pattern)-1] == '\n')
pattern[strlen(pattern)-1] = '\0';
return sl_list;
}
-int calc_check_exclude(filename)
-char *filename;
+int
+calc_check_exclude(
+ char * filename)
{
sle_t *an_exclude;
if(is_empty_sl(exclude_sl)) return 0;
* file named AUTHORS, in the root directory of this distribution.
*/
/*
- * $Id: client_util.c,v 1.32 2006/03/09 16:51:41 martinea Exp $
+ * $Id: client_util.c,v 1.34 2006/05/25 01:47:11 johnfranks Exp $
*
*/
+#include "amanda.h"
#include "client_util.h"
#include "getfsent.h"
#include "util.h"
#define MAXMAXDUMPS 16
-static char *fixup_relative(name, device)
-char *name;
-char *device;
+static int add_exclude(FILE *file_exclude, char *aexc, int verbose);
+static int add_include(char *disk, char *device, FILE *file_include, char *ainc, int verbose);
+static char *build_name(char *disk, char *exin, int verbose);
+static char *get_name(char *diskname, char *exin, time_t t, int n);
+
+
+char *
+fixup_relative(
+ char * name,
+ char * device)
{
char *newname;
if(*name != '/') {
}
-static char *get_name(diskname, exin, t, n)
-char *diskname, *exin;
-time_t t;
-int n;
+static char *
+get_name(
+ char * diskname,
+ char * exin,
+ time_t t,
+ int n)
{
char number[NUM_STR_SIZE];
char *filename;
if(n == 0)
number[0] = '\0';
else
- snprintf(number, sizeof(number), "%03d", n - 1);
+ snprintf(number, SIZEOF(number), "%03d", n - 1);
filename = vstralloc(get_pname(), ".", diskname, ".", ts, number, ".",
exin, NULL);
}
-static char *build_name(disk, exin, verbose)
-char *disk, *exin;
-int verbose;
+static char *
+build_name(
+ char * disk,
+ char * exin,
+ int verbose)
{
- int n=0, fd=-1;
+ int n;
+ int fd;
char *filename = NULL;
char *afilename = NULL;
char *diskname;
time_t curtime;
- char *dbgdir = NULL;
+ char *dbgdir;
char *e = NULL;
DIR *d;
struct dirent *entry;
- char *test_name = NULL;
- int match_len, d_name_len;
-
+ char *test_name;
+ size_t match_len, d_name_len;
+ char *quoted;
time(&curtime);
diskname = sanitise_filename(disk);
dbgdir = stralloc2(AMANDA_TMPDIR, "/");
if((d = opendir(AMANDA_TMPDIR)) == NULL) {
error("open debug directory \"%s\": %s",
- AMANDA_TMPDIR, strerror(errno));
+ AMANDA_TMPDIR, strerror(errno));
+ /*NOTREACHED*/
}
test_name = get_name(diskname, exin,
curtime - (AMANDA_DEBUG_DAYS * 24 * 60 * 60), 0);
do {
filename = get_name(diskname, exin, curtime, n);
afilename = newvstralloc(afilename, dbgdir, filename, NULL);
- if((fd=open(afilename, O_WRONLY|O_CREAT|O_EXCL|O_APPEND, 0600)) < 0){
+ if((fd=open(afilename, O_WRONLY|O_CREAT|O_APPEND, 0600)) < 0){
amfree(afilename);
n++;
}
if(afilename == NULL) {
filename = get_name(diskname, exin, curtime, 0);
afilename = newvstralloc(afilename, dbgdir, filename, NULL);
- dbprintf(("%s: Cannot create '%s'\n", debug_prefix(NULL), afilename));
- if(verbose)
- printf("ERROR [cannot create: %s]\n", afilename);
- amfree(filename);
+ quoted = quote_string(afilename);
+ dbprintf(("%s: Cannot create %s (%s)\n",
+ debug_prefix(NULL), quoted, strerror(errno)));
+ if(verbose) {
+ printf("ERROR [cannot create %s (%s)]\n",
+ quoted, strerror(errno));
+ }
+ amfree(quoted);
amfree(afilename);
+ amfree(filename);
}
amfree(dbgdir);
}
-static int add_exclude(file_exclude, aexc, verbose)
-FILE *file_exclude;
-char *aexc;
-int verbose;
+static int
+add_exclude(
+ FILE * file_exclude,
+ char * aexc,
+ int verbose)
{
- int l;
+ size_t l;
+ char *quoted, *file;
+
+ (void)verbose; /* Quiet unused parameter warning */
l = strlen(aexc);
if(aexc[l-1] == '\n') {
aexc[l-1] = '\0';
l--;
}
- fprintf(file_exclude, "%s\n", aexc);
+ file = quoted = quote_string(aexc);
+ if (*file == '"') {
+ file[strlen(file) - 1] = '\0';
+ file++;
+ }
+ fprintf(file_exclude, "%s\n", file);
+ amfree(quoted);
return 1;
}
-static int add_include(disk, device, file_include, ainc, verbose)
-char *disk, *device;
-FILE *file_include;
-char *ainc;
-int verbose;
+static int
+add_include(
+ char * disk,
+ char * device,
+ FILE * file_include,
+ char * ainc,
+ int verbose)
{
- int l;
+ size_t l;
int nb_exp=0;
+ char *quoted, *file;
+
+ (void)disk; /* Quiet unused parameter warning */
l = strlen(ainc);
if(ainc[l-1] == '\n') {
ainc[l-1] = '\0';
l--;
}
- if(l < 3) {
- dbprintf(("%s: include must be at least 3 character long: %s\n",
- debug_prefix(NULL), ainc));
- if(verbose)
- printf("ERROR [include must be at least 3 character long: %s]\n", ainc);
- return 0;
- }
- else if(ainc[0] != '.' && ainc[0] != '\0' && ainc[1] != '/') {
- dbprintf(("%s: include must start with './': %s\n",
- debug_prefix(NULL), ainc));
- if(verbose)
- printf("ERROR [include must start with './': %s]\n", ainc);
- return 0;
+ if (strncmp(ainc, "./", 2) != 0) {
+ quoted = quote_string(ainc);
+ dbprintf(("%s: include must start with './' (%s)\n",
+ debug_prefix(NULL), quoted));
+ if(verbose) {
+ printf("ERROR [include must start with './' (%s)]\n", quoted);
+ }
+ amfree(quoted);
}
else {
char *incname = ainc+2;
+
if(strchr(incname, '/')) {
- fprintf(file_include, "./%s\n", incname);
+ file = quoted = quote_string(ainc);
+ if (*file == '"') {
+ file[strlen(file) - 1] = '\0';
+ file++;
+ }
+ fprintf(file_include, "%s\n", file);
+ amfree(quoted);
nb_exp++;
}
else {
regex = glob_to_regex(incname);
if((d = opendir(device)) == NULL) {
- dbprintf(("%s: Can't open disk '%s']\n",
- debug_prefix(NULL), device));
- if(verbose)
- printf("ERROR [Can't open disk '%s']\n", device);
- amfree(regex);
- return 0;
+ quoted = quote_string(device);
+ dbprintf(("%s: Can't open disk %s\n",
+ debug_prefix(NULL), quoted));
+ if(verbose) {
+ printf("ERROR [Can't open disk %s]\n", quoted);
+ }
+ amfree(quoted);
}
else {
while((entry = readdir(d)) != NULL) {
continue;
}
if(match(regex, entry->d_name)) {
- fprintf(file_include, "./%s\n", entry->d_name);
+ incname = vstralloc("./", entry->d_name, NULL);
+ file = quoted = quote_string(incname);
+ if (*file == '"') {
+ file[strlen(file) - 1] = '\0';
+ file++;
+ }
+ fprintf(file_include, "%s\n", file);
+ amfree(quoted);
+ amfree(incname);
nb_exp++;
}
}
return nb_exp;
}
-char *build_exclude(disk, device, options, verbose)
-char *disk, *device;
-option_t *options;
-int verbose;
+char *
+build_exclude(
+ char * disk,
+ char * device,
+ option_t * options,
+ int verbose)
{
char *filename;
FILE *file_exclude;
FILE *exclude;
- char *aexc = NULL;
+ char *aexc;
sle_t *excl;
int nb_exclude = 0;
+ char *quoted;
if(options->exclude_file) nb_exclude += options->exclude_file->nb_element;
if(options->exclude_list) nb_exclude += options->exclude_list->nb_element;
char *exclname = fixup_relative(excl->name, device);
if((exclude = fopen(exclname, "r")) != NULL) {
while ((aexc = agets(exclude)) != NULL) {
+ if (aexc[0] == '\0') {
+ amfree(aexc);
+ continue;
+ }
add_exclude(file_exclude, aexc,
verbose && options->exclude_optional == 0);
amfree(aexc);
fclose(exclude);
}
else {
- dbprintf(("%s: Can't open exclude file '%s': %s\n",
+ quoted = quote_string(exclname);
+ dbprintf(("%s: Can't open exclude file %s (%s)\n",
debug_prefix(NULL),
- exclname, strerror(errno)));
+ quoted, strerror(errno)));
if(verbose && (options->exclude_optional == 0 ||
- errno != ENOENT))
- printf("ERROR [Can't open exclude file '%s': %s]\n",
- exclname, strerror(errno));
+ errno != ENOENT)) {
+ printf("ERROR [Can't open exclude file %s (%s)]\n",
+ quoted, strerror(errno));
+ }
+ amfree(quoted);
}
amfree(exclname);
}
fclose(file_exclude);
}
else {
- dbprintf(("%s: Can't create exclude file '%s': %s\n",
+ quoted = quote_string(filename);
+ dbprintf(("%s: Can't create exclude file %s (%s)\n",
debug_prefix(NULL),
- filename, strerror(errno)));
- if(verbose)
- printf("ERROR [Can't create exclude file '%s': %s]\n", filename,
- strerror(errno));
+ quoted, strerror(errno)));
+ if(verbose) {
+ printf("ERROR [Can't create exclude file %s (%s)]\n",
+ quoted, strerror(errno));
+ }
+ amfree(quoted);
}
}
return filename;
}
-char *build_include(disk, device, options, verbose)
-char *disk;
-char *device;
-option_t *options;
-int verbose;
+char *
+build_include(
+ char * disk,
+ char * device,
+ option_t * options,
+ int verbose)
{
char *filename;
FILE *file_include;
sle_t *incl;
int nb_include = 0;
int nb_exp = 0;
+ char *quoted;
if(options->include_file) nb_include += options->include_file->nb_element;
if(options->include_list) nb_include += options->include_list->nb_element;
incl = incl->next) {
nb_exp += add_include(disk, device, file_include,
incl->name,
- verbose && options->include_optional == 0);
+ verbose && options->include_optional == 0);
}
}
char *inclname = fixup_relative(incl->name, device);
if((include = fopen(inclname, "r")) != NULL) {
while ((ainc = agets(include)) != NULL) {
+ if (ainc[0] == '\0') {
+ amfree(ainc);
+ continue;
+ }
nb_exp += add_include(disk, device,
file_include, ainc,
verbose && options->include_optional == 0);
fclose(include);
}
else {
- dbprintf(("%s: Can't open include file '%s': %s\n",
- debug_prefix(NULL),
- inclname, strerror(errno)));
+ quoted = quote_string(inclname);
+ dbprintf(("%s: Can't open include file %s (%s)\n",
+ debug_prefix(NULL), quoted, strerror(errno)));
if(verbose && (options->include_optional == 0 ||
- errno != ENOENT))
- printf("ERROR [Can't open include file '%s': %s]\n",
- inclname, strerror(errno));
+ errno != ENOENT)) {
+ printf("ERROR [Can't open include file %s (%s)]\n",
+ quoted, strerror(errno));
+ }
+ amfree(quoted);
}
amfree(inclname);
}
fclose(file_include);
}
else {
- dbprintf(("%s: Can't create include file '%s': %s\n",
- debug_prefix(NULL),
- filename, strerror(errno)));
- if(verbose)
- printf("ERROR [Can't create include file '%s': %s]\n", filename,
- strerror(errno));
+ quoted = quote_string(filename);
+ dbprintf(("%s: Can't create include file %s (%s)\n",
+ debug_prefix(NULL), quoted, strerror(errno)));
+ if(verbose) {
+ printf("ERROR [Can't create include file %s (%s)]\n",
+ quoted, strerror(errno));
+ }
+ amfree(quoted);
}
}
if(nb_exp == 0) {
- dbprintf(("%s: No include for '%s'\n", debug_prefix(NULL), disk));
- if(verbose && options->include_optional == 0)
- printf("ERROR [No include for '%s']\n", disk);
+ quoted = quote_string(disk);
+ dbprintf(("%s: No include for %s\n", debug_prefix(NULL), quoted));
+ if(verbose && options->include_optional == 0) {
+ printf("ERROR [No include for %s]\n", quoted);
+ }
+ amfree(quoted);
}
return filename;
}
-void init_options(options)
-option_t *options;
+void
+init_options(
+ option_t *options)
{
options->str = NULL;
options->compress = NO_COMPR;
}
-option_t *parse_options(str, disk, device, fs, verbose)
-char *str;
-char *disk, *device;
-am_feature_t *fs;
-int verbose;
+option_t *
+parse_options(
+ char *str,
+ char *disk,
+ char *device,
+ am_feature_t *fs,
+ int verbose)
{
char *exc;
+ char *inc;
option_t *options;
char *p, *tok;
+ char *quoted;
+
+ (void)disk; /* Quiet unused parameter warning */
+ (void)device; /* Quiet unused parameter warning */
- options = alloc(sizeof(option_t));
+ options = alloc(SIZEOF(option_t));
init_options(options);
options->str = stralloc(str);
if(am_has_feature(fs, fe_options_auth)
&& BSTRNCMP(tok,"auth=") == 0) {
if(options->auth != NULL) {
- dbprintf(("%s: multiple auth option \"%s\"\n",
- debug_prefix(NULL), tok+5));
+ quoted = quote_string(tok + 5);
+ dbprintf(("%s: multiple auth option %s\n",
+ debug_prefix(NULL), quoted));
if(verbose) {
- printf("ERROR [multiple auth option \"%s\"\n", tok+5);
+ printf("ERROR [multiple auth option %s]\n", quoted);
}
+ amfree(quoted);
}
options->auth = stralloc(&tok[5]);
}
else if(am_has_feature(fs, fe_options_bsd_auth)
&& BSTRNCMP(tok, "bsd-auth") == 0) {
if(options->auth != NULL) {
- dbprintf(("%s: multiple auth option \n",
+ dbprintf(("%s: multiple auth option\n",
debug_prefix(NULL)));
if(verbose) {
- printf("ERROR [multiple auth option \n");
+ printf("ERROR [multiple auth option]\n");
}
}
options->auth = stralloc("bsd");
else if(am_has_feature(fs, fe_options_krb4_auth)
&& BSTRNCMP(tok, "krb4-auth") == 0) {
if(options->auth != NULL) {
- dbprintf(("%s: multiple auth option \n",
+ dbprintf(("%s: multiple auth option\n",
debug_prefix(NULL)));
if(verbose) {
- printf("ERROR [multiple auth option \n");
+ printf("ERROR [multiple auth option]\n");
}
}
options->auth = stralloc("krb4");
}
else if(BSTRNCMP(tok, "compress-fast") == 0) {
if(options->compress != NO_COMPR) {
- dbprintf(("%s: multiple compress option \n",
+ dbprintf(("%s: multiple compress option\n",
debug_prefix(NULL)));
if(verbose) {
- printf("ERROR [multiple compress option \n");
+ printf("ERROR [multiple compress option]\n");
}
}
options->compress = COMPR_FAST;
}
else if(BSTRNCMP(tok, "compress-best") == 0) {
if(options->compress != NO_COMPR) {
- dbprintf(("%s: multiple compress option \n",
+ dbprintf(("%s: multiple compress option\n",
debug_prefix(NULL)));
if(verbose) {
- printf("ERROR [multiple compress option \n");
+ printf("ERROR [multiple compress option]\n");
}
}
options->compress = COMPR_BEST;
}
else if(BSTRNCMP(tok, "srvcomp-fast") == 0) {
if(options->compress != NO_COMPR) {
- dbprintf(("%s: multiple compress option \n",
+ dbprintf(("%s: multiple compress option\n",
debug_prefix(NULL)));
if(verbose) {
- printf("ERROR [multiple compress option \n");
+ printf("ERROR [multiple compress option]\n");
}
}
options->compress = COMPR_SERVER_FAST;
}
else if(BSTRNCMP(tok, "srvcomp-best") == 0) {
if(options->compress != NO_COMPR) {
- dbprintf(("%s: multiple compress option \n",
+ dbprintf(("%s: multiple compress option\n",
debug_prefix(NULL)));
if(verbose) {
- printf("ERROR [multiple compress option \n");
+ printf("ERROR [multiple compress option]\n");
}
}
options->compress = COMPR_SERVER_BEST;
printf("ERROR [multiple compress option]\n");
}
}
- options->srvcompprog = stralloc(tok + sizeof("srvcomp-cust=") -1);
+ options->srvcompprog = stralloc(tok + SIZEOF("srvcomp-cust=") -1);
options->compress = COMPR_SERVER_CUST;
}
else if(BSTRNCMP(tok, "comp-cust=") == 0) {
printf("ERROR [multiple compress option]\n");
}
}
- options->clntcompprog = stralloc(tok + sizeof("comp-cust=") -1);
+ options->clntcompprog = stralloc(tok + SIZEOF("comp-cust=") -1);
options->compress = COMPR_CUST;
/* parse encryption options */
}
printf("ERROR [multiple encrypt option]\n");
}
}
- options->srv_encrypt = stralloc(tok + sizeof("encrypt-serv-cust=") -1);
+ options->srv_encrypt = stralloc(tok + SIZEOF("encrypt-serv-cust=") -1);
options->encrypt = ENCRYPT_SERV_CUST;
}
else if(BSTRNCMP(tok, "encrypt-cust=") == 0) {
printf("ERROR [multiple encrypt option]\n");
}
}
- options->clnt_encrypt= stralloc(tok + sizeof("encrypt-cust=") -1);
+ options->clnt_encrypt= stralloc(tok + SIZEOF("encrypt-cust=") -1);
options->encrypt = ENCRYPT_CUST;
}
else if(BSTRNCMP(tok, "server-decrypt-option=") == 0) {
- options->srv_decrypt_opt = stralloc(tok + sizeof("server-decrypt-option=") -1);
+ options->srv_decrypt_opt = stralloc(tok + SIZEOF("server-decrypt-option=") -1);
}
else if(BSTRNCMP(tok, "client-decrypt-option=") == 0) {
- options->clnt_decrypt_opt = stralloc(tok + sizeof("client-decrypt-option=") -1);
+ options->clnt_decrypt_opt = stralloc(tok + SIZEOF("client-decrypt-option=") -1);
}
else if(BSTRNCMP(tok, "no-record") == 0) {
if(options->no_record != 0) {
- dbprintf(("%s: multiple no-record option \n",
+ dbprintf(("%s: multiple no-record option\n",
debug_prefix(NULL)));
if(verbose) {
- printf("ERROR [multiple no-record option \n");
+ printf("ERROR [multiple no-record option]\n");
}
}
options->no_record = 1;
}
else if(BSTRNCMP(tok, "index") == 0) {
if(options->createindex != 0) {
- dbprintf(("%s: multiple index option \n",
+ dbprintf(("%s: multiple index option\n",
debug_prefix(NULL)));
if(verbose) {
- printf("ERROR [multiple index option \n");
+ printf("ERROR [multiple index option]\n");
}
}
options->createindex = 1;
}
else if(BSTRNCMP(tok, "exclude-optional") == 0) {
if(options->exclude_optional != 0) {
- dbprintf(("%s: multiple exclude-optional option \n",
+ dbprintf(("%s: multiple exclude-optional option\n",
debug_prefix(NULL)));
if(verbose) {
- printf("ERROR [multiple exclude-optional option \n");
+ printf("ERROR [multiple exclude-optional option]\n");
}
}
options->exclude_optional = 1;
}
else if(strcmp(tok, "include-optional") == 0) {
if(options->include_optional != 0) {
- dbprintf(("%s: multiple include-optional option \n",
+ dbprintf(("%s: multiple include-optional option\n",
debug_prefix(NULL)));
if(verbose) {
- printf("ERROR [multiple include-optional option \n");
+ printf("ERROR [multiple include-optional option]\n");
}
}
options->include_optional = 1;
}
else if(BSTRNCMP(tok,"exclude-file=") == 0) {
- exc = &tok[13];
- options->exclude_file = append_sl(options->exclude_file,exc);
+ exc = unquote_string(&tok[13]);
+ options->exclude_file = append_sl(options->exclude_file, exc);
+ amfree(exc);
}
else if(BSTRNCMP(tok,"exclude-list=") == 0) {
- exc = &tok[13];
+ exc = unquote_string(&tok[13]);
options->exclude_list = append_sl(options->exclude_list, exc);
+ amfree(exc);
}
else if(BSTRNCMP(tok,"include-file=") == 0) {
- exc = &tok[13];
- options->include_file = append_sl(options->include_file,exc);
+ inc = unquote_string(&tok[13]);
+ options->include_file = append_sl(options->include_file, inc);
+ amfree(inc);
}
else if(BSTRNCMP(tok,"include-list=") == 0) {
- exc = &tok[13];
- options->include_list = append_sl(options->include_list, exc);
- }
- else if(strcmp(tok,"|") == 0) {
- }
- else {
- dbprintf(("%s: unknown option \"%s\"\n", debug_prefix(NULL), tok));
+ inc = unquote_string(&tok[13]);
+ options->include_list = append_sl(options->include_list, inc);
+ amfree(inc);
+ }
+ else if(strcmp(tok,"|") != 0) {
+ quoted = quote_string(tok);
+ dbprintf(("%s: unknown option %s\n",
+ debug_prefix(NULL), quoted));
if(verbose) {
- printf("ERROR [unknown option \"%s\"]\n", tok);
+ printf("ERROR [unknown option: %s]\n", quoted);
}
+ amfree(quoted);
}
tok = strtok(NULL, ";");
}
amfree(p);
return options;
}
-
-
-void init_g_options(g_options)
-g_option_t *g_options;
-{
- g_options->features = NULL;
- g_options->hostname = NULL;
- g_options->maxdumps = 0;
-}
-
-
-g_option_t *parse_g_options(str, verbose)
-char *str;
-int verbose;
-{
- g_option_t *g_options;
- char *p, *tok;
- int new_maxdumps;
-
- g_options = alloc(sizeof(g_option_t));
- init_g_options(g_options);
- g_options->str = stralloc(str);
-
- p = stralloc(str);
- tok = strtok(p,";");
-
- while (tok != NULL) {
- if(strncmp(tok,"features=", 9) == 0) {
- if(g_options->features != NULL) {
- dbprintf(("%s: multiple features option\n",
- debug_prefix(NULL)));
- if(verbose) {
- printf("ERROR [multiple features option]\n");
- }
- }
- if((g_options->features = am_string_to_feature(tok+9)) == NULL) {
- dbprintf(("%s: bad features value \"%s\n",
- debug_prefix(NULL), tok+10));
- if(verbose) {
- printf("ERROR [bad features value \"%s\"]\n", tok+10);
- }
- }
- }
- else if(strncmp(tok,"hostname=", 9) == 0) {
- if(g_options->hostname != NULL) {
- dbprintf(("%s: multiple hostname option\n",
- debug_prefix(NULL)));
- if(verbose) {
- printf("ERROR [multiple hostname option]\n");
- }
- }
- g_options->hostname = stralloc(tok+9);
- }
- else if(strncmp(tok,"maxdumps=", 9) == 0) {
- if(g_options->maxdumps != 0) {
- dbprintf(("%s: multiple maxdumps option\n",
- debug_prefix(NULL)));
- if(verbose) {
- printf("ERROR [multiple maxdumps option]\n");
- }
- }
- if(sscanf(tok+9, "%d;", &new_maxdumps) == 1) {
- if (new_maxdumps > MAXMAXDUMPS) {
- g_options->maxdumps = MAXMAXDUMPS;
- }
- else if (new_maxdumps > 0) {
- g_options->maxdumps = new_maxdumps;
- }
- else {
- dbprintf(("%s: bad maxdumps value \"%s\"\n",
- debug_prefix(NULL), tok+9));
- if(verbose) {
- printf("ERROR [bad maxdumps value \"%s\"]\n",
- tok+9);
- }
- }
- }
- else {
- dbprintf(("%s: bad maxdumps value \"%s\"\n",
- debug_prefix(NULL), tok+9));
- if(verbose) {
- printf("ERROR [bad maxdumps value \"%s\"]\n",
- tok+9);
- }
- }
- }
- else {
- dbprintf(("%s: unknown option \"%s\"\n",
- debug_prefix(NULL), tok));
- if(verbose) {
- printf("ERROR [unknown option \"%s\"]\n", tok);
- }
- }
- tok = strtok(NULL, ";");
- }
- if(g_options->features == NULL) {
- g_options->features = am_set_default_feature_set();
- }
- if(g_options->maxdumps == 0) /* default */
- g_options->maxdumps = 1;
- amfree(p);
- return g_options;
-}
* file named AUTHORS, in the root directory of this distribution.
*/
/*
- * $Id: client_util.h,v 1.12 2005/12/09 03:22:52 paddy_s Exp $
+ * $Id: client_util.h,v 1.14 2006/05/25 01:47:11 johnfranks Exp $
*
*/
int include_optional;
} option_t;
-typedef struct g_option_s {
- char *str;
- am_feature_t *features;
- char *hostname;
- int maxdumps;
-} g_option_t;
-
#define NO_COMPR 0
#define COMPR_FAST 1
#define COMPR_BEST 2
#define ENCRYPT_CUST 1 /* client-side custom encryption */
#define ENCRYPT_SERV_CUST 2 /* server-side custom encryption */
-char *build_exclude P((char *disk, char *device, option_t *options, int verbose));
-char *build_include P((char *disk, char *device, option_t *options, int verbose));
-void init_options P((option_t *options));
-option_t *parse_options P((char *str,
+char *build_exclude(char *disk, char *device, option_t *options, int verbose);
+char *build_include(char *disk, char *device, option_t *options, int verbose);
+void init_options(option_t *options);
+option_t *parse_options(char *str,
char *disk,
char *device,
am_feature_t *features,
- int verbose));
+ int verbose);
-void init_g_options P((g_option_t *g_options));
-g_option_t *parse_g_options P((char *str, int verbose));
+char *fixup_relative(char *name, char *device);
#endif
--- /dev/null
+/*
+ * Amanda, The Advanced Maryland Automatic Network Disk Archiver
+ * Copyright (c) 1991-2000 University of Maryland at College Park
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of U.M. not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. U.M. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: James da Silva, Systems Design and Analysis Group
+ * Computer Science Department
+ * University of Maryland at College Park
+ */
+/*
+ * $Id: clientconf.c,v 1.17 2006/07/25 19:36:48 martinea Exp $
+ *
+ * read configuration file
+ */
+/*
+ *
+ * XXX - I'm not happy *at all* with this implementation, but I don't
+ * think YACC would be any easier. A more table based implementation
+ * would be better. Also clean up memory leaks.
+ */
+#include "amanda.h"
+#include "arglist.h"
+#include "util.h"
+#include "clientconf.h"
+#include "clock.h"
+
+/* configuration parameters */
+static char *cln_config_dir = NULL;
+
+val_t client_conf[CLN_CLN];
+
+command_option_t *client_options = NULL;
+int client_options_size = 0;
+
+/* predeclare local functions */
+
+static void init_defaults(void);
+static void read_conffile_recursively(char *filename);
+
+static int read_confline(void);
+
+keytab_t client_keytab[] = {
+ { "CONF", CONF_CONF },
+ { "INDEX_SERVER", CONF_INDEX_SERVER },
+ { "TAPE_SERVER", CONF_TAPE_SERVER },
+ { "TAPEDEV", CONF_TAPEDEV },
+ { "AUTH", CONF_AUTH },
+ { "SSH_KEYS", CONF_SSH_KEYS },
+ { "AMANDAD_PATH", CONF_AMANDAD_PATH },
+ { "CLIENT_USERNAME", CONF_CLIENT_USERNAME },
+ { "GNUTAR_LIST_DIR", CONF_GNUTAR_LIST_DIR },
+ { "AMANDATES", CONF_AMANDATES },
+ { "INCLUDEFILE", CONF_INCLUDEFILE },
+ { NULL, CONF_UNKNOWN },
+};
+
+t_conf_var client_var [] = {
+ { CONF_CONF , CONFTYPE_STRING, read_string, CLN_CONF , NULL },
+ { CONF_INDEX_SERVER , CONFTYPE_STRING, read_string, CLN_INDEX_SERVER , NULL },
+ { CONF_TAPE_SERVER , CONFTYPE_STRING, read_string, CLN_TAPE_SERVER , NULL },
+ { CONF_TAPEDEV , CONFTYPE_STRING, read_string, CLN_TAPEDEV , NULL },
+ { CONF_AUTH , CONFTYPE_STRING, read_string, CLN_AUTH , NULL },
+ { CONF_SSH_KEYS , CONFTYPE_STRING, read_string, CLN_SSH_KEYS , NULL },
+ { CONF_AMANDAD_PATH , CONFTYPE_STRING, read_string, CLN_AMANDAD_PATH , NULL },
+ { CONF_CLIENT_USERNAME, CONFTYPE_STRING, read_string, CLN_CLIENT_USERNAME, NULL },
+ { CONF_GNUTAR_LIST_DIR, CONFTYPE_STRING, read_string, CLN_GNUTAR_LIST_DIR, NULL },
+ { CONF_AMANDATES , CONFTYPE_STRING, read_string, CLN_AMANDATES , NULL },
+ { CONF_UNKNOWN , CONFTYPE_INT , NULL , CLN_CLN , NULL }
+};
+
+static int first_file = 1;
+
+/*
+** ------------------------
+** External entry points
+** ------------------------
+*/
+
+/* return 0 on success */
+/* return 1 on error */
+/* return -1 if file not found */
+
+int read_clientconf(
+ char *filename)
+{
+ if(first_file == 1) {
+ init_defaults();
+ first_file = 0;
+ } else {
+ allow_overwrites = 1;
+ }
+
+ /* We assume that conf_confname & conf are initialized to NULL above */
+ read_conffile_recursively(filename);
+
+ command_overwrite(client_options, client_var, client_keytab, client_conf,
+ "");
+
+ return got_parserror;
+}
+
+
+char *
+client_getconf_byname(
+ char * str)
+{
+ static char *tmpstr;
+ char number[NUM_STR_SIZE];
+ t_conf_var *np;
+ keytab_t *kt;
+ char *s;
+ char ch;
+
+ tmpstr = stralloc(str);
+ s = tmpstr;
+ while((ch = *s++) != '\0') {
+ if(islower((int)ch))
+ s[-1] = (char)toupper(ch);
+ }
+
+ for(kt = client_keytab; kt->token != CONF_UNKNOWN; kt++)
+ if(kt->keyword && strcmp(kt->keyword, tmpstr) == 0) break;
+
+ if(kt->token == CONF_UNKNOWN) return NULL;
+
+ for(np = client_var; np->token != CONF_UNKNOWN; np++)
+ if(np->token == kt->token) break;
+
+ if(np->type == CONFTYPE_INT) {
+ snprintf(number, SIZEOF(number), "%d", client_getconf_int(np->parm));
+ tmpstr = newstralloc(tmpstr, number);
+ } else if(np->type == CONFTYPE_BOOL) {
+ if(client_getconf_boolean(np->parm) == 0) {
+ tmpstr = newstralloc(tmpstr, "off");
+ }
+ else {
+ tmpstr = newstralloc(tmpstr, "on");
+ }
+ } else if(np->type == CONFTYPE_REAL) {
+ snprintf(number, SIZEOF(number), "%lf", client_getconf_real(np->parm));
+ tmpstr = newstralloc(tmpstr, number);
+ } else {
+ tmpstr = newstralloc(tmpstr, client_getconf_str(np->parm));
+ }
+
+ return tmpstr;
+}
+
+int
+client_getconf_seen(
+ cconfparm_t parm)
+{
+ t_conf_var *np;
+ np = get_np(client_var, parm);
+ return(client_conf[np->parm].seen);
+}
+
+int
+client_getconf_boolean(
+ cconfparm_t parm)
+{
+ t_conf_var *np;
+ np = get_np(client_var, parm);
+ if (np->type != CONFTYPE_BOOL) {
+ error("client_getconf_boolean: np is not a CONFTYPE_BOOL");
+ /*NOTREACHED*/
+ }
+ return(client_conf[np->parm].v.i != 0);
+}
+
+int
+client_getconf_int(
+ cconfparm_t parm)
+{
+ t_conf_var *np;
+ np = get_np(client_var, parm);
+ if (np->type != CONFTYPE_INT) {
+ error("client_getconf_int: np is not a CONFTYPE_INT");
+ /*NOTREACHED*/
+ }
+
+ return(client_conf[np->parm].v.i);
+}
+
+off_t
+client_getconf_am64(
+ cconfparm_t parm)
+{
+ t_conf_var *np;
+ np = get_np(client_var, parm);
+ if (np->type != CONFTYPE_AM64) {
+ error("client_getconf_am64: np is not a CONFTYPE_AM64");
+ /*NOTREACHED*/
+ }
+ return(client_conf[np->parm].v.am64);
+}
+
+double
+client_getconf_real(
+ cconfparm_t parm)
+{
+ t_conf_var *np;
+ np = get_np(client_var, parm);
+ if (np->type != CONFTYPE_REAL) {
+ error("client_getconf_real: np is not a CONFTYPE_REAL");
+ /*NOTREACHED*/
+ }
+ return(client_conf[np->parm].v.r);
+}
+
+char *
+client_getconf_str(
+ cconfparm_t parm)
+{
+ t_conf_var *np;
+ np = get_np(client_var, parm);
+ if (np->type != CONFTYPE_STRING) {
+ error("client_getconf_string: np is not a CONFTYPE_STRING");
+ /*NOTREACHED*/
+ }
+ return(client_conf[np->parm].v.s);
+}
+
+/*
+** ------------------------
+** Internal routines
+** ------------------------
+*/
+
+
+static void
+init_defaults(void)
+{
+ char *s;
+
+ /* defaults for exported variables */
+
+#ifdef DEFAULT_CONFIG
+ s = DEFAULT_CONFIG;
+#else
+ s = "";
+#endif
+ conf_init_string(&client_conf[CLN_CONF], s);
+
+#ifdef DEFAULT_SERVER
+ s = DEFAULT_SERVER;
+#else
+ s = "";
+#endif
+ conf_init_string(&client_conf[CLN_INDEX_SERVER], s);
+
+
+#ifdef DEFAULT_TAPE_SERVER
+ s = DEFAULT_TAPE_SERVER;
+#else
+#ifdef DEFAULT_SERVER
+ s = DEFAULT_SERVER;
+#else
+ s = "";
+#endif
+#endif
+ conf_init_string(&client_conf[CLN_TAPE_SERVER], s);
+
+#ifdef DEFAULT_TAPE_DEVICE
+ s = DEFAULT_TAPE_DEVICE;
+#else
+ s = NULL;
+#endif
+ conf_init_string(&client_conf[CLN_TAPEDEV], s);
+
+ conf_init_string(&client_conf[CLN_AUTH], "bsd");
+ conf_init_string(&client_conf[CLN_SSH_KEYS], "");
+ conf_init_string(&client_conf[CLN_AMANDAD_PATH], "");
+ conf_init_string(&client_conf[CLN_CLIENT_USERNAME], "");
+#ifdef GNUTAR_LISTED_INCREMENTAL_DIR
+ conf_init_string(&client_conf[CLN_GNUTAR_LIST_DIR],
+ GNUTAR_LISTED_INCREMENTAL_DIR);
+#else
+ conf_init_string(&client_conf[CLN_GNUTAR_LIST_DIR], NULL);
+#endif
+ conf_init_string(&client_conf[CLN_AMANDATES], "/etc/amandates");
+ /* defaults for internal variables */
+
+ conf_line_num = got_parserror = 0;
+ allow_overwrites = 0;
+ token_pushed = 0;
+
+}
+
+static void
+read_conffile_recursively(
+ char * filename)
+{
+ /* Save globals used in read_confline(), elsewhere. */
+ int save_line_num = conf_line_num;
+ FILE *save_conf = conf_conf;
+ char *save_confname = conf_confname;
+ int rc;
+
+ if (*filename == '/' || cln_config_dir == NULL) {
+ conf_confname = stralloc(filename);
+ } else {
+ conf_confname = stralloc2(cln_config_dir, filename);
+ }
+
+ if((conf_conf = fopen(conf_confname, "r")) == NULL) {
+ dbprintf(("Could not open conf file \"%s\": %s\n", conf_confname,
+ strerror(errno)));
+ amfree(conf_confname);
+ got_parserror = -1;
+ return;
+ }
+ dbprintf(("Reading conf file \"%s\".\n", conf_confname));
+
+ conf_line_num = 0;
+
+ /* read_confline() can invoke us recursively via "includefile" */
+ do {
+ rc = read_confline();
+ } while (rc != 0);
+ afclose(conf_conf);
+
+ amfree(conf_confname);
+
+ /* Restore globals */
+ conf_line_num = save_line_num;
+ conf_conf = save_conf;
+ conf_confname = save_confname;
+}
+
+
+/* ------------------------ */
+
+
+static int
+read_confline(void)
+{
+ t_conf_var *np;
+
+ keytable = client_keytab;
+
+ conf_line_num += 1;
+ get_conftoken(CONF_ANY);
+ switch(tok) {
+ case CONF_INCLUDEFILE:
+ {
+ char *fn;
+
+ get_conftoken(CONF_STRING);
+ fn = tokenval.v.s;
+ read_conffile_recursively(fn);
+ }
+ break;
+
+ case CONF_NL: /* empty line */
+ break;
+
+ case CONF_END: /* end of file */
+ return 0;
+
+ default:
+ {
+ for(np = client_var; np->token != CONF_UNKNOWN; np++)
+ if(np->token == tok) break;
+
+ if(np->token == CONF_UNKNOWN) {
+ conf_parserror("configuration keyword expected");
+ } else {
+ np->read_function(np, &client_conf[np->parm]);
+ if(np->validate)
+ np->validate(np, &client_conf[np->parm]);
+ }
+ }
+ }
+ if(tok != CONF_NL)
+ get_conftoken(CONF_NL);
+ return 1;
+}
+
+
+
+/* ------------------------ */
+
+#ifdef TEST
+
+static char *cln_config_name = NULL;
+static char *cln_config_dir = NULL;
+
+void
+dump_client_configuration(
+ char *filename)
+{
+ printf("AMANDA CLIENT CONFIGURATION FROM FILE \"%s\":\n\n", filename);
+
+ printf("cln_conf = \"%s\"\n", client_getconf_str(CLN_CONF));
+ printf("cln_index_server = \"%s\"\n", client_getconf_str(CLN_INDEX_SERVER));
+ printf("cln_tape_server = \"%s\"\n", client_getconf_str(CLN_TAPE_SERVER));
+ printf("cln_tapedev = \"%s\"\n", client_getconf_str(CLN_TAPEDEV));
+ printf("cln_auth = \"%s\"\n", client_getconf_str(CLN_AUTH));
+ printf("cln_ssh_keys = \"%s\"\n", client_getconf_str(CLN_SSH_KEYS));
+}
+
+int
+main(
+ int argc,
+ char ** argv)
+{
+ char *conffile;
+ char *diskfile;
+ disklist_t lst;
+ int result;
+ unsigned long malloc_hist_1, malloc_size_1;
+ unsigned long malloc_hist_2, malloc_size_2;
+
+ safe_fd(-1, 0);
+
+ set_pname("conffile");
+
+ /* Don't die when child closes pipe */
+ signal(SIGPIPE, SIG_IGN);
+
+ malloc_size_1 = malloc_inuse(&malloc_hist_1);
+
+ startclock();
+
+ if (argc > 1) {
+ if (argv[1][0] == '/') {
+ cln_config_dir = stralloc(argv[1]);
+ cln_config_name = strrchr(cln_config_dir, '/') + 1;
+ cln_config_name[-1] = '\0';
+ cln_config_dir = newstralloc2(cln_config_dir, cln_config_dir, "/");
+ } else {
+ cln_config_name = stralloc(argv[1]);
+ cln_config_dir = vstralloc(CONFIG_DIR, "/", cln_config_name, "/", NULL);
+ }
+ } else {
+ char my_cwd[STR_SIZE];
+
+ if (getcwd(my_cwd, SIZEOF(my_cwd)) == NULL) {
+ error("cannot determine current working directory");
+ }
+ cln_config_dir = stralloc2(my_cwd, "/");
+ if ((cln_config_name = strrchr(my_cwd, '/')) != NULL) {
+ cln_config_name = stralloc(cln_config_name + 1);
+ }
+ }
+
+ conffile = stralloc2(cln_config_dir, CONFFILE_NAME);
+ result = read_conffile(conffile);
+ if (result == 0) {
+ diskfile = client_getconf_str(CNF_DISKFILE);
+ if (diskfile != NULL && access(diskfile, R_OK) == 0) {
+ result = read_diskfile(diskfile, &lst);
+ }
+ }
+ dump_client_configuration(CONFFILE_NAME);
+ amfree(conffile);
+
+ malloc_size_2 = malloc_inuse(&malloc_hist_2);
+
+ if(malloc_size_1 != malloc_size_2) {
+ malloc_list(fileno(stderr), malloc_hist_1, malloc_hist_2);
+ }
+
+ return result;
+}
+
+#endif /* TEST */
+
+char *
+generic_client_get_security_conf(
+ char * string,
+ void * arg)
+{
+ (void)arg; /* Quiet unused parameter warning */
+
+ if(!string || !*string)
+ return(NULL);
+
+ if(strcmp(string, "conf")==0) {
+ return(client_getconf_str(CLN_CONF));
+ } else if(strcmp(string, "index_server")==0) {
+ return(client_getconf_str(CLN_INDEX_SERVER));
+ } else if(strcmp(string, "tape_server")==0) {
+ return(client_getconf_str(CLN_TAPE_SERVER));
+ } else if(strcmp(string, "tapedev")==0) {
+ return(client_getconf_str(CLN_TAPEDEV));
+ } else if(strcmp(string, "auth")==0) {
+ return(client_getconf_str(CLN_AUTH));
+ } else if(strcmp(string, "ssh_keys")==0) {
+ return(client_getconf_str(CLN_SSH_KEYS));
+ } else if(strcmp(string, "amandad_path")==0) {
+ return(client_getconf_str(CLN_AMANDAD_PATH));
+ } else if(strcmp(string, "client_username")==0) {
+ return(client_getconf_str(CLN_CLIENT_USERNAME));
+ } else if(strcmp(string, "gnutar_list_dir")==0) {
+ return(client_getconf_str(CLN_GNUTAR_LIST_DIR));
+ } else if(strcmp(string, "amandates")==0) {
+ return(client_getconf_str(CLN_AMANDATES));
+/*
+ } else if(strcmp(string, "krb5principal")==0) {
+ return(client_getconf_str(CNF_KRB5PRINCIPAL));
+ } else if(strcmp(string, "krb5keytab")==0) {
+ return(client_getconf_str(CNF_KRB5KEYTAB));
+*/
+ }
+ return(NULL);
+}
+
+
+void
+parse_client_conf(
+ int parse_argc,
+ char **parse_argv,
+ int *new_argc,
+ char ***new_argv)
+{
+ int i;
+ char **my_argv;
+ char *myarg, *value;
+ command_option_t *client_option;
+
+ client_options = alloc((size_t)(parse_argc+1) * SIZEOF(*client_options));
+ client_options_size = parse_argc+1;
+ client_option = client_options;
+ client_option->name = NULL;
+
+ my_argv = alloc((size_t)parse_argc * SIZEOF(char *));
+ *new_argv = my_argv;
+ *new_argc = 0;
+ i=0;
+ while(i<parse_argc) {
+ if(strncmp(parse_argv[i],"-o",2) == 0) {
+ if(strlen(parse_argv[i]) > 2)
+ myarg = &parse_argv[i][2];
+ else {
+ i++;
+ if(i >= parse_argc)
+ error("expect something after -o");
+ myarg = parse_argv[i];
+ }
+ value = index(myarg,'=');
+ if (value == NULL) {
+ conf_parserror("Must specify a value for %s.\n", myarg);
+ } else {
+ *value = '\0';
+ value++;
+ client_option->used = 0;
+ client_option->name = stralloc(myarg);
+ client_option->value = stralloc(value);
+ client_option++;
+ client_option->name = NULL;
+ }
+ }
+ else {
+ my_argv[*new_argc] = stralloc(parse_argv[i]);
+ *new_argc += 1;
+ }
+ i++;
+ }
+}
+
+/* return 0 on success */
+/* return -1 if it is already there */
+/* return -2 if other failure */
+int
+add_client_conf(
+ cconfparm_t parm,
+ char *value)
+{
+ t_conf_var *np;
+ keytab_t *kt;
+ command_option_t *command_option;
+ int nb_option;
+
+ for(np = client_var; np->token != CONF_UNKNOWN; np++)
+ if(np->parm == (int)parm) break;
+
+ if(np->token == CONF_UNKNOWN) return -2;
+
+ for(kt = client_keytab; kt->token != CONF_UNKNOWN; kt++)
+ if(kt->token == np->token) break;
+
+ if(kt->token == CONF_UNKNOWN) return -2;
+
+ /* Try to find it */
+ nb_option = 0;
+ for(command_option = client_options; command_option->name != NULL;
+ command_option++) {
+ if(strcasecmp(command_option->name, kt->keyword) == 0) {
+ return -1;
+ }
+ nb_option++;
+ }
+
+ /* Increase size of client_options if needed */
+ if(nb_option >= client_options_size-1) {
+ client_options_size *= 2;
+ client_options = realloc(client_options,
+ client_options_size * SIZEOF(*client_options));
+ if (client_options == NULL) {
+ error("Can't realloc client_options: %s\n", strerror(errno));
+ /*NOTREACHED*/
+ }
+ for(command_option = client_options; command_option->name != NULL;
+ command_option++) {
+ }
+ }
+
+ /* add it */
+ command_option->used = 0;
+ command_option->name = stralloc(kt->keyword);
+ command_option->value = stralloc(value);
+ command_option++;
+ command_option->name = NULL;
+ return 0;
+}
+
+void
+report_bad_client_arg(void)
+{
+ command_option_t *command_option;
+
+ for(command_option = client_options; command_option->name != NULL;
+ command_option++) {
+ if(command_option->used == 0) {
+ fprintf(stderr,"argument -o%s=%s not used\n",
+ command_option->name, command_option->value);
+ }
+ }
+}
--- /dev/null
+/*
+ * Amanda, The Advanced Maryland Automatic Network Disk Archiver
+ * Copyright (c) 1991-2000 University of Maryland at College Park
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of U.M. not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. U.M. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: James da Silva, Systems Design and Analysis Group
+ * Computer Science Department
+ * University of Maryland at College Park
+ */
+/*
+ * $Id: clientconf.h,v 1.9 2006/07/25 19:06:46 martinea Exp $
+ *
+ * interface for client config file reading code
+ */
+#ifndef CLIENTCONF_H
+#define CLIENTCONF_H
+
+#include "sl.h"
+
+#define CLIENTCONFFILE_NAME "client.conf"
+
+typedef enum conf_e {
+ CLN_CONF,
+ CLN_INDEX_SERVER,
+ CLN_TAPE_SERVER,
+ CLN_TAPEDEV,
+ CLN_AUTH,
+ CLN_SSH_KEYS,
+ CLN_AMANDAD_PATH,
+ CLN_CLIENT_USERNAME,
+ CLN_GNUTAR_LIST_DIR,
+ CLN_AMANDATES,
+ CLN_CLN
+} cconfparm_t;
+
+extern char *config_name;
+extern char *config_dir;
+
+void parse_client_conf(int, char **, int *, char ***);
+int add_client_conf(cconfparm_t parm, char *value);
+void report_bad_client_arg(void);
+int read_clientconf(char *filename);
+int client_getconf_seen(cconfparm_t parameter);
+int client_getconf_boolean(cconfparm_t parameter);
+int client_getconf_int(cconfparm_t parameter);
+off_t client_getconf_am64(cconfparm_t parameter);
+double client_getconf_real(cconfparm_t parameter);
+char *client_getconf_str(cconfparm_t parameter);
+char *client_getconf_byname(char *confname);
+
+/* this is in securityconf.h */
+char *generic_client_get_security_conf(char *, void *);
+#endif /* ! CONFFILE_H */
* file named AUTHORS, in the root directory of this distribution.
*/
/*
- * $Id: findpass.c,v 1.12 2001/08/01 22:37:32 jrjackson Exp $
+ * $Id: findpass.c,v 1.13 2006/05/25 01:47:11 johnfranks Exp $
*
* Support routines for Amanda SAMBA support
*/
+#include "amanda.h"
#include "findpass.h"
+#include "util.h"
/*
* Find the Samba password and optional domain for a given disk.
* as soon as reasonable.
*/
-char *findpass(disk, domain)
-char *disk, **domain;
+char *
+findpass(
+ char * disk,
+ char ** domain)
{
FILE *fp;
static char *buffer = NULL;
char *s, *d, *pw = NULL;
int ch;
+ char *qname;
*domain = NULL; /* just to be sure */
if ( (fp = fopen("/etc/amandapass", "r")) ) {
amfree(buffer);
for (; (buffer = agets(fp)) != NULL; free(buffer)) {
+ if (buffer[0] == '\0')
+ continue;
s = buffer;
ch = *s++;
skip_whitespace(s, ch); /* find start of disk name */
if (!ch || ch == '#') {
continue;
}
- d = s-1; /* start of disk name */
- skip_non_whitespace_cs(s, ch);
+ qname = s-1; /* start of disk name */
+ skip_quoted_string(s, ch);
if (ch && ch != '#') {
s[-1] = '\0'; /* terminate disk name */
+ d = unquote_string(qname);
if ((strcmp(d,"*") == 0) || (strcmp(disk, d) == 0)) {
skip_whitespace(s, ch); /* find start of password */
if (ch && ch != '#') {
*domain = stralloc(*domain);
}
}
+ amfree(d);
break;
}
+ amfree(d);
}
}
afclose(fp);
* Returns a new name alloc-d that the caller is responsible
* for free-ing.
*/
-char *makesharename(disk, shell)
-char *disk;
-int shell;
+char *
+makesharename(
+ char * disk,
+ int shell)
{
char *buffer;
- int buffer_size;
+ size_t buffer_size;
char *s;
int ch;
*
* the caller is expected to release share & subdir
*/
-void parsesharename (disk, share, subdir)
-char *disk;
-char **share;
-char **subdir;
+void
+parsesharename(
+ char * disk,
+ char ** share,
+ char ** subdir)
{
char *ch=NULL;
int slashcnt=0;
* file named AUTHORS, in the root directory of this distribution.
*/
/*
- * $Id: findpass.h,v 1.6 2001/08/01 22:37:32 jrjackson Exp $
+ * $Id: findpass.h,v 1.7 2006/05/25 01:47:11 johnfranks Exp $
*
* interface to findpass module
*/
#include "amanda.h"
-extern char *findpass P((char *disk, char **domain));
-extern char *makesharename P((char *disk, int shell));
-void parsesharename P((char *disk, char **share, char **subdir));
+extern char *findpass(char *disk, char **domain);
+extern char *makesharename(char *disk, int shell);
+void parsesharename(char *disk, char **share, char **subdir);
#endif
* file named AUTHORS, in the root directory of this distribution.
*/
/*
- * $Id: getfsent.c,v 1.34 2006/01/14 04:37:18 paddy_s Exp $
+ * $Id: getfsent.c,v 1.38 2006/07/19 17:41:14 martinea Exp $
*
* generic version of code to read fstab
*/
#ifdef TEST
# include <stdio.h>
# include <sys/types.h>
-# undef P
-# define P(x) x
#endif
#include "getfsent.h"
-static char *dev2rdev P((char *));
-static int samefile P((struct stat[3], struct stat *));
+static char *dev2rdev(char *);
/*
* You are in a twisty maze of passages, all alike.
#include <fstab.h>
-int open_fstab()
+int
+open_fstab(void)
{
return setfsent();
}
-void close_fstab()
+void
+close_fstab(void)
{
endfsent();
}
-int get_fstab_nextentry(fsent)
-generic_fsent_t *fsent;
+int
+get_fstab_nextentry(
+ generic_fsent_t * fsent)
{
struct fstab *sys_fsent = getfsent();
static char *xfsname = NULL, *xmntdir = NULL;
static FILE *fstabf = NULL;
-int open_fstab()
+int
+open_fstab(void)
{
close_fstab();
return (fstabf = fopen(VFSTAB, "r")) != NULL;
}
-void close_fstab()
+void
+close_fstab(void)
{
if(fstabf)
afclose(fstabf);
fstabf = NULL;
}
-int get_fstab_nextentry(fsent)
-generic_fsent_t *fsent;
+int
+get_fstab_nextentry(
+ generic_fsent_t * fsent)
{
struct vfstab sys_fsent;
+ memset(&sys_fsent, 0, SIZEOF(sys_fsent));
if(getvfsent(fstabf, &sys_fsent) != 0)
return 0;
static FILE *fstabf2 = NULL; /* MOUNTED */
static FILE *fstabf3 = NULL; /* MNTTAB */
-int open_fstab()
+int
+open_fstab(void)
{
close_fstab();
#if defined(HAVE_SETMNTENT)
return (fstabf1 != NULL || fstabf2 != NULL || fstabf3 != NULL);
}
-void close_fstab()
+void
+close_fstab(void)
{
if (fstabf1) {
AMCLOSE_MNTENT(fstabf1);
}
}
-int get_fstab_nextentry(fsent)
-generic_fsent_t *fsent;
+int
+get_fstab_nextentry(
+ generic_fsent_t * fsent)
{
struct mntent *sys_fsent = NULL;
static FILE *fstabf = NULL;
-int open_fstab()
+int
+open_fstab(void)
{
close_fstab();
return (fstabf = fopen(FSTAB, "r")) != NULL;
}
-void close_fstab()
+void
+close_fstab(void)
{
if(fstabf)
afclose(fstabf);
static generic_fsent_t _fsent;
-int get_fstab_nextentry(fsent)
-generic_fsent_t *fsent;
+int
+get_fstab_nextentry(
+ generic_fsent_t * fsent)
{
static char *lfsnam = NULL;
static char *opts = NULL;
amfree(cp);
for (; (cp = agets(fstabf)) != NULL; free(cp)) {
+ if (cp[0] == '\0')
+ continue;
fsent->fsname = strtok(cp, " \t");
if ( fsent->fsname && *fsent->fsname != '#' )
break;
fsent->fstype = lfsnam;
#define sc "hs"
- if (strncmp(fsent->fstype, sc, sizeof(sc)-1) == 0)
+ if (strncmp(fsent->fstype, sc, SIZEOF(sc)-1) == 0)
fsent->fstype = "iso9660";
#undef sc
static FILE *fstabf = NULL;
-int open_fstab()
+int
+open_fstab(void)
{
close_fstab();
return (fstabf = fopen(MNTTAB, "r")) != NULL;
}
-void close_fstab()
+void
+close_fstab(void)
{
if(fstabf)
afclose(fstabf);
static generic_fsent_t _fsent;
-int get_fstab_nextentry(fsent)
-generic_fsent_t *fsent;
+int
+get_fstab_nextentry(
+ generic_fsent_t *fsent)
{
struct statfs fsd;
char typebuf[FSTYPSZ];
static struct mnttab mnt;
char *dp, *ep;
- if(!fread (&mnt, sizeof mnt, 1, fstabf))
+ if(!fread (&mnt, SIZEOF(mnt), 1, fstabf))
return 0;
fsent->fsname = mnt.mt_dev;
fsent->mntdir = mnt.mt_filsys;
fsent->fstype = "";
- if (statfs (fsent->mntdir, &fsd, sizeof fsd, 0) != -1
+ if (statfs (fsent->mntdir, &fsd, SIZEOF(fsd), 0) != -1
&& sysfs (GETFSTYP, fsd.f_fstyp, typebuf) != -1) {
dp = typebuf;
ep = fsent->fstype = malloc(strlen(typebuf)+2);
*=====================================================================
*/
-static char *dev2rdev(name)
-char *name;
+static char *
+dev2rdev(
+ char * name)
{
char *fname = NULL;
struct stat st;
if (ch == '/') {
s[-1] = '\0';
fname = newvstralloc(fname, name, "/r", s, NULL);
- s[-1] = ch;
+ s[-1] = (char)ch;
if(stat(fname, &st) == 0 && S_ISCHR(st.st_mode)) return fname;
}
ch = *s++;
return stralloc(name); /* no match */
}
-static int samefile(stats, estat)
-struct stat stats[3], *estat;
+#ifndef IGNORE_FSTAB
+static int samefile(struct stat[3], struct stat *);
+
+static int
+samefile(
+ struct stat stats[3],
+ struct stat *estat)
{
int i;
for(i = 0; i < 3; ++i) {
}
return 0;
}
+#endif /* !IGNORE_FSTAB */
-int search_fstab(name, fsent, check_dev)
- char *name;
- generic_fsent_t *fsent;
- int check_dev;
+int
+search_fstab(
+ char * name,
+ generic_fsent_t * fsent,
+ int check_dev)
{
#ifdef IGNORE_FSTAB
/* There is no real mount table so this will always fail and
* we are using GNU tar so we can just return here.
*/
+ (void)name; /* Quiet unused parameter warning */
+ (void)fsent; /* Quiet unused parameter warning */
+ (void)check_dev; /* Quiet unused parameter warning */
return 0;
#else
struct stat stats[3];
if (!name)
return 0;
- stats[0].st_dev = stats[1].st_dev = stats[2].st_dev = -1;
+ memset(stats, 0, SIZEOF(stats));
+ stats[0].st_dev = stats[1].st_dev = stats[2].st_dev = (dev_t)-1;
if (stat(name, &stats[0]) == -1)
- stats[0].st_dev = -1;
+ stats[0].st_dev = (dev_t)-1;
if (name[0] != '/') {
fullname = stralloc2(DEV_PREFIX, name);
if (stat(fullname, &stats[1]) == -1)
- stats[1].st_dev = -1;
+ stats[1].st_dev = (dev_t)-1;
fullname = newstralloc2(fullname, RDEV_PREFIX, name);
if (stat(fullname, &stats[2]) == -1)
- stats[2].st_dev = -1;
+ stats[2].st_dev = (dev_t)-1;
amfree(fullname);
}
else if (stat((rdev = dev2rdev(name)), &stats[1]) == -1)
- stats[1].st_dev = -1;
+ stats[1].st_dev = (dev_t)-1;
amfree(rdev);
#endif /* !IGNORE_FSTAB */
}
-int is_local_fstype(fsent)
-generic_fsent_t *fsent;
+int
+is_local_fstype(
+ generic_fsent_t * fsent)
{
if(fsent->fstype == NULL) /* unknown, assume local */
return 1;
}
-char *amname_to_devname(str)
-char *str;
+char *
+amname_to_devname(
+ char * str)
{
generic_fsent_t fsent;
return dev2rdev(str);
}
-char *amname_to_dirname(str)
-char *str;
+char *
+amname_to_dirname(
+ char * str)
{
generic_fsent_t fsent;
return stralloc(str);
}
-char *amname_to_fstype(str)
-char *str;
+char *amname_to_fstype(
+ char * str)
{
generic_fsent_t fsent;
#ifdef TEST
+void print_entry(generic_fsent_t *fsent);
+
void
-print_entry(fsent)
-generic_fsent_t *fsent;
+print_entry(
+ generic_fsent_t * fsent)
{
#define nchk(s) ((s)? (s) : "<NULL>")
printf("%-20.20s %-14.14s %-7.7s %4d %5d %s\n",
fsent->freq, fsent->passno, nchk(fsent->mntopts));
}
-int main(argc, argv)
- int argc;
- char **argv;
+int
+main(
+ int argc,
+ char ** argv)
{
generic_fsent_t fsent;
char *s;
set_pname("getfsent");
+ dbopen(NULL);
+
/* Don't die when child closes pipe */
signal(SIGPIPE, SIG_IGN);
* file named AUTHORS, in the root directory of this distribution.
*/
/*
- * $Id: getfsent.h,v 1.7 2002/10/27 22:58:33 martinea Exp $
+ * $Id: getfsent.h,v 1.8 2006/05/25 01:47:11 johnfranks Exp $
*
* interfaces for obtaining filesystem information
*/
int passno;
} generic_fsent_t;
-int open_fstab P((void));
-void close_fstab P((void));
+int open_fstab(void);
+void close_fstab(void);
-int get_fstab_nextentry P((generic_fsent_t *fsent));
-int search_fstab P((char *name, generic_fsent_t *fsent, int check_dev));
-int is_local_fstype P((generic_fsent_t *fsent));
+int get_fstab_nextentry(generic_fsent_t *fsent);
+int search_fstab(char *name, generic_fsent_t *fsent, int check_dev);
+int is_local_fstype(generic_fsent_t *fsent);
-char *amname_to_devname P((char *str));
-char *amname_to_dirname P((char *str));
+char *amname_to_devname(char *str);
+char *amname_to_dirname(char *str);
-char *amname_to_fstype P((char *str));
+char *amname_to_fstype(char *str);
#endif /* ! GETFSENT_H */
* file named AUTHORS, in the root directory of this distribution.
*/
/*
- * $Id: killpgrp.c,v 1.12 2005/09/20 21:32:25 jrjackson Exp $
+ * $Id: killpgrp.c,v 1.17 2006/07/25 18:27:56 martinea Exp $
*
* if it is the process group leader, it kills all processes in its
* process group when it is killed itself.
+ *
+ * argv[0] is the killpgrp program name
+ * argv[1] is the config name or NOCONFIG
+ *
*/
#include "amanda.h"
#include "version.h"
#define AM_GETPGRP() getpid()
#endif
-int main P((int argc, char **argv));
-static void term_kill_soft P((int sig));
-static void term_kill_hard P((int sig));
+int main(int argc, char **argv);
+static void term_kill_soft(int sig);
+static void term_kill_hard(int sig);
-int main(argc, argv)
-int argc;
-char **argv;
+int main(
+ int argc,
+ char **argv)
{
+ int ch;
amwait_t status;
safe_fd(-1, 0);
set_pname("killpgrp");
- dbopen();
- dbprintf(("%s: version %s\n", argv[0], version()));
+ dbopen(DBG_SUBDIR_CLIENT);
+ if (argc < 2) {
+ error("%s: Need at least 2 arguments\n", debug_prefix(NULL));
+ /*NOTREACHED*/
+ }
+ dbprintf(("%s: version %s\n", debug_prefix(NULL), version()));
+ dbprintf(("config: %s\n", argv[1]));
+ if (strcmp(argv[1], "NOCONFIG") != 0)
+ dbrename(argv[1], DBG_SUBDIR_CLIENT);
if(client_uid == (uid_t) -1) {
error("error [cannot find user %s in passwd file]", CLIENT_LOGIN);
+ /*NOTREACHED*/
}
#ifdef FORCE_USERID
- if (getuid() != client_uid)
+ if (getuid() != client_uid) {
error("error [must be invoked by %s]", CLIENT_LOGIN);
-
- if (geteuid() != 0)
+ /*NOTREACHED*/
+ }
+ if (geteuid() != 0) {
error("error [must be setuid root]");
+ /*NOTREACHED*/
+ }
#endif /* FORCE_USERID */
#if !defined (DONT_SUID_ROOT)
if (AM_GETPGRP() != getpid()) {
error("error [must be the process group leader]");
+ /*NOTREACHED*/
}
+ /* Consume any extranious input */
signal(SIGTERM, term_kill_soft);
- while (getchar() != EOF) {
+ do {
+ ch = getchar();
/* wait until EOF */
- }
+ } while (ch != EOF);
term_kill_soft(0);
break;
if (errno != EINTR) {
error("error [wait() failed: %s]", strerror(errno));
- return -1;
+ /*NOTREACHED*/
}
}
+ /*@ignore@*/
dbprintf(("child process exited with status %d\n", WEXITSTATUS(status)));
return WEXITSTATUS(status);
+ /*@end@*/
}
-static void term_kill_soft(sig)
-int sig;
+static void term_kill_soft(
+ int sig)
{
pid_t dumppid = getpid();
int killerr;
+ (void)sig; /* Quiet unused parameter warning */
+
signal(SIGTERM, SIG_IGN);
signal(SIGALRM, term_kill_hard);
alarm(3);
}
}
-static void term_kill_hard(sig)
-int sig;
+static void term_kill_hard(
+ int sig)
{
pid_t dumppid = getpid();
int killerr;
+ (void)sig; /* Quiet unused parameter warning */
+
dbprintf(("it won\'t die with SIGTERM, but SIGKILL should do\n"));
dbprintf(("do\'t expect any further output, this will be suicide\n"));
killerr = kill(-dumppid, SIGKILL);
*/
/*
- * $Id: noop.c,v 1.3 2006/01/14 04:37:18 paddy_s Exp $
+ * $Id: noop.c,v 1.5 2006/06/01 14:54:39 martinea Exp $
*
* send back features. This was pulled out to it's own program for
* consistancy and because it's a hell of a lot easier to code in
#include "amfeatures.h"
#include "util.h"
-int main P((int argc, char **argv));
+int main(int argc, char **argv);
int
-main(argc, argv)
- int argc;
- char **argv;
+main(
+ int argc,
+ char ** argv)
{
char ch;
am_feature_t *our_features = NULL;
char *our_feature_string = NULL;
char *options;
- int n;
+ ssize_t n;
+
+ (void)argc; /* Quiet unused parameter warning */
+ (void)argv; /* Quiet unused parameter warning */
/* Don't die when child closes pipe */
signal(SIGPIPE, SIG_IGN);
+ safe_fd(-1, 0);
do {
/* soak up any stdin */
n = read(0, &ch, 1);
our_features = NULL;
if (fullwrite(1, options, strlen(options)) < 0) {
error("error sending noop response: %s", strerror(errno));
+ /*NOTREACHED*/
}
amfree(options);
- exit(0);
+ close(0);
+ close(1);
+ close(2);
+ return (0); /* exit */
}
-#! /bin/sh
+#! @SHELL@
#
# patch inetd.conf and services
# originally by Axel Zinser (fifi@hiss.han.de)
* file named AUTHORS, in the root directory of this distribution.
*/
/*
- * $Id: rundump.c,v 1.28 2006/01/14 04:37:18 paddy_s Exp $
+ * $Id: rundump.c,v 1.33 2006/07/25 18:27:56 martinea Exp $
*
* runs DUMP program as root
+ *
+ * argv[0] is the rundump program name
+ * argv[1] is the config name or NOCONFIG
+ * argv[2] will be argv[0] of the DUMP program
+ * ...
*/
#include "amanda.h"
#include "version.h"
-int main P((int argc, char **argv));
+int main(int argc, char **argv);
#if defined(VDUMP) || defined(XFSDUMP)
# undef USE_RUNDUMP
# endif
#endif
-int main(argc, argv)
-int argc;
-char **argv;
+int
+main(
+ int argc,
+ char ** argv)
{
#ifndef ERRMSG
char *dump_program;
/* Don't die when child closes pipe */
signal(SIGPIPE, SIG_IGN);
- dbopen();
- dbprintf(("%s: version %s\n", argv[0], version()));
+ dbopen(DBG_SUBDIR_CLIENT);
+ if (argc < 3) {
+ error("%s: Need at least 3 arguments\n", debug_prefix(NULL));
+ /*NOTREACHED*/
+ }
+
+ dbprintf(("%s: version %s\n", debug_prefix(NULL), version()));
#ifdef ERRMSG /* { */
if(client_uid == (uid_t) -1) {
error("error [cannot find user %s in passwd file]\n", CLIENT_LOGIN);
+ /*NOTREACHED*/
}
#ifdef FORCE_USERID
- if (getuid() != client_uid)
+ if (getuid() != client_uid) {
error("error [must be invoked by %s]\n", CLIENT_LOGIN);
+ /*NOTREACHED*/
+ }
- if (geteuid() != 0)
+ if (geteuid() != 0) {
error("error [must be setuid root]\n");
+ /*NOTREACHED*/
+ }
#endif /* FORCE_USERID */
#if !defined (DONT_SUID_ROOT)
setuid(0);
#endif
+ /* skip argv[0] */
+ argc--;
+ argv++;
+
+ dbprintf(("config: %s\n", argv[0]));
+ if (strcmp(argv[0], "NOCONFIG") != 0)
+ dbrename(argv[0], DBG_SUBDIR_CLIENT);
+ argc--;
+ argv++;
+
#ifdef XFSDUMP
if (strcmp(argv[0], "xfsdump") == 0)
* file named AUTHORS, in the root directory of this distribution.
*/
/*
- * $Id: runtar.c,v 1.17 2006/01/14 04:37:18 paddy_s Exp $
+ * $Id: runtar.c,v 1.24 2006/08/25 11:41:31 martinea Exp $
*
* runs GNUTAR program as root
+ *
+ * argv[0] is the runtar program name
+ * argv[1] is the config name or NOCONFIG
+ * argv[2] will be argv[0] of the gtar program
+ * ...
*/
#include "amanda.h"
#include "version.h"
+#include "util.h"
-int main P((int argc, char **argv));
+int main(int argc, char **argv);
-int main(argc, argv)
-int argc;
-char **argv;
+int
+main(
+ int argc,
+ char ** argv)
{
#ifdef GNUTAR
int i;
/* Don't die when child closes pipe */
signal(SIGPIPE, SIG_IGN);
- dbopen();
- dbprintf(("%s: version %s\n", argv[0], version()));
+ dbopen(DBG_SUBDIR_CLIENT);
+ if (argc < 3) {
+ error("%s: Need at least 3 arguments\n", debug_prefix(NULL));
+ /*NOTREACHED*/
+ }
+
+ dbprintf(("%s: version %s\n", debug_prefix(NULL), version()));
+
+ if (strcmp(argv[3], "--create") != 0) {
+ error("%s: Can only be used to create tar archives\n",
+ debug_prefix(NULL));
+ /*NOTREACHED*/
+ }
#ifndef GNUTAR
#else
+ /*
+ * Print out version information for tar.
+ */
+ do {
+ FILE * version_file;
+ char version_buf[80];
+
+ if ((version_file = popen(GNUTAR " --version 2>&1", "r")) != NULL) {
+ if (fgets(version_buf, (int)sizeof(version_buf), version_file) != NULL) {
+ dbprintf((GNUTAR " version: %s\n", version_buf));
+ } else {
+ if (ferror(version_file)) {
+ dbprintf((GNUTAR " version: Read failure: %s\n", strerror(errno)));
+ } else {
+ dbprintf((GNUTAR " version: Read failure; EOF\n"));
+ }
+ }
+ } else {
+ dbprintf((GNUTAR " version: unavailable: %s\n", strerror(errno)));
+ }
+ } while(0);
+
if(client_uid == (uid_t) -1) {
error("error [cannot find user %s in passwd file]\n", CLIENT_LOGIN);
+ /*NOTREACHED*/
}
#ifdef FORCE_USERID
- if (getuid() != client_uid)
+ if (getuid() != client_uid) {
error("error [must be invoked by %s]\n", CLIENT_LOGIN);
+ /*NOTREACHED*/
+ }
- if (geteuid() != 0)
+ if (geteuid() != 0) {
error("error [must be setuid root]\n");
+ /*NOTREACHED*/
+ }
#endif
#if !defined (DONT_SUID_ROOT)
setuid(0);
#endif
+ /* skip argv[0] */
+ argc--;
+ argv++;
+
+ dbprintf(("config: %s\n", argv[0]));
+ if (strcmp(argv[0], "NOCONFIG") != 0)
+ dbrename(argv[0], DBG_SUBDIR_CLIENT);
+ argc--;
+ argv++;
+
+
dbprintf(("running: %s: ",GNUTAR));
- for (i=0; argv[i]; i++)
- dbprintf(("%s ", argv[i]));
+ for (i=0; argv[i]; i++) {
+ char *quoted;
+
+ quoted = quote_string(argv[i]);
+ dbprintf(("'%s' ", quoted));
+ amfree(quoted);
+ }
dbprintf(("\n"));
dbf = dbfn();
if (dbf) {
* University of Maryland at College Park
*/
/*
- * $Id: selfcheck.c,v 1.76 2006/01/14 04:37:18 paddy_s Exp $
+ * $Id: selfcheck.c,v 1.95 2006/08/29 11:21:00 martinea Exp $
*
* do self-check and send back any error messages
*/
#include "pipespawn.h"
#include "amfeatures.h"
#include "client_util.h"
+#include "clientconf.h"
+#include "amandad.h"
#ifdef SAMBA_CLIENT
#include "findpass.h"
int need_calcsize=0;
int program_is_wrapper=0;
+static char *amandad_auth = NULL;
static am_feature_t *our_features = NULL;
static char *our_feature_string = NULL;
static g_option_t *g_options = NULL;
/* local functions */
-int main P((int argc, char **argv));
-
-static void check_options P((char *program, char *calcprog, char *disk, char *amdevice, option_t *options));
-static void check_disk P((char *program, char *calcprog, char *disk, char *amdevice, int level, char *optstr));
-static void check_overall P((void));
-static void check_access P((char *filename, int mode));
-static void check_file P((char *filename, int mode));
-static void check_dir P((char *dirname, int mode));
-static void check_suid P((char *filename));
-static void check_space P((char *dir, long kbytes));
-
-int main(argc, argv)
-int argc;
-char **argv;
+int main(int argc, char **argv);
+
+static void check_options(char *program, char *calcprog, char *disk, char *amdevice, option_t *options);
+static void check_disk(char *program, char *calcprog, char *disk, char *amdevice, int level, char *optstr);
+static void check_overall(void);
+static void check_access(char *filename, int mode);
+static void check_file(char *filename, int mode);
+static void check_dir(char *dirname, int mode);
+static void check_suid(char *filename);
+static void check_space(char *dir, off_t kbytes);
+
+int
+main(
+ int argc,
+ char ** argv)
{
int level;
char *line = NULL;
char *program = NULL;
char *calcprog = NULL;
char *disk = NULL;
+ char *qdisk = NULL;
char *amdevice = NULL;
+ char *qamdevice = NULL;
char *optstr = NULL;
char *err_extra = NULL;
char *s, *fp;
+ char *conffile;
+ option_t *options;
int ch;
+#if defined(USE_DBMALLOC)
unsigned long malloc_hist_1, malloc_size_1;
unsigned long malloc_hist_2, malloc_size_2;
- option_t *options;
+#endif
/* initialize */
/* Don't die when child closes pipe */
signal(SIGPIPE, SIG_IGN);
+#if defined(USE_DBMALLOC)
malloc_size_1 = malloc_inuse(&malloc_hist_1);
+#endif
erroutput_type = (ERR_INTERACTIVE|ERR_SYSLOG);
- dbopen();
+ dbopen(DBG_SUBDIR_CLIENT);
startclock();
dbprintf(("%s: version %s\n", get_pname(), version()));
+ if(argc > 2 && strcmp(argv[1], "amandad") == 0) {
+ amandad_auth = stralloc(argv[2]);
+ }
+
+ conffile = vstralloc(CONFIG_DIR, "/", "amanda-client.conf", NULL);
+ if (read_clientconf(conffile) > 0) {
+ printf("ERROR [reading conffile: %s]\n", conffile);
+ error("error reading conffile: %s", conffile);
+ /*NOTREACHED*/
+ }
+ amfree(conffile);
+
our_features = am_init_feature_set();
our_feature_string = am_feature_to_string(our_features);
/* handle all service requests */
+ /*@ignore@*/
for(; (line = agets(stdin)) != NULL; free(line)) {
+ /*@end@*/
+ if (line[0] == '\0')
+ continue;
+
#define sc "OPTIONS "
- if(strncmp(line, sc, sizeof(sc)-1) == 0) {
+ if(strncmp(line, sc, SIZEOF(sc)-1) == 0) {
#undef sc
g_options = parse_g_options(line+8, 1);
if(!g_options->hostname) {
}
printf("\n");
fflush(stdout);
+
+ if (g_options->config) {
+ conffile = vstralloc(CONFIG_DIR, "/", g_options->config, "/",
+ "amanda-client.conf", NULL);
+ if (read_clientconf(conffile) > 0) {
+ printf("ERROR [reading conffile: %s]\n", conffile);
+ error("error reading conffile: %s", conffile);
+ /*NOTREACHED*/
+ }
+ amfree(conffile);
+
+ dbrename(g_options->config, DBG_SUBDIR_CLIENT);
+ }
+
continue;
}
if (ch == '\0') {
goto err; /* no disk */
}
- disk = s - 1;
- skip_non_whitespace(s, ch);
+ qdisk = s - 1;
+ skip_quoted_string(s, ch);
s[-1] = '\0'; /* terminate the disk name */
+ disk = unquote_string(qdisk);
skip_whitespace(s, ch); /* find the device or level */
if (ch == '\0') {
}
if(!isdigit((int)s[-1])) {
fp = s - 1;
- skip_non_whitespace(s, ch);
+ skip_quoted_string(s, ch);
s[-1] = '\0'; /* terminate the device */
- amdevice = stralloc(fp);
+ qamdevice = stralloc(fp);
+ amdevice = unquote_string(qamdevice);
skip_whitespace(s, ch); /* find level number */
}
else {
skip_whitespace(s, ch);
#define sc "OPTIONS "
- if (ch && strncmp (s - 1, sc, sizeof(sc)-1) == 0) {
- s += sizeof(sc)-1;
+ if (ch && strncmp (s - 1, sc, SIZEOF(sc)-1) == 0) {
+ s += SIZEOF(sc)-1;
ch = s[-1];
#undef sc
skip_whitespace(s, ch); /* find the option string */
goto err; /* bad options string */
}
optstr = s - 1;
- skip_non_whitespace(s, ch);
+ skip_quoted_string(s, ch);
s[-1] = '\0'; /* terminate the options */
options = parse_options(optstr, disk, amdevice, g_options->features, 1);
+ /*@ignore@*/
check_options(program, calcprog, disk, amdevice, options);
check_disk(program, calcprog, disk, amdevice, level, &optstr[2]);
+ /*@end@*/
free_sl(options->exclude_file);
free_sl(options->exclude_list);
free_sl(options->include_file);
need_gnutar=1;
need_compress_path=1;
need_calcsize=1;
+ /*@ignore@*/
check_disk(program, calcprog, disk, amdevice, level, "");
+ /*@end@*/
} else {
goto err; /* bad syntax */
}
+ amfree(disk);
amfree(amdevice);
}
amfree(g_options->hostname);
amfree(g_options);
+#if defined(USE_DBMALLOC)
malloc_size_2 = malloc_inuse(&malloc_hist_2);
if(malloc_size_1 != malloc_size_2) {
-#if defined(USE_DBMALLOC)
extern int dbfd;
malloc_list(dbfd(), malloc_hist_1, malloc_hist_2);
-#endif
}
+#endif
dbclose();
return 0;
static void
-check_options(program, calcprog, disk, amdevice, options)
- char *program, *calcprog, *disk, *amdevice;
- option_t *options;
+check_options(
+ char * program,
+ char * calcprog,
+ char * disk,
+ char * amdevice,
+ option_t * options)
{
char *myprogram = program;
amfree(file_include);
need_calcsize=1;
- myprogram = calcprog;
+ if (calcprog == NULL) {
+ printf("ERROR [no program name for calcsize]\n");
+ } else {
+ myprogram = calcprog;
+ }
}
if(strcmp(myprogram,"GNUTAR") == 0) {
need_restore=1;
#endif
}
- if(program_is_wrapper==1) {
- }
- if(options->compress == COMPR_BEST || options->compress == COMPR_FAST || options->compress == COMPR_CUST)
+ if ((options->compress == COMPR_BEST) || (options->compress == COMPR_FAST)
+ || (options->compress == COMPR_CUST)) {
need_compress_path=1;
+ }
+ if(options->auth && amandad_auth) {
+ if(strcasecmp(options->auth, amandad_auth) != 0) {
+ fprintf(stdout,"ERROR [client configured for auth=%s while server requested '%s']\n",
+ amandad_auth, options->auth);
+ }
+ }
}
-static void check_disk(program, calcprog, disk, amdevice, level, optstr)
-char *program, *calcprog, *disk, *amdevice;
-int level;
-char *optstr;
+static void
+check_disk(
+ char * program,
+ char * calcprog,
+ char * disk,
+ char * amdevice,
+ int level,
+ char * optstr)
{
- char *device = NULL;
+ char *device = stralloc("nodevice");
char *err = NULL;
- char *user_and_password = NULL, *domain = NULL;
+ char *user_and_password = NULL;
+ char *domain = NULL;
char *share = NULL, *subdir = NULL;
- int lpass = 0;
+ size_t lpass = 0;
int amode;
int access_result;
char *access_type;
char *extra_info = NULL;
char *myprogram = program;
+ char *qdisk = quote_string(disk);
+ char *qamdevice = quote_string(amdevice);
+ char *qdevice = NULL;
+
+ (void)level; /* Quiet unused parameter warning */
+
+ dbprintf(("%s: checking disk %s\n", debug_prefix_time(NULL), qdisk));
if(strcmp(myprogram,"CALCSIZE") == 0) {
if(amdevice[0] == '/' && amdevice[1] == '/') {
myprogram = calcprog;
}
- dbprintf(("%s: checking disk %s\n", debug_prefix_time(NULL), disk));
-
- if (strcmp(myprogram, "GNUTAR") == 0) {
+ if (strcmp(myprogram, "GNUTAR")==0) {
if(amdevice[0] == '/' && amdevice[1] == '/') {
#ifdef SAMBA_CLIENT
int nullfd, checkerr;
int passwdfd;
char *pwtext;
- int pwtext_len;
- int checkpid;
+ size_t pwtext_len;
+ pid_t checkpid;
amwait_t retstat;
char number[NUM_STR_SIZE];
- int wpid;
+ pid_t wpid;
int ret, sig, rc;
char *line;
char *sep;
goto common_exit;
}
*pwtext++ = '\0';
- pwtext_len = strlen(pwtext);
+ pwtext_len = (size_t)strlen(pwtext);
+ amfree(device);
if ((device = makesharename(share, 0)) == NULL) {
err = stralloc2("cannot make share name of ", share);
goto common_exit;
#endif
"-c", "quit",
NULL);
- if (domain) {
- memset(domain, '\0', strlen(domain));
- amfree(domain);
- }
+ amfree(domain);
aclose(nullfd);
- if (pwtext_len > 0 && fullwrite(passwdfd, pwtext, pwtext_len) < 0) {
+ /*@ignore@*/
+ if ((pwtext_len > 0)
+ && fullwrite(passwdfd, pwtext, (size_t)pwtext_len) < 0) {
err = vstralloc("password write failed: ",
amdevice,
": ",
aclose(passwdfd);
goto common_exit;
}
- memset(user_and_password, '\0', lpass);
+ /*@end@*/
+ memset(user_and_password, '\0', (size_t)lpass);
amfree(user_and_password);
aclose(passwdfd);
ferr = fdopen(checkerr, "r");
+ if (!ferr) {
+ printf("ERROR [Can't fdopen: %s]\n", strerror(errno));
+ error("Can't fdopen: %s", strerror(errno));
+ /*NOTREACHED*/
+ }
sep = "";
errdos = 0;
for(sep = ""; (line = agets(ferr)) != NULL; free(line)) {
+ if (line[0] == '\0')
+ continue;
strappend(extra_info, sep);
strappend(extra_info, line);
sep = ": ";
} else {
strappend(err, "returned ");
}
- snprintf(number, sizeof(number), "%d", ret);
+ snprintf(number, (size_t)sizeof(number), "%d", ret);
strappend(err, number);
}
}
amfree(extra_info);
}
#else
- err = stralloc2("This client is not configured for samba: ", disk);
+ err = stralloc2("This client is not configured for samba: ", qdisk);
#endif
goto common_exit;
}
amode = F_OK;
+ amfree(device);
device = amname_to_dirname(amdevice);
} else if (strcmp(program, "DUMP") == 0) {
if(amdevice[0] == '/' && amdevice[1] == '/') {
err = vstralloc("The DUMP program cannot handle samba shares,",
" use GNUTAR: ",
- disk,
+ qdisk,
NULL);
goto common_exit;
}
if (1)
#endif /* } */
{
+ amfree(device);
device = amname_to_dirname(amdevice);
amode = F_OK;
} else
#endif /* } */
{
+ amfree(device);
device = amname_to_devname(amdevice);
#ifdef USE_RUNDUMP
amode = F_OK;
}
}
else { /* program_is_wrapper==1 */
- int pid_wrapper;
+ pid_t pid_wrapper;
fflush(stdout);fflush(stdin);
switch (pid_wrapper = fork()) {
- case -1: error("fork: %s", strerror(errno));
+ case -1:
+ printf("ERROR [fork: %s]\n", strerror(errno));
+ error("fork: %s", strerror(errno));
+ /*NOTREACHED*/
+
case 0: /* child */
{
char *argvchild[6];
}
}
fflush(stdout);fflush(stdin);
+ amfree(device);
+ amfree(qamdevice);
+ amfree(qdisk);
return;
}
- dbprintf(("%s: device %s\n", debug_prefix_time(NULL), device));
+ qdevice = quote_string(device);
+ dbprintf(("%s: device %s\n", debug_prefix_time(NULL), qdevice));
/* skip accessability test if this is an AFS entry */
if(strncmp(device, "afs:", 4) != 0) {
access_type = "access";
#endif
if(access_result == -1) {
- err = vstralloc("could not ", access_type, " ", device,
- " (", disk, "): ", strerror(errno), NULL);
+ err = vstralloc("could not ", access_type, " ", qdevice,
+ " (", qdisk, "): ", strerror(errno), NULL);
}
#ifdef CHECK_FOR_ACCESS_WITH_OPEN
aclose(access_result);
amfree(share);
amfree(subdir);
if(user_and_password) {
- memset(user_and_password, '\0', lpass);
+ memset(user_and_password, '\0', (size_t)lpass);
amfree(user_and_password);
}
- if(domain) {
- memset(domain, '\0', strlen(domain));
- amfree(domain);
- }
+ amfree(domain);
if(err) {
printf("ERROR [%s]\n", err);
dbprintf(("%s: %s\n", debug_prefix_time(NULL), err));
amfree(err);
} else {
- printf("OK %s\n", disk);
- dbprintf(("%s: disk \"%s\" OK\n", debug_prefix_time(NULL), disk));
- printf("OK %s\n", amdevice);
- dbprintf(("%s: amdevice \"%s\" OK\n",
- debug_prefix_time(NULL), amdevice));
- printf("OK %s\n", device);
- dbprintf(("%s: device \"%s\" OK\n", debug_prefix_time(NULL), device));
+ printf("OK %s\n", qdisk);
+ dbprintf(("%s: disk %s OK\n", debug_prefix_time(NULL), qdisk));
+ printf("OK %s\n", qamdevice);
+ dbprintf(("%s: amdevice %s OK\n",
+ debug_prefix_time(NULL), qamdevice));
+ printf("OK %s\n", qdevice);
+ dbprintf(("%s: device %s OK\n", debug_prefix_time(NULL), qdevice));
}
if(extra_info) {
dbprintf(("%s: extra info: %s\n", debug_prefix_time(NULL), extra_info));
amfree(extra_info);
}
+ amfree(qdisk);
+ amfree(qdevice);
+ amfree(qamdevice);
amfree(device);
/* XXX perhaps do something with level: read dumpdates and sanity check */
}
-static void check_overall()
+static void
+check_overall(void)
{
char *cmd;
struct stat buf;
int testfd;
+ char *gnutar_list_dir;
+ int need_amandates = 0;
if( need_runtar )
{
#else
printf("ERROR [GNUTAR program not available]\n");
#endif
-#ifdef AMANDATES_FILE
- check_file(AMANDATES_FILE, R_OK|W_OK);
-#endif
-#ifdef GNUTAR_LISTED_INCREMENTAL_DIR
- check_dir(GNUTAR_LISTED_INCREMENTAL_DIR,R_OK|W_OK);
-#endif
+ need_amandates = 1;
+ gnutar_list_dir = client_getconf_str(CLN_GNUTAR_LIST_DIR);
+ if (strlen(gnutar_list_dir) == 0)
+ gnutar_list_dir = NULL;
+ if (gnutar_list_dir)
+ check_dir(gnutar_list_dir, R_OK|W_OK);
}
+ if (need_amandates) {
+ char *amandates_file;
+ amandates_file = client_getconf_str(CLN_AMANDATES);
+ check_file(amandates_file, R_OK|W_OK);
+ }
if( need_calcsize ) {
char *cmd;
check_file("/etc/vdumpdates", F_OK);
check_access("/dev/null", R_OK|W_OK);
- check_space(AMANDA_TMPDIR, 64); /* for amandad i/o */
+ check_space(AMANDA_TMPDIR, (off_t)64); /* for amandad i/o */
#ifdef AMANDA_DBGDIR
- check_space(AMANDA_DBGDIR, 64); /* for amandad i/o */
+ check_space(AMANDA_DBGDIR, (off_t)64); /* for amandad i/o */
#endif
- check_space("/etc", 64); /* for /etc/dumpdates writing */
+ check_space("/etc", (off_t)64); /* for /etc/dumpdates writing */
}
-static void check_space(dir, kbytes)
-char *dir;
-long kbytes;
+static void
+check_space(
+ char * dir,
+ off_t kbytes)
{
generic_fs_stats_t statp;
-
- if(get_fs_stats(dir, &statp) == -1)
- printf("ERROR [cannot statfs %s: %s]\n", dir, strerror(errno));
- else if(statp.avail < kbytes)
- printf("ERROR [dir %s needs %ldKB, only has %ldKB available.]\n",
- dir, kbytes, statp.avail);
- else
- printf("OK %s has more than %ld KB available.\n", dir, kbytes);
+ char *quoted = quote_string(dir);
+
+ if(get_fs_stats(dir, &statp) == -1) {
+ printf("ERROR [cannot statfs %s: %s]\n", quoted, strerror(errno));
+ } else if(statp.avail < kbytes) {
+ printf("ERROR [dir %s needs " OFF_T_FMT "KB, only has "
+ OFF_T_FMT "KB available.]\n", quoted,
+ (OFF_T_FMT_TYPE)kbytes,
+ (OFF_T_FMT_TYPE)statp.avail);
+ } else {
+ printf("OK %s has more than " OFF_T_FMT " KB available.\n",
+ quoted, (OFF_T_FMT_TYPE)kbytes);
+ }
+ amfree(quoted);
}
-static void check_access(filename, mode)
-char *filename;
-int mode;
+static void
+check_access(
+ char * filename,
+ int mode)
{
char *noun, *adjective;
+ char *quoted = quote_string(filename);
if(mode == F_OK)
noun = "find", adjective = "exists";
noun = "access", adjective = "accessible";
if(access(filename, mode) == -1)
- printf("ERROR [can not %s %s: %s]\n", noun, filename, strerror(errno));
+ printf("ERROR [can not %s %s: %s]\n", noun, quoted, strerror(errno));
else
- printf("OK %s %s\n", filename, adjective);
+ printf("OK %s %s\n", quoted, adjective);
+ amfree(quoted);
}
-static void check_file(filename, mode)
-char *filename;
-int mode;
+static void
+check_file(
+ char * filename,
+ int mode)
{
struct stat stat_buf;
+ char *quoted;
+
if(!stat(filename, &stat_buf)) {
if(!S_ISREG(stat_buf.st_mode)) {
- printf("ERROR [%s is not a file]\n", filename);
+ quoted = quote_string(filename);
+ printf("ERROR [%s is not a file]\n", quoted);
+ amfree(quoted);
}
}
check_access(filename, mode);
}
-static void check_dir(dirname, mode)
-char *dirname;
-int mode;
+static void
+check_dir(
+ char * dirname,
+ int mode)
{
struct stat stat_buf;
+ char *quoted;
char *dir;
if(!stat(dirname, &stat_buf)) {
if(!S_ISDIR(stat_buf.st_mode)) {
- printf("ERROR [%s is not a directory]\n", dirname);
+ quoted = quote_string(dirname);
+ printf("ERROR [%s is not a directory]\n", quoted);
+ amfree(quoted);
}
}
dir = stralloc2(dirname, "/.");
amfree(dir);
}
-static void check_suid(filename)
-char *filename;
+static void
+check_suid(
+ char * filename)
{
/* The following is only valid for real Unixs */
#ifndef IGNORE_UID_CHECK
struct stat stat_buf;
+ char *quoted = quote_string(filename);
+
if(!stat(filename, &stat_buf)) {
if(stat_buf.st_uid != 0 ) {
- printf("ERROR [%s is not owned by root]\n",filename);
+ printf("ERROR [%s is not owned by root]\n", quoted);
}
if((stat_buf.st_mode & S_ISUID) != S_ISUID) {
- printf("ERROR [%s is not SUID root]\n",filename);
+ printf("ERROR [%s is not SUID root]\n", quoted);
}
}
else {
- printf("ERROR [can not stat %s]\n",filename);
+ printf("ERROR [can not stat %s]\n", quoted);
}
+ amfree(quoted);
+#else
+ (void)filename; /* Quiet unused parameter warning */
#endif
}
* file named AUTHORS, in the root directory of this distribution.
*/
/*
- * $Id: sendbackup-dump.c,v 1.88 2006/03/09 20:06:11 johnfranks Exp $
+ * $Id: sendbackup-dump.c,v 1.90 2006/07/25 18:10:07 martinea Exp $
*
* send backup data using BSD dump
*/
+#include "amanda.h"
#include "sendbackup.h"
#include "getfsent.h"
#include "clock.h"
#define LEAF_AND_DIRS "sed -e \'\ns/^leaf[ \t]*[0-9]*[ \t]*\\.//\nt\n/^dir[ \t]/ {\ns/^dir[ \t]*[0-9]*[ \t]*\\.//\ns%$%/%\nt\n}\nd\n\'"
-static regex_t re_table[] = {
+static amregex_t re_table[] = {
/* the various encodings of dump size */
/* this should also match BSDI pre-3.0's buggy dump program, that
produced doubled DUMP: DUMP: messages */
AM_STRANGE_RE(NULL)
};
+static void start_backup(char *host, char *disk, char *amdevice, int level,
+ char *dumpdate, int dataf, int mesgf, int indexf);
+static void end_backup(int status);
+
/*
* doing similar to $ dump | compression | encryption
*/
-static void start_backup(host, disk, amdevice, level, dumpdate, dataf, mesgf, indexf)
- char *host;
- char *disk, *amdevice;
- int level, dataf, mesgf, indexf;
- char *dumpdate;
+static void
+start_backup(
+ char * host,
+ char * disk,
+ char * amdevice,
+ int level,
+ char * dumpdate,
+ int dataf,
+ int mesgf,
+ int indexf)
{
int dumpin, dumpout, compout;
char *dumpkeys = NULL;
char level_str[NUM_STR_SIZE];
char *compopt = NULL;
char *encryptopt = skip_argument;
+ char *qdisk;
+ char *config;
+
+ (void)dumpdate; /* Quiet unused parameter warning */
+ snprintf(level_str, SIZEOF(level_str), "%d", level);
- snprintf(level_str, sizeof(level_str), "%d", level);
+ qdisk = quote_string(disk);
+ dbprintf(("%s: start: %s:%s lev %d\n",
+ get_pname(), host, qdisk, level));
fprintf(stderr, "%s: start [%s:%s level %d]\n",
- get_pname(), host, disk, level);
+ get_pname(), host, qdisk, level);
+ amfree(qdisk);
- /* apply client-side encryption here */
- if ( options->encrypt == ENCRYPT_CUST ) {
- encpid = pipespawn(options->clnt_encrypt, STDIN_PIPE,
+ /* apply client-side encryption here */
+ if ( options->encrypt == ENCRYPT_CUST ) {
+ encpid = pipespawn(options->clnt_encrypt, STDIN_PIPE,
&compout, &dataf, &mesgf,
options->clnt_encrypt, encryptopt, NULL);
- dbprintf(("%s: pid %ld: %s\n",
+ dbprintf(("%s: pid %ld: %s\n",
debug_prefix_time("-gnutar"), (long)encpid, options->clnt_encrypt));
- } else {
+ } else {
compout = dataf;
encpid = -1;
- }
- /* now do the client-side compression */
+ }
+ /* now do the client-side compression */
if(options->compress == COMPR_FAST || options->compress == COMPR_BEST) {
#if defined(USE_RUNDUMP) || !defined(DUMP)
cmd = vstralloc(libexecdir, "/", "rundump", versionsuffix(), NULL);
+ if (g_options->config)
+ config = g_options->config;
+ else
+ config = "NOCONFIG";
#else
cmd = stralloc(DUMP);
+ config = skip_argument;
#endif
#ifndef AIX_BACKUP /* { */
{
char *progname = cmd = newvstralloc(cmd, libexecdir, "/", "rundump",
versionsuffix(), NULL);
+ if (g_options->config)
+ config = g_options->config;
+ else
+ config = "NOCONFIG";
+
program->backup_name = XFSDUMP;
program->restore_name = XFSRESTORE;
dumpkeys = stralloc(level_str);
dumppid = pipespawn(progname, STDIN_PIPE,
&dumpin, &dumpout, &mesgf,
+ config, /* JLM */
"xfsdump",
options->no_record ? "-J" : skip_argument,
"-F",
#ifdef USE_RUNDUMP
char *progname = cmd = newvstralloc(cmd, libexecdir, "/", "rundump",
versionsuffix(), NULL);
+ if (g_options->config)
+ config = g_options->config;
+ else
+ config = "NOCONFIG";
#else
char *progname = cmd = newvstralloc(cmd, VXDUMP, NULL);
+ config = skip_argument;
#endif
program->backup_name = VXDUMP;
program->restore_name = VXRESTORE;
dumppid = pipespawn(progname, STDIN_PIPE,
&dumpin, &dumpout, &mesgf,
+ progname, config, /* JLM */
"vxdump",
dumpkeys,
"1048576",
{
char *progname = cmd = newvstralloc(cmd, libexecdir, "/", "rundump",
versionsuffix(), NULL);
+ if (g_options->config)
+ config = g_options->config;
+ else
+ config = "NOCONFIG";
device = newstralloc(device, amname_to_dirname(amdevice));
program->backup_name = VDUMP;
program->restore_name = VRESTORE;
dumppid = pipespawn(cmd, STDIN_PIPE,
&dumpin, &dumpout, &mesgf,
+ cmd, config,
"vdump",
dumpkeys,
"60",
dumppid = pipespawn(cmd, STDIN_PIPE,
&dumpin, &dumpout, &mesgf,
+ cmd, config,
"dump",
dumpkeys,
"1048576",
dumppid = pipespawn(cmd, STDIN_PIPE,
&dumpin, &dumpout, &mesgf,
+ cmd, config,
"backup",
dumpkeys,
"-",
aclose(indexf);
}
-static void end_backup(status)
-int status;
+static void
+end_backup(
+ int status)
{
+ (void)status; /* Quiet unused parameter warning */
+
/* don't need to do anything for dump */
}
* file named AUTHORS, in the root directory of this distribution.
*/
/*
- * $Id: sendbackup-gnutar.c,v 1.92 2005/12/09 03:22:52 paddy_s Exp $
+ * $Id: sendbackup-gnutar.c,v 1.98 2006/07/25 18:35:21 martinea Exp $
*
* send backup data using GNU tar
*/
#include "util.h"
#include "getfsent.h" /* for amname_to_dirname lookup */
#include "version.h"
+#include "clientconf.h"
#ifdef SAMBA_CLIENT
#include "findpass.h"
#endif
-static regex_t re_table[] = {
+static amregex_t re_table[] = {
/* tar prints the size in bytes */
AM_SIZE_RE("^ *Total bytes written: [0-9][0-9]*", 1),
AM_NORMAL_RE("^Elapsed time:"),
char *cur_disk;
time_t cur_dumptime;
-#ifdef GNUTAR_LISTED_INCREMENTAL_DIR
+static char *gnutar_list_dir = NULL;
static char *incrname = NULL;
-#endif
+static char *amandates_file;
/*
* doing similar to $ gtar | compression | encryption
*/
-static void start_backup(host, disk, amdevice, level, dumpdate, dataf, mesgf, indexf)
- char *host;
- char *disk, *amdevice;
- int level, dataf, mesgf, indexf;
- char *dumpdate;
+static void
+start_backup(
+ char * host,
+ char * disk,
+ char * amdevice,
+ int level,
+ char * dumpdate,
+ int dataf,
+ int mesgf,
+ int indexf)
{
int dumpin, dumpout, compout;
char *cmd = NULL;
char *error_pn = NULL;
char *compopt = NULL;
char *encryptopt = skip_argument;
+ char *quoted;
+ char *qdisk;
+ int infd, outfd;
+ ssize_t nb;
+ char buf[32768];
+
+ (void)dumpdate; /* Quiet unused parameter warning */
error_pn = stralloc2(get_pname(), "-smbclient");
+ qdisk = quote_string(disk);
+ dbprintf(("%s: start: %s:%s lev %d\n",
+ get_pname(), host, qdisk, level));
fprintf(stderr, "%s: start [%s:%s level %d]\n",
- get_pname(), host, disk, level);
+ get_pname(), host, qdisk, level);
+
/* apply client-side encryption here */
if ( options->encrypt == ENCRYPT_CUST ) {
- encpid = pipespawn(options->clnt_encrypt, STDIN_PIPE,
+ encpid = pipespawn(options->clnt_encrypt, STDIN_PIPE,
&compout, &dataf, &mesgf,
options->clnt_encrypt, encryptopt, NULL);
- dbprintf(("%s: pid %ld: %s\n",
+ dbprintf(("%s: pid %ld: %s\n",
debug_prefix_time("-gnutar"), (long)encpid, options->clnt_encrypt));
} else {
compout = dataf;
comppid = -1;
}
-#ifdef GNUTAR_LISTED_INCREMENTAL_DIR /* { */
+ gnutar_list_dir = client_getconf_str(CLN_GNUTAR_LIST_DIR);
+ if (strlen(gnutar_list_dir) == 0)
+ gnutar_list_dir = NULL;
+
#ifdef SAMBA_CLIENT /* { */
if (amdevice[0] == '/' && amdevice[1]=='/')
amfree(incrname);
else
#endif /* } */
- {
+ if (gnutar_list_dir) {
char *basename = NULL;
char number[NUM_STR_SIZE];
char *s;
int ch;
char *inputname = NULL;
- FILE *in = NULL;
- FILE *out;
int baselevel;
- char *line = NULL;
- basename = vstralloc(GNUTAR_LISTED_INCREMENTAL_DIR,
+ basename = vstralloc(gnutar_list_dir,
"/",
host,
disk,
* The loop starts at the first character of the host name,
* not the '/'.
*/
- s = basename + sizeof(GNUTAR_LISTED_INCREMENTAL_DIR);
+ s = basename + strlen(gnutar_list_dir) + 1;
while((ch = *s++) != '\0') {
- if(ch == '/' || isspace(ch)) s[-1] = '_';
+ if(ch == '/')
+ s[-1] = '_';
}
- snprintf(number, sizeof(number), "%d", level);
+ snprintf(number, SIZEOF(number), "%d", level);
incrname = vstralloc(basename, "_", number, ".new", NULL);
unlink(incrname);
/*
- * Open the listed incremental file for the previous level. Search
+ * Open the listed incremental file from the previous level. Search
* backward until one is found. If none are found (which will also
* be true for a level 0), arrange to read from /dev/null.
*/
baselevel = level;
- while (in == NULL) {
+ infd = -1;
+ while (infd == -1) {
if (--baselevel >= 0) {
- snprintf(number, sizeof(number), "%d", baselevel);
+ snprintf(number, SIZEOF(number), "%d", baselevel);
inputname = newvstralloc(inputname,
basename, "_", number, NULL);
} else {
inputname = newstralloc(inputname, "/dev/null");
}
- if ((in = fopen(inputname, "r")) == NULL) {
+ if ((infd = open(inputname, O_RDONLY)) == -1) {
int save_errno = errno;
+ char *qname = quote_string(inputname);
- dbprintf(("%s: error opening %s: %s\n",
+ dbprintf(("%s: error opening '%s': %s\n",
debug_prefix_time("-gnutar"),
- inputname,
+ qname,
strerror(save_errno)));
if (baselevel < 0) {
- error("error [opening %s: %s]", inputname, strerror(save_errno));
+ error("error [opening '%s': %s]", qname, strerror(save_errno));
+ /*NOTREACHED*/
}
+ amfree(qname);
}
}
/*
* Copy the previous listed incremental file to the new one.
*/
- if ((out = fopen(incrname, "w")) == NULL) {
- error("error [opening %s: %s]", incrname, strerror(errno));
+ if ((outfd = open(incrname, O_WRONLY|O_CREAT, 0600)) == -1) {
+ error("error [opening '%s': %s]", incrname, strerror(errno));
+ /*NOTREACHED*/
}
- for (; (line = agets(in)) != NULL; free(line)) {
- if(fputs(line, out) == EOF || putc('\n', out) == EOF) {
- error("error [writing to %s: %s]", incrname, strerror(errno));
+ while ((nb = read(infd, &buf, SIZEOF(buf))) > 0) {
+ if (fullwrite(outfd, &buf, (size_t)nb) < nb) {
+ error("error [writing to '%s': %s]", incrname,
+ strerror(errno));
+ /*NOTREACHED*/
}
}
- amfree(line);
- if (ferror(in)) {
- error("error [reading from %s: %s]", inputname, strerror(errno));
+ if (nb < 0) {
+ error("error [reading from '%s': %s]", inputname, strerror(errno));
+ /*NOTREACHED*/
}
- if (fclose(in) == EOF) {
- error("error [closing %s: %s]", inputname, strerror(errno));
+
+ if (close(infd) != 0) {
+ error("error [closing '%s': %s]", inputname, strerror(errno));
+ /*NOTREACHED*/
}
- in = NULL;
- if (fclose(out) == EOF) {
- error("error [closing %s: %s]", incrname, strerror(errno));
+ if (close(outfd) != 0) {
+ error("error [closing '%s': %s]", incrname, strerror(errno));
+ /*NOTREACHED*/
}
- out = NULL;
dbprintf(("%s: doing level %d dump as listed-incremental",
debug_prefix_time("-gnutar"), level));
if(baselevel >= 0) {
- dbprintf((" from %s", inputname));
+ quoted = quote_string(inputname);
+ dbprintf((" from '%s'", quoted));
+ amfree(quoted);
}
- dbprintf((" to %s\n", incrname));
+ quoted = quote_string(incrname);
+ dbprintf((" to '%s'\n", quoted));
+ amfree(quoted);
amfree(inputname);
amfree(basename);
}
-#endif /* } */
/* find previous dump time */
- if(!start_amandates(0))
- error("error [opening %s: %s]", AMANDATES_FILE, strerror(errno));
+ amandates_file = client_getconf_str(CLN_AMANDATES);
+ if(!start_amandates(amandates_file, 0)) {
+ error("error [opening %s: %s]", amandates_file, strerror(errno));
+ /*NOTREACHED*/
+ }
amdates = amandates_lookup(disk);
free_amandates();
gmtm = gmtime(&prev_dumptime);
- snprintf(dumptimestr, sizeof(dumptimestr),
+ snprintf(dumptimestr, SIZEOF(dumptimestr),
"%04d-%02d-%02d %2d:%02d:%02d GMT",
gmtm->tm_year + 1900, gmtm->tm_mon+1, gmtm->tm_mday,
gmtm->tm_hour, gmtm->tm_min, gmtm->tm_sec);
if (amdevice[0] == '/' && amdevice[1]=='/') {
char *sharename = NULL, *user_and_password = NULL, *domain = NULL;
char *share = NULL, *subdir = NULL;
- char *pwtext;
+ char *pwtext = NULL;
char *taropt;
- int passwdf;
- int lpass;
- int pwtext_len;
+ int passwdf = -1;
+ size_t lpass;
+ size_t pwtext_len;
char *pw_fd_env;
parsesharename(amdevice, &share, &subdir);
amfree(subdir);
set_pname(error_pn);
amfree(error_pn);
- error("cannot parse disk entry '%s' for share/subdir", disk);
+ error("cannot parse disk entry %s for share/subdir", qdisk);
+ /*NOTREACHED*/
}
if ((subdir) && (SAMBA_VERSION < 2)) {
amfree(share);
amfree(subdir);
set_pname(error_pn);
amfree(error_pn);
- error("subdirectory specified for share '%s' but samba not v2 or better", disk);
+ error("subdirectory specified for share %s but samba not v2 or better", qdisk);
+ /*NOTREACHED*/
}
if ((user_and_password = findpass(share, &domain)) == NULL) {
if(domain) {
set_pname(error_pn);
amfree(error_pn);
error("error [invalid samba host or password not found?]");
+ /*NOTREACHED*/
}
lpass = strlen(user_and_password);
if ((pwtext = strchr(user_and_password, '%')) == NULL) {
}
set_pname(error_pn);
amfree(error_pn);
- error("password field not \'user%%pass\' for %s", disk);
+ error("password field not \'user%%pass\' for %s", qdisk);
+ /*NOTREACHED*/
}
*pwtext++ = '\0';
pwtext_len = strlen(pwtext);
set_pname(error_pn);
amfree(error_pn);
error("error [can't make share name of %s]", share);
+ /*NOTREACHED*/
}
taropt = stralloc("-T");
set_pname(error_pn);
amfree(error_pn);
error("error [password write failed: %s]", strerror(save_errno));
+ /*NOTREACHED*/
}
memset(user_and_password, '\0', lpass);
amfree(user_and_password);
if(nb_exclude > 0) file_exclude = build_exclude(disk, amdevice, options, 0);
if(nb_include > 0) file_include = build_include(disk, amdevice, options, 0);
- my_argv = alloc(sizeof(char *) * (17 + (nb_exclude*2)+(nb_include*2)));
+ my_argv = alloc(SIZEOF(char *) * (22 + (nb_exclude*2)+(nb_include*2)));
cmd = vstralloc(libexecdir, "/", "runtar", versionsuffix(), NULL);
info_tapeheader();
start_index(options->createindex, dumpout, mesgf, indexf, indexcmd);
+ my_argv[i++] = "runtar";
+ if (g_options->config)
+ my_argv[i++] = g_options->config;
+ else
+ my_argv[i++] = "NOCONFIG";
my_argv[i++] = "gtar";
my_argv[i++] = "--create";
my_argv[i++] = "--file";
my_argv[i++] = "--directory";
my_argv[i++] = dirname;
my_argv[i++] = "--one-file-system";
-#ifdef GNUTAR_LISTED_INCREMENTAL_DIR
- my_argv[i++] = "--listed-incremental";
- my_argv[i++] = incrname;
-#else
- my_argv[i++] = "--incremental";
- my_argv[i++] = "--newer";
- my_argv[i++] = dumptimestr;
-#endif
+ if (gnutar_list_dir && incrname) {
+ my_argv[i++] = "--listed-incremental";
+ my_argv[i++] = incrname;
+ } else {
+ my_argv[i++] = "--incremental";
+ my_argv[i++] = "--newer";
+ my_argv[i++] = dumptimestr;
+ }
#ifdef ENABLE_GNUTAR_ATIME_PRESERVE
/* --atime-preserve causes gnutar to call
* utime() after reading files in order to
cmd,
(long)dumppid));
+ amfree(qdisk);
amfree(dirname);
amfree(cmd);
amfree(indexcmd);
aclose(indexf);
}
-static void end_backup(goterror)
-int goterror;
+static void
+end_backup(
+ int goterror)
{
if(!options->no_record && !goterror) {
-#ifdef GNUTAR_LISTED_INCREMENTAL_DIR
if (incrname != NULL && strlen(incrname) > 4) {
char *nodotnew;
amfree(nodotnew);
amfree(incrname);
}
-#endif
- if(!start_amandates(1)) {
+ if(!start_amandates(amandates_file, 1)) {
fprintf(stderr, "%s: warning [opening %s: %s]", get_pname(),
- AMANDATES_FILE, strerror(errno));
+ amandates_file, strerror(errno));
}
else {
amandates_updateone(cur_disk, cur_level, cur_dumptime);
* file named AUTHORS, in the root directory of this distribution.
*/
/*
- * $Id: sendbackup.c,v 1.77 2006/03/09 16:51:41 martinea Exp $
+ * $Id: sendbackup.c,v 1.88 2006/07/25 18:27:56 martinea Exp $
*
* common code for the sendbackup-* programs.
*/
#include "arglist.h"
#include "getfsent.h"
#include "version.h"
+#include "clientconf.h"
#define TIMEOUT 30
-int comppid = -1;
-int dumppid = -1;
-int tarpid = -1;
-int encpid = -1;
-int indexpid = -1;
+pid_t comppid = (pid_t)-1;
+pid_t dumppid = (pid_t)-1;
+pid_t tarpid = (pid_t)-1;
+pid_t encpid = (pid_t)-1;
+pid_t indexpid = (pid_t)-1;
char *errorstr = NULL;
int datafd;
int indexfd;
option_t *options;
+g_option_t *g_options = NULL;
long dump_size = -1;
static am_feature_t *our_features = NULL;
static char *our_feature_string = NULL;
-static g_option_t *g_options = NULL;
+static char *amandad_auth = NULL;
/* local functions */
-int main P((int argc, char **argv));
-char *optionstr P((option_t *options));
-char *childstr P((int pid));
-int check_status P((int pid, amwait_t w));
-
-int pipefork P((void (*func) P((void)), char *fname, int *stdinfd,
- int stdoutfd, int stderrfd));
-void parse_backup_messages P((int mesgin));
-static void process_dumpline P((char *str));
-static void save_fd P((int *, int));
-
-char *optionstr(options)
-option_t *options;
+int main(int argc, char **argv);
+char *optionstr(option_t *options);
+char *childstr(pid_t pid);
+int check_status(pid_t pid, amwait_t w);
+
+pid_t pipefork(void (*func)(void), char *fname, int *stdinfd,
+ int stdoutfd, int stderrfd);
+void parse_backup_messages(int mesgin);
+static void process_dumpline(char *str);
+static void save_fd(int *, int);
+
+double first_num(char *str);
+
+
+
+char *
+optionstr(
+ option_t * options)
{
static char *optstr = NULL;
char *compress_opt;
strappend(exclude_list_opt, exc);
}
}
+ amfree(exc);
optstr = newvstralloc(optstr,
compress_opt,
encrypt_opt,
}
-int main(argc, argv)
-int argc;
-char **argv;
+int
+main(
+ int argc,
+ char ** argv)
{
int interactive = 0;
- int level, mesgpipe[2];
- char *prog, *disk, *amdevice, *dumpdate, *stroptions;
+ int level = 0;
+ int mesgpipe[2];
+ char *prog, *dumpdate, *stroptions;
+ char *disk = NULL;
+ char *qdisk = NULL;
+ char *amdevice = NULL;
+ char *qamdevice = NULL;
char *line = NULL;
char *err_extra = NULL;
char *s;
+ char *conffile;
int i;
int ch;
unsigned long malloc_hist_1, malloc_size_1;
/* initialize */
- safe_fd(DATA_FD_OFFSET, DATA_FD_COUNT);
+ safe_fd(DATA_FD_OFFSET, DATA_FD_COUNT*2);
+
safe_cd();
set_pname("sendbackup");
/* Don't die when child closes pipe */
signal(SIGPIPE, SIG_IGN);
+ /* Don't die when interrupt received */
+ signal(SIGINT, SIG_IGN);
+
malloc_size_1 = malloc_inuse(&malloc_hist_1);
- interactive = (argc > 1 && strcmp(argv[1],"-t") == 0);
+ if(argc > 1 && strcmp(argv[1],"-t") == 0) {
+ interactive = 1;
+ argc--;
+ argv++;
+ } else {
+ interactive = 0;
+ }
+
erroutput_type = (ERR_INTERACTIVE|ERR_SYSLOG);
- dbopen();
+ dbopen(DBG_SUBDIR_CLIENT);
startclock();
dbprintf(("%s: version %s\n", get_pname(), version()));
+ if(argc > 2 && strcmp(argv[1], "amandad") == 0) {
+ amandad_auth = stralloc(argv[2]);
+ }
+
our_features = am_init_feature_set();
our_feature_string = am_feature_to_string(our_features);
+ conffile = vstralloc(CONFIG_DIR, "/", "amanda-client.conf", NULL);
+ if (read_clientconf(conffile) > 0) {
+ error("error reading conffile: %s", conffile);
+ /*NOTREACHED*/
+ }
+ amfree(conffile);
+
if(interactive) {
/*
* In interactive (debug) mode, the backup data is sent to
prog = NULL;
disk = NULL;
+ qdisk = NULL;
amdevice = NULL;
dumpdate = NULL;
stroptions = NULL;
for(; (line = agets(stdin)) != NULL; free(line)) {
+ if (line[0] == '\0')
+ continue;
if(interactive) {
fprintf(stderr, "%s> ", get_pname());
fflush(stderr);
}
#define sc "OPTIONS "
- if(strncmp(line, sc, sizeof(sc)-1) == 0) {
+ if(strncmp(line, sc, SIZEOF(sc)-1) == 0) {
#undef sc
g_options = parse_g_options(line+8, 1);
if(!g_options->hostname) {
gethostname(g_options->hostname, MAX_HOSTNAME_LENGTH);
g_options->hostname[MAX_HOSTNAME_LENGTH] = '\0';
}
+
+ if (g_options->config) {
+ conffile = vstralloc(CONFIG_DIR, "/", g_options->config, "/",
+ "amanda-client.conf", NULL);
+ if (read_clientconf(conffile) > 0) {
+ error("error reading conffile: %s", conffile);
+ /*NOTREACHED*/
+ }
+ amfree(conffile);
+
+ dbrename(g_options->config, DBG_SUBDIR_CLIENT);
+ }
continue;
}
goto err;
}
+ dbprintf((" sendbackup req: <%s>\n", line));
s = line;
ch = *s++;
err_extra = "no disk name";
goto err; /* no disk name */
}
+
amfree(disk);
- disk = s - 1;
- skip_non_whitespace(s, ch);
+ amfree(qdisk);
+ qdisk = s - 1;
+ ch = *qdisk;
+ skip_quoted_string(s, ch);
s[-1] = '\0';
- disk = stralloc(disk);
+ qdisk = stralloc(qdisk);
+ disk = unquote_string(qdisk);
skip_whitespace(s, ch); /* find the device or level */
if (ch == '\0') {
if(!isdigit((int)s[-1])) {
amfree(amdevice);
+ amfree(qamdevice);
amdevice = s - 1;
skip_non_whitespace(s, ch);
s[-1] = '\0';
else {
amdevice = stralloc(disk);
}
-
+ qamdevice = quote_string(amdevice);
/* find the level number */
if(ch == '\0' || sscanf(s - 1, "%d", &level) != 1) {
err_extra = "bad level";
goto err; /* no options */
}
#define sc "OPTIONS "
- if(strncmp(s - 1, sc, sizeof(sc)-1) != 0) {
+ if(strncmp(s - 1, sc, SIZEOF(sc)-1) != 0) {
err_extra = "no OPTIONS keyword";
goto err; /* no options */
}
- s += sizeof(sc)-1;
+ s += SIZEOF(sc)-1;
ch = s[-1];
#undef sc
skip_whitespace(s, ch); /* find the options string */
}
amfree(line);
+ if (prog == NULL ||
+ disk == NULL ||
+ amdevice == NULL ||
+ dumpdate == NULL ||
+ stroptions == NULL) {
+ err_extra = "no valid sendbackup request";
+ goto err;
+ }
+
dbprintf((" parsed request as: program `%s'\n", prog));
- dbprintf((" disk `%s'\n", disk));
- dbprintf((" device `%s'\n", amdevice));
+ dbprintf((" disk `%s'\n", qdisk));
+ dbprintf((" device `%s'\n", qamdevice));
dbprintf((" level %d\n", level));
dbprintf((" since %s\n", dumpdate));
dbprintf((" options `%s'\n", stroptions));
}
if (programs[i] == NULL) {
error("ERROR [%s: unknown program %s]", get_pname(), prog);
+ /*NOTREACHED*/
}
program = programs[i];
if(!interactive) {
datafd = DATA_FD_OFFSET + 0;
- mesgfd = DATA_FD_OFFSET + 1;
- indexfd = DATA_FD_OFFSET + 2;
+ mesgfd = DATA_FD_OFFSET + 2;
+ indexfd = DATA_FD_OFFSET + 4;
}
if (!options->createindex)
indexfd = -1;
+ if(options->auth && amandad_auth) {
+ if(strcasecmp(options->auth, amandad_auth) != 0) {
+ printf("ERROR [client configured for auth=%s while server requested '%s']\n",
+ amandad_auth, options->auth);
+ exit(-1);
+ }
+ }
+
printf("CONNECT DATA %d MESG %d INDEX %d\n",
- datafd, mesgfd, indexfd);
+ DATA_FD_OFFSET, DATA_FD_OFFSET+1,
+ indexfd == -1 ? -1 : DATA_FD_OFFSET+2);
printf("OPTIONS ");
if(am_has_feature(g_options->features, fe_rep_options_features)) {
printf("features=%s;", our_feature_string);
s = strerror(errno);
error("ERROR [%s: open of /dev/null for debug data stream: %s]\n",
get_pname(), s);
+ /*NOTREACHED*/
}
mesgfd = 2;
indexfd = 1;
if(pipe(mesgpipe) == -1) {
error("error [opening mesg pipe: %s]", strerror(errno));
+ /*NOTREACHED*/
}
program->start_backup(g_options->hostname, disk, amdevice, level, dumpdate, datafd, mesgpipe[1],
amfree(prog);
amfree(disk);
+ amfree(qdisk);
amfree(amdevice);
+ amfree(qamdevice);
amfree(dumpdate);
amfree(stroptions);
amfree(our_feature_string);
return 1;
}
-char *childstr(pid)
-int pid;
+
/*
* Returns a string for a child process. Checks the saved dump and
* compress pids to see which it is.
*/
+
+char *
+childstr(
+ pid_t pid)
{
if(pid == dumppid) return program->backup_name;
if(pid == comppid) return "compress";
}
-int check_status(pid, w)
-int pid;
-amwait_t w;
/*
* Determine if the child return status really indicates an error.
* If so, add the error message to the error string; more than one
* child can have an error.
*/
+
+int
+check_status(
+ pid_t pid,
+ amwait_t w)
{
char *thiserr = NULL;
char *str;
}
if(ret == 0) {
- snprintf(number, sizeof(number), "%d", sig);
+ snprintf(number, SIZEOF(number), "%d", sig);
thiserr = vstralloc(str, " got signal ", number, NULL);
} else {
- snprintf(number, sizeof(number), "%d", ret);
+ snprintf(number, SIZEOF(number), "%d", ret);
thiserr = vstralloc(str, " returned ", number, NULL);
}
}
-/* Send header info to the message file.
-*/
-void info_tapeheader()
+/*
+ *Send header info to the message file.
+ */
+void
+info_tapeheader(void)
{
fprintf(stderr, "%s: info BACKUP=%s\n", get_pname(), program->backup_name);
#endif
);
- fprintf(stderr, "%s -f... -\n", program->restore_name);
+ fprintf(stderr, "%s -f - ...\n", program->restore_name);
if (options->compress == COMPR_FAST || options->compress == COMPR_BEST)
fprintf(stderr, "%s: info COMPRESS_SUFFIX=%s\n",
fprintf(stderr, "%s: info end\n", get_pname());
}
-int pipefork(func, fname, stdinfd, stdoutfd, stderrfd)
-void (*func) P((void));
-char *fname;
-int *stdinfd;
-int stdoutfd, stderrfd;
+pid_t
+pipefork(
+ void (*func)(void),
+ char * fname,
+ int * stdinfd,
+ int stdoutfd,
+ int stderrfd)
{
- int pid, inpipe[2];
+ int inpipe[2];
+ pid_t pid;
dbprintf(("%s: forking function %s in pipeline\n",
debug_prefix_time(NULL), fname));
if(pipe(inpipe) == -1) {
error("error [open pipe to %s: %s]", fname, strerror(errno));
+ /*NOTREACHED*/
}
switch(pid = fork()) {
case -1:
error("error [fork %s: %s]", fname, strerror(errno));
+ /*NOTREACHED*/
default: /* parent process */
aclose(inpipe[0]); /* close input side of pipe */
*stdinfd = inpipe[1];
if(dup2(inpipe[0], 0) == -1) {
error("error [fork %s: dup2(%d, in): %s]",
fname, inpipe[0], strerror(errno));
+ /*NOTRACHED*/
}
if(dup2(stdoutfd, 1) == -1) {
error("error [fork %s: dup2(%d, out): %s]",
fname, stdoutfd, strerror(errno));
+ /*NOTRACHED*/
}
if(dup2(stderrfd, 2) == -1) {
error("error [fork %s: dup2(%d, err): %s]",
fname, stderrfd, strerror(errno));
+ /*NOTRACHED*/
}
func();
exit(0);
- /* NOTREACHED */
+ /*NOTREACHED*/
}
return pid;
}
-void parse_backup_messages(mesgin)
-int mesgin;
+void
+parse_backup_messages(
+ int mesgin)
{
- int goterror, wpid;
+ int goterror;
+ pid_t wpid;
amwait_t retstat;
char *line;
if(errno) {
error("error [read mesg pipe: %s]", strerror(errno));
+ /*NOTREACHED*/
}
while((wpid = wait(&retstat)) != -1) {
if(errorstr) {
error("error [%s]", errorstr);
+ /*NOTREACHED*/
} else if(dump_size == -1) {
error("error [no backup size line]");
+ /*NOTREACHED*/
}
program->end_backup(goterror);
}
-double first_num P((char *str));
-
-double first_num(str)
-char *str;
/*
* Returns the value of the first integer in a string.
*/
+
+double
+first_num(
+ char * str)
{
char *num;
int ch;
while(isdigit(ch) || ch == '.') ch = *str++;
str[-1] = '\0';
d = atof(num);
- str[-1] = ch;
+ str[-1] = (char)ch;
return d;
}
-static void process_dumpline(str)
-char *str;
+static void
+process_dumpline(
+ char * str)
{
- regex_t *rp;
+ amregex_t *rp;
char *type;
char startchr;
}
-/* start_index. Creates an index file from the output of dump/tar.
- It arranges that input is the fd to be written by the dump process.
- If createindex is not enabled, it does nothing. If it is not, a
- new process will be created that tees input both to a pipe whose
- read fd is dup2'ed input and to a program that outputs an index
- file to `index'.
-
- make sure that the chat from restore doesn't go to stderr cause
- this goes back to amanda which doesn't expect to see it
- (2>/dev/null should do it)
-
- Originally by Alan M. McIvor, 13 April 1996
-
- Adapted by Alexandre Oliva, 1 May 1997
-
- This program owes a lot to tee.c from GNU sh-utils and dumptee.c
- from the DeeJay backup package.
-
-*/
-
-static volatile int index_finished = 0;
+/*
+ * start_index. Creates an index file from the output of dump/tar.
+ * It arranges that input is the fd to be written by the dump process.
+ * If createindex is not enabled, it does nothing. If it is not, a
+ * new process will be created that tees input both to a pipe whose
+ * read fd is dup2'ed input and to a program that outputs an index
+ * file to `index'.
+ *
+ * make sure that the chat from restore doesn't go to stderr cause
+ * this goes back to amanda which doesn't expect to see it
+ * (2>/dev/null should do it)
+ *
+ * Originally by Alan M. McIvor, 13 April 1996
+ *
+ * Adapted by Alexandre Oliva, 1 May 1997
+ *
+ * This program owes a lot to tee.c from GNU sh-utils and dumptee.c
+ * from the DeeJay backup package.
+ */
-static void save_fd(fd, min)
-int *fd, min;
+static void
+save_fd(
+ int * fd,
+ int min)
{
int origfd = *fd;
debug_prefix_time(NULL), origfd, *fd));
}
-void start_index(createindex, input, mesg, index, cmd)
-int createindex, input, mesg, index;
-char *cmd;
+void
+start_index(
+ int createindex,
+ int input,
+ int mesg,
+ int index,
+ char * cmd)
{
int pipefd[2];
FILE *pipe_fp;
if (pipe(pipefd) != 0) {
error("creating index pipe: %s", strerror(errno));
+ /*NOTREACHED*/
}
switch(indexpid = fork()) {
case -1:
error("forking index tee process: %s", strerror(errno));
+ /*NOTREACHED*/
default:
aclose(pipefd[0]);
if (dup2(pipefd[1], input) == -1) {
error("dup'ping index tee output: %s", strerror(errno));
+ /*NOTREACHED*/
}
aclose(pipefd[1]);
return;
if ((pipe_fp = popen(cmd, "w")) == NULL) {
error("couldn't start index creator [%s]", strerror(errno));
+ /*NOTREACHED*/
}
dbprintf(("%s: started index creator: \"%s\"\n",
debug_prefix_time(NULL), cmd));
while(1) {
char buffer[BUFSIZ], *ptr;
- int bytes_read;
- int bytes_written;
- int just_written;
+ ssize_t bytes_read;
+ size_t bytes_written;
+ ssize_t just_written;
do {
- bytes_read = read(0, buffer, sizeof(buffer));
+ bytes_read = read(0, buffer, SIZEOF(buffer));
} while ((bytes_read < 0) && ((errno == EINTR) || (errno == EAGAIN)));
if (bytes_read < 0) {
error("index tee cannot read [%s]", strerror(errno));
+ /*NOTREACHED*/
}
if (bytes_read == 0)
/* write the stuff to the subprocess */
ptr = buffer;
bytes_written = 0;
- just_written = fullwrite(fileno(pipe_fp), ptr, bytes_read);
+ just_written = fullwrite(fileno(pipe_fp), ptr, (size_t)bytes_read);
if (just_written < 0) {
- /* the signal handler may have assigned to index_finished
+ /*
* just as we waited for write() to complete.
*/
if (errno != EPIPE) {
occurs */
ptr = buffer;
bytes_written = 0;
- just_written = fullwrite(3, ptr, bytes_read);
+ just_written = fullwrite(3, ptr, (size_t)bytes_read);
if (just_written < 0) {
error("index tee cannot write [%s]", strerror(errno));
- /* NOTREACHED */
+ /*NOTREACHED*/
} else {
bytes_written += just_written;
ptr += just_written;
* file named AUTHORS, in the root directory of this distribution.
*/
/*
- * $Id: sendbackup.h,v 1.18 2005/12/09 03:22:52 paddy_s Exp $
+ * $Id: sendbackup.h,v 1.20 2006/07/25 18:10:07 martinea Exp $
*
* a few common decls for the sendbackup-* sources
*/
+#ifndef SENDBACKUP_H
+#define SENDBACKUP_H
+
#include "amanda.h"
#include "pipespawn.h"
#include "client_util.h"
+#include "amandad.h"
-void info_tapeheader P((void));
-void start_index P((int createindex, int input, int mesg,
- int index, char *cmd));
+void info_tapeheader(void);
+void start_index(int createindex, int input, int mesg,
+ int index, char *cmd);
/*
* Dump output lines are scanned for two types of regex matches.
int srcline;
int scale; /* only used for size lines */
dmpline_t typ;
-} regex_t;
+} amregex_t;
#define AM_NORMAL_RE(re) {(re), __LINE__, 0, DMP_NORMAL}
#define AM_STRANGE_RE(re) {(re), __LINE__, 0, DMP_STRANGE}
#define AM_SIZE_RE(re,s) {(re), __LINE__, (s), DMP_SIZE}
#define AM_ERROR_RE(re) {(re), __LINE__, 0, DMP_ERROR}
-extern int comppid, dumppid, encpid, tarpid;
-extern int indexpid;
+extern pid_t comppid, dumppid, encpid, tarpid;
+extern pid_t indexpid;
extern option_t *options;
+extern g_option_t *g_options;
typedef struct backup_program_s {
char *name, *backup_name, *restore_name;
- regex_t *re_table;
- void (*start_backup) P((char *host, char *disk, char *amdevice, int level, char *dumpdate,
- int dataf, int mesgf, int indexf));
- void (*end_backup) P((int goterror));
+ amregex_t *re_table;
+ void (*start_backup)(char *host, char *disk, char *amdevice, int level, char *dumpdate, int dataf, int mesgf, int indexf);
+ void (*end_backup)(int goterror);
} backup_program_t;
extern backup_program_t *programs[], *program;
+#endif /* !SENDBACKUP_H */
* file named AUTHORS, in the root directory of this distribution.
*/
/*
- * $Id: sendsize.c,v 1.152 2006/03/09 16:51:41 martinea Exp $
+ * $Id: sendsize.c,v 1.171 2006/08/24 01:57:15 paddy_s Exp $
*
* send estimated backup sizes using dump
*/
#include "getfsent.h"
#include "version.h"
#include "client_util.h"
+#include "clientconf.h"
+#include "amandad.h"
#ifdef SAMBA_CLIENT
#include "findpass.h"
typedef struct disk_estimates_s {
struct disk_estimates_s *next;
char *amname;
+ char *qamname;
char *amdevice;
+ char *qamdevice;
char *dirname;
+ char *qdirname;
char *program;
char *calcprog;
int program_is_wrapper;
static g_option_t *g_options = NULL;
/* local functions */
-int main P((int argc, char **argv));
-void add_diskest P((char *disk, char *amdevice, int level, int spindle,
+int main(int argc, char **argv);
+void add_diskest(char *disk, char *amdevice, int level, int spindle,
int program_is_wrapper, char *prog, char *calcprog,
- option_t *options));
-void calc_estimates P((disk_estimates_t *est));
-void free_estimates P((disk_estimates_t *est));
-void dump_calc_estimates P((disk_estimates_t *));
-void smbtar_calc_estimates P((disk_estimates_t *));
-void gnutar_calc_estimates P((disk_estimates_t *));
-void wrapper_calc_estimates P((disk_estimates_t *));
-void generic_calc_estimates P((disk_estimates_t *));
-
-
-int main(argc, argv)
-int argc;
-char **argv;
+ option_t *options);
+void calc_estimates(disk_estimates_t *est);
+void free_estimates(disk_estimates_t *est);
+void dump_calc_estimates(disk_estimates_t *);
+void star_calc_estimates(disk_estimates_t *);
+void smbtar_calc_estimates(disk_estimates_t *);
+void gnutar_calc_estimates(disk_estimates_t *);
+void wrapper_calc_estimates(disk_estimates_t *);
+void generic_calc_estimates(disk_estimates_t *);
+
+
+int
+main(
+ int argc,
+ char ** argv)
{
int level, spindle;
- char *prog, *calcprog, *disk, *amdevice, *dumpdate;
+ char *prog, *calcprog, *dumpdate;
option_t *options = NULL;
int program_is_wrapper;
disk_estimates_t *est;
char *s, *fp;
int ch;
char *err_extra = NULL;
- unsigned long malloc_hist_1, malloc_size_1;
- unsigned long malloc_hist_2, malloc_size_2;
int done;
int need_wait;
int dumpsrunning;
+ char *disk = NULL;
+ char *qdisk = NULL;
+ char *qlist = NULL;
+ char *amdevice = NULL;
+ char *qamdevice = NULL;
+ char *conffile;
+ char *amandates_file;
+#if defined(USE_DBMALLOC)
+ unsigned long malloc_hist_1, malloc_size_1;
+ unsigned long malloc_hist_2, malloc_size_2;
+#endif
+ (void)argc; /* Quiet unused parameter warning */
+ (void)argv; /* Quiet unused parameter warning */
/* initialize */
/* Don't die when child closes pipe */
signal(SIGPIPE, SIG_IGN);
+#if defined(USE_DBMALLOC)
malloc_size_1 = malloc_inuse(&malloc_hist_1);
+#endif
erroutput_type = (ERR_INTERACTIVE|ERR_SYSLOG);
- dbopen();
+ dbopen(DBG_SUBDIR_CLIENT);
startclock();
dbprintf(("%s: version %s\n", get_pname(), version()));
set_debug_prefix_pid(getpid());
+ conffile = vstralloc(CONFIG_DIR, "/", "amanda-client.conf", NULL);
+ if (read_clientconf(conffile) > 0) {
+ error("error reading conffile: %s", conffile);
+ /*NOTREACHED*/
+ }
+ amfree(conffile);
+
/* handle all service requests */
- start_amandates(0);
+ amandates_file = client_getconf_str(CLN_AMANDATES);
+ if(!start_amandates(amandates_file, 0))
+ error("error [opening %s: %s]", amandates_file, strerror(errno));
for(; (line = agets(stdin)) != NULL; free(line)) {
+ if (line[0] == '\0')
+ continue;
#define sc "OPTIONS "
- if(strncmp(line, sc, sizeof(sc)-1) == 0) {
+ if(strncmp(line, sc, SIZEOF(sc)-1) == 0) {
#undef sc
g_options = parse_g_options(line+8, 1);
if(!g_options->hostname) {
}
printf("\n");
fflush(stdout);
+
+ if (g_options->config) {
+ conffile = vstralloc(CONFIG_DIR, "/", g_options->config, "/",
+ "amanda-client.conf", NULL);
+ if (read_clientconf(conffile) > 0) {
+ error("error reading conffile: %s", conffile);
+ /*NOTREACHED*/
+ }
+ amfree(conffile);
+
+ dbrename(g_options->config, DBG_SUBDIR_CLIENT);
+ }
+
continue;
}
skip_whitespace(s, ch); /* find the program name */
if(ch == '\0') {
- err_extra = "no program name";
+ err_extra = stralloc("no program name");
goto err; /* no program name */
}
prog = s - 1;
if(strncmp(prog, "CALCSIZE", 8) == 0) {
skip_whitespace(s, ch); /* find the program name */
if(ch == '\0') {
- err_extra = "no program name";
+ err_extra = stralloc("no program name");
goto err;
}
calcprog = s - 1;
skip_whitespace(s, ch); /* find the disk name */
if(ch == '\0') {
- err_extra = "no disk name";
+ err_extra = stralloc("no disk name");
goto err; /* no disk name */
}
- disk = s - 1;
- skip_non_whitespace(s, ch);
- s[-1] = '\0';
+
+ if (qdisk != NULL)
+ amfree(qdisk);
+ if (disk != NULL)
+ amfree(disk);
+
+ fp = s - 1;
+ skip_quoted_string(s, ch);
+ s[-1] = '\0'; /* terminate the disk name */
+ qdisk = stralloc(fp);
+ disk = unquote_string(qdisk);
skip_whitespace(s, ch); /* find the device or level */
if (ch == '\0') {
- err_extra = "bad level";
+ err_extra = stralloc("bad level");
goto err;
}
if(!isdigit((int)s[-1])) {
fp = s - 1;
- skip_non_whitespace(s, ch);
+ skip_quoted_string(s, ch);
s[-1] = '\0';
- amdevice = stralloc(fp);
+ qamdevice = stralloc(fp);
+ amdevice = unquote_string(qamdevice);
skip_whitespace(s, ch); /* find level number */
}
else {
amdevice = stralloc(disk);
+ qamdevice = stralloc(qdisk);
}
/* find the level number */
if(ch == '\0' || sscanf(s - 1, "%d", &level) != 1) {
- err_extra = "bad level";
+ err_extra = stralloc("bad level");
goto err; /* bad level */
}
+ if (level < 0 || level >= DUMP_LEVELS) {
+ err_extra = stralloc("bad level");
+ goto err;
+ }
skip_integer(s, ch);
skip_whitespace(s, ch); /* find the dump date */
if(ch == '\0') {
- err_extra = "no dumpdate";
+ err_extra = stralloc("no dumpdate");
goto err; /* no dumpdate */
}
dumpdate = s - 1;
skip_non_whitespace(s, ch);
s[-1] = '\0';
+ (void)dumpdate; /* XXX: Set but not used */
spindle = 0; /* default spindle */
skip_whitespace(s, ch); /* find the spindle */
if(ch != '\0') {
if(sscanf(s - 1, "%d", &spindle) != 1) {
- err_extra = "bad spindle";
+ err_extra = stralloc("bad spindle");
goto err; /* bad spindle */
}
skip_integer(s, ch);
- skip_whitespace(s, ch); /* find the exclusion list */
+ skip_whitespace(s, ch); /* find the parameters */
if(ch != '\0') {
if(strncmp(s-1, "OPTIONS |;",10) == 0) {
options = parse_options(s + 8,
0);
}
else {
- options = alloc(sizeof(option_t));
+ options = alloc(SIZEOF(option_t));
init_options(options);
- if(strncmp(s-1, "exclude-file=", 13) == 0) {
- options->exclude_file =
- append_sl(options->exclude_file, s+12);
- }
- if(strncmp(s-1, "exclude-list=", 13) == 0) {
- options->exclude_list =
- append_sl(options->exclude_list, s+12);
- }
-
- skip_non_whitespace(s, ch);
- if(ch) {
- err_extra = "extra text at end";
- goto err; /* should have gotten to end */
+ while (ch != '\0') {
+ if(strncmp(s-1, "exclude-file=", 13) == 0) {
+ qlist = unquote_string(s+12);
+ options->exclude_file =
+ append_sl(options->exclude_file, qlist);
+ amfree(qlist);
+ } else if(strncmp(s-1, "exclude-list=", 13) == 0) {
+ options->exclude_list =
+ append_sl(options->exclude_list, qlist);
+ qlist = unquote_string(s+12);
+ amfree(qlist);
+ } else if(strncmp(s-1, "include-file=", 13) == 0) {
+ options->include_file =
+ append_sl(options->include_file, qlist);
+ qlist = unquote_string(s+12);
+ amfree(qlist);
+ } else if(strncmp(s-1, "include-list=", 13) == 0) {
+ options->include_list =
+ append_sl(options->include_list, qlist);
+ qlist = unquote_string(s+12);
+ amfree(qlist);
+ } else {
+ err_extra = vstralloc("Invalid parameter (",
+ s-1, ")", NULL);
+ goto err; /* should have gotten to end */
+ }
+ skip_quoted_string(s, ch);
+ skip_whitespace(s, ch); /* find the inclusion list */
+ amfree(qlist);
}
}
}
else {
- options = alloc(sizeof(option_t));
+ options = alloc(SIZEOF(option_t));
init_options(options);
}
}
+ else {
+ options = alloc(SIZEOF(option_t));
+ init_options(options);
+ }
+ /*@ignore@*/
add_diskest(disk, amdevice, level, spindle, program_is_wrapper, prog, calcprog, options);
+ /*@end@*/
+ amfree(disk);
+ amfree(qdisk);
amfree(amdevice);
+ amfree(qamdevice);
+ }
+ if (g_options == NULL) {
+ error("Missing OPTIONS line in sendsize input\n");
+ /*NOTREACHED*/
}
amfree(line);
child_pid = wait(&child_status);
if(child_pid == -1) {
error("wait failed: %s", strerror(errno));
+ /*NOTREACHED*/
}
if(WIFSIGNALED(child_status)) {
dbprintf(("%s: child %ld terminated with signal %d\n",
exit(0);
} else if(est->child == -1) {
error("calc_estimates fork failed: %s", strerror(errno));
+ /*NOTREACHED*/
}
dumpsrunning++; /* parent */
}
amfree(g_options->str);
amfree(g_options);
+#if defined(USE_DBMALLOC)
malloc_size_2 = malloc_inuse(&malloc_hist_2);
if(malloc_size_1 != malloc_size_2) {
-#if defined(USE_DBMALLOC)
malloc_list(dbfd(), malloc_hist_1, malloc_hist_2);
-#endif
}
+#endif
dbclose();
return 0;
debug_prefix_time(NULL),
err_extra ? ": " : "",
err_extra ? err_extra : ""));
+ amfree(err_extra);
dbclose();
return 1;
}
-void add_diskest(disk, amdevice, level, spindle, program_is_wrapper, prog, calcprog, options)
-char *disk, *amdevice, *prog, *calcprog;
-int level, spindle, program_is_wrapper;
-option_t *options;
+void
+add_diskest(
+ char * disk,
+ char * amdevice,
+ int level,
+ int spindle,
+ int program_is_wrapper,
+ char * prog,
+ char * calcprog,
+ option_t * options)
{
disk_estimates_t *newp, *curp;
amandates_t *amdp;
int dumplev, estlev;
time_t dumpdate;
+ if (level < 0)
+ level = 0;
+ if (level >= DUMP_LEVELS)
+ level = DUMP_LEVELS - 1;
+
for(curp = est_list; curp != NULL; curp = curp->next) {
if(strcmp(curp->amname, disk) == 0) {
/* already have disk info, just note the level request */
}
}
- newp = (disk_estimates_t *) alloc(sizeof(disk_estimates_t));
- memset(newp, 0, sizeof(*newp));
+ newp = (disk_estimates_t *) alloc(SIZEOF(disk_estimates_t));
+ memset(newp, 0, SIZEOF(*newp));
newp->next = est_list;
est_list = newp;
newp->amname = stralloc(disk);
+ newp->qamname = quote_string(disk);
newp->amdevice = stralloc(amdevice);
+ newp->qamdevice = quote_string(amdevice);
newp->dirname = amname_to_dirname(newp->amdevice);
+ newp->qdirname = quote_string(newp->dirname);
newp->program = stralloc(prog);
if(calcprog != NULL)
newp->calcprog = stralloc(calcprog);
}
-void free_estimates(est)
-disk_estimates_t *est;
+void
+free_estimates(
+ disk_estimates_t * est)
{
amfree(est->amname);
+ amfree(est->qamname);
amfree(est->amdevice);
+ amfree(est->qamdevice);
amfree(est->dirname);
+ amfree(est->qdirname);
amfree(est->program);
if(est->options) {
free_sl(est->options->exclude_file);
*
*/
-void calc_estimates(est)
-disk_estimates_t *est;
+void
+calc_estimates(
+ disk_estimates_t * est)
{
- dbprintf(("%s: calculating for amname '%s', dirname '%s', spindle %d\n",
+ dbprintf(("%s: calculating for amname %s, dirname %s, spindle %d\n",
debug_prefix_time(NULL),
- est->amname, est->dirname, est->spindle));
-
+ est->qamname, est->qdirname, est->spindle));
+
if(est->program_is_wrapper == 1)
wrapper_calc_estimates(est);
else
if (est->amdevice[0] == '/' && est->amdevice[1] == '/')
dbprintf(("%s: Can't use CALCSIZE for samba estimate: %s %s\n",
debug_prefix_time(NULL),
- est->amname, est->dirname));
+ est->qamname, est->qdirname));
else
#endif
generic_calc_estimates(est);
- dbprintf(("%s: done with amname '%s', dirname '%s', spindle %d\n",
+ dbprintf(("%s: done with amname %s dirname %s spindle %d\n",
debug_prefix_time(NULL),
- est->amname, est->dirname, est->spindle));
+ est->qamname, est->qdirname, est->spindle));
}
/*
*/
/* local functions */
-long getsize_dump P((char *disk, char *amdevice, int level, option_t *options));
-long getsize_smbtar P((char *disk, char *amdevice, int level, option_t *options));
-long getsize_gnutar P((char *disk, char *amdevice, int level,
- option_t *options, time_t dumpsince));
-long getsize_wrapper P((char *program, char *disk, char *amdevice, int level,
- option_t *options, time_t dumpsince));
-long handle_dumpline P((char *str));
-double first_num P((char *str));
-
-void wrapper_calc_estimates(est)
-disk_estimates_t *est;
+off_t getsize_dump(char *disk, char *amdevice, int level, option_t *options);
+off_t getsize_star(char *disk, char *amdevice, int level,
+ option_t *options, time_t dumpsince);
+off_t getsize_smbtar(char *disk, char *amdevice, int level, option_t *options);
+off_t getsize_gnutar(char *disk, char *amdevice, int level,
+ option_t *options, time_t dumpsince);
+off_t getsize_wrapper(char *program, char *disk, char *amdevice, int level,
+ option_t *options, time_t dumpsince);
+off_t handle_dumpline(char *str);
+double first_num(char *str);
+
+void
+wrapper_calc_estimates(
+ disk_estimates_t * est)
{
int level;
- long size;
+ off_t size;
for(level = 0; level < DUMP_LEVELS; level++) {
if (est->est[level].needestimate) {
dbprintf(("%s: getting size via wrapper for %s level %d\n",
- debug_prefix_time(NULL), est->amname, level));
- size = getsize_wrapper(est->program, est->amname, est->amdevice, level, est->options,
- est->est[level].dumpsince);
+ debug_prefix_time(NULL), est->qamname, level));
+ size = getsize_wrapper(est->program, est->amname, est->amdevice,
+ level, est->options, est->est[level].dumpsince);
amflock(1, "size");
- fseek(stdout, (off_t)0, SEEK_SET);
+ if (fseek(stdout, 0L, SEEK_END) < 0) {
+ dbprintf(("wrapper_calc_estimates: warning - seek failed: %s\n",
+ strerror(errno)));
+ }
- printf("%s %d SIZE %ld\n", est->amname, level, size);
+ printf("%s %d SIZE " OFF_T_FMT "\n", est->qamname, level,
+ (OFF_T_FMT_TYPE)size);
fflush(stdout);
amfunlock(1, "size");
}
-void generic_calc_estimates(est)
-disk_estimates_t *est;
+void
+generic_calc_estimates(
+ disk_estimates_t * est)
{
int pipefd = -1, nullfd = -1;
char *cmd;
- char *my_argv[DUMP_LEVELS*2+20];
+ char *my_argv[DUMP_LEVELS*2+22];
char number[NUM_STR_SIZE];
- int i, level, my_argc, calcpid;
+ int i, level, my_argc, status;
+ pid_t calcpid;
int nb_exclude = 0;
int nb_include = 0;
char *file_exclude = NULL;
char *file_include = NULL;
times_t start_time;
FILE *dumpout = NULL;
- long size = 1;
+ off_t size = (off_t)1;
char *line = NULL;
char *match_expr;
cmd = vstralloc(libexecdir, "/", "calcsize", versionsuffix(), NULL);
my_argc = 0;
+
my_argv[my_argc++] = stralloc("calcsize");
+ if (g_options->config)
+ my_argv[my_argc++] = stralloc(g_options->config);
+ else
+ my_argv[my_argc++] = stralloc("NOCONFIG");
+
my_argv[my_argc++] = stralloc(est->calcprog);
my_argv[my_argc++] = stralloc(est->amname);
nb_include += est->options->include_list->nb_element;
if(nb_exclude > 0)
- file_exclude = build_exclude(est->amname, est->amdevice,est->options,0);
+ file_exclude = build_exclude(est->amname,
+ est->amdevice, est->options, 0);
if(nb_include > 0)
- file_include = build_include(est->amname, est->amdevice,est->options,0);
+ file_include = build_include(est->amname,
+ est->amdevice, est->options, 0);
if(file_exclude) {
my_argv[my_argc++] = stralloc("-X");
for(level = 0; level < DUMP_LEVELS; level++) {
if(est->est[level].needestimate) {
- snprintf(number, sizeof(number), "%d", level);
+ snprintf(number, SIZEOF(number), "%d", level);
my_argv[my_argc++] = stralloc(number);
dbprintf((" %s", number));
- snprintf(number, sizeof(number),
+ snprintf(number, SIZEOF(number),
"%ld", (long)est->est[level].dumpsince);
my_argv[my_argc++] = stralloc(number);
dbprintf((" %s", number));
amfree(cmd);
dumpout = fdopen(pipefd,"r");
- match_expr = vstralloc(est->amname," %d SIZE %ld", NULL);
- for(size = -1; (line = agets(dumpout)) != NULL; free(line)) {
+ if (!dumpout) {
+ error("Can't fdopen: %s", strerror(errno));
+ /*NOTREACHED*/
+ }
+ match_expr = vstralloc(est->qamname," %d SIZE " OFF_T_FMT, NULL);
+ for(size = (off_t)-1; (line = agets(dumpout)) != NULL; free(line)) {
+ if (line[0] == '\0')
+ continue;
if(sscanf(line, match_expr, &level, &size) == 2) {
printf("%s\n", line); /* write to amandad */
- dbprintf(("%s: estimate size for %s level %d: %ld KB\n",
+ dbprintf(("%s: estimate size for %s level %d: " OFF_T_FMT " KB\n",
debug_prefix(NULL),
- est->amname,
+ est->qamname,
level,
size));
}
}
amfree(match_expr);
- dbprintf(("%s: waiting for %s \"%s\" child\n",
- debug_prefix_time(NULL), my_argv[0], est->amdevice));
- wait(NULL);
- dbprintf(("%s: after %s \"%s\" wait\n",
- debug_prefix_time(NULL), my_argv[0], est->amdevice));
+ dbprintf(("%s: waiting for %s %s child (pid=%d)\n",
+ debug_prefix_time(NULL), my_argv[0], est->qamdevice, calcpid));
+ wait(&status);
+ dbprintf(("%s: after %s %s wait: child pid=%d status=%d\n",
+ debug_prefix_time(NULL), my_argv[0], est->qamdevice,
+ calcpid, WEXITSTATUS(status)));
dbprintf(("%s: .....\n", debug_prefix_time(NULL)));
dbprintf(("%s: estimate time for %s: %s\n",
debug_prefix(NULL),
- est->amname,
+ est->qamname,
walltime_str(timessub(curclock(), start_time))));
common_exit:
}
-void dump_calc_estimates(est)
-disk_estimates_t *est;
+void
+dump_calc_estimates(
+ disk_estimates_t * est)
{
int level;
- long size;
+ off_t size;
for(level = 0; level < DUMP_LEVELS; level++) {
if(est->est[level].needestimate) {
dbprintf(("%s: getting size via dump for %s level %d\n",
- debug_prefix_time(NULL), est->amname, level));
- size = getsize_dump(est->amname, est->amdevice,level, est->options);
+ debug_prefix_time(NULL), est->qamname, level));
+ size = getsize_dump(est->amname, est->amdevice,
+ level, est->options);
amflock(1, "size");
- fseek(stdout, (off_t)0, SEEK_SET);
+ if (fseek(stdout, 0L, SEEK_END) < 0) {
+ dbprintf(("dump_calc_estimates: warning - seek failed: %s\n",
+ strerror(errno)));
+ }
- printf("%s %d SIZE %ld\n", est->amname, level, size);
+ printf("%s %d SIZE " OFF_T_FMT "\n",
+ est->qamname, level, (OFF_T_FMT_TYPE)size);
fflush(stdout);
amfunlock(1, "size");
}
#ifdef SAMBA_CLIENT
-void smbtar_calc_estimates(est)
-disk_estimates_t *est;
+void
+smbtar_calc_estimates(
+ disk_estimates_t * est)
{
int level;
- long size;
+ off_t size;
for(level = 0; level < DUMP_LEVELS; level++) {
if(est->est[level].needestimate) {
dbprintf(("%s: getting size via smbclient for %s level %d\n",
- debug_prefix_time(NULL), est->amname, level));
+ debug_prefix_time(NULL), est->qamname, level));
size = getsize_smbtar(est->amname, est->amdevice, level, est->options);
amflock(1, "size");
- fseek(stdout, (off_t)0, SEEK_SET);
+ if (fseek(stdout, 0L, SEEK_END) < 0) {
+ dbprintf(("smbtar_calc_estimates: warning - seek failed: %s\n",
+ strerror(errno)));
+ }
- printf("%s %d SIZE %ld\n", est->amname, level, size);
+ printf("%s %d SIZE " OFF_T_FMT "\n",
+ est->qamname, level, (OFF_T_FMT_TYPE)size);
fflush(stdout);
amfunlock(1, "size");
#endif
#ifdef GNUTAR
-void gnutar_calc_estimates(est)
-disk_estimates_t *est;
+void
+gnutar_calc_estimates(
+ disk_estimates_t * est)
{
int level;
- long size;
+ off_t size;
for(level = 0; level < DUMP_LEVELS; level++) {
if (est->est[level].needestimate) {
dbprintf(("%s: getting size via gnutar for %s level %d\n",
- debug_prefix_time(NULL), est->amname, level));
+ debug_prefix_time(NULL), est->qamname, level));
size = getsize_gnutar(est->amname, est->amdevice, level,
est->options, est->est[level].dumpsince);
amflock(1, "size");
- fseek(stdout, (off_t)0, SEEK_SET);
+ if (fseek(stdout, 0L, SEEK_END) < 0) {
+ dbprintf(("gnutar_calc_estimates: warning - seek failed: %s\n",
+ strerror(errno)));
+ }
- printf("%s %d SIZE %ld\n", est->amname, level, size);
+ printf("%s %d SIZE " OFF_T_FMT "\n",
+ est->qamname, level, (OFF_T_FMT_TYPE)size);
fflush(stdout);
amfunlock(1, "size");
int scale;
} regex_t;
+/*@ignore@*/
regex_t re_size[] = {
#ifdef DUMP
{" DUMP: estimated -*[0-9][0-9]* tape blocks", 1024},
{" DUMP: [Ee]stimated [0-9][0-9]* blocks", 512},
- {" DUMP: [Ee]stimated [0-9][0-9]* bytes", 1}, /* Ultrix 4.4 */
- {" UFSDUMP: estimated [0-9][0-9]* blocks", 512}, /* NEC EWS-UX */
+ {" DUMP: [Ee]stimated [0-9][0-9]* bytes", 1}, /* Ultrix 4.4 */
+ {" UFSDUMP: estimated [0-9][0-9]* blocks", 512}, /* NEC EWS-UX */
{"dump: Estimate: [0-9][0-9]* tape blocks", 1024}, /* OSF/1 */
{"backup: There are an estimated [0-9][0-9]* tape blocks.",1024}, /* AIX */
{"backup: estimated [0-9][0-9]* 1k blocks", 1024}, /* AIX */
{"backup: [0-9][0-9]* tape blocks on [0-9][0-9]* tape(s)",1024}, /* AIX */
{"backup: [0-9][0-9]* 1k blocks on [0-9][0-9]* volume(s)",1024}, /* AIX */
{"dump: Estimate: [0-9][0-9]* blocks being output to pipe",1024},
- /* DU 4.0 dump */
- {"dump: Dumping [0-9][0-9]* bytes, ", 1}, /* DU 4.0 vdump */
- {"DUMP: estimated [0-9][0-9]* KB output", 1024}, /* HPUX */
- {"DUMP: estimated [0-9][0-9]* KB\\.", 1024}, /* NetApp */
- {" UFSDUMP: estimated [0-9][0-9]* blocks", 512}, /* Sinix */
+ /* DU 4.0 dump */
+ {"dump: Dumping [0-9][0-9]* bytes, ", 1}, /* DU 4.0 vdump */
+ {"DUMP: estimated [0-9][0-9]* KB output", 1024}, /* HPUX */
+ {"DUMP: estimated [0-9][0-9]* KB\\.", 1024}, /* NetApp */
+ {" UFSDUMP: estimated [0-9][0-9]* blocks", 512}, /* Sinix */
#ifdef HAVE_DUMP_ESTIMATE
{"[0-9][0-9]* blocks, [0-9][0-9]*.[0-9][0-9]* volumes", 1024},
- /* DU 3.2g dump -E */
- {"^[0-9][0-9]* blocks$", 1024}, /* DU 4.0 dump -E */
- {"^[0-9][0-9]*$", 1}, /* Solaris ufsdump -S */
+ /* DU 3.2g dump -E */
+ {"^[0-9][0-9]* blocks$", 1024}, /* DU 4.0 dump -E */
+ {"^[0-9][0-9]*$", 1}, /* Solaris ufsdump -S */
#endif
#endif
#ifdef VDUMP
- {"vdump: Dumping [0-9][0-9]* bytes, ", 1}, /* OSF/1 vdump */
+ {"vdump: Dumping [0-9][0-9]* bytes, ", 1}, /* OSF/1 vdump */
#endif
#ifdef VXDUMP
- {"vxdump: estimated [0-9][0-9]* blocks", 512}, /* HPUX's vxdump */
- {" VXDUMP: estimated [0-9][0-9]* blocks", 512}, /* Sinix */
+ {"vxdump: estimated [0-9][0-9]* blocks", 512}, /* HPUX's vxdump */
+ {" VXDUMP: estimated [0-9][0-9]* blocks", 512}, /* Sinix */
#endif
#ifdef XFSDUMP
{ NULL, 0 }
};
-
-
-long getsize_dump(disk, amdevice, level, options)
- char *disk, *amdevice;
- int level;
- option_t *options;
+/*@end@*/
+
+off_t
+getsize_dump(
+ char *disk,
+ char *amdevice,
+ int level,
+ option_t * options)
{
int pipefd[2], nullfd, stdoutfd, killctl[2];
pid_t dumppid;
- long size;
+ off_t size;
FILE *dumpout;
char *dumpkeys = NULL;
char *device = NULL;
char level_str[NUM_STR_SIZE];
int s;
times_t start_time;
+ char *qdisk = quote_string(disk);
+ char *qdevice;
+ char *config;
+#ifdef DUMP
+ int is_rundump = 1;
+#endif
+
+ (void)options; /* Quiet unused parameter warning */
- snprintf(level_str, sizeof(level_str), "%d", level);
+ (void)getsize_smbtar; /* Quiet unused parameter warning */
+
+ snprintf(level_str, SIZEOF(level_str), "%d", level);
device = amname_to_devname(amdevice);
+ qdevice = quote_string(device);
fstype = amname_to_fstype(amdevice);
- dbprintf(("%s: calculating for device '%s' with '%s'\n",
- debug_prefix_time(NULL), device, fstype));
+ dbprintf(("%s: calculating for device %s with %s\n",
+ debug_prefix_time(NULL), qdevice, fstype));
cmd = vstralloc(libexecdir, "/rundump", versionsuffix(), NULL);
rundump_cmd = stralloc(cmd);
-
+ if (g_options->config)
+ config = g_options->config;
+ else
+ config = "NOCONFIG";
if ((stdoutfd = nullfd = open("/dev/null", O_RDWR)) == -1) {
dbprintf(("getsize_dump could not open /dev/null: %s\n",
- strerror(errno)));
+ strerror(errno)));
amfree(cmd);
amfree(rundump_cmd);
amfree(fstype);
amfree(device);
+ amfree(qdevice);
+ amfree(qdisk);
return(-1);
}
pipefd[0] = pipefd[1] = killctl[0] = killctl[1] = -1;
- pipe(pipefd);
+ if (pipe(pipefd) < 0) {
+ dbprintf(("getsize_dump could create data pipes: %s\n",
+ strerror(errno)));
+ amfree(cmd);
+ amfree(rundump_cmd);
+ amfree(fstype);
+ amfree(device);
+ amfree(qdevice);
+ amfree(qdisk);
+ return(-1);
+ }
#ifdef XFSDUMP /* { */
#ifdef DUMP /* { */
if (1)
#endif /* } */
{
- name = stralloc(" (xfsdump)");
+ name = stralloc(" (xfsdump)");
dbprintf(("%s: running \"%s%s -F -J -l %s - %s\"\n",
- debug_prefix_time(NULL), cmd, name, level_str, device));
+ debug_prefix_time(NULL), cmd, name, level_str, qdevice));
}
else
#endif /* } */
#endif /* } */
{
#ifdef USE_RUNDUMP
- name = stralloc(" (vxdump)");
+ name = stralloc(" (vxdump)");
#else
name = stralloc("");
cmd = newstralloc(cmd, VXDUMP);
+ config = skip_argument;
+ is_rundump = 0;
#endif
dumpkeys = vstralloc(level_str, "s", "f", NULL);
- dbprintf(("%s: running \"%s%s %s 1048576 - %s\"\n",
- debug_prefix_time(NULL), cmd, name, dumpkeys, device));
+ dbprintf(("%s: running \"%s%s %s 1048576 - %s\"\n",
+ debug_prefix_time(NULL), cmd, name, dumpkeys, qdevice));
}
else
#endif /* } */
{
name = stralloc(" (vdump)");
amfree(device);
+ amfree(qdevice);
device = amname_to_dirname(amdevice);
+ qdevice = quote_string(device);
dumpkeys = vstralloc(level_str, "b", "f", NULL);
dbprintf(("%s: running \"%s%s %s 60 - %s\"\n",
- debug_prefix_time(NULL), cmd, name, dumpkeys, device));
+ debug_prefix_time(NULL), cmd, name, dumpkeys, qdevice));
}
else
#endif /* } */
# else /* } { */
name = stralloc("");
cmd = newstralloc(cmd, DUMP);
+ config = skip_argument;
+ is_rundump = 0;
# endif /* } */
# ifdef AIX_BACKUP /* { */
dumpkeys = vstralloc("-", level_str, "f", NULL);
dbprintf(("%s: running \"%s%s %s - %s\"\n",
- debug_prefix_time(NULL), cmd, name, dumpkeys, device));
+ debug_prefix_time(NULL), cmd, name, dumpkeys, qdevice));
# else /* } { */
dumpkeys = vstralloc(level_str,
# ifdef HAVE_DUMP_ESTIMATE /* { */
# ifdef HAVE_HONOR_NODUMP /* { */
dbprintf(("%s: running \"%s%s %s 0 1048576 - %s\"\n",
- debug_prefix_time(NULL), cmd, name, dumpkeys, device));
+ debug_prefix_time(NULL), cmd, name, dumpkeys, qdevice));
# else /* } { */
dbprintf(("%s: running \"%s%s %s 1048576 - %s\"\n",
- debug_prefix_time(NULL), cmd, name, dumpkeys, device));
+ debug_prefix_time(NULL), cmd, name, dumpkeys, qdevice));
# endif /* } */
# endif /* } */
}
#endif /* } */
{
error("no dump program available");
+ /*NOTREACHED*/
}
- pipe(killctl);
+ if (pipe(killctl) < 0) {
+ dbprintf(("%s: Could not create pipe: %s\n",
+ debug_prefix(NULL), strerror(errno)));
+ /* Message will be printed later... */
+ killctl[0] = killctl[1] = -1;
+ }
start_time = curclock();
switch(dumppid = fork()) {
amfree(cmd);
amfree(rundump_cmd);
amfree(device);
+ amfree(qdevice);
+ amfree(qdisk);
amfree(name);
amfree(fstype);
return -1;
if(SETPGRP == -1)
SETPGRP_FAILED();
else if (killctl[0] == -1 || killctl[1] == -1)
- dbprintf(("%s: pipe for killpgrp failed, trying without killpgrp\n",
- debug_prefix(NULL)));
+ dbprintf(("%s: Trying without killpgrp\n", debug_prefix(NULL)));
else {
switch(fork()) {
case -1:
default:
{
+ char *config;
char *killpgrp_cmd = vstralloc(libexecdir, "/killpgrp",
versionsuffix(), NULL);
dbprintf(("%s: running %s\n",
close(pipefd[1]);
close(killctl[1]);
close(nullfd);
- execle(killpgrp_cmd, killpgrp_cmd, (char *)0, safe_env());
+ if (g_options->config)
+ config = g_options->config;
+ else
+ config = "NOCONFIG";
+ execle(killpgrp_cmd, killpgrp_cmd, config, (char *)0,
+ safe_env());
dbprintf(("%s: cannot execute %s: %s\n",
debug_prefix(NULL), killpgrp_cmd, strerror(errno)));
exit(-1);
#else
if (1)
#endif
- execle(cmd, "xfsdump", "-F", "-J", "-l", level_str, "-", device,
- (char *)0, safe_env());
+ if (is_rundump)
+ execle(cmd, "rundump", config, "xfsdump", "-F", "-J", "-l",
+ level_str, "-", device, (char *)0, safe_env());
+ else
+ execle(cmd, "xfsdump", "-F", "-J", "-l",
+ level_str, "-", device, (char *)0, safe_env());
else
#endif
#ifdef VXDUMP
#else
if (1)
#endif
- execle(cmd, "vxdump", dumpkeys, "1048576", "-", device, (char *)0,
- safe_env());
+ if (is_rundump)
+ execle(cmd, "rundump", config, "vxdump", dumpkeys, "1048576",
+ "-", device, (char *)0, safe_env());
+ else
+ execle(cmd, "vxdump", dumpkeys, "1048576", "-",
+ device, (char *)0, safe_env());
else
#endif
#ifdef VDUMP
#else
if (1)
#endif
- execle(cmd, "vdump", dumpkeys, "60", "-", device, (char *)0,
- safe_env());
+ if (is_rundump)
+ execle(cmd, "rundump", config, "vdump", dumpkeys, "60", "-",
+ device, (char *)0, safe_env());
+ else
+ execle(cmd, "vdump", dumpkeys, "60", "-",
+ device, (char *)0, safe_env());
else
#endif
#ifdef DUMP
# ifdef AIX_BACKUP
- execle(cmd, "backup", dumpkeys, "-", device, (char *)0, safe_env());
+ if (is_rundump)
+ execle(cmd, "rundump", config, "backup", dumpkeys, "-",
+ device, (char *)0, safe_env());
+ else
+ execle(cmd, "backup", dumpkeys, "-",
+ device, (char *)0, safe_env());
# else
- execle(cmd, "dump", dumpkeys,
+ if (is_rundump) {
+ execle(cmd, "rundump", config, "dump", dumpkeys,
#ifdef HAVE_HONOR_NODUMP
- "0",
+ "0",
#endif
- "1048576", "-", device, (char *)0, safe_env());
+ "1048576", "-", device, (char *)0, safe_env());
+ } else {
+ execle(cmd, "dump", dumpkeys,
+#ifdef HAVE_HONOR_NODUMP
+ "0",
+#endif
+ "1048576", "-", device, (char *)0, safe_env());
# endif
+ }
#endif
{
error("exec %s failed or no dump program available: %s",
cmd, strerror(errno));
+ /*NOTREACHED*/
}
}
if (killctl[0] != -1)
aclose(killctl[0]);
dumpout = fdopen(pipefd[0],"r");
+ if (!dumpout) {
+ error("Can't fdopen: %s", strerror(errno));
+ /*NOTREACHED*/
+ }
- for(size = -1; (line = agets(dumpout)) != NULL; free(line)) {
+ for(size = (off_t)-1; (line = agets(dumpout)) != NULL; free(line)) {
+ if (line[0] == '\0')
+ continue;
dbprintf(("%s: %s\n", debug_prefix_time(NULL), line));
size = handle_dumpline(line);
- if(size > -1) {
+ if(size > (off_t)-1) {
amfree(line);
- if((line = agets(dumpout)) != NULL) {
+ while ((line = agets(dumpout)) != NULL) {
+ if (line[0] != '\0')
+ break;
+ amfree(line);
+ }
+ if (line != NULL) {
dbprintf(("%s: %s\n", debug_prefix_time(NULL), line));
}
break;
dbprintf(("%s: .....\n", debug_prefix_time(NULL)));
dbprintf(("%s: estimate time for %s level %d: %s\n",
debug_prefix(NULL),
- disk,
+ qdisk,
level,
walltime_str(timessub(curclock(), start_time))));
- if(size == -1) {
+ if(size == (off_t)-1) {
dbprintf(("%s: no size line match in %s%s output for \"%s\"\n",
debug_prefix(NULL), cmd, name, disk));
dbprintf(("%s: .....\n", debug_prefix(NULL)));
dbprintf(("%s: Run %s%s manually to check for errors\n",
debug_prefix(NULL), cmd, name));
- } else if(size == 0 && level == 0) {
+ } else if(size == (off_t)0 && level == 0) {
dbprintf(("%s: possible %s%s problem -- is \"%s\" really empty?\n",
debug_prefix(NULL), cmd, name, disk));
dbprintf(("%s: .....\n", debug_prefix(NULL)));
} else {
dbprintf(("%s: estimate size for %s level %d: %ld KB\n",
debug_prefix(NULL),
- disk,
+ qdisk,
level,
size));
}
}
dbprintf(("%s: waiting for %s%s \"%s\" child\n",
- debug_prefix_time(NULL), cmd, name, disk));
+ debug_prefix_time(NULL), cmd, name, qdisk));
wait(NULL);
- dbprintf(("%s: after %s%s \"%s\" wait\n",
- debug_prefix_time(NULL), cmd, name, disk));
+ dbprintf(("%s: after %s%s %s wait\n",
+ debug_prefix_time(NULL), cmd, name, qdisk));
terminated:
afclose(dumpout);
amfree(device);
+ amfree(qdevice);
+ amfree(qdisk);
amfree(fstype);
amfree(cmd);
}
#ifdef SAMBA_CLIENT
-long getsize_smbtar(disk, amdevice, level, optionns)
- char *disk, *amdevice;
- int level;
- option_t *optionns;
+off_t
+getsize_smbtar(
+ char *disk,
+ char *amdevice,
+ int level,
+ option_t * options)
{
int pipefd = -1, nullfd = -1, passwdfd = -1;
- int dumppid;
- long size;
+ pid_t dumppid;
+ off_t size;
FILE *dumpout;
char *tarkeys, *sharename, *user_and_password = NULL, *domain = NULL;
char *share = NULL, *subdir = NULL;
- int lpass;
+ size_t lpass;
char *pwtext;
- int pwtext_len;
+ size_t pwtext_len;
char *line;
char *pw_fd_env;
times_t start_time;
char *error_pn = NULL;
+ char *qdisk = quote_string(disk);
+
+ (void)options; /* Quiet unused parameter warning */
error_pn = stralloc2(get_pname(), "-smbclient");
amfree(subdir);
set_pname(error_pn);
amfree(error_pn);
- error("cannot parse disk entry '%s' for share/subdir", disk);
+ error("cannot parse disk entry %s for share/subdir", qdisk);
+ /*NOTREACHED*/
}
if ((subdir) && (SAMBA_VERSION < 2)) {
amfree(share);
amfree(subdir);
set_pname(error_pn);
amfree(error_pn);
- error("subdirectory specified for share '%s' but samba not v2 or better", disk);
+ error("subdirectory specified for share %s but samba not v2 or better", qdisk);
+ /*NOTREACHED*/
}
if ((user_and_password = findpass(share, &domain)) == NULL) {
set_pname(error_pn);
amfree(error_pn);
error("cannot find password for %s", disk);
+ /*NOTREACHED*/
}
lpass = strlen(user_and_password);
if ((pwtext = strchr(user_and_password, '%')) == NULL) {
- memset(user_and_password, '\0', lpass);
+ memset(user_and_password, '\0', (size_t)lpass);
amfree(user_and_password);
if(domain) {
memset(domain, '\0', strlen(domain));
set_pname(error_pn);
amfree(error_pn);
error("password field not \'user%%pass\' for %s", disk);
+ /*NOTREACHED*/
}
*pwtext++ = '\0';
pwtext_len = strlen(pwtext);
if ((sharename = makesharename(share, 0)) == NULL) {
- memset(user_and_password, '\0', lpass);
+ memset(user_and_password, '\0', (size_t)lpass);
amfree(user_and_password);
if(domain) {
memset(domain, '\0', strlen(domain));
set_pname(error_pn);
amfree(error_pn);
error("cannot make share name of %s", share);
+ /*NOTREACHED*/
}
if ((nullfd = open("/dev/null", O_RDWR)) == -1) {
- memset(user_and_password, '\0', lpass);
+ memset(user_and_password, '\0', (size_t)lpass);
amfree(user_and_password);
if(domain) {
memset(domain, '\0', strlen(domain));
amfree(sharename);
error("could not open /dev/null: %s\n",
strerror(errno));
+ /*NOTREACHED*/
}
#if SAMBA_VERSION >= 2
amfree(domain);
}
aclose(nullfd);
- if(pwtext_len > 0 && fullwrite(passwdfd, pwtext, pwtext_len) < 0) {
+ if(pwtext_len > 0 && fullwrite(passwdfd, pwtext, (size_t)pwtext_len) < 0) {
int save_errno = errno;
- memset(user_and_password, '\0', lpass);
+ memset(user_and_password, '\0', (size_t)lpass);
amfree(user_and_password);
aclose(passwdfd);
set_pname(error_pn);
amfree(error_pn);
error("password write failed: %s", strerror(save_errno));
+ /*NOTREACHED*/
}
- memset(user_and_password, '\0', lpass);
+ memset(user_and_password, '\0', (size_t)lpass);
amfree(user_and_password);
aclose(passwdfd);
amfree(sharename);
amfree(subdir);
amfree(error_pn);
dumpout = fdopen(pipefd,"r");
+ if (!dumpout) {
+ error("Can't fdopen: %s", strerror(errno));
+ /*NOTREACHED*/
+ }
- for(size = -1; (line = agets(dumpout)) != NULL; free(line)) {
+ for(size = (off_t)-1; (line = agets(dumpout)) != NULL; free(line)) {
+ if (line[0] == '\0')
+ continue;
dbprintf(("%s: %s\n", debug_prefix_time(NULL), line));
size = handle_dumpline(line);
if(size > -1) {
amfree(line);
- if((line = agets(dumpout)) != NULL) {
+ while ((line = agets(dumpout)) != NULL) {
+ if (line[0] != '\0')
+ break;
+ amfree(line);
+ }
+ if(line != NULL) {
dbprintf(("%s: %s\n", debug_prefix_time(NULL), line));
}
break;
dbprintf(("%s: .....\n", debug_prefix_time(NULL)));
dbprintf(("%s: estimate time for %s level %d: %s\n",
debug_prefix(NULL),
- disk,
+ qdisk,
level,
walltime_str(timessub(curclock(), start_time))));
- if(size == -1) {
+ if(size == (off_t)-1) {
dbprintf(("%s: no size line match in %s output for \"%s\"\n",
debug_prefix(NULL), SAMBA_CLIENT, disk));
dbprintf(("%s: .....\n", debug_prefix(NULL)));
- } else if(size == 0 && level == 0) {
+ } else if(size == (off_t)0 && level == 0) {
dbprintf(("%s: possible %s problem -- is \"%s\" really empty?\n",
debug_prefix(NULL), SAMBA_CLIENT, disk));
dbprintf(("%s: .....\n", debug_prefix(NULL)));
}
dbprintf(("%s: estimate size for %s level %d: %ld KB\n",
debug_prefix(NULL),
- disk,
+ qdisk,
level,
size));
kill(-dumppid, SIGTERM);
dbprintf(("%s: waiting for %s \"%s\" child\n",
- debug_prefix_time(NULL), SAMBA_CLIENT, disk));
+ debug_prefix_time(NULL), SAMBA_CLIENT, qdisk));
wait(NULL);
- dbprintf(("%s: after %s \"%s\" wait\n",
- debug_prefix_time(NULL), SAMBA_CLIENT, disk));
+ dbprintf(("%s: after %s %s wait\n",
+ debug_prefix_time(NULL), SAMBA_CLIENT, qdisk));
afclose(dumpout);
pipefd = -1;
amfree(error_pn);
+ amfree(qdisk);
return size;
}
#endif
#ifdef GNUTAR
-long getsize_gnutar(disk, amdevice, level, options, dumpsince)
-char *disk, *amdevice;
-int level;
-option_t *options;
-time_t dumpsince;
+off_t
+getsize_gnutar(
+ char *disk,
+ char *amdevice,
+ int level,
+ option_t * options,
+ time_t dumpsince)
{
- int pipefd = -1, nullfd = -1, dumppid;
- long size = -1;
+ int pipefd = -1, nullfd = -1;
+ pid_t dumppid;
+ off_t size = (off_t)-1;
FILE *dumpout = NULL;
char *incrname = NULL;
char *basename = NULL;
char *file_exclude = NULL;
char *file_include = NULL;
times_t start_time;
+ int infd, outfd;
+ ssize_t nb;
+ char buf[32768];
+ char *qdisk = quote_string(disk);
+ char *gnutar_list_dir;
if(options->exclude_file) nb_exclude += options->exclude_file->nb_element;
if(options->exclude_list) nb_exclude += options->exclude_list->nb_element;
if(nb_exclude > 0) file_exclude = build_exclude(disk, amdevice, options, 0);
if(nb_include > 0) file_include = build_include(disk, amdevice, options, 0);
- my_argv = alloc(sizeof(char *) * 21);
+ my_argv = alloc(SIZEOF(char *) * 22);
i = 0;
-#ifdef GNUTAR_LISTED_INCREMENTAL_DIR
- {
+ gnutar_list_dir = client_getconf_str(CLN_GNUTAR_LIST_DIR);
+ if (strlen(gnutar_list_dir) == 0)
+ gnutar_list_dir = NULL;
+ if (gnutar_list_dir) {
char number[NUM_STR_SIZE];
char *s;
int ch;
int baselevel;
- basename = vstralloc(GNUTAR_LISTED_INCREMENTAL_DIR,
+ basename = vstralloc(gnutar_list_dir,
"/",
g_options->hostname,
disk,
* The loop starts at the first character of the host name,
* not the '/'.
*/
- s = basename + sizeof(GNUTAR_LISTED_INCREMENTAL_DIR);
+ s = basename + strlen(gnutar_list_dir) + 1;
while((ch = *s++) != '\0') {
if(ch == '/' || isspace(ch)) s[-1] = '_';
}
- snprintf(number, sizeof(number), "%d", level);
+ snprintf(number, SIZEOF(number), "%d", level);
incrname = vstralloc(basename, "_", number, ".new", NULL);
unlink(incrname);
* be true for a level 0), arrange to read from /dev/null.
*/
baselevel = level;
- while (in == NULL) {
+ infd = -1;
+ while (infd == -1) {
if (--baselevel >= 0) {
- snprintf(number, sizeof(number), "%d", baselevel);
+ snprintf(number, SIZEOF(number), "%d", baselevel);
inputname = newvstralloc(inputname,
basename, "_", number, NULL);
} else {
inputname = newstralloc(inputname, "/dev/null");
}
- if ((in = fopen(inputname, "r")) == NULL) {
+ if ((infd = open(inputname, O_RDONLY)) == -1) {
int save_errno = errno;
dbprintf(("%s: gnutar: error opening %s: %s\n",
/*
* Copy the previous listed incremental file to the new one.
*/
- if ((out = fopen(incrname, "w")) == NULL) {
+ if ((outfd = open(incrname, O_WRONLY|O_CREAT, 0600)) == -1) {
dbprintf(("%s: opening %s: %s\n",
debug_prefix(NULL), incrname, strerror(errno)));
goto common_exit;
}
- for (; (line = agets(in)) != NULL; free(line)) {
- if (fputs(line, out) == EOF || putc('\n', out) == EOF) {
+ while ((nb = read(infd, &buf, SIZEOF(buf))) > 0) {
+ if (fullwrite(outfd, &buf, (size_t)nb) < nb) {
dbprintf(("%s: writing to %s: %s\n",
debug_prefix(NULL), incrname, strerror(errno)));
goto common_exit;
}
}
- amfree(line);
- if (ferror(in)) {
+ if (nb < 0) {
dbprintf(("%s: reading from %s: %s\n",
debug_prefix(NULL), inputname, strerror(errno)));
goto common_exit;
}
- if (fclose(in) == EOF) {
+
+ if (close(infd) != 0) {
dbprintf(("%s: closing %s: %s\n",
debug_prefix(NULL), inputname, strerror(errno)));
- in = NULL;
goto common_exit;
}
- in = NULL;
- if (fclose(out) == EOF) {
+ if (close(outfd) != 0) {
dbprintf(("%s: closing %s: %s\n",
debug_prefix(NULL), incrname, strerror(errno)));
- out = NULL;
goto common_exit;
}
- out = NULL;
amfree(inputname);
amfree(basename);
}
-#endif
gmtm = gmtime(&dumpsince);
- snprintf(dumptimestr, sizeof(dumptimestr),
+ snprintf(dumptimestr, SIZEOF(dumptimestr),
"%04d-%02d-%02d %2d:%02d:%02d GMT",
gmtm->tm_year + 1900, gmtm->tm_mon+1, gmtm->tm_mday,
gmtm->tm_hour, gmtm->tm_min, gmtm->tm_sec);
dirname = amname_to_dirname(amdevice);
-
-
-#ifdef GNUTAR
cmd = vstralloc(libexecdir, "/", "runtar", versionsuffix(), NULL);
+ my_argv[i++] = "runtar";
+ if (g_options->config)
+ my_argv[i++] = g_options->config;
+ else
+ my_argv[i++] = "NOCONFIG";
+#ifdef GNUTAR
my_argv[i++] = GNUTAR;
#else
my_argv[i++] = "tar";
my_argv[i++] = "--directory";
my_argv[i++] = dirname;
my_argv[i++] = "--one-file-system";
-#ifdef GNUTAR_LISTED_INCREMENTAL_DIR
- my_argv[i++] = "--listed-incremental";
- my_argv[i++] = incrname;
-#else
- my_argv[i++] = "--incremental";
- my_argv[i++] = "--newer";
- my_argv[i++] = dumptimestr;
-#endif
+ if (gnutar_list_dir) {
+ my_argv[i++] = "--listed-incremental";
+ my_argv[i++] = incrname;
+ } else {
+ my_argv[i++] = "--incremental";
+ my_argv[i++] = "--newer";
+ my_argv[i++] = dumptimestr;
+ }
#ifdef ENABLE_GNUTAR_ATIME_PRESERVE
/* --atime-preserve causes gnutar to call
* utime() after reading files in order to
start_time = curclock();
- nullfd = open("/dev/null", O_RDWR);
+ if ((nullfd = open("/dev/null", O_RDWR)) == -1) {
+ dbprintf(("Cannot access /dev/null : %s\n", strerror(errno)));
+ goto common_exit;
+ }
+
dumppid = pipespawnv(cmd, STDERR_PIPE, &nullfd, &nullfd, &pipefd, my_argv);
- amfree(cmd);
- amfree(file_exclude);
- amfree(file_include);
dumpout = fdopen(pipefd,"r");
+ if (!dumpout) {
+ error("Can't fdopen: %s", strerror(errno));
+ /*NOTREACHED*/
+ }
- for(size = -1; (line = agets(dumpout)) != NULL; free(line)) {
+ for(size = (off_t)-1; (line = agets(dumpout)) != NULL; free(line)) {
+ if (line[0] == '\0')
+ continue;
dbprintf(("%s: %s\n", debug_prefix_time(NULL), line));
size = handle_dumpline(line);
- if(size > -1) {
+ if(size > (off_t)-1) {
amfree(line);
- if((line = agets(dumpout)) != NULL) {
+ while ((line = agets(dumpout)) != NULL) {
+ if (line[0] != '\0') {
+ break;
+ }
+ amfree(line);
+ }
+ if (line != NULL) {
dbprintf(("%s: %s\n", debug_prefix_time(NULL), line));
+ break;
}
break;
}
dbprintf(("%s: .....\n", debug_prefix_time(NULL)));
dbprintf(("%s: estimate time for %s level %d: %s\n",
debug_prefix(NULL),
- disk,
+ qdisk,
level,
walltime_str(timessub(curclock(), start_time))));
- if(size == -1) {
+ if(size == (off_t)-1) {
dbprintf(("%s: no size line match in %s output for \"%s\"\n",
debug_prefix(NULL), my_argv[0], disk));
dbprintf(("%s: .....\n", debug_prefix(NULL)));
- } else if(size == 0 && level == 0) {
+ } else if(size == (off_t)0 && level == 0) {
dbprintf(("%s: possible %s problem -- is \"%s\" really empty?\n",
debug_prefix(NULL), my_argv[0], disk));
dbprintf(("%s: .....\n", debug_prefix(NULL)));
}
dbprintf(("%s: estimate size for %s level %d: %ld KB\n",
debug_prefix(NULL),
- disk,
+ qdisk,
level,
size));
kill(-dumppid, SIGTERM);
dbprintf(("%s: waiting for %s \"%s\" child\n",
- debug_prefix_time(NULL), my_argv[0], disk));
+ debug_prefix_time(NULL), my_argv[0], qdisk));
wait(NULL);
- dbprintf(("%s: after %s \"%s\" wait\n",
- debug_prefix_time(NULL), my_argv[0], disk));
+ dbprintf(("%s: after %s %s wait\n",
+ debug_prefix_time(NULL), my_argv[0], qdisk));
common_exit:
amfree(dirname);
amfree(inputname);
amfree(my_argv);
+ amfree(qdisk);
+ amfree(cmd);
+ amfree(file_exclude);
+ amfree(file_include);
aclose(nullfd);
afclose(dumpout);
}
#endif
-long getsize_wrapper(program, disk, amdevice, level, options, dumpsince)
-char *program, *disk, *amdevice;
-int level;
-option_t *options;
-time_t dumpsince;
+off_t
+getsize_wrapper(
+ char *program,
+ char *disk,
+ char *amdevice,
+ int level,
+ option_t * options,
+ time_t dumpsince)
{
- int pipefd[2], nullfd, dumppid;
- long size;
+ int pipefd[2], nullfd;
+ pid_t dumppid;
+ off_t size = (off_t)-1;
FILE *dumpout;
char *line = NULL;
char *cmd = NULL;
int i, j;
char *argvchild[10];
char *newoptstr = NULL;
- long size1, size2;
+ off_t size1, size2;
times_t start_time;
+ char *qdisk = quote_string(disk);
+ char *qamdevice = quote_string(amdevice);
gmtm = gmtime(&dumpsince);
- snprintf(dumptimestr, sizeof(dumptimestr),
+ snprintf(dumptimestr, SIZEOF(dumptimestr),
"%04d-%02d-%02d %2d:%02d:%02d GMT",
gmtm->tm_year + 1900, gmtm->tm_mon+1, gmtm->tm_mday,
gmtm->tm_hour, gmtm->tm_min, gmtm->tm_sec);
argvchild[i++] = "full";
else {
char levelstr[NUM_STR_SIZE];
- snprintf(levelstr,sizeof(levelstr),"%d",level);
+ snprintf(levelstr,SIZEOF(levelstr),"%d",level);
argvchild[i++] = "level";
argvchild[i++] = levelstr;
}
dbprintf((" %s", argvchild[j]));
}
dbprintf(("\n"));
- nullfd = open("/dev/null", O_RDWR);
- pipe(pipefd);
+
+ if ((nullfd = open("/dev/null", O_RDWR)) == -1) {
+ dbprintf(("Cannot access /dev/null : %s\n", strerror(errno)));
+ goto common_exit;
+ }
+
+ if (pipe(pipefd) < 0) {
+ dbprintf(("getsize_wrapper could create data pipes: %s\n",
+ strerror(errno)));
+ goto common_exit;
+ }
start_time = curclock();
switch(dumppid = fork()) {
case -1:
- size = -1;
+ size = (off_t)-1;
goto common_exit;
default:
break; /* parent */
execve(cmd, argvchild, safe_env());
error("exec %s failed: %s", cmd, strerror(errno));
+ /*NOTREACHED*/
}
amfree(newoptstr);
aclose(pipefd[1]);
dumpout = fdopen(pipefd[0],"r");
+ if (!dumpout) {
+ error("Can't fdopen: %s", strerror(errno));
+ /*NOTREACHED*/
+ }
- for(size = -1; (line = agets(dumpout)) != NULL; free(line)) {
+ for(size = (off_t)-1; (line = agets(dumpout)) != NULL; free(line)) {
+ if (line[0] == '\0')
+ continue;
dbprintf(("%s: %s\n", debug_prefix_time(NULL), line));
- i = sscanf(line,"%ld %ld",&size1, &size2);
+ i = sscanf(line, OFF_T_FMT " " OFF_T_FMT,
+ (OFF_T_FMT_TYPE *)&size1,
+ (OFF_T_FMT_TYPE *)&size2);
if(i == 2) {
size = size1 * size2;
}
if(size > -1) {
amfree(line);
- if((line = agets(dumpout)) != NULL) {
+ while ((line = agets(dumpout)) != NULL) {
+ if (line[0] != '\0')
+ break;
+ amfree(line);
+ }
+ if(line != NULL) {
dbprintf(("%s: %s\n", debug_prefix_time(NULL), line));
}
break;
dbprintf(("%s: .....\n", debug_prefix_time(NULL)));
dbprintf(("%s: estimate time for %s level %d: %s\n",
debug_prefix(NULL),
- amdevice,
+ qamdevice,
level,
walltime_str(timessub(curclock(), start_time))));
- if(size == -1) {
+ if(size == (off_t)-1) {
dbprintf(("%s: no size line match in %s output for \"%s\"\n",
- debug_prefix(NULL), cmd, disk));
+ debug_prefix(NULL), cmd, qdisk));
dbprintf(("%s: .....\n", debug_prefix(NULL)));
- } else if(size == 0 && level == 0) {
+ } else if(size == (off_t)0 && level == 0) {
dbprintf(("%s: possible %s problem -- is \"%s\" really empty?\n",
- debug_prefix(NULL), cmd, disk));
+ debug_prefix(NULL), cmd, qdisk));
dbprintf(("%s: .....\n", debug_prefix(NULL)));
}
- dbprintf(("%s: estimate size for %s level %d: %ld KB\n",
+ dbprintf(("%s: estimate size for %s level %d: " OFF_T_FMT " KB\n",
debug_prefix(NULL),
- amdevice,
+ qamdevice,
level,
size));
kill(-dumppid, SIGTERM);
dbprintf(("%s: waiting for %s \"%s\" child\n",
- debug_prefix_time(NULL), cmd, disk));
+ debug_prefix_time(NULL), cmd, qdisk));
wait(NULL);
- dbprintf(("%s: after %s \"%s\" wait\n",
- debug_prefix_time(NULL), cmd, disk));
+ dbprintf(("%s: after %s %s wait\n",
+ debug_prefix_time(NULL), cmd, qdisk));
aclose(nullfd);
afclose(dumpout);
amfree(cmd);
amfree(newoptstr);
+ amfree(qdisk);
+ amfree(qamdevice);
return size;
}
-double first_num(str)
-char *str;
/*
* Returns the value of the first integer in a string.
*/
+
+double
+first_num(
+ char * str)
{
char *start;
int ch;
while(isdigit(ch) || (ch == '.')) ch = *str++;
str[-1] = '\0';
d = atof(start);
- str[-1] = ch;
+ str[-1] = (char)ch;
return d;
}
-long handle_dumpline(str)
-char *str;
/*
* Checks the dump output line against the error and size regex tables.
*/
+
+off_t
+handle_dumpline(
+ char * str)
{
regex_t *rp;
double size;
/* check for size match */
+ /*@ignore@*/
for(rp = re_size; rp->regex != NULL; rp++) {
if(match(rp->regex, str)) {
size = ((first_num(str)*rp->scale+1023.0)/1024.0);
- if(size < 0) size = 1; /* found on NeXT -- sigh */
- return (long) size;
+ if(size < 0.0)
+ size = 1.0; /* found on NeXT -- sigh */
+ return (off_t)size;
}
}
- return -1;
+ /*@end@*/
+ return (off_t)-1;
}
* SUCH DAMAGE.
*/
-/* $Id: unctime.c,v 1.2 1997/08/27 08:11:44 amcore Exp $ */
+/* $Id: unctime.c,v 1.3 2006/05/25 01:47:11 johnfranks Exp $ */
#include "amanda.h"
#define E_SECOND 17
#define E_YEAR 20
-static int lookup P((char *));
+static int lookup(char *);
time_t
-unctime(str)
- char *str;
+unctime(
+ char *str)
{
struct tm then;
char dbuf[26];
- (void) strncpy(dbuf, str, sizeof(dbuf) - 1);
- dbuf[sizeof(dbuf) - 1] = '\0';
+ (void) strncpy(dbuf, str, SIZEOF(dbuf) - 1);
+ dbuf[SIZEOF(dbuf) - 1] = '\0';
dbuf[E_MONTH+3] = '\0';
if ((then.tm_mon = lookup(&dbuf[E_MONTH])) < 0)
return -1;
"JanFebMarAprMayJunJulAugSepOctNovDec";
static int
-lookup(str)
- char *str;
+lookup(
+ char * str)
{
register char *cp, *cp2;
for (cp = months, cp2 = str; *cp != '\0'; cp += 3)
if (strncmp(cp, cp2, 3) == 0)
- return ((cp-months) / 3);
+ return ((int)(cp-months) / 3);
return -1;
}
* file named AUTHORS, in the root directory of this distribution.
*/
/*
- * $Id: versionsuffix.c,v 1.8 2005/09/20 21:32:25 jrjackson Exp $
+ * $Id: versionsuffix.c,v 1.9 2006/05/25 01:47:11 johnfranks Exp $
*
* prints the (possibly empty) suffix appended to amanda program names
*/
#include "amanda.h"
#include "version.h"
-int main P((void));
+int main(int argc, char **argv);
-int main()
+int main(int argc, char **argv)
{
safe_fd(-1, 0);
+ (void)argc; /* Quiet unused parameter warning */
+ (void)argv; /* Quiet unused parameter warning */
+
set_pname("versionsuffix");
printf("%s\n", versionsuffix());
INCLUDES = -I$(REGsrcdir)
-libamanda_la_SOURCES = \
- alloc.c amflock.c \
- bsd-security.c \
- clock.c \
- debug.c dgram.c \
- event.c error.c \
- amfeatures.c \
- file.c fileheader.c \
- krb4-security.c krb5-security.c \
- match.c \
- packet.c pipespawn.c protocol.c \
- regcomp.c regerror.c regexec.c regfree.c \
- rsh-security.c \
- security.c sl.c ssh-security.c statfs.c \
- stream.c tapelist.c \
- token.c \
- util.c \
- versuff.c version.c
+LINT=@AMLINT@
+LINTFLAGS=@AMLINTFLAGS@
+
+libamanda_la_SOURCES = \
+ alloc.c \
+ amfeatures.c \
+ amflock.c \
+ bsd-security.c \
+ bsdtcp-security.c \
+ bsdudp-security.c \
+ clock.c \
+ debug.c \
+ dgram.c \
+ error.c \
+ event.c \
+ file.c \
+ fileheader.c \
+ krb4-security.c \
+ krb5-security.c \
+ match.c \
+ packet.c \
+ pipespawn.c \
+ protocol.c \
+ regcomp.c \
+ regerror.c \
+ regexec.c \
+ regfree.c \
+ rsh-security.c \
+ security.c \
+ security-util.c \
+ sl.c \
+ ssh-security.c \
+ statfs.c \
+ stream.c \
+ tapelist.c \
+ token.c \
+ util.c \
+ version.c \
+ versuff.c
libamanda_la_LIBADD = @LTLIBOBJS@ @LTALLOCA@
libamanda_la_LDFLAGS = -release $(VERSION)
-noinst_HEADERS = amanda.h amregex.h arglist.h \
- clock.h \
- dgram.h \
- event.h \
- amfeatures.h \
- packet.h pipespawn.h protocol.h \
- queue.h \
- sl.h security.h statfs.h \
- stream.h \
- tapelist.h \
- token.h \
- util.h \
- version.h \
- fileheader.h
+noinst_HEADERS = \
+ amanda.h \
+ amfeatures.h \
+ amregex.h \
+ arglist.h \
+ clock.h \
+ dgram.h \
+ event.h \
+ fileheader.h \
+ packet.h \
+ pipespawn.h \
+ protocol.h \
+ queue.h \
+ security.h \
+ security-util.h \
+ sl.h \
+ statfs.h \
+ stream.h \
+ tapelist.h \
+ token.h \
+ util.h \
+ version.h
.sh:
cat $< > $@
EXTRA_PROGRAMS = genversion $(TEST_PROGS)
genversion_SOURCES = genversion.c
-genversion_LDADD = $(libamanda_la_LIBADD) versuff.o
+genversion_LDADD = $(libamanda_la_LIBADD) versuff.lo
genversion.@OBJEXT@: genversion.h
genversion.h: $(top_builddir)/config.status
regerror.@OBJEXT@ regerror.lo: regex.h regerror.ih
regfree.@OBJEXT@ regfree.lo: regex.h
-REGEXHSRC = $(REGsrcdir)/regex2.h \
- $(REGsrcdir)/regcomp.c \
- $(REGsrcdir)/regexec.c \
- $(REGsrcdir)/regerror.c \
+REGEXCSRC = $(REGsrcdir)/regcomp.c \
+ $(REGsrcdir)/regexec.c \
+ $(REGsrcdir)/regerror.c \
$(REGsrcdir)/regfree.c
+REGEXHSRC = $(REGsrcdir)/regex2.h \
+ $(REGEXCSRC)
+
# these are used for testing only:
TEST_PROGS = statfs token file bsdsecurity amfeatures
DISTCLEANFILES = version.c genversion.h genversion amanda-int.h
regex.h: $(REGEXHSRC) $(REGsrcdir)/mkh
- sh $(REGsrcdir)/mkh -o -i _REGEX_H_ $(REGEXHSRC) >$@
+ sh $(REGsrcdir)/mkh -i _REGEX_H_ $(REGEXHSRC) >$@
regcomp.ih: $(REGsrcdir)/regcomp.c $(REGsrcdir)/mkh
- sh $(REGsrcdir)/mkh -o -p $(REGsrcdir)/regcomp.c >$@
+ sh $(REGsrcdir)/mkh -p $(REGsrcdir)/regcomp.c >$@
engine.ih: $(REGsrcdir)/engine.c $(REGsrcdir)/mkh
- sh $(REGsrcdir)/mkh -o -p $(REGsrcdir)/engine.c >$@
+ sh $(REGsrcdir)/mkh -p $(REGsrcdir)/engine.c >$@
regerror.ih: $(REGsrcdir)/regerror.c $(REGsrcdir)/mkh
- sh $(REGsrcdir)/mkh -o -p $(REGsrcdir)/regerror.c >$@
+ sh $(REGsrcdir)/mkh -p $(REGsrcdir)/regerror.c >$@
# used for testing only
clock.$(OBJEXT) \
debug.$(OBJEXT) \
error.$(OBJEXT) \
- util.$(OBJEXT)
+ util.$(OBJEXT) \
+ match.$(OBJEXT)
STANDARD_COMMON_STUFF = \
$(STANDARD_COMMON_STUFF_NOT_FILE) \
amfeatures_SOURCES = amfeatures.test.c
amfeatures_LDADD = $(libamanda_la_LIBADD) $(STANDARD_COMMON_STUFF)
+lint:
+ @echo $(LINT) $(libamanda_la_SOURCES)
+ @$(LINT) $(LINTFLAGS) $(CPPFLAGS) $(DEFS) -I. -I../config $(INCLUDES) $(libamanda_la_SOURCES)
+ @echo $(LINT) $(genversion_SOURCES)
+ @$(LINT) $(LINTFLAGS) $(CPPFLAGS) $(DEFS) -I. -I../config $(INCLUDES) $(genversion_SOURCES)
+
+listlibsrc:
+ @ for p in $(libamanda_la_SOURCES) $(REGEXCSRC); do \
+ listlibsrcs="$$listlibsrcs `pwd`/$$p"; \
+ done; \
+ echo $$listlibsrcs >listlibsrc.output
+
%.test.c: $(srcdir)/%.c
echo '#define TEST' >$@
echo '#include "$<"' >>$@
libLTLIBRARIES_INSTALL = $(INSTALL)
LTLIBRARIES = $(lib_LTLIBRARIES)
libamanda_la_DEPENDENCIES = @LTLIBOBJS@ @LTALLOCA@
-am_libamanda_la_OBJECTS = alloc.lo amflock.lo bsd-security.lo clock.lo \
- debug.lo dgram.lo event.lo error.lo amfeatures.lo file.lo \
- fileheader.lo krb4-security.lo krb5-security.lo match.lo \
- packet.lo pipespawn.lo protocol.lo regcomp.lo regerror.lo \
- regexec.lo regfree.lo rsh-security.lo security.lo sl.lo \
+am_libamanda_la_OBJECTS = alloc.lo amfeatures.lo amflock.lo \
+ bsd-security.lo bsdtcp-security.lo bsdudp-security.lo clock.lo \
+ debug.lo dgram.lo error.lo event.lo file.lo fileheader.lo \
+ krb4-security.lo krb5-security.lo match.lo packet.lo \
+ pipespawn.lo protocol.lo regcomp.lo regerror.lo regexec.lo \
+ regfree.lo rsh-security.lo security.lo security-util.lo sl.lo \
ssh-security.lo statfs.lo stream.lo tapelist.lo token.lo \
- util.lo versuff.lo version.lo
+ util.lo version.lo versuff.lo
libamanda_la_OBJECTS = $(am_libamanda_la_OBJECTS)
am__EXEEXT_1 = statfs$(EXEEXT) token$(EXEEXT) file$(EXEEXT) \
bsdsecurity$(EXEEXT) amfeatures$(EXEEXT)
amfeatures_OBJECTS = $(am_amfeatures_OBJECTS)
am__DEPENDENCIES_1 = @LTLIBOBJS@ @LTALLOCA@
am__DEPENDENCIES_2 = alloc.$(OBJEXT) clock.$(OBJEXT) debug.$(OBJEXT) \
- error.$(OBJEXT) util.$(OBJEXT)
+ error.$(OBJEXT) util.$(OBJEXT) match.$(OBJEXT)
am__DEPENDENCIES_3 = $(am__DEPENDENCIES_2) file.$(OBJEXT)
amfeatures_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_3)
am_bsdsecurity_OBJECTS = bsd-security.test.$(OBJEXT)
file_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2)
am_genversion_OBJECTS = genversion.$(OBJEXT)
genversion_OBJECTS = $(am_genversion_OBJECTS)
-genversion_DEPENDENCIES = $(am__DEPENDENCIES_1) versuff.o
+genversion_DEPENDENCIES = $(am__DEPENDENCIES_1) versuff.lo
am_statfs_OBJECTS = statfs.test.$(OBJEXT)
statfs_OBJECTS = $(am_statfs_OBJECTS)
statfs_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_3)
AMANDA_TMPDIR = @AMANDA_TMPDIR@
AMDEP_FALSE = @AMDEP_FALSE@
AMDEP_TRUE = @AMDEP_TRUE@
+AMLINT = @AMLINT@
+AMLINTFLAGS = @AMLINTFLAGS@
AMPLOT_CAT_COMPRESS = @AMPLOT_CAT_COMPRESS@
AMPLOT_CAT_GZIP = @AMPLOT_CAT_GZIP@
AMPLOT_CAT_PACK = @AMPLOT_CAT_PACK@
AMPLOT_COMPRESS = @AMPLOT_COMPRESS@
AMTAR = @AMTAR@
+AM_CFLAGS = @AM_CFLAGS@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AWK = @AWK@
AWK_VAR_ASSIGNMENT_OPT = @AWK_VAR_ASSIGNMENT_OPT@
BINARY_OWNER = @BINARY_OWNER@
+BUILD_MAN_PAGES_FALSE = @BUILD_MAN_PAGES_FALSE@
+BUILD_MAN_PAGES_TRUE = @BUILD_MAN_PAGES_TRUE@
CAT = @CAT@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
REGDIR = ../regex-src
REGsrcdir = $(srcdir)/$(REGDIR)
INCLUDES = -I$(REGsrcdir)
+LINT = @AMLINT@
+LINTFLAGS = @AMLINTFLAGS@
libamanda_la_SOURCES = \
- alloc.c amflock.c \
- bsd-security.c \
- clock.c \
- debug.c dgram.c \
- event.c error.c \
- amfeatures.c \
- file.c fileheader.c \
- krb4-security.c krb5-security.c \
- match.c \
- packet.c pipespawn.c protocol.c \
- regcomp.c regerror.c regexec.c regfree.c \
- rsh-security.c \
- security.c sl.c ssh-security.c statfs.c \
- stream.c tapelist.c \
- token.c \
- util.c \
- versuff.c version.c
+ alloc.c \
+ amfeatures.c \
+ amflock.c \
+ bsd-security.c \
+ bsdtcp-security.c \
+ bsdudp-security.c \
+ clock.c \
+ debug.c \
+ dgram.c \
+ error.c \
+ event.c \
+ file.c \
+ fileheader.c \
+ krb4-security.c \
+ krb5-security.c \
+ match.c \
+ packet.c \
+ pipespawn.c \
+ protocol.c \
+ regcomp.c \
+ regerror.c \
+ regexec.c \
+ regfree.c \
+ rsh-security.c \
+ security.c \
+ security-util.c \
+ sl.c \
+ ssh-security.c \
+ statfs.c \
+ stream.c \
+ tapelist.c \
+ token.c \
+ util.c \
+ version.c \
+ versuff.c
libamanda_la_LIBADD = @LTLIBOBJS@ @LTALLOCA@
libamanda_la_LDFLAGS = -release $(VERSION)
-noinst_HEADERS = amanda.h amregex.h arglist.h \
- clock.h \
- dgram.h \
- event.h \
- amfeatures.h \
- packet.h pipespawn.h protocol.h \
- queue.h \
- sl.h security.h statfs.h \
- stream.h \
- tapelist.h \
- token.h \
- util.h \
- version.h \
- fileheader.h
+noinst_HEADERS = \
+ amanda.h \
+ amfeatures.h \
+ amregex.h \
+ arglist.h \
+ clock.h \
+ dgram.h \
+ event.h \
+ fileheader.h \
+ packet.h \
+ pipespawn.h \
+ protocol.h \
+ queue.h \
+ security.h \
+ security-util.h \
+ sl.h \
+ statfs.h \
+ stream.h \
+ tapelist.h \
+ token.h \
+ util.h \
+ version.h
genversion_SOURCES = genversion.c
-genversion_LDADD = $(libamanda_la_LIBADD) versuff.o
-REGEXHSRC = $(REGsrcdir)/regex2.h \
- $(REGsrcdir)/regcomp.c \
- $(REGsrcdir)/regexec.c \
- $(REGsrcdir)/regerror.c \
+genversion_LDADD = $(libamanda_la_LIBADD) versuff.lo
+REGEXCSRC = $(REGsrcdir)/regcomp.c \
+ $(REGsrcdir)/regexec.c \
+ $(REGsrcdir)/regerror.c \
$(REGsrcdir)/regfree.c
+REGEXHSRC = $(REGsrcdir)/regex2.h \
+ $(REGEXCSRC)
+
# these are used for testing only:
TEST_PROGS = statfs token file bsdsecurity amfeatures
clock.$(OBJEXT) \
debug.$(OBJEXT) \
error.$(OBJEXT) \
- util.$(OBJEXT)
+ util.$(OBJEXT) \
+ match.$(OBJEXT)
STANDARD_COMMON_STUFF = \
$(STANDARD_COMMON_STUFF_NOT_FILE) \
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/amflock.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bsd-security.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bsd-security.test.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bsdtcp-security.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bsdudp-security.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/clock.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/debug.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dgram.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/regexec.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/regfree.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rsh-security.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/security-util.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/security.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sl.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssh-security.Plo@am__quote@
regfree.@OBJEXT@ regfree.lo: regex.h
regex.h: $(REGEXHSRC) $(REGsrcdir)/mkh
- sh $(REGsrcdir)/mkh -o -i _REGEX_H_ $(REGEXHSRC) >$@
+ sh $(REGsrcdir)/mkh -i _REGEX_H_ $(REGEXHSRC) >$@
regcomp.ih: $(REGsrcdir)/regcomp.c $(REGsrcdir)/mkh
- sh $(REGsrcdir)/mkh -o -p $(REGsrcdir)/regcomp.c >$@
+ sh $(REGsrcdir)/mkh -p $(REGsrcdir)/regcomp.c >$@
engine.ih: $(REGsrcdir)/engine.c $(REGsrcdir)/mkh
- sh $(REGsrcdir)/mkh -o -p $(REGsrcdir)/engine.c >$@
+ sh $(REGsrcdir)/mkh -p $(REGsrcdir)/engine.c >$@
regerror.ih: $(REGsrcdir)/regerror.c $(REGsrcdir)/mkh
- sh $(REGsrcdir)/mkh -o -p $(REGsrcdir)/regerror.c >$@
+ sh $(REGsrcdir)/mkh -p $(REGsrcdir)/regerror.c >$@
+
+lint:
+ @echo $(LINT) $(libamanda_la_SOURCES)
+ @$(LINT) $(LINTFLAGS) $(CPPFLAGS) $(DEFS) -I. -I../config $(INCLUDES) $(libamanda_la_SOURCES)
+ @echo $(LINT) $(genversion_SOURCES)
+ @$(LINT) $(LINTFLAGS) $(CPPFLAGS) $(DEFS) -I. -I../config $(INCLUDES) $(genversion_SOURCES)
+
+listlibsrc:
+ @ for p in $(libamanda_la_SOURCES) $(REGEXCSRC); do \
+ listlibsrcs="$$listlibsrcs `pwd`/$$p"; \
+ done; \
+ echo $$listlibsrcs >listlibsrc.output
%.test.c: $(srcdir)/%.c
echo '#define TEST' >$@
* file named AUTHORS, in the root directory of this distribution.
*/
/*
- * $Id: alloc.c,v 1.35 2005/12/21 19:07:49 paddy_s Exp $
+ * $Id: alloc.c,v 1.37 2006/07/05 10:41:32 martinea Exp $
*
* Memory allocators with error handling. If the allocation fails,
* errordump() is called, relieving the caller from checking the return
#include "arglist.h"
#include "queue.h"
-static char *internal_vstralloc P((const char *, va_list));
+static char *internal_vstralloc(const char *, va_list);
/*
*=====================================================================
*/
const char *
-debug_caller_loc(file, line)
- const char *file;
- int line;
+debug_caller_loc(
+ const char *file,
+ int line)
{
+ /*@keep@*/
struct loc_str {
char *str;
LIST_ENTRY(loc_str) le;
if ((p = strrchr(file, '/')) != NULL)
file = p + 1; /* just the last path element */
- snprintf(loc, sizeof(loc), "%s@%d", file, line);
+ snprintf(loc, SIZEOF(loc), "%s@%d", file, line);
for (ls = LIST_FIRST(&root); ls != NULL; ls = LIST_NEXT(ls, le)) {
if (strcmp(loc, ls->str) == 0) {
/*
* This is a new entry. Put it at the head of the list.
*/
- ls = malloc(sizeof(*ls));
+ ls = malloc(SIZEOF(*ls));
if (ls == NULL)
return ("??"); /* not much better than abort */
ls->str = malloc(strlen(loc) + 1);
static int saved_line;
int
-debug_alloc_push (s, l)
- char *s;
- int l;
+debug_alloc_push(
+ char *s,
+ int l)
{
debug_alloc_loc_info[debug_alloc_ptr].file = s;
debug_alloc_loc_info[debug_alloc_ptr].line = l;
*/
void
-debug_alloc_pop ()
+debug_alloc_pop(void)
{
debug_alloc_ptr =
(debug_alloc_ptr + DEBUG_ALLOC_SAVE_MAX - 1) % DEBUG_ALLOC_SAVE_MAX;
* alloc - a wrapper for malloc.
*/
void *
-debug_alloc(s, l, size)
- const char *s;
- int l;
- size_t size;
+debug_alloc(
+ const char *s,
+ int l,
+ size_t size)
{
void *addr;
malloc_enter(debug_caller_loc(s, l));
addr = (void *)malloc(max(size, 1));
if (addr == NULL) {
- errordump("%s@%d: memory allocation failed (%u bytes requested)",
+ errordump("%s@%d: memory allocation failed (" SIZE_T_FMT " bytes requested)",
s ? s : "(unknown)",
s ? l : -1,
- size);
+ (SIZE_T_FMT_TYPE)size);
+ /*NOTREACHED*/
}
malloc_leave(debug_caller_loc(s, l));
return addr;
* newalloc - free existing buffer and then alloc a new one.
*/
void *
-debug_newalloc(s, l, old, size)
- const char *s;
- int l;
- void *old;
- size_t size;
+debug_newalloc(
+ const char *s,
+ int l,
+ void *old,
+ size_t size)
{
char *addr;
* Just like strdup()!
*/
char *
-debug_stralloc(s, l, str)
- const char *s;
- int l;
- const char *str;
+debug_stralloc(
+ const char *s,
+ int l,
+ const char *str)
{
char *addr;
/* vstrextend -- Extends the existing string by appending the other
* arguments. */
-arglist_function(char *vstrextend,
- char **,
- oldstr)
+/*@ignore@*/
+arglist_function(
+ char *vstrextend,
+ char **, oldstr)
{
char *keep = *oldstr;
va_list ap;
arglist_end(ap);
return *oldstr;
}
+/*@end@*/
/*
* internal_vstralloc - copies up to MAX_STR_ARGS strings into newly
#define MAX_VSTRALLOC_ARGS 32
static char *
-internal_vstralloc(str, argp)
- const char *str;
- va_list argp;
+internal_vstralloc(
+ const char *str,
+ va_list argp)
{
char *next;
char *result;
- int a;
+ int a, b;
size_t total_len;
const char *arg[MAX_VSTRALLOC_ARGS+1];
size_t len[MAX_VSTRALLOC_ARGS+1];
size_t l;
- const char *s;
if (str == NULL) {
- return NULL; /* probably will not happen */
+ errordump("internal_vstralloc: str is NULL");
+ /*NOTREACHED*/
}
a = 0;
continue; /* minor optimisation */
}
if (a >= MAX_VSTRALLOC_ARGS) {
- errordump("%s@%d: more than %d arg%s to vstralloc",
+ errordump("%s@%d: more than %d args to vstralloc",
saved_file ? saved_file : "(unknown)",
saved_file ? saved_line : -1,
- MAX_VSTRALLOC_ARGS,
- (MAX_VSTRALLOC_ARGS == 1) ? "" : "s");
+ MAX_VSTRALLOC_ARGS);
+ /*NOTREACHED*/
}
arg[a] = next;
len[a] = l;
total_len += l;
a++;
}
- arg[a] = NULL;
- len[a] = 0;
- next = result = debug_alloc(saved_file, saved_line, total_len+1);
- for (a = 0; (s = arg[a]) != NULL; a++) {
- memcpy(next, s, len[a]);
- next += len[a];
+ result = debug_alloc(saved_file, saved_line, total_len+1);
+
+ next = result;
+ for (b = 0; b < a; b++) {
+ memcpy(next, arg[b], len[b]);
+ next += len[b];
}
*next = '\0';
/*
* vstralloc - copies multiple strings into newly allocated memory.
*/
-arglist_function(char *debug_vstralloc, const char *, str)
+arglist_function(
+ char *debug_vstralloc,
+ const char *, str)
{
va_list argp;
char *result;
* newstralloc - free existing string and then stralloc a new one.
*/
char *
-debug_newstralloc(s, l, oldstr, newstr)
- const char *s;
- int l;
- char *oldstr;
- const char *newstr;
+debug_newstralloc(
+ const char *s,
+ int l,
+ char *oldstr,
+ const char *newstr)
{
char *addr;
/*
* newvstralloc - free existing string and then vstralloc a new one.
*/
-arglist_function1(char *debug_newvstralloc,
- char *,
- oldstr,
- const char *,
- newstr)
+arglist_function1(
+ char *debug_newvstralloc,
+ char *, oldstr,
+ const char *, newstr)
{
va_list argp;
char *result;
* safe_env - build a "safe" environment list.
*/
char **
-safe_env()
+safe_env(void)
{
static char *safe_env_list[] = {
"TZ",
* safe_env_list so our result is always a valid, although possibly
* empty, environment list.
*/
-#define SAFE_ENV_CNT (sizeof(safe_env_list) / sizeof(*safe_env_list))
+#define SAFE_ENV_CNT (size_t)(sizeof(safe_env_list) / sizeof(*safe_env_list))
char **envp = safe_env_list + SAFE_ENV_CNT - 1;
char **p;
char *v;
size_t l1, l2;
- if ((q = (char **)malloc(sizeof(safe_env_list))) != NULL) {
+ if ((q = (char **)malloc(SIZEOF(safe_env_list))) != NULL) {
envp = q;
for (p = safe_env_list; *p != NULL; p++) {
if ((v = getenv(*p)) == NULL) {
*/
int
-debug_amtable_alloc(s, l, table, current, elsize, count, bump, init_func)
- const char *s;
- int l;
- void **table;
- int *current;
- size_t elsize;
- int count;
- int bump;
- void (*init_func)(void *);
+debug_amtable_alloc(
+ const char *s,
+ int l,
+ void **table,
+ size_t *current,
+ size_t elsize,
+ size_t count,
+ int bump,
+ void (*init_func)(void *))
{
void *table_new;
- int table_count_new;
- int i;
+ size_t table_count_new;
+ size_t i;
if (count >= *current) {
table_count_new = ((count + bump) / bump) * bump;
*/
void
-amtable_free(table, current)
- void **table;
- int *current;
+amtable_free(
+ void **table,
+ size_t *current)
{
amfree(*table);
*current = 0;
allocating any. It is a good idea to use alloca(0) in
your main control loop, etc. to force garbage collection. */
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
+#include "amanda.h"
#ifndef HAVE_ALLOCA
alignment chunk size. The following default should work okay. */
#ifndef ALIGN_SIZE
-#define ALIGN_SIZE sizeof(double)
+#define ALIGN_SIZE SIZEOF(double)
#endif
typedef union hdr
/* Allocate combined header + user data storage. */
{
- register pointer new = malloc (sizeof (header) + size);
+ register pointer new = malloc (SIZEOF (header) + size);
/* Address of header. */
((header *) new)->h.next = last_alloca_header;
/* User storage begins just after header. */
- return (pointer) ((char *) new + sizeof (header));
+ return (pointer) ((char *) new + SIZEOF (header));
}
}
* file named AUTHORS, in the root directory of this distribution.
*/
/*
- * $Id: amanda.h,v 1.123 2006/03/03 15:05:15 vectro Exp $
+ * $Id: amanda.h,v 1.131 2006/07/25 18:27:56 martinea Exp $
*
* the central header file included by all amanda sources
*/
#include "config.h"
#endif
+/*
+ * Force large file source even if configure guesses wrong.
+ */
+#ifndef _LARGE_FILE_SOURCE
+#define _LARGE_FILES 1
+#endif
+
+#ifndef _LARGEFILE64_SOURCE
+#define _LARGEFILE64_SOURCE 1
+#endif
+
+#ifndef _FILE_OFFSET_BITS
+#define _FILE_OFFSET_BITS 64
+#endif
+
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+
/*
* I would prefer that each Amanda module include only those system headers
* that are locally needed, but on most Unixes the system header files are not
# include <alloca.h>
#endif
-#if 0
-/* an explanation for this is available in the CHANGES file for
- amanda-2.4.0b5 */
-#ifdef HAVE_ASM_BYTEORDER_H
-# include <asm/byteorder.h>
-#endif
-#endif
-
-#ifdef HAVE_SYS_TYPES_H
-# include <sys/types.h>
-#endif
-
/* from the autoconf documentation */
#ifdef HAVE_DIRENT_H
# include <dirent.h>
# include <stdlib.h>
#endif
+#ifdef HAVE_LIBGEN_H
+# include <libgen.h>
+#endif
+
#ifdef HAVE_STRING_H
# include <string.h>
#endif
# include <syslog.h>
#endif
+#ifdef HAVE_MATH_H
+# include <math.h>
+#endif
+
#ifdef HAVE_SYS_FILE_H
# include <sys/file.h>
#endif
# include <sys/wait.h>
#endif
+#ifdef HAVE_STDARG_H
+#include <stdarg.h>
+#endif
+
#ifdef WAIT_USES_INT
typedef int amwait_t;
# ifndef WEXITSTATUS
#ifdef USE_DBMALLOC
#include "dbmalloc.h"
#else
-#define malloc_enter(func)
-#define malloc_leave(func)
-#define malloc_mark(ptr)
-#define malloc_chain_check()
-#define malloc_dump(fd)
-#define malloc_list(a,b,c)
+#define malloc_enter(func) ((void)0)
+#define malloc_leave(func) ((void)0)
+#define malloc_mark(ptr) ((void)0)
+#define malloc_chain_check() ((void)0)
+#define malloc_dump(fd) ((void)0)
+#define malloc_list(a,b,c) ((void)0)
#define malloc_inuse(hist) (*(hist) = 0, 0)
#define dbmalloc_caller_loc(x,y) (x)
#endif
extern int errno;
#endif
+/*
+ * Some compilers have int for type of sizeof() some use size_t.
+ * size_t is the one we want...
+ */
+#define SIZEOF(x) (size_t)sizeof(x)
+
/*
* Some older BSD systems don't have these FD_ macros, so if not, provide them.
*/
-#ifndef FD_SET
-# define FD_SETSIZE (sizeof(fd_set) * 8)
-# define FD_SET(n, p) (((fd_set *) (p))->fds_bits[0] |= (1 << ((n) % 32)))
-# define FD_CLR(n, p) (((fd_set *) (p))->fds_bits[0] &= ~(1 << ((n) % 32)))
-# define FD_ISSET(n, p) (((fd_set *) (p))->fds_bits[0] & (1 << ((n) % 32)))
-# define FD_ZERO(p) memset((p), 0, sizeof(*(p)))
+#if !defined(FD_SET) || defined(LINT) || defined(__lint)
+# undef FD_SETSIZE
+# define FD_SETSIZE (int)(SIZEOF(fd_set) * CHAR_BIT)
+
+# undef FD_SET
+# define FD_SET(n, p) (((fd_set *)(p))->fds_bits[(n)/WORD_BIT] |= (int)((1 << ((n) % WORD_BIT))))
+
+# undef FD_CLR
+# define FD_CLR(n, p) (((fd_set *)(p))->fds_bits[(n)/WORD_BIT] &= (int)(~(1 << ((n) % WORD_BIT))))
+
+# undef FD_ISSET
+# define FD_ISSET(n, p) (((fd_set *)(p))->fds_bits[(n)/WORD_BIT] & (1 << ((n) % WORD_BIT)))
+
+# undef FD_ZERO
+# define FD_ZERO(p) memset((p), 0, SIZEOF(*(p)))
#endif
#ifndef FD_COPY
-# define FD_COPY(p, q) memcpy((q), (p), sizeof(fd_set))
+# define FD_COPY(p, q) memcpy((q), (p), SIZEOF(*(p)))
#endif
# define void char
#endif
-/*
- * Macros to allow code to adapt to both ANSI and class C environments.
- *
- * P(): prototype argument macro - removes arguments from prototypes in
- * class C environments
- * stringize(): turn a bare word or words into a quoted string
- * stringconcat(): turn two quoted strings into one
- */
-#if STDC_HEADERS
-# define P(parms) parms
-# define stringize(x) #x
-# define stringconcat(x, y) x ## y
-#else
-# define P(parms) ()
-# define stringize(x) "x"
-# define stringconcat(x, y) x/**/y
-#endif
+#define stringize(x) #x
+#define stringconcat(x, y) x ## y
/*
* So that we can use GNUC attributes (such as to get -Wall warnings
* for printf-like functions). Only do this in gcc 2.7 or later ...
* it may work on earlier stuff, but why chance it.
*/
-#if !defined(__GNUC__) || __GNUC__ < 2 || __GNUC_MINOR__ < 7
+#if !defined(__GNUC__) || __GNUC__ < 2 || __GNUC_MINOR__ < 7 || defined(S_SPLINT_S) || defined(LINT) || defined(__lint)
+#undef __attribute__
#define __attribute__(__x)
#endif
onerror(abort); \
error("assert: %s false, file %s, line %d", \
stringize(exp), __FILE__, __LINE__); \
+ /*NOTREACHED*/ \
} \
} while (0)
*/
#ifdef DEBUG_CODE /* { */
-# define dbopen() debug_open()
+# define dbopen(a) debug_open(a)
# define dbreopen(a,b) debug_reopen(a,b)
+# define dbrename(a,b) debug_rename(a,b)
# define dbclose() debug_close()
-# define dbprintf(p) (debug? (debug_printf p, 0) : 0)
+# define dbprintf(p) (debug_printf p)
# define dbfd() debug_fd()
# define dbfp() debug_fp()
# define dbfn() debug_fn()
-extern void debug_open P((void));
-extern void debug_reopen P((char *file, char *notation));
-extern void debug_close P((void));
-extern void debug_printf P((const char *format, ...))
+extern void debug_open(char *subdir);
+extern void debug_reopen(char *file, char *notation);
+extern void debug_rename(char *config, char *subdir);
+extern void debug_close(void);
+extern void debug_printf(const char *format, ...)
__attribute__ ((format (printf, 1, 2)));
-extern int debug_fd P((void));
-extern FILE * debug_fp P((void));
-extern char * debug_fn P((void));
-extern void set_debug_prefix_pid P((pid_t));
-extern char *debug_prefix P((char *));
-extern char *debug_prefix_time P((char *));
+extern int debug_fd(void);
+extern FILE * debug_fp(void);
+extern char * debug_fn(void);
+extern void set_debug_prefix_pid(pid_t);
+extern char *debug_prefix(char *);
+extern char *debug_prefix_time(char *);
#else /* }{ */
-# define dbopen()
+# define dbopen(a)
# define dbreopen(a,b)
# define dbclose()
# define dbprintf(p)
/* amanda #days calculation, with roundoff */
#define SECS_PER_DAY (24*60*60)
-#define days_diff(a, b) (((b) - (a) + SECS_PER_DAY/2) / SECS_PER_DAY)
+#define days_diff(a, b) (int)(((b) - (a) + SECS_PER_DAY/2) / SECS_PER_DAY)
/* Global constants. */
#ifndef AMANDA_SERVICE_NAME
#define SERVICE_SUFFIX ""
#endif
#ifndef AMANDA_SERVICE_DEFAULT
-#define AMANDA_SERVICE_DEFAULT 10080
+#define AMANDA_SERVICE_DEFAULT ((in_port_t)10080)
#endif
#ifndef KAMANDA_SERVICE_DEFAULT
-#define KAMANDA_SERVICE_DEFAULT 10081
+#define KAMANDA_SERVICE_DEFAULT ((in_port_t)10081)
#endif
#define am_round(v,u) ((((v) + (u) - 1) / (u)) * (u))
/* Maximum length of tape label, plus one for null-terminator. */
#define MAX_TAPE_LABEL_LEN (10240)
#define MAX_TAPE_LABEL_BUF (MAX_TAPE_LABEL_LEN+1)
+#define MAX_TAPE_LABEL_FMT "%10240s"
/* Define miscellaneous amanda functions. */
#define ERR_INTERACTIVE 1
#define ERR_SYSLOG 2
#define ERR_AMANDALOG 4
-extern void set_logerror P((void (*f)(char *)));
-extern void set_pname P((char *pname));
-extern char *get_pname P((void));
+extern void set_logerror(void (*f)(char *));
+extern void set_pname(char *pname);
+extern char *get_pname(void);
extern int erroutput_type;
-extern void error P((const char *format, ...))
+extern void error(const char *format, ...)
__attribute__ ((format (printf, 1, 2), noreturn));
-extern void errordump P((const char *format, ...))
+extern void errordump(const char *format, ...)
__attribute__ ((format (printf, 1, 2), noreturn));
-extern int onerror P((void (*errf)(void)));
+extern int onerror(void (*errf)(void));
-extern void *debug_alloc P((const char *c, int l, size_t size));
-extern void *debug_newalloc P((const char *c, int l, void *old, size_t size));
-extern char *debug_stralloc P((const char *c, int l, const char *str));
-extern char *debug_newstralloc P((const char *c, int l, char *oldstr,
- const char *newstr));
-extern const char *debug_caller_loc P((const char *file, int line));
-extern int debug_alloc_push P((char *file, int line));
-extern void debug_alloc_pop P((void));
+extern void *debug_alloc (const char *c, int l, size_t size);
+extern void *debug_newalloc (const char *c, int l, void *old, size_t size);
+extern char *debug_stralloc (const char *c, int l, const char *str);
+extern char *debug_newstralloc(const char *c, int l, char *oldstr,
+ const char *newstr);
+extern const char *debug_caller_loc (const char *file, int line);
+extern int debug_alloc_push (char *file, int line);
+extern void debug_alloc_pop (void);
#define alloc(s) debug_alloc(__FILE__, __LINE__, (s))
#define newalloc(p,s) debug_newalloc(__FILE__, __LINE__, (p), (s))
#define vstralloc debug_alloc_push(__FILE__,__LINE__)?0:debug_vstralloc
#define newvstralloc debug_alloc_push(__FILE__,__LINE__)?0:debug_newvstralloc
-extern char *debug_vstralloc P((const char *str, ...));
-extern char *debug_newvstralloc P((char *oldstr, const char *newstr, ...));
+extern char *debug_vstralloc(const char *str, ...);
+extern char *debug_newvstralloc(char *oldstr, const char *newstr, ...);
#define stralloc2(s1,s2) vstralloc((s1),(s2),NULL)
#define newstralloc2(p,s1,s2) newvstralloc((p),(s1),(s2),NULL)
/* Usage: vstrextend(foo, "bar, "baz", NULL). Extends the existing
* string, or allocates a brand new one. */
-extern char *vstrextend P((char **oldstr, ...));
+extern char *vstrextend(char **oldstr, ...);
-extern char *debug_agets P((const char *c, int l, FILE *file));
-extern char *debug_areads P((const char *c, int l, int fd));
+extern /*@only@*/ /*@null@*/ char *debug_agets(const char *c, int l, FILE *file);
+extern /*@only@*/ /*@null@*/ char *debug_areads(const char *c, int l, int fd);
#define agets(f) debug_agets(__FILE__,__LINE__,(f))
#define areads(f) debug_areads(__FILE__,__LINE__,(f))
-extern int debug_amtable_alloc P((const char *file,
+extern int debug_amtable_alloc(const char *file,
int line,
void **table,
- int *current,
+ size_t *current,
size_t elsize,
- int count,
+ size_t count,
int bump,
- void (*init_func)(void *)));
+ void (*init_func)(void *));
+
#define amtable_alloc(t,c,s,n,b,f) debug_amtable_alloc(__FILE__, \
__LINE__, \
(t), \
(b), \
(f))
-extern void amtable_free P((void **table, int *current));
+extern void amtable_free(void **table, size_t *current);
extern uid_t client_uid;
extern gid_t client_gid;
-extern void safe_fd P((int fd_start, int fd_count));
-extern void safe_cd P((void));
-extern void save_core P((void));
-extern char **safe_env P((void));
-extern char *validate_regexp P((char *regex));
-extern char *validate_glob P((char *glob));
-extern char *clean_regex P((char *regex));
-extern int match P((char *regex, char *str));
-extern int match_glob P((char *glob, char *str));
-extern char *glob_to_regex P((char *glob));
-extern int match_tar P((char *glob, char *str));
-extern char *tar_to_regex P((char *glob));
-extern int match_host P((char *glob, char *host));
-extern int match_disk P((char *glob, char *disk));
-extern int match_datestamp P((char *dateexp, char *datestamp));
-extern int match_level P((char *levelexp, char *level));
-extern time_t unctime P((char *timestr));
-extern ssize_t areads_dataready P((int fd));
-extern void areads_relbuf P((int fd));
+
+void safe_fd(int fd_start, int fd_count);
+void safe_cd(void);
+void save_core(void);
+char ** safe_env(void);
+char * validate_regexp(const char *regex);
+char * validate_glob(const char *glob);
+char * clean_regex(const char *regex);
+int match(const char *regex, const char *str);
+int match_glob(const char *glob, const char *str);
+char * glob_to_regex(const char *glob);
+int match_tar(const char *glob, const char *str);
+char * tar_to_regex(const char *glob);
+int match_host(const char *glob, const char *host);
+int match_disk(const char *glob, const char *disk);
+int match_datestamp(const char *dateexp, const char *datestamp);
+int match_level(const char *levelexp, const char *level);
+time_t unctime(char *timestr);
+ssize_t areads_dataready(int fd);
+void areads_relbuf(int fd);
/*
* amfree(ptr) -- if allocated, release space and set ptr to NULL.
*/
#define amfree(ptr) do { \
- if(ptr) { \
+ if((ptr) != NULL) { \
int e__errno = errno; \
free(ptr); \
(ptr) = NULL; \
errno = e__errno; \
+ (void)(ptr); /* Fix value never used warning at end of routines */ \
} \
-} while(0)
+} while (0)
#define strappend(s1,s2) do { \
char *t_t_t = (s1) ? stralloc2((s1),(s2)) : stralloc((s2)); \
areads_relbuf(fd); \
} \
(fd) = -1; \
+ (void)(fd); /* Fix value never used warning at end of routines */ \
} while(0)
#define afclose(f) do { \
if((f) != NULL) { \
fclose(f); \
+ (f) = NULL; \
+ (void)(f); /* Fix value never used warning at end of routines */ \
} \
- (f) = NULL; \
} while(0)
#define apclose(p) do { \
if((p) != NULL) { \
pclose(p); \
+ (p) = NULL; \
+ (void)(p); /* Fix value never used warning at end of routines */ \
} \
- (p) = NULL; \
} while(0)
/*
* Return the number of elements in an array.
*/
-#define am_countof(a) (sizeof(a) / sizeof((a)[0]))
+#define am_countof(a) (int)(SIZEOF(a) / SIZEOF((a)[0]))
/*
* min/max. Don't do something like
*/
#define STR_SIZE 4096 /* a generic string buffer size */
-#define NUM_STR_SIZE 32 /* a generic number buffer size */
+#define NUM_STR_SIZE 128 /* a generic number buffer size */
#define skip_whitespace(ptr,c) do { \
while((c) != '\n' && isspace(c)) (c) = *(ptr)++; \
while(isdigit(c)) (c) = *(ptr)++; \
} while(0)
+#define skip_quoted_string(ptr, c) do { \
+ int iq = 0; \
+ while (((c) != '\0') && !((iq == 0) && isspace(c))) { \
+ if ((c) == '"') { \
+ iq = !iq; \
+ } else if (((c) == '\\') && (*(ptr) == '"')) { \
+ (ptr)++; \
+ } \
+ (c) = *(ptr)++; \
+ } \
+} while (0)
+
+#define skip_quoted_line(ptr, c) do { \
+ int iq = 0; \
+ while((c) && !((iq == 0) && ((c) == '\n'))) { \
+ if ((c) == '"') \
+ iq = !iq; \
+ (c) = *(ptr)++; \
+ } \
+ if(c) \
+ (c) = *(ptr)++; \
+} while(0)
+
#define skip_line(ptr,c) do { \
- while((c) && (c) != '\n') (c) = *(ptr)++; \
- if(c) (c) = *(ptr)++; \
+ while((c) && (c) != '\n') \
+ (c) = *(ptr)++; \
+ if(c) \
+ (c) = *(ptr)++; \
} while(0)
#define copy_string(ptr,c,f,l,fp) do { \
if((fp) >= (f) + (l) - 1) { \
*(fp) = '\0'; \
(fp) = NULL; \
+ (void)(fp); /* Fix value never used warning at end of routines */ \
break; \
} \
*(fp)++ = (c); \
(c) = *(ptr)++; \
} \
- if(fp) *fp = '\0'; \
+ if(fp) \
+ *fp = '\0'; \
} while(0)
#define copy_string_cs(ptr,c,f,l,fp) do { \
|| ((s)[1] == '.' && (s)[2] == '\0')))
/* from amflock.c */
-extern int amflock P((int fd, char *resource));
-extern int amroflock P((int fd, char *resource));
-extern int amfunlock P((int fd, char *resource));
+extern int amflock(int fd, char *resource);
+extern int amroflock(int fd, char *resource);
+extern int amfunlock(int fd, char *resource);
/* from file.c */
-extern int mkpdir P((char *file, int mode, uid_t uid, gid_t gid));
-extern int rmpdir P((char *file, char *topdir));
-extern char *sanitise_filename P((char *inp));
-
-/* from bsd-security.c */
-extern char *check_user_ruserok P((const char *host,
- struct passwd *pwd,
- const char *user));
-extern char *check_user_amandahosts P((const char *host,
- struct passwd *pwd,
- const char *user));
+extern int mkpdir(char *file, mode_t mode, uid_t uid, gid_t gid);
+extern int rmpdir(char *file, char *topdir);
+extern char *sanitise_filename(char *inp);
+/* from old bsd-security.c */
extern int debug;
-extern int check_security P((struct sockaddr_in *, char *, unsigned long,
- char **));
-
+extern int check_security(struct sockaddr_in *, char *, unsigned long, char **);
/*
* Handle functions which are not always declared on all systems. This
/* AIX #defines accept, and provides a prototype for the alternate name */
#if !defined(HAVE_ACCEPT_DECL) && !defined(accept)
-extern int accept P((int s, struct sockaddr *addr, int *addrlen));
+extern int accept(int s, struct sockaddr *addr, socklen_t *addrlen);
#endif
#ifndef HAVE_ATOF_DECL
-extern double atof P((const char *ptr));
+extern double atof(const char *ptr);
#endif
#ifndef HAVE_BCOPY
# define bcopy(from,to,n) ((void)memmove((to), (from), (n)))
#else
# ifndef HAVE_BCOPY_DECL
-extern void bcopy P((const void *s1, void *s2, size_t n));
+extern void bcopy(const void *s1, void *s2, size_t n);
# endif
#endif
#ifndef HAVE_BIND_DECL
-extern int bind P((int s, const struct sockaddr *name, int namelen));
+extern int bind(int s, const struct sockaddr *name, socklen_t namelen);
#endif
#ifndef HAVE_BZERO
#define bzero(s,n) ((void)memset((s),0,(n)))
#else
# ifndef HAVE_BZERO_DECL
-extern void bzero P((void *s, size_t n));
+extern void bzero(void *s, size_t n);
# endif
#endif
#ifndef HAVE_CLOSELOG_DECL
-extern void closelog P((void));
+extern void closelog(void);
#endif
#ifndef HAVE_CONNECT_DECL
-extern int connect P((int s, struct sockaddr *name, int namelen));
+extern int connect(int s, struct sockaddr *name, socklen_t namelen);
#endif
#if !defined(TEXTDB) && !defined(HAVE_DBM_OPEN_DECL)
} datum;
#endif
- extern DBM *dbm_open P((char *file, int flags, int mode));
- extern void dbm_close P((DBM *db));
- extern datum dbm_fetch P((DBM *db, datum key));
- extern datum dbm_firstkey P((DBM *db));
- extern datum dbm_nextkey P((DBM *db));
- extern int dbm_delete P((DBM *db, datum key));
- extern int dbm_store P((DBM *db, datum key, datum content, int flg));
+ extern DBM *dbm_open(char *file, int flags, int mode);
+ extern void dbm_close(DBM *db);
+ extern datum dbm_fetch(DBM *db, datum key);
+ extern datum dbm_firstkey(DBM *db);
+ extern datum dbm_nextkey(DBM *db);
+ extern int dbm_delete(DBM *db, datum key);
+ extern int dbm_store(DBM *db, datum key, datum content, int flg);
#endif
#ifndef HAVE_FCLOSE_DECL
-extern int fclose P((FILE *stream));
+extern int fclose(FILE *stream);
#endif
#ifndef HAVE_FFLUSH_DECL
-extern int fflush P((FILE *stream));
+extern int fflush(FILE *stream);
#endif
#ifndef HAVE_FPRINTF_DECL
-extern int fprintf P((FILE *stream, const char *format, ...));
+extern int fprintf(FILE *stream, const char *format, ...);
#endif
#ifndef HAVE_FPUTC_DECL
-extern int fputc P((int c, FILE *stream));
+extern int fputc(int c, FILE *stream);
#endif
#ifndef HAVE_FPUTS_DECL
-extern int fputs P((const char *s, FILE *stream));
+extern int fputs(const char *s, FILE *stream);
#endif
#ifndef HAVE_FREAD_DECL
-extern size_t fread P((void *ptr, size_t size, size_t nitems, FILE *stream));
+extern size_t fread(void *ptr, size_t size, size_t nitems, FILE *stream);
#endif
#ifndef HAVE_FSEEK_DECL
-extern int fseek P((FILE *stream, long offset, int ptrname));
+extern int fseek(FILE *stream, long offset, int ptrname);
#endif
#ifndef HAVE_FWRITE_DECL
-extern size_t fwrite P((const void *ptr, size_t size, size_t nitems,
- FILE *stream));
+extern size_t fwrite(const void *ptr, size_t size, size_t nitems,
+ FILE *stream);
#endif
#ifndef HAVE_GETHOSTNAME_DECL
-extern int gethostname P((char *name, int namelen));
+extern int gethostname(char *name, int namelen);
#endif
#ifndef HAVE_GETOPT_DECL
extern char *optarg;
-extern int getopt P((int argc, char * const *argv, const char *optstring));
+extern int getopt(int argc, char * const *argv, const char *optstring);
#endif
/* AIX #defines getpeername, and provides a prototype for the alternate name */
#if !defined(HAVE_GETPEERNAME_DECL) && !defined(getpeername)
-extern int getpeername P((int s, struct sockaddr *name, int *namelen));
+extern int getpeername(int s, struct sockaddr *name, socklen_t *namelen);
#endif
/* AIX #defines getsockname, and provides a prototype for the alternate name */
#if !defined(HAVE_GETSOCKNAME_DECL) && !defined(getsockname)
-extern int getsockname P((int s, struct sockaddr *name, int *namelen));
+extern int getsockname(int s, struct sockaddr *name, socklen_t *namelen);
#endif
#ifndef HAVE_GETSOCKOPT_DECL
-extern int getsockopt P((int s, int level, int optname, char *optval,
- int *optlen));
+extern int getsockopt(int s, int level, int optname, char *optval,
+ socklen_t *optlen);
#endif
#ifndef HAVE_GETTIMEOFDAY_DECL
# ifdef HAVE_TWO_ARG_GETTIMEOFDAY
-extern int gettimeofday P((struct timeval *tp, struct timezone *tzp));
+extern int gettimeofday(struct timeval *tp, struct timezone *tzp);
# else
-extern int gettimeofday P((struct timeval *tp));
+extern int gettimeofday(struct timeval *tp);
# endif
#endif
# define initgroups(name,basegid) 0
#else
# ifndef HAVE_INITGROUPS_DECL
-extern int initgroups P((const char *name, gid_t basegid));
+extern int initgroups(const char *name, gid_t basegid);
# endif
#endif
#ifndef HAVE_IOCTL_DECL
-extern int ioctl P((int fildes, int request, ...));
+extern int ioctl(int fildes, int request, ...);
+#endif
+
+#ifndef isnormal
+#ifndef HAVE_ISNORMAL
+#define isnormal(f) (((f) < 0.0) || ((f) > 0.0))
+#endif
#endif
#ifndef HAVE_LISTEN_DECL
-extern int listen P((int s, int backlog));
+extern int listen(int s, int backlog);
#endif
#ifndef HAVE_LSTAT_DECL
-extern int lstat P((const char *path, struct stat *buf));
+extern int lstat(const char *path, struct stat *buf);
#endif
#ifndef HAVE_MALLOC_DECL
-extern void *malloc P((size_t size));
+extern void *malloc (size_t size);
#endif
#ifndef HAVE_MEMMOVE_DECL
#ifdef HAVE_MEMMOVE
-extern void *memmove P((void *to, const void *from, size_t n));
+extern void *memmove(void *to, const void *from, size_t n);
#else
-extern char *memmove P((char *to, /*const*/ char *from, size_t n));
+extern char *memmove(char *to, /*const*/ char *from, size_t n);
#endif
#endif
#ifndef HAVE_MEMSET_DECL
-extern void *memset P((void *s, int c, size_t n));
+extern void *memset(void *s, int c, size_t n);
#endif
#ifndef HAVE_MKTEMP_DECL
-extern char *mktemp P((char *template));
+extern char *mktemp(char *template);
#endif
#ifndef HAVE_MKSTEMP_DECL
-extern int mkstemp P((char *template));
+extern int mkstemp(char *template);
#endif
#ifndef HAVE_MKTIME_DECL
-extern time_t mktime P((struct tm *timeptr));
+extern time_t mktime(struct tm *timeptr);
#endif
#ifndef HAVE_OPENLOG_DECL
#ifdef LOG_AUTH
-extern void openlog P((const char *ident, int logopt, int facility));
+extern void openlog(const char *ident, int logopt, int facility);
#else
-extern void openlog P((const char *ident, int logopt));
+extern void openlog(const char *ident, int logopt);
#endif
#endif
#ifndef HAVE_PCLOSE_DECL
-extern int pclose P((FILE *stream));
+extern int pclose(FILE *stream);
#endif
#ifndef HAVE_PERROR_DECL
-extern void perror P((const char *s));
+extern void perror(const char *s);
#endif
#ifndef HAVE_PRINTF_DECL
-extern int printf P((const char *format, ...));
+extern int printf(const char *format, ...);
#endif
#ifndef HAVE_PUTS_DECL
-extern int puts P((const char *s));
+extern int puts(const char *s);
#endif
#ifndef HAVE_REALLOC_DECL
-extern void *realloc P((void *ptr, size_t size));
+extern void *realloc(void *ptr, size_t size);
#endif
/* AIX #defines recvfrom, and provides a prototype for the alternate name */
#if !defined(HAVE_RECVFROM_DECL) && !defined(recvfrom)
-extern int recvfrom P((int s, char *buf, int len, int flags,
- struct sockaddr *from, int *fromlen));
+extern int recvfrom(int s, char *buf, int len, int flags,
+ struct sockaddr *from, socklen_t *fromlen);
#endif
#ifndef HAVE_REMOVE_DECL
-extern int remove P((const char *path));
+extern int remove(const char *path);
#endif
#ifndef HAVE_RENAME_DECL
-extern int rename P((const char *old, const char *new));
+extern int rename(const char *old, const char *new);
#endif
#ifndef HAVE_REWIND_DECL
-extern void rewind P((FILE *stream));
+extern void rewind(FILE *stream);
#endif
#ifndef HAVE_RUSEROK_DECL
-extern int ruserok P((const char *rhost, int suser,
- const char *ruser, const char *luser));
+extern int ruserok(const char *rhost, int suser,
+ const char *ruser, const char *luser);
#endif
#ifndef HAVE_SELECT_DECL
-extern int select P((int nfds,
+extern int select(int nfds,
SELECT_ARG_TYPE *readfds,
SELECT_ARG_TYPE *writefds,
SELECT_ARG_TYPE *exceptfds,
- struct timeval *timeout));
+ struct timeval *timeout);
#endif
#ifndef HAVE_SENDTO_DECL
-extern int sendto P((int s, const char *msg, int len, int flags,
- const struct sockaddr *to, int tolen));
+extern int sendto(int s, const char *msg, int len, int flags,
+ const struct sockaddr *to, int tolen);
#endif
#ifdef HAVE_SETRESGID
-#define setegid(x) setresgid(-1,(x),-1)
+#define setegid(x) setresgid((gid_t)-1,(x),(gid_t)-1)
#ifndef HAVE_SETRESGID_DECL
-extern int setresgid P((gid_t rgid, gid_t egid, gid_t sgid));
+extern int setresgid(gid_t rgid, gid_t egid, gid_t sgid);
#endif
#else
#ifndef HAVE_SETEGID_DECL
-extern int setegid P((gid_t egid));
+extern int setegid(gid_t egid);
#endif
#endif
#ifdef HAVE_SETRESUID
-#define seteuid(x) setresuid(-1,(x),-1)
+#define seteuid(x) setresuid((uid_t)-1,(x),(uid_t)-1)
#ifndef HAVE_SETRESUID_DECL
-extern int setresuid P((uid_t ruid, uid_t euid, uid_t suid));
+extern int setresuid(uid_t ruid, uid_t euid, uid_t suid);
#endif
#else
#ifndef HAVE_SETEUID_DECL
-extern int seteuid P((uid_t euid));
+extern int seteuid(uid_t euid);
#endif
#endif
#ifndef HAVE_SETPGID_DECL
#ifdef HAVE_SETPGID
-extern int setpgid P((int pid, int pgid));
+extern int setpgid(pid_t pid, pid_t pgid);
#endif
#endif
#ifndef HAVE_SETPGRP_DECL
#ifdef SETPGRP_VOID
-extern pid_t setpgrp P((void));
+extern pid_t setpgrp(void);
#else
-extern pid_t setpgrp P((int pgrp, int pid));
+extern pid_t setpgrp(pid_t pgrp, pid_t pid);
#endif
#endif
#ifndef HAVE_SETSOCKOPT_DECL
-extern int setsockopt P((int s, int level, int optname,
- const char *optval, int optlen));
+extern int setsockopt(int s, int level, int optname,
+ const char *optval, int optlen);
#endif
#ifdef HAVE_SHMGET
#ifndef HAVE_SHMAT_DECL
-extern void *shmat P((int shmid, const SHM_ARG_TYPE *shmaddr, int shmflg));
+extern void *shmat(int shmid, const SHM_ARG_TYPE *shmaddr, int shmflg);
#endif
#ifndef HAVE_SHMCTL_DECL
-extern int shmctl P((int shmid, int cmd, struct shmid_ds *buf));
+extern int shmctl(int shmid, int cmd, struct shmid_ds *buf);
#endif
#ifndef HAVE_SHMDT_DECL
-extern int shmdt P((SHM_ARG_TYPE *shaddr));
+extern int shmdt(SHM_ARG_TYPE *shaddr);
#endif
#ifndef HAVE_SHMGET_DECL
-extern int shmget P((key_t key, size_t size, int shmflg));
+extern int shmget(key_t key, size_t size, int shmflg);
#endif
#endif
#ifndef HAVE_SNPRINTF_DECL
#include "arglist.h"
-int snprintf P((char *buf, size_t len, const char *format,...))
+int snprintf(char *buf, size_t len, const char *format,...)
__attribute__((format(printf,3,4)));
#endif
#ifndef HAVE_VSNPRINTF_DECL
#include "arglist.h"
-int vsnprintf P((char *buf, size_t len, const char *format, va_list ap));
+int vsnprintf(char *buf, size_t len, const char *format, va_list ap);
#endif
#ifndef HAVE_SOCKET_DECL
-extern int socket P((int domain, int type, int protocol));
+extern int socket(int domain, int type, int protocol);
#endif
#ifndef HAVE_SOCKETPAIR_DECL
-extern int socketpair P((int domain, int type, int protocol, int sv[2]));
+extern int socketpair(int domain, int type, int protocol, int sv[2]);
#endif
#ifndef HAVE_SSCANF_DECL
-extern int sscanf P((const char *s, const char *format, ...));
+extern int sscanf(const char *s, const char *format, ...);
#endif
#ifndef HAVE_STRCASECMP_DECL
-extern int strcasecmp P((const char *s1, const char *s2));
+extern int strcasecmp(const char *s1, const char *s2);
#endif
#ifndef HAVE_STRERROR_DECL
-extern char *strerror P((int errnum));
+extern char *strerror(int errnum);
#endif
#ifndef HAVE_STRFTIME_DECL
-extern size_t strftime P((char *s, size_t maxsize, const char *format,
- const struct tm *timeptr));
+extern size_t strftime(char *s, size_t maxsize, const char *format,
+ const struct tm *timeptr);
#endif
#ifndef HAVE_STRNCASECMP_DECL
-extern int strncasecmp P((const char *s1, const char *s2, int n));
+extern int strncasecmp(const char *s1, const char *s2, int n);
#endif
#ifndef HAVE_SYSLOG_DECL
-extern void syslog P((int priority, const char *logstring, ...))
+extern void syslog(int priority, const char *logstring, ...)
__attribute__ ((format (printf, 2, 3)));
#endif
#ifndef HAVE_SYSTEM_DECL
-extern int system P((const char *string));
+extern int system(const char *string);
#endif
#ifndef HAVE_TIME_DECL
-extern time_t time P((time_t *tloc));
+extern time_t time(time_t *tloc);
#endif
#ifndef HAVE_TOLOWER_DECL
-extern int tolower P((int c));
+extern int tolower(int c);
#endif
#ifndef HAVE_TOUPPER_DECL
-extern int toupper P((int c));
+extern int toupper(int c);
#endif
#ifndef HAVE_UNGETC_DECL
-extern int ungetc P((int c, FILE *stream));
+extern int ungetc(int c, FILE *stream);
#endif
#ifndef HAVE_VFPRINTF_DECL
#include "arglist.h"
-extern int vfprintf P((FILE *stream, const char *format, va_list ap));
+extern int vfprintf(FILE *stream, const char *format, va_list ap);
#endif
#ifndef HAVE_VPRINTF_DECL
#include "arglist.h"
-extern int vprintf P((const char *format, va_list ap));
+extern int vprintf(const char *format, va_list ap);
#endif
#if !defined(S_ISCHR) && defined(_S_IFCHR) && defined(_S_IFMT)
#ifdef HAVE_WAIT4
#define waitpid(pid,status,options) wait4(pid,status,options,0)
#else
-extern pid_t waitpid P((pid_t pid, amwait_t *stat_loc, int options));
+extern pid_t waitpid(pid_t pid, amwait_t *stat_loc, int options);
#endif
#endif
#ifndef HAVE_WRITEV_DECL
-extern ssize_t writev P((int fd, const struct iovec *iov, int iovcnt));
+extern ssize_t writev(int fd, const struct iovec *iov, int iovcnt);
#endif
#ifndef STDIN_FILENO
#if defined(_S_IFMT) && defined(_S_IFDIR)
#define S_ISDIR(mode) (((mode) & (_S_IFMT)) == (_S_IFDIR))
#else
-error: Don t know how to define S_ISDIR
+#error Don t know how to define S_ISDIR
+#endif
+#endif
+
+#if SIZEOF_SIZE_T == SIZEOF_INT
+# define SIZE_T_FMT "%u"
+# define SIZE_T_FMT_TYPE unsigned
+# define SIZE_T_ATOI (size_t)atoi
+# ifndef SIZE_MAX
+# define SIZE_MAX UINT_MAX
+# endif
+#else
+# define SIZE_T_FMT "%lu"
+# define SIZE_T_FMT_TYPE unsigned long
+# define SIZE_T_ATOI (size_t)atol
+# ifndef SIZE_MAX
+# define SIZE_MAX ULONG_MAX
+# endif
+#endif
+
+#if SIZEOF_SSIZE_T == SIZEOF_INT
+# define SSIZE_T_FMT "%d"
+# define SSIZE_T_FMT_TYPE int
+# define SSIZE_T_ATOI (ssize_t)atoi
+# ifndef SSIZE_MAX
+# define SSIZE_MAX INT_MAX
+# endif
+# ifndef SSIZE_MIN
+# define SSIZE_MIN INT_MIN
+# endif
+#else
+# define SSIZE_T_FMT "%ld"
+# define SSIZE_T_FMT_TYPE long
+# define SSIZE_T_ATOI (ssize_t)atol
+# ifndef SSIZE_MAX
+# define SSIZE_MAX LONG_MAX
+# endif
+# ifndef SSIZE_MIN
+# define SSIZE_MIN LONG_MIN
+# endif
#endif
+
+#if SIZEOF_TIME_T == SIZEOF_INT
+# define TIME_T_FMT "%u"
+# define TIME_T_FMT_TYPE unsigned
+# define TIME_T_ATOI (time_t)atoi
+# ifndef TIME_MAX
+# define TIME_MAX UINT_MAX
+# endif
+#else
+# define TIME_T_FMT "%lu"
+# define TIME_T_FMT_TYPE unsigned long
+# define TIME_T_ATOI (time_t)atol
+# ifndef TIME_MAX
+# define TIME_MAX ULONG_MAX
+# endif
#endif
#if SIZEOF_OFF_T > SIZEOF_LONG
-# define OFF_T_FMT LL_FMT
+# define OFF_T_FMT "%lld"
+# define OFF_T_RFMT "lld"
+# define OFF_T_FMT_TYPE long long
+# define OFF_T_ATOI (off_t)atoll
+# define OFF_T_STRTOL (off_t)strtoll
#else
-# define OFF_T_FMT "%ld"
+# if SIZEOF_OFF_T == SIZEOF_LONG
+# define OFF_T_FMT "%ld"
+# define OFF_T_RFMT "ld"
+# define OFF_T_FMT_TYPE long
+# define OFF_T_ATOI (off_t)atol
+# define OFF_T_STRTOL (off_t)strtol
+# else
+# define OFF_T_FMT "%d"
+# define OFF_T_RFMT "d"
+# define OFF_T_FMT_TYPE int
+# define OFF_T_ATOI (off_t)atoi
+# define OFF_T_STRTOL (off_t)strtol
+# endif
#endif
+#if SIZEOF_OFF_T == 8
+# ifdef OFF_MAX
+# define AM64_MAX (off_t)(OFF_MAX)
+# else
+# define AM64_MAX (off_t)(9223372036854775807LL)
+# endif
+# ifdef OFF_MIN
+# define AM64_MIN (off_t)(OFF_MIN)
+# else
+# define AM64_MIN (off_t)(-9223372036854775807LL -1LL)
+# endif
+# define AM64_FMT OFF_T_FMT
+#else
#if SIZEOF_LONG == 8
- typedef long am64_t;
# ifdef LONG_MAX
-# define AM64_MAX LONG_MAX
+# define AM64_MAX (off_t)(LONG_MAX)
# else
-# define AM64_MAX 9223372036854775807L
+# define AM64_MAX (off_t)9223372036854775807L
# endif
# ifdef LONG_MIN
-# define AM64_MIN LONG_MIN
+# define AM64_MIN (off_t)(LONG_MIN)
# else
-# define AM64_MIN -9223372036854775807L -1L
+# define AM64_MIN (off_t)(-9223372036854775807L -1L)
# endif
# define AM64_FMT "%ld"
#else
#if SIZEOF_LONG_LONG == 8
- typedef long long am64_t;
# ifdef LONG_LONG_MAX
-# define AM64_MAX LONG_LONG_MAX
+# define AM64_MAX (off_t)(LONG_LONG_MAX)
# else
-# define AM64_MAX 9223372036854775807LL
+# define AM64_MAX (off_t)9223372036854775807LL
# endif
# ifdef LONG_LONG_MIN
-# define AM64_MIN LONG_LONG_MIN
+# define AM64_MIN (off_t)(LONG_LONG_MIN)
# else
-# define AM64_MIN -9223372036854775807LL -1LL
+# define AM64_MIN (off_t)(-9223372036854775807LL -1LL)
# endif
# define AM64_FMT LL_FMT
#else
#if SIZEOF_INTMAX_T == 8
- typedef intmax_t am64_t;
# ifdef INTMAX_MAX
-# define AM64_MAX INTMAX_MAX
+# define AM64_MAX (off_t)(INTMAX_MAX)
# else
-# define AM64_MAX 9223372036854775807LL
+# define AM64_MAX (off_t)9223372036854775807LL
# endif
# ifdef INTMAX_MIN
-# define AM64_MIN INTMAX_MIN
+# define AM64_MIN (off_t)(INTMAX_MIN)
# else
-# define AM64_MIN -9223372036854775807LL -1LL
+# define AM64_MIN (off_t)(-9223372036854775807LL -1LL)
# endif
# define AM64_FMT LL_FMT
-#else
-#if SIZEOF_OFF_T == 8
- typedef off_t am64_t;
-# ifdef OFF_MAX
-# define AM64_MAX OFF_MAX
-# else
-# define AM64_MAX 9223372036854775807LL
-# endif
-# ifdef OFF_MIN
-# define AM64_MIN OFF_MIN
-# else
-# define AM64_MIN -9223372036854775807LL -1LL
-# endif
-# define AM64_FMT OFF_T_FMT
-#else /* no 64 bits tyupe found, use long. */
- typedef long am64_t;
+#else /* no 64 bits type found, use long. */
# ifdef LONG_MAX
-# define AM64_MAX LONG_MAX
+# define AM64_MAX (off_t)(LONG_MAX)
# else
-# define AM64_MAX 2147483647
+# define AM64_MAX (off_t)2147483647
# endif
# ifdef LONG_MIN
-# define AM64_MIN LONG_MIN
+# define AM64_MIN (off_t)(LONG_MIN)
# else
-# define AM64_MIN -2147483647 -1
+# define AM64_MIN (off_t)(-2147483647 -1)
# endif
# define AM64_FMT "%ld"
#endif
#endif
#endif
+#ifdef HAVE_LIBREADLINE
+# ifdef HAVE_READLINE_READLINE_H
+# include <readline/readline.h>
+# ifdef HAVE_READLINE_HISTORY_H
+# include <readline/history.h>
+# endif
+# else
+# ifdef HAVE_READLINE_H
+# include <readline.h>
+# ifdef HAVE_HISTORY_H
+# include <history.h>
+# endif
+# else
+# undef HAVE_LIBREADLINE
+# endif
+# endif
+#else
+
+char * readline(const char *prompt);
+void add_history(const char *line);
+
+#endif
+
+#define BIND_CYCLE_RETRIES 120 /* Total of 30 minutes */
+
+#define DBG_SUBDIR_SERVER "server"
+#define DBG_SUBDIR_CLIENT "client"
+#define DBG_SUBDIR_AMANDAD "amandad"
+
#endif /* !AMANDA_H */
*/
/*
- * $Id: amfeatures.c,v 1.18 2006/03/14 13:11:58 martinea Exp $
+ * $Id: amfeatures.c,v 1.24 2006/07/19 17:46:07 martinea Exp $
*
* Feature test related code.
*/
*/
am_feature_t *
-am_init_feature_set()
+am_init_feature_set(void)
{
- am_feature_t *f = NULL;
+ am_feature_t *f;
if ((f = am_allocate_feature_set()) != NULL) {
/*
am_add_feature(f, fe_amidxtaped_nargs);
am_add_feature(f, fe_amidxtaped_config);
- am_add_feature(f, fe_recover_splits);
- am_add_feature(f, fe_amidxtaped_exchange_features);
-
+ am_add_feature(f, fe_recover_splits);
+ am_add_feature(f, fe_amidxtaped_exchange_features);
am_add_feature(f, fe_partial_estimate);
am_add_feature(f, fe_calcsize_estimate);
am_add_feature(f, fe_selfcheck_calcsize);
-
am_add_feature(f, fe_options_compress_cust);
am_add_feature(f, fe_options_srvcomp_cust);
am_add_feature(f, fe_options_encrypt_cust);
am_add_feature(f, fe_options_client_decrypt_option);
am_add_feature(f, fe_options_server_decrypt_option);
- am_add_feature(f, fe_amindexd_marshall_in_OLSD);
- am_add_feature(f, fe_amindexd_marshall_in_ORLD);
- am_add_feature(f, fe_amindexd_marshall_in_DHST);
+ am_add_feature(f, fe_amindexd_marshall_in_OLSD);
+ am_add_feature(f, fe_amindexd_marshall_in_ORLD);
+ am_add_feature(f, fe_amindexd_marshall_in_DHST);
am_add_feature(f, fe_amrecover_FEEDME);
+ am_add_feature(f, fe_amrecover_timestamp);
+
+ am_add_feature(f, fe_interface_quoted_text);
+
+ am_add_feature(f, fe_program_star);
+
+ am_add_feature(f, fe_amindexd_options_hostname);
+ am_add_feature(f, fe_amindexd_options_features);
+ am_add_feature(f, fe_amindexd_options_auth);
+
+ am_add_feature(f, fe_amidxtaped_options_hostname);
+ am_add_feature(f, fe_amidxtaped_options_features);
+ am_add_feature(f, fe_amidxtaped_options_auth);
+
+ am_add_feature(f, fe_amrecover_message);
+ am_add_feature(f, fe_amrecover_feedme_tape);
+
+ am_add_feature(f, fe_req_options_config);
+
}
return f;
}
*/
am_feature_t *
-am_allocate_feature_set()
+am_allocate_feature_set(void)
{
size_t nbytes;
am_feature_t *result;
- result = (am_feature_t *)alloc(sizeof(*result));
- memset(result, 0, sizeof(*result));
+ result = (am_feature_t *)alloc(SIZEOF(*result));
+ memset(result, 0, SIZEOF(*result));
nbytes = (((size_t)last_feature) + 8) >> 3;
result->size = nbytes;
result->bytes = (unsigned char *)alloc(nbytes);
*/
void
-am_release_feature_set(f)
- am_feature_t *f;
+am_release_feature_set(
+ am_feature_t *f)
{
if (f != NULL) {
amfree(f->bytes);
*/
int
-am_add_feature(f, n)
- am_feature_t *f;
- am_feature_e n;
+am_add_feature(
+ am_feature_t *f,
+ am_feature_e n)
{
size_t byte;
int bit;
byte = ((size_t)n) >> 3;
if (byte < f->size) {
bit = ((int)n) & 0x7;
- f->bytes[byte] |= (1 << bit);
+ f->bytes[byte] = (unsigned char)((int)f->bytes[byte] | (unsigned char)(1 << bit));
result = 1;
}
}
*/
int
-am_remove_feature(f, n)
- am_feature_t *f;
- am_feature_e n;
+am_remove_feature(
+ am_feature_t *f,
+ am_feature_e n)
{
size_t byte;
int bit;
byte = ((size_t)n) >> 3;
if (byte < f->size) {
bit = ((int)n) & 0x7;
- f->bytes[byte] &= ~(1 << bit);
+ f->bytes[byte] = (unsigned char)((int)f->bytes[byte] & (unsigned char)~(1 << bit));
result = 1;
}
}
*/
int
-am_has_feature(f, n)
- am_feature_t *f;
- am_feature_e n;
+am_has_feature(
+ am_feature_t *f,
+ am_feature_e n)
{
size_t byte;
int bit;
*/
char *
-am_feature_to_string(f)
- am_feature_t *f;
+am_feature_to_string(
+ am_feature_t *f)
{
char *result;
size_t i;
*/
am_feature_t *
-am_string_to_feature(s)
- char *s;
+am_string_to_feature(
+ char *s)
{
am_feature_t *f = NULL;
size_t i;
amfree(f); /* bad conversion */
break;
}
- f->bytes[i] = (ch1 << 4) | ch2;
+ f->bytes[i] = (unsigned char)((ch1 << 4) | ch2);
}
}
return f;
#if defined(TEST)
int
-main(argc, argv)
- int argc;
- char **argv;
+main(
+ int argc,
+ char **argv)
{
am_feature_t *f;
am_feature_t *f1;
*/
/*
- * $Id: amfeatures.h,v 1.15 2006/03/14 13:11:58 martinea Exp $
+ * $Id: amfeatures.h,v 1.21 2006/07/19 17:46:07 martinea Exp $
*
* Define feature test related items.
*/
fe_amindexd_marshall_in_ORLD,
fe_amindexd_marshall_in_DHST,
fe_amrecover_FEEDME,
+ fe_amrecover_timestamp,
+
+ fe_interface_quoted_text,
+
+ fe_program_star,
+
+ fe_amindexd_options_hostname,
+ fe_amindexd_options_features,
+ fe_amindexd_options_auth,
+
+ fe_amidxtaped_options_hostname,
+ fe_amidxtaped_options_features,
+ fe_amidxtaped_options_auth,
+
+ fe_amrecover_message,
+ fe_amrecover_feedme_tape,
+
+ fe_req_options_config,
/*
* All new features must be inserted immediately *before* this entry.
/*
* Functions.
*/
-extern am_feature_t *am_init_feature_set P((void));
-extern am_feature_t *am_set_default_feature_set P((void));
-extern am_feature_t *am_allocate_feature_set P((void));
-extern void am_release_feature_set P((am_feature_t *));
-extern int am_add_feature P((am_feature_t *f, am_feature_e n));
-extern int am_remove_feature P((am_feature_t *f, am_feature_e n));
-extern int am_has_feature P((am_feature_t *f, am_feature_e n));
-extern char *am_feature_to_string P((am_feature_t *f));
-extern am_feature_t *am_string_to_feature P((char *s));
+extern am_feature_t *am_init_feature_set(void);
+extern am_feature_t *am_set_default_feature_set(void);
+extern am_feature_t *am_allocate_feature_set(void);
+extern void am_release_feature_set(am_feature_t *);
+extern int am_add_feature(am_feature_t *f, am_feature_e n);
+extern int am_remove_feature(am_feature_t *f, am_feature_e n);
+extern int am_has_feature(am_feature_t *f, am_feature_e n);
+extern char *am_feature_to_string(am_feature_t *f);
+extern am_feature_t *am_string_to_feature(char *s);
#endif /* !AMFEATURES_H */
* file named AUTHORS, in the root directory of this distribution.
*/
/*
- * $Id: amflock.c,v 1.27 2005/10/06 17:26:21 martinea Exp $
+ * $Id: amflock.c,v 1.28 2006/05/25 01:47:11 johnfranks Exp $
*
* file locking routines, put here to hide the system dependant stuff
* from the rest of the code
# endif
# if !defined(HAVE_FLOCK_DECL) && !defined(CONFIGURE_TEST)
- extern int flock P((int fd, int operation));
+ extern int flock(int fd, int operation);
# endif
#endif
** - returns errors for some non-files like pipes.
** - probably only works for files open for writing.
*/
-int use_lockf(fd, op)
-int fd; /* fd of file to operate on */
-int op; /* true to lock; false to unlock */
+int
+use_lockf(
+ int fd, /* fd of file to operate on */
+ int op) /* true to lock; false to unlock */
{
off_t pos;
/* Delete a lock file.
*/
-int delete_lock(fn)
-char *fn;
+int
+delete_lock(
+ char *fn)
{
int rc;
/* Create a lock file.
*/
-int create_lock(fn, pid)
-char *fn;
-long pid;
+int
+create_lock(
+ char *fn,
+ pid_t pid)
{
int fd;
FILE *f;
(void)delete_lock(fn); /* that's MY file! */
mask = umask(0027);
- fd = open(fn, O_WRONLY|O_CREAT|O_EXCL, 0640);
+ fd = open(fn, O_WRONLY | O_CREAT | O_EXCL, 0640);
umask(mask);
if (fd == -1) return -1;
/* Read the pid out of a lock file.
** -1=error, otherwise pid.
*/
-long read_lock(fn)
-char *fn; /* name of lock file */
+long
+read_lock(
+ char * fn) /* name of lock file */
{
int save_errno;
FILE *f;
/* Link a lock if we can.
** 0=done, 1=already locked, -1=error.
*/
-int link_lock(lk, tlk)
-char *lk; /* real lock file */
-char *tlk; /* temp lock file */
+int
+link_lock(
+ char * lk, /* real lock file */
+ char * tlk) /* temp lock file */
{
int rc;
int serrno; /* saved errno */
/* Steal a lock if we can.
** 0=done; 1=still in use; -1 = error.
*/
-int steal_lock(fn, mypid, sres)
-char *fn; /* name of lock file to steal */
-long mypid; /* my process id */
-char *sres; /* name of steal-resource to lock */
+int
+steal_lock(
+ char * fn, /* name of lock file to steal */
+ pid_t mypid, /* my process id */
+ char * sres) /* name of steal-resource to lock */
{
int fd;
char buff[64];
/* Locking using existance of a file.
*/
-int ln_lock(res, op)
-char *res; /* name of resource to lock */
-int op; /* true to lock; false to unlock */
+int
+ln_lock(
+ char * res, /* name of resource to lock */
+ int op) /* true to lock; false to unlock */
{
long mypid;
char *lockfile = NULL;
/* lock the resource */
- snprintf(pid_str, sizeof(pid_str), "%ld", mypid);
+ snprintf(pid_str, SIZEOF(pid_str), "%ld", mypid);
tlockfile = vstralloc(AMANDA_TMPDIR, "am", res, ".", pid_str, NULL);
(void)create_lock(tlockfile, mypid);
#endif
-/* Get a file lock (for read-only files).
-*/
-int amroflock(fd, resource)
-int fd;
-char *resource;
+/*
+ * Get a file lock (for read-only files).
+ */
+int
+amroflock(
+ int fd,
+ char * resource)
{
int r;
#ifdef USE_POSIX_FCNTL
+ (void)resource; /* Quiet unused paramater warning */
lock.l_type = F_RDLCK;
lock.l_whence = SEEK_SET;
r = fcntl(fd, F_SETLKW, &lock);
#else
+ (void)fd; /* Quiet unused paramater warning */
r = amflock(fd, resource);
#endif
/* Get a file lock (for read/write files).
*/
-int amflock(fd, resource)
-int fd;
-char *resource;
+int
+amflock(
+ int fd,
+ char * resource)
{
int r;
#ifdef USE_POSIX_FCNTL
+ (void)resource; /* Quiet unused paramater warning */
lock.l_type = F_WRLCK;
lock.l_whence = SEEK_SET;
r = fcntl(fd, F_SETLKW, &lock);
#else
#ifdef USE_FLOCK
+ (void)resource; /* Quiet unused paramater warning */
r = flock(fd, LOCK_EX);
#else
#ifdef USE_LOCKF
+ (void)resource; /* Quiet unused paramater warning */
r = use_lockf(fd, 1);
#else
#ifdef USE_LNLOCK
+ (void)fd; /* Quiet unused paramater warning */
r = ln_lock(resource, 1);
#else
+ (void)fd; /* Quiet unused paramater warning */
+ (void)resource; /* Quiet unused paramater warning */
r = 0;
#endif
#endif
/* Release a file lock.
*/
-int amfunlock(fd, resource)
-int fd;
-char *resource;
+int
+amfunlock(
+ int fd,
+ char * resource)
{
int r;
#ifdef USE_POSIX_FCNTL
+ (void)resource; /* Quiet unused paramater warning */
lock.l_type = F_UNLCK;
lock.l_whence = SEEK_SET;
r = fcntl(fd, F_SETLK, &lock);
#else
#ifdef USE_FLOCK
+ (void)resource; /* Quiet unused paramater warning */
r = flock(fd, LOCK_UN);
#else
#ifdef USE_LOCKF
+ (void)fd; /* Quiet unused paramater warning */
r = use_lockf(fd, 0);
#else
#ifdef USE_LNLOCK
+ (void)fd; /* Quiet unused paramater warning */
r = ln_lock(resource, 0);
#else
+ (void)fd; /* Quiet unused paramater warning */
+ (void)resource; /* Quiet unused paramater warning */
r = 0;
#endif
#endif
** for ever.
*/
#ifdef CONFIGURE_TEST
-main()
+int
+main(
+ int argc,
+ char **argv)
{
int lockfd;
char *filen = "/tmp/conftest.lock";
char *resn = "test";
int fd;
+ (void)argc; /* Quiet compiler warning */
+ (void)argv; /* Quiet compiler warning */
+
unlink(filen);
- if ((lockfd = open(filen, O_RDONLY|O_CREAT|O_EXCL, 0600)) == -1) {
+ if ((lockfd = open(filen, O_RDONLY | O_CREAT | O_EXCL, 0600)) == -1) {
perror (filen);
exit(10);
}
close(lockfd);
unlink(filen);
- if ((lockfd = open(filen, O_WRONLY|O_CREAT|O_EXCL, 0600)) == -1) {
+ if ((lockfd = open(filen, O_WRONLY | O_CREAT | O_EXCL, 0600)) == -1) {
perror (filen);
exit(20);
}
* file named AUTHORS, in the root directory of this distribution.
*/
/*
- * $Id: amregex.h,v 1.10 1999/04/10 06:18:44 kashmir Exp $
+ * $Id: amregex.h,v 1.11 2006/05/25 01:47:11 johnfranks Exp $
*
* compatibility header file for Henry Spencer's regex library.
*/
#define CHAR_BIT 8
#endif
-#if STDC_HEADERS
-# define P(parms) parms
-#else
-# define P(parms) ()
-#endif
-
/*
* So that we can use GNUC attributes (such as to get -Wall warnings
* for printf-like functions). Only do this in gcc 2.7 or later ...
#endif
#ifndef HAVE_BCOPY_DECL
-extern void bcopy P((const void *from, void *to, size_t n));
+extern void bcopy(const void *from, void *to, size_t n);
#endif
#ifndef HAVE_MEMMOVE_DECL
-extern char *memmove P((char *to, char *from, size_t n));
+extern char *memmove(char *to, char *from, size_t n);
#endif
#ifndef HAVE_MEMSET_DECL
-extern void *memset P((void *s, int c, size_t n));
+extern void *memset(void *s, int c, size_t n);
#endif
#if !defined(HAVE_MEMMOVE) && defined(HAVE_BCOPY)
#ifndef HAVE_SNPRINTF_DECL
#include "arglist.h"
-int snprintf P((char *buf, size_t len, const char *format,...))
+int snprintf (char *buf, size_t len, const char *format,...)
__attribute__((format(printf,3,4)));
#endif
#ifndef HAVE_VSNPRINTF_DECL
#include "arglist.h"
-int vsnprintf P((char *buf, size_t len, const char *format, va_list ap));
+int vsnprintf(char *buf, size_t len, const char *format, va_list ap);
#endif
#define POSIX_MISTAKE
* file named AUTHORS, in the root directory of this distribution.
*/
/*
- * $Id: arglist.h,v 1.7 2002/12/03 21:36:39 martinea Exp $
+ * $Id: arglist.h,v 1.9 2006/06/16 11:33:43 martinea Exp $
*
* support macros for variable argument list declaration and definition
*/
arg2_type arg2_name, \
hook_type hook_name, ...)
+#define printf_arglist_function3(fdecl, \
+ arg1_type, arg1_name, \
+ arg2_type, arg2_name, \
+ arg3_type, arg3_name, \
+ hook_type, hook_name) \
+ __attribute__ ((format (printf, 4, 0))) \
+ fdecl(arg1_type arg1_name, \
+ arg2_type arg2_name, \
+ arg3_type arg3_name, \
+ hook_type hook_name, ...)
+
#define arglist_function(fdecl, \
hook_type, hook_name) \
fdecl(hook_type hook_name, ...)
* file named AUTHORS, in the root directory of this distribution.
*/
/*
- * $Id: bsd-security.c,v 1.54 2006/03/09 16:51:41 martinea Exp $
+ * $Id: bsd-security.c,v 1.75 2006/07/19 17:41:14 martinea Exp $
*
* "BSD" security module
*/
#include "event.h"
#include "packet.h"
#include "security.h"
+#include "security-util.h"
#include "stream.h"
#include "version.h"
#define bsdprintf(p) printf p
#endif /* } */
-/*
- * This is the private handle data
- */
-struct bsd_handle {
- /*
- * This must be first. Instances of bsd_handle will be cast to
- * security_handle_t's.
- */
- security_handle_t sech;
-
- /*
- * protocol handle for this request. Each request gets its own
- * handle, so we differentiate packets for them with a "handle" header
- * in each packet.
- *
- */
- int event_id; /* unique event_id */
- char *proto_handle;
-
- /*
- * sequence number.
- */
- int sequence;
-
- /*
- * The remote host we're transmitting to
- */
- char hostname[256];
- struct sockaddr_in peer;
-
- /*
- * Function to call when recvpkt detects new incoming data for this
- * handle
- */
- void (*fn) P((void *, pkt_t *, security_status_t));
-
- /*
- * Argument for previous function
- */
- void *arg;
-
- /*
- * read (EV_WAIT) handle for a recv
- */
- event_handle_t *ev_read;
-
- /*
- * Timeout handle for a recv
- */
- event_handle_t *ev_timeout;
-
- struct bsd_handle *prev, *next;
-};
-
-struct bsd_handle *bh_first=NULL, *bh_last=NULL;
-
-/*
- * This is the internal security_stream data
- */
-struct bsd_stream {
- /*
- * This must be first, because instances of this will be cast
- * to security_stream_t's outside of this module.
- */
- security_stream_t secstr;
-
- /*
- * This is the file descriptor which we will do io on
- */
- int fd;
-
- /*
- * This is the file descriptor which we will listen for incoming
- * connections on (for streams which receive connections)
- */
- int socket;
-
- /*
- * This is the local port this stream is bound to
- */
- int port;
-
- /*
- * This is the read event handle for this data stream
- */
- event_handle_t *ev_read;
-
- /*
- * This is the function and argument that is called when this stream
- * is readable. It is passed a buffer of data read.
- */
- void (*fn) P((void *, void *, ssize_t));
- void *arg;
-
- /*
- * This is the buffer that we read data into that will be passed
- * to the read callback.
- */
- char databuf[NETWORK_BLOCK_BYTES];
-};
-
/*
* Interface functions
*/
-static void bsd_connect P((const char *,
- char *(*)(char *, void *),
- void (*)(void *, security_handle_t *, security_status_t), void *));
-static void bsd_accept P((int, int, void (*)(security_handle_t *, pkt_t *)));
-static void bsd_close P((void *));
-static int bsd_sendpkt P((void *, pkt_t *));
-static void bsd_recvpkt P((void *,
- void (*)(void *, pkt_t *, security_status_t), void *, int));
-static void bsd_recvpkt_cancel P((void *));
-
-static void *bsd_stream_server P((void *));
-static int bsd_stream_accept P((void *));
-static void *bsd_stream_client P((void *, int));
-static void bsd_stream_close P((void *));
-static int bsd_stream_auth P((void *));
-static int bsd_stream_id P((void *));
-static int bsd_stream_write P((void *, const void *, size_t));
-static void bsd_stream_read P((void *, void (*)(void *, void *, ssize_t),
- void *));
-static void bsd_stream_read_cancel P((void *));
+static void bsd_connect(const char *, char *(*)(char *, void *),
+ void (*)(void *, security_handle_t *, security_status_t),
+ void *, void *);
+static void bsd_accept(const struct security_driver *, int, int,
+ void (*)(security_handle_t *, pkt_t *));
+static void bsd_close(void *);
+static void * bsd_stream_server(void *);
+static int bsd_stream_accept(void *);
+static void * bsd_stream_client(void *, int);
+static void bsd_stream_close(void *);
+static int bsd_stream_auth(void *);
+static int bsd_stream_id(void *);
+static void bsd_stream_read(void *, void (*)(void *, void *, ssize_t), void *);
+static ssize_t bsd_stream_read_sync(void *, void **);
+static void bsd_stream_read_cancel(void *);
/*
* This is our interface to the outside world
bsd_connect,
bsd_accept,
bsd_close,
- bsd_sendpkt,
- bsd_recvpkt,
- bsd_recvpkt_cancel,
+ udpbsd_sendpkt,
+ udp_recvpkt,
+ udp_recvpkt_cancel,
bsd_stream_server,
bsd_stream_accept,
bsd_stream_client,
bsd_stream_close,
bsd_stream_auth,
bsd_stream_id,
- bsd_stream_write,
+ tcp_stream_write,
bsd_stream_read,
+ bsd_stream_read_sync,
bsd_stream_read_cancel,
+ sec_close_connection_none,
};
/*
* This is data local to the datagram socket. We have one datagram
* per process, so it is global.
*/
-static struct {
- dgram_t dgram; /* datagram to read/write from */
- struct sockaddr_in peer; /* who sent it to us */
- pkt_t pkt; /* parsed form of dgram */
- char *handle; /* handle from recvd packet */
- int sequence; /* seq no of packet */
- event_handle_t *ev_read; /* read event handle from dgram */
- int refcnt; /* number of handles blocked for reading */
-} netfd;
+static udp_handle_t netfd;
+static int not_init = 1;
/* generate new handles from here */
static int newhandle = 0;
-static int newevent = 0;
-
-/*
- * We register one event handler for our network fd which takes
- * care of all of our async requests. When all async requests
- * have either been satisfied or cancelled, we unregister our
- * network event handler.
- */
-#define netfd_addref() do { \
- if (netfd.refcnt++ == 0) { \
- assert(netfd.ev_read == NULL); \
- netfd.ev_read = event_register(netfd.dgram.socket, EV_READFD, \
- netfd_read_callback, NULL); \
- } \
- assert(netfd.refcnt > 0); \
-} while (0)
-
-/*
- * If this is the last request to be removed, then remove the
- * reader event from the netfd.
- */
-#define netfd_delref() do { \
- assert(netfd.refcnt > 0); \
- if (--netfd.refcnt == 0) { \
- assert(netfd.ev_read != NULL); \
- event_release(netfd.ev_read); \
- netfd.ev_read = NULL; \
- } \
-} while (0)
-
-/*
- * This is the function and argument that is called when new requests
- * arrive on the netfd.
- */
-static void (*accept_fn) P((security_handle_t *, pkt_t *));
/*
* These are the internal helper functions
*/
-static char *check_user P((struct bsd_handle *, const char *));
-static int inithandle P((struct bsd_handle *, struct hostent *,
- int, char *, int));
-static const char *pkthdr2str P((const struct bsd_handle *, const pkt_t *));
-static int str2pkthdr P((void));
-static void netfd_read_callback P((void *));
-static void recvpkt_callback P((void *));
-static void recvpkt_timeout P((void *));
-static int recv_security_ok P((struct bsd_handle *));
-static void stream_read_callback P((void *));
-
-
-#if defined(SHOW_SECURITY_DETAIL) /* { */
-/*
- * Display stat() information about a file.
- */
-void show_stat_info(a, b)
- char *a, *b;
-{
- char *name = vstralloc(a, b, NULL);
- struct stat sbuf;
- struct passwd *pwptr;
- char *owner;
- struct group *grptr;
- char *group;
-
- if (stat(name, &sbuf) != 0) {
- bsdprintf(("%s: cannot stat %s: %s\n",
- debug_prefix_time(NULL), name, strerror(errno)));
- amfree(name);
- return;
- }
- if ((pwptr = getpwuid(sbuf.st_uid)) == NULL) {
- owner = alloc(NUM_STR_SIZE + 1);
- snprintf(owner, NUM_STR_SIZE, "%ld", (long)sbuf.st_uid);
- } else {
- owner = stralloc(pwptr->pw_name);
- }
- if ((grptr = getgrgid(sbuf.st_gid)) == NULL) {
- group = alloc(NUM_STR_SIZE + 1);
- snprintf(owner, NUM_STR_SIZE, "%ld", (long)sbuf.st_gid);
- } else {
- group = stralloc(grptr->gr_name);
- }
- bsdprintf(("%s: processing file: %s\n", debug_prefix(NULL), name));
- bsdprintf(("%s: owner=%s group=%s mode=%03o\n",
- debug_prefix(NULL), owner, group, (int) (sbuf.st_mode & 0777)));
- amfree(name);
- amfree(owner);
- amfree(group);
-}
-#endif /* } */
+static void stream_read_callback(void *);
+static void stream_read_sync_callback(void *);
/*
* Setup and return a handle outgoing to a client
*/
+
static void
-bsd_connect(hostname, conf_fn, fn, arg)
- const char *hostname;
- char *(*conf_fn) P((char *, void *));
- void (*fn) P((void *, security_handle_t *, security_status_t));
- void *arg;
-{
- struct bsd_handle *bh;
+bsd_connect(
+ const char * hostname,
+ char * (*conf_fn)(char *, void *),
+ void (*fn)(void *, security_handle_t *, security_status_t),
+ void * arg,
+ void * datap)
+{
+ struct sec_handle *bh;
struct servent *se;
struct hostent *he;
- int port;
+ in_port_t port = 0;
struct timeval sequence_time;
amanda_timezone dontcare;
int sequence;
assert(hostname != NULL);
- bh = alloc(sizeof(*bh));
+ (void)conf_fn; /* Quiet unused parameter warning */
+ (void)datap; /* Quiet unused parameter warning */
+
+ bh = alloc(SIZEOF(*bh));
bh->proto_handle=NULL;
+ bh->udp = &netfd;
security_handleinit(&bh->sech, &bsd_security_driver);
/*
* Only init the socket once
*/
- if (netfd.dgram.socket == 0) {
+ if (not_init == 1) {
uid_t euid;
dgram_zero(&netfd.dgram);
-
+
euid = geteuid();
- seteuid(0);
+ seteuid((uid_t)0);
dgram_bind(&netfd.dgram, &port);
seteuid(euid);
+ netfd.handle = NULL;
+ netfd.pkt.body = NULL;
+ netfd.recv_security_ok = &bsd_recv_security_ok;
+ netfd.prefix_packet = &bsd_prefix_packet;
/*
* We must have a reserved port. Bomb if we didn't get one.
*/
if (port >= IPPORT_RESERVED) {
security_seterror(&bh->sech,
- "unable to bind to a reserved port (got port %d)",
- port);
+ "unable to bind to a reserved port (got port %u)",
+ (unsigned int)port);
(*fn)(arg, &bh->sech, S_ERROR);
return;
}
+ not_init = 0;
}
if ((he = gethostbyname(hostname)) == NULL) {
(*fn)(arg, &bh->sech, S_ERROR);
return;
}
+ bsdprintf(("Resolved hostname=%s\n", hostname));
if ((se = getservbyname(AMANDA_SERVICE_NAME, "udp")) == NULL)
- port = htons(AMANDA_SERVICE_DEFAULT);
+ port = (in_port_t)htons(AMANDA_SERVICE_DEFAULT);
else
- port = se->s_port;
+ port = (in_port_t)se->s_port;
amanda_gettimeofday(&sequence_time, &dontcare);
sequence = (int)sequence_time.tv_sec ^ (int)sequence_time.tv_usec;
- handle=malloc(15);
- snprintf(handle,14,"000-%08x", newhandle++);
- if (inithandle(bh, he, port, handle, sequence) < 0)
+ handle=alloc(15);
+ snprintf(handle, 14, "000-%08x", (unsigned)newhandle++);
+ if (udp_inithandle(&netfd, bh, he, port, handle, sequence) < 0) {
(*fn)(arg, &bh->sech, S_ERROR);
+ amfree(bh->hostname);
+ amfree(bh);
+ }
else
(*fn)(arg, &bh->sech, S_OK);
+ amfree(handle);
}
/*
* Setup to accept new incoming connections
*/
static void
-bsd_accept(in, out, fn)
- int in, out;
- void (*fn) P((security_handle_t *, pkt_t *));
+bsd_accept(
+ const struct security_driver * driver,
+ int in,
+ int out,
+ void (*fn)(security_handle_t *, pkt_t *))
{
assert(in >= 0 && out >= 0);
assert(fn != NULL);
+ (void)out; /* Quiet unused parameter warning */
+ (void)driver; /* Quiet unused parameter warning */
+
/*
* We assume in and out point to the same socket, and just use
* in.
* the recvpkt callback will call this function when it discovers
* new incoming connections
*/
- accept_fn = fn;
-
- netfd_addref();
-}
-
-/*
- * Given a hostname and a port, setup a bsd_handle
- */
-static int
-inithandle(bh, he, port, handle, sequence)
- struct bsd_handle *bh;
- struct hostent *he;
- int port;
- char *handle;
- int sequence;
-{
- int i;
-
- assert(he != NULL);
- assert(port > 0);
-
- /*
- * Save the hostname and port info
- */
- strncpy(bh->hostname, he->h_name, sizeof(bh->hostname) - 1);
- bh->hostname[sizeof(bh->hostname) - 1] = '\0';
- bh->peer.sin_addr = *(struct in_addr *)he->h_addr;
- bh->peer.sin_port = port;
- bh->peer.sin_family = AF_INET;
-
- bh->prev = bh_last;
- if(bh_last) {bh->prev->next = bh;}
- if(!bh_first) {bh_first = bh;}
- bh->next = NULL;
- bh_last = bh;
-
- /*
- * Do a forward lookup of the hostname. This is unnecessary if we
- * are initiating the connection, but is very serious if we are
- * receiving. We want to make sure the hostname
- * resolves back to the remote ip for security reasons.
- */
- if ((he = gethostbyname(bh->hostname)) == NULL) {
- security_seterror(&bh->sech,
- "%s: could not resolve hostname", bh->hostname);
- return (-1);
- }
- /*
- * Make sure the hostname matches. This should always work.
- */
- if (strncasecmp(bh->hostname, he->h_name, strlen(bh->hostname)) != 0) {
- security_seterror(&bh->sech,
- "%s: did not resolve to %s", bh->hostname, bh->hostname);
- return (-1);
- }
-
- /*
- * Now look for a matching ip address.
- */
- for (i = 0; he->h_addr_list[i] != NULL; i++) {
- if (memcmp(&bh->peer.sin_addr, he->h_addr_list[i],
- sizeof(struct in_addr)) == 0) {
- break;
- }
- }
-
- /*
- * If we didn't find it, try the aliases. This is a workaround for
- * Solaris if DNS goes over NIS.
- */
- if (he->h_addr_list[i] == NULL) {
- const char *ipstr = inet_ntoa(bh->peer.sin_addr);
- for (i = 0; he->h_aliases[i] != NULL; i++) {
- if (strcmp(he->h_aliases[i], ipstr) == 0)
- break;
- }
- /*
- * No aliases either. Failure. Someone is fooling with us or
- * DNS is messed up.
- */
- if (he->h_aliases[i] == NULL) {
- security_seterror(&bh->sech,
- "DNS check failed: no matching ip address for %s",
- bh->hostname);
- return (-1);
- }
- }
-
- bh->sequence = sequence;
- bh->event_id = newevent++;
- bh->proto_handle = handle;
- bh->fn = NULL;
- bh->arg = NULL;
- bh->ev_read = NULL;
- bh->ev_timeout = NULL;
-
- bsdprintf(("%s: adding handle '%s'\n",
- debug_prefix_time(NULL), bh->proto_handle));
+ netfd.accept_fn = fn;
+ netfd.recv_security_ok = &bsd_recv_security_ok;
+ netfd.prefix_packet = &bsd_prefix_packet;
+ netfd.driver = &bsd_security_driver;
- return(0);
+ udp_addref(&netfd, &udp_netfd_read_callback);
}
/*
* Frees a handle allocated by the above
*/
static void
-bsd_close(cookie)
- void *cookie;
+bsd_close(
+ void * cookie)
{
- struct bsd_handle *bh = cookie;
+ struct sec_handle *bh = cookie;
if(bh->proto_handle == NULL) {
return;
}
- bsdprintf(("%s: close handle '%s'\n",
+ bsdprintf(("%s: bsd: close handle '%s'\n",
debug_prefix_time(NULL), bh->proto_handle));
- bsd_recvpkt_cancel(bh);
+ udp_recvpkt_cancel(bh);
if(bh->next) {
bh->next->prev = bh->prev;
}
else {
- bh_last = bh->prev;
+ netfd.bh_last = bh->prev;
}
if(bh->prev) {
bh->prev->next = bh->next;
}
else {
- bh_first = bh->next;
+ netfd.bh_first = bh->next;
}
+ amfree(bh->proto_handle);
+ amfree(bh->hostname);
amfree(bh);
}
-/*
- * Transmit a packet. Add security information first.
- */
-static int
-bsd_sendpkt(cookie, pkt)
- void *cookie;
- pkt_t *pkt;
-{
- struct bsd_handle *bh = cookie;
- struct passwd *pwd;
-
- assert(bh != NULL);
- assert(pkt != NULL);
-
- /*
- * Initialize this datagram, and add the header
- */
- dgram_zero(&netfd.dgram);
- dgram_cat(&netfd.dgram, pkthdr2str(bh, pkt));
-
- /*
- * Add the security info. This depends on which kind of packet we're
- * sending.
- */
- switch (pkt->type) {
- case P_REQ:
- /*
- * Requests get sent with our username in the body
- */
- if ((pwd = getpwuid(geteuid())) == NULL) {
- security_seterror(&bh->sech,
- "can't get login name for my uid %ld", (long)getuid());
- return (-1);
- }
- dgram_cat(&netfd.dgram, "SECURITY USER %s\n", pwd->pw_name);
- break;
-
- default:
- break;
- }
-
- /*
- * Add the body, and send it
- */
- dgram_cat(&netfd.dgram, pkt->body);
- if (dgram_send_addr(bh->peer, &netfd.dgram) != 0) {
- security_seterror(&bh->sech,
- "send %s to %s failed: %s", pkt_type2str(pkt->type),
- bh->hostname, strerror(errno));
- return (-1);
- }
- return (0);
-}
-
-/*
- * Set up to receive a packet asynchronously, and call back when it has
- * been read.
- */
-static void
-bsd_recvpkt(cookie, fn, arg, timeout)
- void *cookie, *arg;
- void (*fn) P((void *, pkt_t *, security_status_t));
- int timeout;
-{
- struct bsd_handle *bh = cookie;
-
- assert(bh != NULL);
- assert(fn != NULL);
-
-
- /*
- * Subsequent recvpkt calls override previous ones
- */
- if (bh->ev_read == NULL) {
- netfd_addref();
- bh->ev_read = event_register(bh->event_id, EV_WAIT,
- recvpkt_callback, bh);
- }
- if (bh->ev_timeout != NULL)
- event_release(bh->ev_timeout);
- if (timeout < 0)
- bh->ev_timeout = NULL;
- else
- bh->ev_timeout = event_register(timeout, EV_TIME, recvpkt_timeout, bh);
- bh->fn = fn;
- bh->arg = arg;
-}
-
-/*
- * Remove a async receive request on this handle from the queue.
- * If it is the last one to be removed, then remove the event
- * handler for our network fd
- */
-static void
-bsd_recvpkt_cancel(cookie)
- void *cookie;
-{
- struct bsd_handle *bh = cookie;
-
- assert(bh != NULL);
-
- if (bh->ev_read != NULL) {
- netfd_delref();
- event_release(bh->ev_read);
- bh->ev_read = NULL;
- }
-
- if (bh->ev_timeout != NULL) {
- event_release(bh->ev_timeout);
- bh->ev_timeout = NULL;
- }
-}
-
-/*
- * Callback for received packets. This is the function bsd_recvpkt
- * registers with the event handler. It is called when the event handler
- * realizes that data is waiting to be read on the network socket.
- */
-static void
-netfd_read_callback(cookie)
- void *cookie;
-{
- struct bsd_handle *bh;
- struct hostent *he;
- int a;
-
- assert(cookie == NULL);
-
-#ifndef TEST /* { */
- /*
- * Receive the packet.
- */
- dgram_zero(&netfd.dgram);
- if (dgram_recv(&netfd.dgram, 0, &netfd.peer) < 0)
- return;
-#endif /* !TEST */ /* } */
-
- /*
- * Parse the packet.
- */
- if (str2pkthdr() < 0)
- return;
-
- /*
- * If there are events waiting on this handle, we're done
- */
- bh = bh_first;
- while(bh != NULL && (strcmp(bh->proto_handle, netfd.handle) != 0 ||
- bh->sequence != netfd.sequence ||
- bh->peer.sin_addr.s_addr != netfd.peer.sin_addr.s_addr ||
- bh->peer.sin_port != netfd.peer.sin_port)) {
- bh = bh->next;
- }
- if (bh && event_wakeup(bh->event_id) > 0)
- return;
-
- /*
- * If we didn't find a handle, then check for a new incoming packet.
- * If no accept handler was setup, then just return.
- */
- if (accept_fn == NULL)
- return;
-
- he = gethostbyaddr((void *)&netfd.peer.sin_addr,
- (int)sizeof(netfd.peer.sin_addr), AF_INET);
- if (he == NULL)
- return;
- bh = alloc(sizeof(*bh));
- bh->proto_handle=NULL;
- security_handleinit(&bh->sech, &bsd_security_driver);
- a = inithandle(bh,
- he,
- netfd.peer.sin_port,
- netfd.handle,
- netfd.sequence);
- if (a < 0) {
- if(bh->next) {
- bh->next->prev = bh->prev;
- }
- else {
- bh_last = bh->prev;
- }
- if(bh->prev) {
- bh->prev->next = bh->next;
- }
- else {
- bh_first = bh->prev;
- }
-
- bsdprintf(("%s: closeX handle '%s'\n",
- debug_prefix_time(NULL), bh->proto_handle));
-
- amfree(bh);
- return;
- }
- /*
- * Check the security of the packet. If it is bad, then pass NULL
- * to the accept function instead of a packet.
- */
- if (recv_security_ok(bh) < 0)
- (*accept_fn)(&bh->sech, NULL);
- else
- (*accept_fn)(&bh->sech, &netfd.pkt);
-}
-
-/*
- * This is called when a handle is woken up because data read off of the
- * net is for it.
- */
-static void
-recvpkt_callback(cookie)
- void *cookie;
-{
- struct bsd_handle *bh = cookie;
- void (*fn) P((void *, pkt_t *, security_status_t));
- void *arg;
-
- assert(bh != NULL);
- bsdprintf(("%s: receive handle '%s' netfd '%s'\n",
- debug_prefix_time(NULL), bh->proto_handle,netfd.handle));
-
- if(strcmp(bh->proto_handle,netfd.handle) != 0) assert(1);
-
- /* if it didn't come from the same host/port, forget it */
- if (memcmp(&bh->peer.sin_addr, &netfd.peer.sin_addr,
- sizeof(netfd.peer.sin_addr)) != 0 ||
- bh->peer.sin_port != netfd.peer.sin_port) {
- netfd.handle = NULL;
- return;
- }
-
- /*
- * We need to cancel the recvpkt request before calling the callback
- * because the callback may reschedule us.
- */
- fn = bh->fn;
- arg = bh->arg;
- bsd_recvpkt_cancel(bh);
-
- /*
- * Check the security of the packet. If it is bad, then pass NULL
- * to the packet handling function instead of a packet.
- */
- if (recv_security_ok(bh) < 0)
- (*fn)(arg, NULL, S_ERROR);
- else
- (*fn)(arg, &netfd.pkt, S_OK);
-}
-
-/*
- * This is called when a handle times out before receiving a packet.
- */
-static void
-recvpkt_timeout(cookie)
- void *cookie;
-{
- struct bsd_handle *bh = cookie;
- void (*fn) P((void *, pkt_t *, security_status_t));
- void *arg;
-
- assert(bh != NULL);
-
- assert(bh->ev_timeout != NULL);
- fn = bh->fn;
- arg = bh->arg;
- bsd_recvpkt_cancel(bh);
- (*fn)(arg, NULL, S_TIMEOUT);
-
-}
-
-/*
- * Check the security of a received packet. Returns negative on security
- * violation, or returns 0 if ok. Removes the security info from the pkt_t.
- */
-static int
-recv_security_ok(bh)
- struct bsd_handle *bh;
-{
- char *tok, *security, *body, *result;
- pkt_t *pkt = &netfd.pkt;
-
- /*
- * Set this preempively before we mangle the body.
- */
- security_seterror(&bh->sech,
- "bad SECURITY line: '%s'", pkt->body);
-
- /*
- * Now, find the SECURITY line in the body, and parse it out
- * into an argv.
- */
- if (strncmp(pkt->body, "SECURITY", sizeof("SECURITY") - 1) == 0) {
- tok = strtok(pkt->body, " ");
- assert(strcmp(tok, "SECURITY") == 0);
- /* security info goes until the newline */
- security = strtok(NULL, "\n");
- body = strtok(NULL, "");
- /*
- * If the body is f-ked, then try to recover
- */
- if (body == NULL) {
- if (security != NULL)
- body = security + strlen(security) + 2;
- else
- body = pkt->body;
- }
- } else {
- security = NULL;
- body = pkt->body;
- }
-
- /*
- * We need to do different things depending on which type of packet
- * this is.
- */
- switch (pkt->type) {
- case P_REQ:
- /*
- * Request packets must come from a reserved port
- */
- if (ntohs(bh->peer.sin_port) >= IPPORT_RESERVED) {
- security_seterror(&bh->sech,
- "host %s: port %d not secure", bh->hostname,
- ntohs(bh->peer.sin_port));
- return (-1);
- }
-
- /*
- * Request packets contain a remote username. We need to check
- * that we allow it in.
- *
- * They will look like:
- * SECURITY USER [username]
- */
-
- /* there must be some security info */
- if (security == NULL) {
- security_seterror(&bh->sech,
- "no bsd SECURITY for P_REQ");
- return (-1);
- }
-
- /* second word must be USER */
- if ((tok = strtok(security, " ")) == NULL)
- return (-1); /* default errmsg */
- if (strcmp(tok, "USER") != 0) {
- security_seterror(&bh->sech,
- "REQ SECURITY line parse error, expecting USER, got %s", tok);
- return (-1);
- }
-
- /* the third word is the username */
- if ((tok = strtok(NULL, "")) == NULL)
- return (-1); /* default errmsg */
- if ((result = check_user(bh, tok)) != NULL) {
- security_seterror(&bh->sech, "%s", result);
- amfree(result);
- return (-1);
- }
-
- /* we're good to go */
- break;
- default:
- break;
- }
-
- /*
- * If there is security info at the front of the packet, we need to
- * shift the rest of the data up and nuke it.
- */
- if (body != pkt->body)
- memmove(pkt->body, body, strlen(body) + 1);
- return (0);
-}
-
-static char *
-check_user(bh, remoteuser)
- struct bsd_handle *bh;
- const char *remoteuser;
-{
- struct passwd *pwd;
- char *r;
- char *result = NULL;
- char *localuser = NULL;
-
- /* lookup our local user name */
- if ((pwd = getpwnam(CLIENT_LOGIN)) == NULL) {
- return vstralloc("getpwnam(", CLIENT_LOGIN, ") fails", NULL);
- }
-
- /*
- * Make a copy of the user name in case getpw* is called by
- * any of the lower level routines.
- */
- localuser = stralloc(pwd->pw_name);
-
-#ifndef USE_AMANDAHOSTS
- r = check_user_ruserok(bh->hostname, pwd, remoteuser);
-#else
- r = check_user_amandahosts(bh->hostname, pwd, remoteuser);
-#endif
- if (r != NULL) {
- result = vstralloc("access as ", localuser, " not allowed",
- " from ", remoteuser, "@", bh->hostname,
- ": ", r,
- NULL);
- amfree(r);
- }
- amfree(localuser);
- return result;
-}
-
-/*
- * See if a remote user is allowed in. This version uses ruserok()
- * and friends.
- *
- * Returns 0 on success, or negative on error.
- */
-char *
-check_user_ruserok(host, pwd, remoteuser)
- const char *host;
- struct passwd *pwd;
- const char *remoteuser;
-{
- int saved_stderr;
- int fd[2];
- FILE *fError;
- amwait_t exitcode;
- pid_t ruserok_pid;
- pid_t pid;
- char *es;
- char *result;
- int ok;
- char number[NUM_STR_SIZE];
- uid_t myuid = getuid();
-
- /*
- * note that some versions of ruserok (eg SunOS 3.2) look in
- * "./.rhosts" rather than "~CLIENT_LOGIN/.rhosts", so we have to
- * chdir ourselves. Sigh.
- *
- * And, believe it or not, some ruserok()'s try an initgroup just
- * for the hell of it. Since we probably aren't root at this point
- * it'll fail, and initgroup "helpfully" will blatt "Setgroups: Not owner"
- * into our stderr output even though the initgroup failure is not a
- * problem and is expected. Thanks a lot. Not.
- */
- if (pipe(fd) != 0) {
- return stralloc2("pipe() fails: ", strerror(errno));
- }
- if ((ruserok_pid = fork()) < 0) {
- return stralloc2("fork() fails: ", strerror(errno));
- } else if (ruserok_pid == 0) {
- int ec;
-
- close(fd[0]);
- fError = fdopen(fd[1], "w");
- /* pamper braindead ruserok's */
- if (chdir(pwd->pw_dir) != 0) {
- fprintf(fError, "chdir(%s) failed: %s",
- pwd->pw_dir, strerror(errno));
- fclose(fError);
- exit(1);
- }
-
-#if defined(SHOW_SECURITY_DETAIL) /* { */
- {
- char *dir = stralloc(pwd->pw_dir);
-
- bsdprintf(("%s: calling ruserok(%s, %d, %s, %s)\n",
- debug_prefix_time(NULL),
- host, myuid == 0, remoteuser, pwd->pw_name));
- if (myuid == 0) {
- bsdprintf(("%s: because you are running as root, ",
- debug_prefix(NULL)));
- bsdprintf(("/etc/hosts.equiv will not be used\n"));
- } else {
- show_stat_info("/etc/hosts.equiv", NULL);
- }
- show_stat_info(dir, "/.rhosts");
- amfree(dir);
- }
-#endif /* } */
-
- saved_stderr = dup(2);
- close(2);
- if (open("/dev/null", O_RDWR) == -1) {
- dbprintf(("Could not open /dev/null: %s\n",
- strerror(errno)));
- ec = 1;
- } else {
- ok = ruserok(host, myuid == 0, remoteuser, CLIENT_LOGIN);
- if (ok < 0) {
- ec = 1;
- } else {
- ec = 0;
- }
- }
- (void)dup2(saved_stderr,2);
- close(saved_stderr);
- exit(ec);
- }
- close(fd[1]);
- fError = fdopen(fd[0], "r");
-
- result = NULL;
- while ((es = agets(fError)) != NULL) {
- if (result == NULL) {
- result = stralloc("");
- } else {
- strappend(result, ": ");
- }
- strappend(result, es);
- }
- close(fd[0]);
-
- while (1) {
- if ((pid = wait(&exitcode)) == (pid_t) -1) {
- if (errno == EINTR) {
- continue;
- }
- amfree(result);
- return stralloc2("ruserok wait failed: %s", strerror(errno));
- }
- if (pid == ruserok_pid) {
- break;
- }
- }
- if (WIFSIGNALED(exitcode)) {
- amfree(result);
- snprintf(number, sizeof(number), "%d", WTERMSIG(exitcode));
- return stralloc2("ruserok child got signal ", number);
- }
- if (WEXITSTATUS(exitcode) == 0) {
- amfree(result);
- } else if (result == NULL) {
- result = stralloc("ruserok failed");
- }
-
- return result;
-}
-
-/*
- * Check to see if a user is allowed in. This version uses .amandahosts
- * Returns -1 on failure, or 0 on success.
- */
-char *
-check_user_amandahosts(host, pwd, remoteuser)
- const char *host;
- struct passwd *pwd;
- const char *remoteuser;
-{
- char *line = NULL;
- char *filehost;
- const char *fileuser;
- char *ptmp = NULL;
- char *result = NULL;
- FILE *fp = NULL;
- int found;
- struct stat sbuf;
- char n1[NUM_STR_SIZE];
- char n2[NUM_STR_SIZE];
- int hostmatch;
- int usermatch;
- uid_t localuid;
- char *localuser = NULL;
-
- /*
- * Save copies of what we need from the passwd structure in case
- * any other code calls getpw*.
- */
- localuid = pwd->pw_uid;
- localuser = stralloc(pwd->pw_name);
-
- ptmp = stralloc2(pwd->pw_dir, "/.amandahosts");
-#if defined(SHOW_SECURITY_DETAIL) /* { */
- show_stat_info(ptmp, "");;
-#endif /* } */
- if ((fp = fopen(ptmp, "r")) == NULL) {
- result = vstralloc("cannot open ", ptmp, ": ", strerror(errno), NULL);
- amfree(ptmp);
- amfree(localuser);
- return result;
- }
-
- /*
- * Make sure the file is owned by the Amanda user and does not
- * have any group/other access allowed.
- */
- if (fstat(fileno(fp), &sbuf) != 0) {
- result = vstralloc("cannot fstat ", ptmp, ": ", strerror(errno), NULL);
- goto common_exit;
- }
- if (sbuf.st_uid != localuid) {
- snprintf(n1, sizeof(n1), "%ld", (long)sbuf.st_uid);
- snprintf(n2, sizeof(n2), "%ld", (long)localuid);
- result = vstralloc(ptmp, ": ",
- "owned by id ", n1,
- ", should be ", n2,
- NULL);
- goto common_exit;
- }
- if ((sbuf.st_mode & 077) != 0) {
- result = stralloc2(ptmp,
- ": incorrect permissions; file must be accessible only by its owner");
- goto common_exit;
- }
-
- /*
- * Now, scan the file for the host/user.
- */
- found = 0;
- while ((line = agets(fp)) != NULL) {
-#if defined(SHOW_SECURITY_DETAIL) /* { */
- bsdprintf(("%s: processing line: <%s>\n", debug_prefix(NULL), line));
-#endif /* } */
- /* get the host out of the file */
- if ((filehost = strtok(line, " \t")) == NULL) {
- amfree(line);
- continue;
- }
-
- /* get the username. If no user specified, then use the local user */
- if ((fileuser = strtok(NULL, " \t")) == NULL) {
- fileuser = localuser;
- }
-
- hostmatch = (strcasecmp(filehost, host) == 0);
- usermatch = (strcasecmp(fileuser, remoteuser) == 0);
-#if defined(SHOW_SECURITY_DETAIL) /* { */
- bsdprintf(("%s: comparing \"%s\" with\n", debug_prefix(NULL), filehost));
- bsdprintf(("%s: \"%s\" (%s)\n", host,
- debug_prefix(NULL), hostmatch ? "match" : "no match"));
- bsdprintf(("%s: and \"%s\" with\n", fileuser, debug_prefix(NULL)));
- bsdprintf(("%s: \"%s\" (%s)\n", remoteuser,
- debug_prefix(NULL), usermatch ? "match" : "no match"));
-#endif /* } */
- amfree(line);
- /* compare */
- if (hostmatch && usermatch) {
- /* success */
- found = 1;
- break;
- }
- }
- if (! found) {
- result = vstralloc(ptmp, ": ",
- "\"", host, " ", remoteuser, "\"",
- " entry not found",
- NULL);
- }
-
-common_exit:
-
- afclose(fp);
- amfree(ptmp);
- amfree(line);
- amfree(localuser);
-
- return result;
-}
-
-/* return 1 on success, 0 on failure */
-int
-check_security(addr, str, cksum, errstr)
-struct sockaddr_in *addr;
-char *str;
-unsigned long cksum;
-char **errstr;
-{
- char *remotehost = NULL, *remoteuser = NULL;
- char *bad_bsd = NULL;
- struct hostent *hp;
- struct passwd *pwptr;
- int myuid, i, j;
- char *s, *fp;
- int ch;
-
- *errstr = NULL;
-
- /* what host is making the request? */
-
- hp = gethostbyaddr((char *)&addr->sin_addr, sizeof(addr->sin_addr),
- AF_INET);
- if(hp == NULL) {
- /* XXX include remote address in message */
- *errstr = vstralloc("[",
- "addr ", inet_ntoa(addr->sin_addr), ": ",
- "hostname lookup failed",
- "]", NULL);
- return 0;
- }
- remotehost = stralloc(hp->h_name);
-
- /* Now let's get the hostent for that hostname */
- hp = gethostbyname( remotehost );
- if(hp == NULL) {
- /* XXX include remote hostname in message */
- *errstr = vstralloc("[",
- "host ", remotehost, ": ",
- "hostname lookup failed",
- "]", NULL);
- amfree(remotehost);
- return 0;
- }
-
- /* Verify that the hostnames match -- they should theoretically */
- if( strncasecmp( remotehost, hp->h_name, strlen(remotehost)+1 ) != 0 ) {
- *errstr = vstralloc("[",
- "hostnames do not match: ",
- remotehost, " ", hp->h_name,
- "]", NULL);
- amfree(remotehost);
- return 0;
- }
-
- /* Now let's verify that the ip which gave us this hostname
- * is really an ip for this hostname; or is someone trying to
- * break in? (THIS IS THE CRUCIAL STEP)
- */
- for (i = 0; hp->h_addr_list[i]; i++) {
- if (memcmp(hp->h_addr_list[i],
- (char *) &addr->sin_addr, sizeof(addr->sin_addr)) == 0)
- break; /* name is good, keep it */
- }
-
- /* If we did not find it, your DNS is messed up or someone is trying
- * to pull a fast one on you. :(
- */
-
- /* Check even the aliases list. Work around for Solaris if dns goes over NIS */
-
- if( !hp->h_addr_list[i] ) {
- for (j = 0; hp->h_aliases[j] !=0 ; j++) {
- if ( strcmp(hp->h_aliases[j],inet_ntoa(addr->sin_addr)) == 0)
- break; /* name is good, keep it */
- }
- if( !hp->h_aliases[j] ) {
- *errstr = vstralloc("[",
- "ip address ", inet_ntoa(addr->sin_addr),
- " is not in the ip list for ", remotehost,
- "]",
- NULL);
- amfree(remotehost);
- return 0;
- }
- }
-
- /* next, make sure the remote port is a "reserved" one */
-
- if(ntohs(addr->sin_port) >= IPPORT_RESERVED) {
- char number[NUM_STR_SIZE];
-
- snprintf(number, sizeof(number), "%d", ntohs(addr->sin_port));
- *errstr = vstralloc("[",
- "host ", remotehost, ": ",
- "port ", number, " not secure",
- "]", NULL);
- amfree(remotehost);
- return 0;
- }
-
- /* extract the remote user name from the message */
-
- s = str;
- ch = *s++;
-
- bad_bsd = vstralloc("[",
- "host ", remotehost, ": ",
- "bad bsd security line",
- "]", NULL);
-
-#define sc "USER "
- if(strncmp(s - 1, sc, sizeof(sc)-1) != 0) {
- *errstr = bad_bsd;
- bad_bsd = NULL;
- amfree(remotehost);
- return 0;
- }
- s += sizeof(sc)-1;
- ch = s[-1];
-#undef sc
-
- skip_whitespace(s, ch);
- if(ch == '\0') {
- *errstr = bad_bsd;
- bad_bsd = NULL;
- amfree(remotehost);
- return 0;
- }
- fp = s - 1;
- skip_non_whitespace(s, ch);
- s[-1] = '\0';
- remoteuser = stralloc(fp);
- s[-1] = ch;
- amfree(bad_bsd);
-
- /* lookup our local user name */
-
- myuid = getuid();
- if((pwptr = getpwuid(myuid)) == NULL)
- error("error [getpwuid(%d) fails]", myuid);
-
- dbprintf(("bsd security: remote host %s user %s local user %s\n",
- remotehost, remoteuser, pwptr->pw_name));
-
-#ifndef USE_AMANDAHOSTS
- s = check_user_ruserok(remotehost, pwptr, remoteuser);
-#else
- s = check_user_amandahosts(remotehost, pwptr, remoteuser);
-#endif
-
- if (s != NULL) {
- *errstr = vstralloc("[",
- "access as ", pwptr->pw_name, " not allowed",
- " from ", remoteuser, "@", remotehost,
- ": ", s, "]", NULL);
- }
- amfree(s);
- amfree(remotehost);
- amfree(remoteuser);
- return *errstr == NULL;
-}
-
-
/*
* Create the server end of a stream. For bsd, this means setup a tcp
* socket for receiving a connection.
*/
static void *
-bsd_stream_server(h)
- void *h;
+bsd_stream_server(
+ void * h)
{
- struct bsd_stream *bs = NULL;
#ifndef TEST /* { */
- struct bsd_handle *bh = h;
+ struct sec_stream *bs = NULL;
+ struct sec_handle *bh = h;
assert(bh != NULL);
- bs = alloc(sizeof(*bs));
+ bs = alloc(SIZEOF(*bs));
security_streaminit(&bs->secstr, &bsd_security_driver);
- bs->socket = stream_server(&bs->port, STREAM_BUFSIZE, STREAM_BUFSIZE);
+ bs->socket = stream_server(&bs->port, (size_t)STREAM_BUFSIZE,
+ (size_t)STREAM_BUFSIZE, 0);
if (bs->socket < 0) {
security_seterror(&bh->sech,
"can't create server stream: %s", strerror(errno));
}
bs->fd = -1;
bs->ev_read = NULL;
-#endif /* !TEST */ /* } */
return (bs);
+#else
+ return (NULL);
+#endif /* !TEST */ /* } */
}
/*
* block on accept()
*/
static int
-bsd_stream_accept(s)
- void *s;
+bsd_stream_accept(
+ void * s)
{
#ifndef TEST /* { */
- struct bsd_stream *bs = s;
+ struct sec_stream *bs = s;
assert(bs != NULL);
assert(bs->socket != -1);
assert(bs->fd < 0);
- bs->fd = stream_accept(bs->socket, 30, -1, -1);
+ bs->fd = stream_accept(bs->socket, 30, STREAM_BUFSIZE, STREAM_BUFSIZE);
if (bs->fd < 0) {
security_stream_seterror(&bs->secstr,
"can't accept new stream connection: %s", strerror(errno));
* Return a connected stream
*/
static void *
-bsd_stream_client(h, id)
- void *h;
- int id;
+bsd_stream_client(
+ void * h,
+ int id)
{
- struct bsd_stream *bs = NULL;
+ struct sec_stream *bs = NULL;
#ifndef TEST /* { */
- struct bsd_handle *bh = h;
+ struct sec_handle *bh = h;
#ifdef DUMPER_SOCKET_BUFFERING
- int rcvbuf = sizeof(bs->databuf) * 2;
+ size_t rcvbuf = SIZEOF(bs->databuf) * 2;
#endif
assert(bh != NULL);
- if (id < 0) {
- security_seterror(&bh->sech,
- "%d: invalid security stream id", id);
- return (NULL);
- }
-
- bs = alloc(sizeof(*bs));
+ bs = alloc(SIZEOF(*bs));
security_streaminit(&bs->secstr, &bsd_security_driver);
- bs->fd = stream_client(bh->hostname, id, STREAM_BUFSIZE, STREAM_BUFSIZE,
- &bs->port, 0);
+ bs->fd = stream_client(bh->hostname, (in_port_t)id,
+ STREAM_BUFSIZE, STREAM_BUFSIZE, &bs->port, 0);
if (bs->fd < 0) {
security_seterror(&bh->sech,
- "can't connect stream to %s port %d: %s", bh->hostname,
+ "can't connect stream to %s port %hd: %s", bh->hostname,
id, strerror(errno));
amfree(bs);
return (NULL);
bs->socket = -1; /* we're a client */
bs->ev_read = NULL;
#ifdef DUMPER_SOCKET_BUFFERING
- setsockopt(bs->fd, SOL_SOCKET, SO_RCVBUF, (void *)&rcvbuf, sizeof(rcvbuf));
+ setsockopt(bs->fd, SOL_SOCKET, SO_RCVBUF, (void *)&rcvbuf, SIZEOF(rcvbuf));
#endif
#endif /* !TEST */ /* } */
return (bs);
* Close and unallocate resources for a stream
*/
static void
-bsd_stream_close(s)
- void *s;
+bsd_stream_close(
+ void * s)
{
- struct bsd_stream *bs = s;
+ struct sec_stream *bs = s;
assert(bs != NULL);
* Authenticate a stream. bsd streams have no authentication
*/
static int
-bsd_stream_auth(s)
- void *s;
+bsd_stream_auth(
+ void * s)
{
+ (void)s; /* Quiet unused parameter warning */
return (0); /* success */
}
* Returns the stream id for this stream. This is just the local port.
*/
static int
-bsd_stream_id(s)
- void *s;
+bsd_stream_id(
+ void * s)
{
- struct bsd_stream *bs = s;
+ struct sec_stream *bs = s;
assert(bs != NULL);
- return (bs->port);
-}
-
-/*
- * Write a chunk of data to a stream. Blocks until completion.
- */
-static int
-bsd_stream_write(s, buf, size)
- void *s;
- const void *buf;
- size_t size;
-{
-#ifndef TEST /* { */
- struct bsd_stream *bs = s;
-
- assert(bs != NULL);
-
- if (fullwrite(bs->fd, buf, size) < 0) {
- security_stream_seterror(&bs->secstr,
- "write error on stream %d: %s", bs->port, strerror(errno));
- return (-1);
- }
-#endif /* !TEST */ /* } */
- return (0);
+ return ((int)bs->port);
}
/*
* and arg when completed.
*/
static void
-bsd_stream_read(s, fn, arg)
- void *s, *arg;
- void (*fn) P((void *, void *, ssize_t));
+bsd_stream_read(
+ void * s,
+ void (*fn)(void *, void *, ssize_t),
+ void * arg)
{
- struct bsd_stream *bs = s;
+ struct sec_stream *bs = s;
/*
* Only one read request can be active per stream.
if (bs->ev_read != NULL)
event_release(bs->ev_read);
- bs->ev_read = event_register(bs->fd, EV_READFD, stream_read_callback, bs);
+ bs->ev_read = event_register((event_id_t)bs->fd, EV_READFD, stream_read_callback, bs);
bs->fn = fn;
bs->arg = arg;
}
/*
- * Cancel a previous stream read request. It's ok if we didn't
- * have a read scheduled.
+ * Read a chunk of data to a stream. Blocks until completion.
*/
-static void
-bsd_stream_read_cancel(s)
- void *s;
+static ssize_t
+bsd_stream_read_sync(
+ void * s,
+ void ** buf)
{
- struct bsd_stream *bs = s;
+ struct sec_stream *bs = s;
assert(bs != NULL);
- if (bs->ev_read != NULL) {
- event_release(bs->ev_read);
- bs->ev_read = NULL;
+ /*
+ * Only one read request can be active per stream.
+ */
+ if(bs->ev_read != NULL) {
+ return -1;
}
+ bs->ev_read = event_register((event_id_t)bs->fd, EV_READFD,
+ stream_read_sync_callback, bs);
+ event_wait(bs->ev_read);
+ *buf = bs->databuf;
+ return (bs->len);
}
+
/*
- * Callback for bsd_stream_read
+ * Callback for bsd_stream_read_sync
*/
static void
-stream_read_callback(arg)
- void *arg;
+stream_read_sync_callback(
+ void * s)
{
- struct bsd_stream *bs = arg;
+ struct sec_stream *bs = s;
ssize_t n;
assert(bs != NULL);
+ bsdprintf(("%s: bsd: stream_read_callback_sync: fd %d\n",
+ debug_prefix_time(NULL), bs->fd));
+
/*
* Remove the event first, in case they reschedule it in the callback.
*/
n = read(bs->fd, bs->databuf, sizeof(bs->databuf));
} while ((n < 0) && ((errno == EINTR) || (errno == EAGAIN)));
if (n < 0)
- security_stream_seterror(&bs->secstr, strerror(errno));
- (*bs->fn)(bs->arg, bs->databuf, n);
+ security_stream_seterror(&bs->secstr, strerror(errno));
+ bs->len = n;
}
/*
- * Convert a packet header into a string
+ * Cancel a previous stream read request. It's ok if we didn't
+ * have a read scheduled.
*/
-static const char *
-pkthdr2str(bh, pkt)
- const struct bsd_handle *bh;
- const pkt_t *pkt;
+static void
+bsd_stream_read_cancel(
+ void * s)
{
- static char retbuf[256];
-
- assert(bh != NULL);
- assert(pkt != NULL);
+ struct sec_stream *bs = s;
- snprintf(retbuf, sizeof(retbuf), "Amanda %d.%d %s HANDLE %s SEQ %d\n",
- VERSION_MAJOR, VERSION_MINOR, pkt_type2str(pkt->type),
- bh->proto_handle, bh->sequence);
-
- bsdprintf(("%s: pkthdr2str handle '%s'\n",
- debug_prefix_time(NULL), bh->proto_handle));
-
- /* check for truncation. If only we had asprintf()... */
- assert(retbuf[strlen(retbuf) - 1] == '\n');
-
- return (retbuf);
+ assert(bs != NULL);
+ if (bs->ev_read != NULL) {
+ event_release(bs->ev_read);
+ bs->ev_read = NULL;
+ }
}
/*
- * Parses out the header line in 'str' into the pkt and handle
- * Returns negative on parse error.
+ * Callback for bsd_stream_read
*/
-static int
-str2pkthdr()
+static void
+stream_read_callback(
+ void * arg)
{
- char *str;
- const char *tok;
- pkt_t *pkt;
-
- pkt = &netfd.pkt;
-
- assert(netfd.dgram.cur != NULL);
- str = stralloc(netfd.dgram.cur);
-
- /* "Amanda %d.%d <ACK,NAK,...> HANDLE %s SEQ %d\n" */
-
- /* Read in "Amanda" */
- if ((tok = strtok(str, " ")) == NULL || strcmp(tok, "Amanda") != 0)
- goto parse_error;
-
- /* nothing is done with the major/minor numbers currently */
- if ((tok = strtok(NULL, " ")) == NULL || strchr(tok, '.') == NULL)
- goto parse_error;
-
- /* Read in the packet type */
- if ((tok = strtok(NULL, " ")) == NULL)
- goto parse_error;
- pkt_init(pkt, pkt_str2type(tok), "");
- if (pkt->type == (pktype_t)-1)
- goto parse_error;
-
- /* Read in "HANDLE" */
- if ((tok = strtok(NULL, " ")) == NULL || strcmp(tok, "HANDLE") != 0)
- goto parse_error;
-
- /* parse the handle */
- if ((tok = strtok(NULL, " ")) == NULL)
- goto parse_error;
- netfd.handle = stralloc(tok);
-
- /* Read in "SEQ" */
- if ((tok = strtok(NULL, " ")) == NULL || strcmp(tok, "SEQ") != 0)
- goto parse_error;
+ struct sec_stream *bs = arg;
+ ssize_t n;
- /* parse the sequence number */
- if ((tok = strtok(NULL, "\n")) == NULL)
- goto parse_error;
- netfd.sequence = atoi(tok);
+ assert(bs != NULL);
- /* Save the body, if any */
- if ((tok = strtok(NULL, "")) != NULL)
- pkt_cat(pkt, "%s", tok);
+ /*
+ * Remove the event first, in case they reschedule it in the callback.
+ */
+ bsd_stream_read_cancel(bs);
+ do {
+ n = read(bs->fd, bs->databuf, SIZEOF(bs->databuf));
+ } while ((n < 0) && ((errno == EINTR) || (errno == EAGAIN)));
- amfree(str);
- return (0);
+ if (n < 0)
+ security_stream_seterror(&bs->secstr, strerror(errno));
-parse_error:
-#if 0 /* XXX we have no way of passing this back up */
- security_seterror(&bh->sech,
- "parse error in packet header : '%s'", origstr);
-#endif
- amfree(str);
- return (-1);
+ (*bs->fn)(bs->arg, bs->databuf, n);
}
#endif /* BSD_SECURITY */ /* } */
* drag in util.o just for the test program.
*/
int
-bind_portrange(s, addrp, first_port, last_port, proto)
- int s;
- struct sockaddr_in *addrp;
- int first_port, last_port;
- char *proto;
-{
+bind_portrange(
+ int s,
+ struct sockaddr_in *addrp,
+ in_port_t first_port,
+ in_port_t last_port,
+ char * proto)
+{
+ (void)s; /* Quiet unused parameter warning */
+ (void)addrp; /* Quiet unused parameter warning */
+ (void)first_port; /* Quiet unused parameter warning */
+ (void)last_port; /* Quiet unused parameter warning */
+ (void)proto; /* Quiet unused parameter warning */
+
return 0;
}
* Construct a datestamp (YYYYMMDD) from a time_t.
*/
char *
-construct_datestamp(t)
- time_t *t;
+construct_datestamp(
+ time_t * t)
{
struct tm *tm;
char datestamp[3*NUM_STR_SIZE];
when = *t;
}
tm = localtime(&when);
- snprintf(datestamp, sizeof(datestamp),
+ snprintf(datestamp, SIZEOF(datestamp),
"%04d%02d%02d", tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday);
return stralloc(datestamp);
}
* Construct a timestamp (YYYYMMDDHHMMSS) from a time_t.
*/
char *
-construct_timestamp(t)
- time_t *t;
+construct_timestamp(
+ time_t * t)
{
struct tm *tm;
char timestamp[6*NUM_STR_SIZE];
when = *t;
}
tm = localtime(&when);
- snprintf(timestamp, sizeof(timestamp),
+ snprintf(timestamp, SIZEOF(timestamp),
"%04d%02d%02d%02d%02d%02d",
tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday,
tm->tm_hour, tm->tm_min, tm->tm_sec);
const security_driver_t krb4_security_driver = {};
const security_driver_t krb5_security_driver = {};
const security_driver_t rsh_security_driver = {};
+const security_driver_t ssh_security_driver = {};
+const security_driver_t bsdtcp_security_driver = {};
+const security_driver_t bsdudp_security_driver = {};
/*
* This function will be called to accept the connection and is used
* to report success or failure.
*/
-static void fake_accept_function(handle, pkt)
- security_handle_t *handle;
- pkt_t *pkt;
+static void fake_accept_function(
+ security_handle_t * handle,
+ pkt_t * pkt)
{
if (pkt == NULL) {
fputs(handle->error, stdout);
}
int
-main (argc, argv)
+main (
+ int argc,
+ char ** argv)
{
char *remoteuser;
char *remotehost;
struct hostent *hp;
- struct bsd_handle *bh;
+ struct sec_handle *bh;
void *save_cur;
struct passwd *pwent;
if (geteuid() == 0) {
if(client_uid == (uid_t) -1) {
error("error [cannot find user %s in passwd file]\n", CLIENT_LOGIN);
+ /*NOTREACHED*/
}
initgroups(CLIENT_LOGIN, client_gid);
setgid(client_gid);
fputs("Remote user: ", stdout);
fflush(stdout);
}
- if ((remoteuser = agets(stdin)) == NULL) {
- return 0;
- }
+ do {
+ amfree(remoteuser);
+ remoteuser = agets(stdin);
+ if (remoteuser == NULL)
+ return 0;
+ } while (remoteuser[0] == '\0');
if (isatty(0)) {
fputs("Remote host: ", stdout);
fflush(stdout);
}
- if ((remotehost = agets(stdin)) == NULL) {
- return 0;
- }
+
+ do {
+ amfree(remotehost);
+ remotehost = agets(stdin);
+ if (remotehost == NULL)
+ return 0;
+ } while (remotehost[0] == '\0');
set_pname("security");
+ dbopen(NULL);
+
startclock();
if ((hp = gethostbyname(remotehost)) == NULL) {
}
memcpy((char *)&netfd.peer.sin_addr,
(char *)hp->h_addr,
- sizeof(hp->h_addr));
+ SIZEOF(hp->h_addr));
/*
* Fake that it is coming from a reserved port.
*/
netfd.peer.sin_port = htons(IPPORT_RESERVED - 1);
- bh = alloc(sizeof(*bh));
+ bh = alloc(SIZEOF(*bh));
bh->proto_handle=NULL;
+ bh->udp = &netfd;
netfd.pkt.type = P_REQ;
dgram_zero(&netfd.dgram);
save_cur = netfd.dgram.cur; /* cheating */
dgram_cat(&netfd.dgram, "SECURITY USER %s\n", remoteuser);
netfd.dgram.cur = save_cur; /* cheating */
- accept_fn = fake_accept_function;
- netfd_read_callback(NULL);
+ netfd.accept_fn = fake_accept_function;
+ netfd.recv_security_ok = &bsd_recv_security_ok;
+ netfd.prefix_packet = &bsd_prefix_packet;
+ udp_netfd_read_callback(&netfd);
return 0;
}
--- /dev/null
+/*
+ * Amanda, The Advanced Maryland Automatic Network Disk Archiver
+ * Copyright (c) 1999 University of Maryland
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of U.M. not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. U.M. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: the Amanda Development Team. Its members are listed in a
+ * file named AUTHORS, in the root directory of this distribution.
+ */
+
+/*
+ * $Id: bsdtcp-security.c,v 1.7 2006/07/13 03:22:20 paddy_s Exp $
+ *
+ * bsdtcp-security.c - security and transport over bsdtcp or a bsdtcp-like command.
+ *
+ * XXX still need to check for initial keyword on connect so we can skip
+ * over shell garbage and other stuff that bsdtcp might want to spew out.
+ */
+
+#include "amanda.h"
+#include "util.h"
+#include "event.h"
+#include "packet.h"
+#include "queue.h"
+#include "security.h"
+#include "security-util.h"
+#include "stream.h"
+#include "version.h"
+
+#ifdef BSDTCP_SECURITY
+
+/*#define BSDTCP_DEBUG*/
+
+#ifdef BSDTCP_DEBUG
+#define bsdtcpprintf(x) dbprintf(x)
+#else
+#define bsdtcpprintf(x)
+#endif
+
+
+/*
+ * Number of seconds bsdtcp has to start up
+ */
+#define CONNECT_TIMEOUT 20
+
+/*
+ * Interface functions
+ */
+static void bsdtcp_accept(const struct security_driver *, int, int,
+ void (*)(security_handle_t *, pkt_t *));
+static void bsdtcp_connect(const char *,
+ char *(*)(char *, void *),
+ void (*)(void *, security_handle_t *, security_status_t), void *, void *);
+
+/*
+ * This is our interface to the outside world.
+ */
+const security_driver_t bsdtcp_security_driver = {
+ "BSDTCP",
+ bsdtcp_connect,
+ bsdtcp_accept,
+ sec_close,
+ stream_sendpkt,
+ stream_recvpkt,
+ stream_recvpkt_cancel,
+ tcpma_stream_server,
+ tcpma_stream_accept,
+ tcpma_stream_client,
+ tcpma_stream_close,
+ sec_stream_auth,
+ sec_stream_id,
+ tcpm_stream_write,
+ tcpm_stream_read,
+ tcpm_stream_read_sync,
+ tcpm_stream_read_cancel,
+ tcpm_close_connection,
+};
+
+static int newhandle = 1;
+
+/*
+ * Local functions
+ */
+static int runbsdtcp(struct sec_handle *);
+
+
+/*
+ * bsdtcp version of a security handle allocator. Logically sets
+ * up a network "connection".
+ */
+static void
+bsdtcp_connect(
+ const char *hostname,
+ char * (*conf_fn)(char *, void *),
+ void (*fn)(void *, security_handle_t *, security_status_t),
+ void * arg,
+ void * datap)
+{
+ struct sec_handle *rh;
+ struct hostent *he;
+
+ assert(fn != NULL);
+ assert(hostname != NULL);
+ (void)conf_fn; /* Quiet unused parameter warning */
+ (void)datap; /* Quiet unused parameter warning */
+
+ bsdtcpprintf(("%s: bsdtcp: bsdtcp_connect: %s\n", debug_prefix_time(NULL),
+ hostname));
+
+ rh = alloc(sizeof(*rh));
+ security_handleinit(&rh->sech, &bsdtcp_security_driver);
+ rh->hostname = NULL;
+ rh->rs = NULL;
+ rh->ev_timeout = NULL;
+ rh->rc = NULL;
+
+ if ((he = gethostbyname(hostname)) == NULL) {
+ security_seterror(&rh->sech,
+ "%s: could not resolve hostname", hostname);
+ (*fn)(arg, &rh->sech, S_ERROR);
+ return;
+ }
+ rh->hostname = stralloc(he->h_name); /* will be replaced */
+ rh->rs = tcpma_stream_client(rh, newhandle++);
+ rh->rc->recv_security_ok = &bsd_recv_security_ok;
+ rh->rc->prefix_packet = &bsd_prefix_packet;
+
+ if (rh->rs == NULL)
+ goto error;
+
+ amfree(rh->hostname);
+ rh->hostname = stralloc(rh->rs->rc->hostname);
+
+ /*
+ * We need to open a new connection.
+ *
+ * XXX need to eventually limit number of outgoing connections here.
+ */
+ if(rh->rc->read == -1) {
+ if (runbsdtcp(rh) < 0)
+ goto error;
+ rh->rc->refcnt++;
+ }
+
+ /*
+ * The socket will be opened async so hosts that are down won't
+ * block everything. We need to register a write event
+ * so we will know when the socket comes alive.
+ *
+ * Overload rh->rs->ev_read to provide a write event handle.
+ * We also register a timeout.
+ */
+ rh->fn.connect = fn;
+ rh->arg = arg;
+ rh->rs->ev_read = event_register((event_id_t)(rh->rs->rc->write),
+ EV_WRITEFD, sec_connect_callback, rh);
+ rh->ev_timeout = event_register(CONNECT_TIMEOUT, EV_TIME,
+ sec_connect_timeout, rh);
+
+ return;
+
+error:
+ (*fn)(arg, &rh->sech, S_ERROR);
+}
+
+/*
+ * Setup to handle new incoming connections
+ */
+static void
+bsdtcp_accept(
+ const struct security_driver *driver,
+ int in,
+ int out,
+ void (*fn)(security_handle_t *, pkt_t *))
+{
+ struct sockaddr_in sin;
+ socklen_t len;
+ struct tcp_conn *rc;
+ struct hostent *he;
+
+ len = sizeof(sin);
+ if (getpeername(in, (struct sockaddr *)&sin, &len) < 0)
+ return;
+ he = gethostbyaddr((void *)&sin.sin_addr, sizeof(sin.sin_addr), AF_INET);
+ if (he == NULL)
+ return;
+
+ rc = sec_tcp_conn_get(he->h_name, 0);
+ rc->recv_security_ok = &bsd_recv_security_ok;
+ rc->prefix_packet = &bsd_prefix_packet;
+ memcpy(&rc->peer.sin_addr, he->h_addr, sizeof(rc->peer.sin_addr));
+ rc->peer.sin_port = sin.sin_port;
+ rc->read = in;
+ rc->write = out;
+ rc->accept_fn = fn;
+ rc->driver = driver;
+ sec_tcp_conn_read(rc);
+}
+
+/*
+ * Forks a bsdtcp to the host listed in rc->hostname
+ * Returns negative on error, with an errmsg in rc->errmsg.
+ */
+static int
+runbsdtcp(
+ struct sec_handle * rh)
+{
+ struct servent * sp;
+ int server_socket;
+ in_port_t my_port;
+ uid_t euid;
+ struct tcp_conn * rc = rh->rc;
+
+ if ((sp = getservbyname("amanda", "tcp")) == NULL) {
+ error("%s/tcp unknown protocol", "amanda");
+ }
+
+ euid = geteuid();
+ seteuid(0);
+
+ server_socket = stream_client_privileged(rc->hostname,
+ (in_port_t)(ntohs((in_port_t)sp->s_port)),
+ STREAM_BUFSIZE,
+ STREAM_BUFSIZE,
+ &my_port,
+ 0);
+
+ if(server_socket < 0) {
+ security_seterror(&rh->sech,
+ "%s", strerror(errno));
+
+ return -1;
+ }
+ seteuid(euid);
+
+ if(my_port >= IPPORT_RESERVED) {
+ security_seterror(&rh->sech,
+ "did not get a reserved port: %d", my_port);
+ }
+
+ rc->read = rc->write = server_socket;
+ return 0;
+}
+
+#endif /* BSDTCP_SECURITY */
--- /dev/null
+/*
+ * Amanda, The Advanced Maryland Automatic Network Disk Archiver
+ * Copyright (c) 1991-1999 University of Maryland at College Park
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of U.M. not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. U.M. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: the Amanda Development Team. Its members are listed in a
+ * file named AUTHORS, in the root directory of this distribution.
+ */
+/*
+ * $Id: bsdudp-security.c,v 1.7 2006/07/05 13:18:20 martinea Exp $
+ *
+ * "BSD" security module
+ */
+
+#include "amanda.h"
+#include "util.h"
+#include "clock.h"
+#include "dgram.h"
+#include "event.h"
+#include "packet.h"
+#include "security.h"
+#include "security-util.h"
+#include "stream.h"
+#include "version.h"
+
+#ifdef BSDUDP_SECURITY
+
+/*#define BSDUDP_DEBUG*/
+
+#ifdef BSDUDP_DEBUG
+#define bsdudpprintf(x) dbprintf(x)
+#else
+#define bsdudpprintf(x)
+#endif
+
+#ifndef SO_RCVBUF
+#undef DUMPER_SOCKET_BUFFERING
+#endif
+
+/*
+ * Change the following from #undef to #define to cause detailed logging
+ * of the security steps, e.g. into /tmp/amanda/amandad*debug.
+ */
+#undef SHOW_SECURITY_DETAIL
+
+#if defined(TEST) /* { */
+#define SHOW_SECURITY_DETAIL
+#undef bsdudpprintf
+#define bsdudpprintf(p) printf p
+#endif /* } */
+
+/*
+ * Interface functions
+ */
+static void bsdudp_connect(const char *,
+ char *(*)(char *, void *),
+ void (*)(void *, security_handle_t *, security_status_t), void *, void *);
+static void bsdudp_accept(const struct security_driver *, int, int, void (*)(security_handle_t *, pkt_t *));
+static void bsdudp_close(void *);
+
+/*
+ * This is our interface to the outside world
+ */
+const security_driver_t bsdudp_security_driver = {
+ "BSDUDP",
+ bsdudp_connect,
+ bsdudp_accept,
+ bsdudp_close,
+ udpbsd_sendpkt,
+ udp_recvpkt,
+ udp_recvpkt_cancel,
+ tcp1_stream_server,
+ tcp1_stream_accept,
+ tcp1_stream_client,
+ tcpma_stream_close,
+ sec_stream_auth,
+ sec_stream_id,
+ tcpm_stream_write,
+ tcpm_stream_read,
+ tcpm_stream_read_sync,
+ tcpm_stream_read_cancel,
+ sec_close_connection_none,
+};
+
+/*
+ * This is data local to the datagram socket. We have one datagram
+ * per process, so it is global.
+ */
+static udp_handle_t netfd;
+static int not_init = 1;
+
+/* generate new handles from here */
+static unsigned int newhandle = 0;
+
+/*
+ * Setup and return a handle outgoing to a client
+ */
+static void
+bsdudp_connect(
+ const char *hostname,
+ char * (*conf_fn)(char *, void *),
+ void (*fn)(void *, security_handle_t *, security_status_t),
+ void * arg,
+ void * datap)
+{
+ struct sec_handle *bh;
+ struct servent *se;
+ struct hostent *he;
+ in_port_t port;
+ struct timeval sequence_time;
+ amanda_timezone dontcare;
+ int sequence;
+ char *handle;
+
+ (void)conf_fn; /* Quiet unused parameter warning */
+ (void)datap; /* Quiet unused parameter warning */
+ assert(hostname != NULL);
+
+ bh = alloc(sizeof(*bh));
+ bh->proto_handle=NULL;
+ bh->udp = &netfd;
+ bh->rc = NULL;
+ security_handleinit(&bh->sech, &bsdudp_security_driver);
+
+ /*
+ * Only init the socket once
+ */
+ if (not_init == 1) {
+ uid_t euid;
+ dgram_zero(&netfd.dgram);
+
+ euid = geteuid();
+ seteuid(0);
+ dgram_bind(&netfd.dgram, &port);
+ seteuid(euid);
+ netfd.handle = NULL;
+ netfd.pkt.body = NULL;
+ netfd.recv_security_ok = &bsd_recv_security_ok;
+ netfd.prefix_packet = &bsd_prefix_packet;
+ /*
+ * We must have a reserved port. Bomb if we didn't get one.
+ */
+ if (port >= IPPORT_RESERVED) {
+ security_seterror(&bh->sech,
+ "unable to bind to a reserved port (got port %u)",
+ (unsigned int)port);
+ (*fn)(arg, &bh->sech, S_ERROR);
+ return;
+ }
+ not_init = 0;
+ }
+
+ if ((he = gethostbyname(hostname)) == NULL) {
+ security_seterror(&bh->sech,
+ "%s: could not resolve hostname", hostname);
+ (*fn)(arg, &bh->sech, S_ERROR);
+ return;
+ }
+ if ((se = getservbyname(AMANDA_SERVICE_NAME, "udp")) == NULL)
+ port = (in_port_t)htons(AMANDA_SERVICE_DEFAULT);
+ else
+ port = (in_port_t)se->s_port;
+ amanda_gettimeofday(&sequence_time, &dontcare);
+ sequence = (int)sequence_time.tv_sec ^ (int)sequence_time.tv_usec;
+ handle=alloc(15);
+ snprintf(handle,14,"000-%08x", newhandle++);
+ if (udp_inithandle(&netfd, bh, he, port, handle, sequence) < 0) {
+ (*fn)(arg, &bh->sech, S_ERROR);
+ amfree(bh->hostname);
+ amfree(bh);
+ } else {
+ (*fn)(arg, &bh->sech, S_OK);
+ }
+ amfree(handle);
+}
+
+/*
+ * Setup to accept new incoming connections
+ */
+static void
+bsdudp_accept(
+ const struct security_driver *driver,
+ int in,
+ int out,
+ void (*fn)(security_handle_t *, pkt_t *))
+{
+ (void)driver; /* Quiet unused parameter warning */
+ (void)out; /* Quiet unused parameter warning */
+
+ assert(in >= 0 && out >= 0);
+ assert(fn != NULL);
+
+ /*
+ * We assume in and out point to the same socket, and just use
+ * in.
+ */
+ dgram_socket(&netfd.dgram, in);
+
+ /*
+ * Assign the function and return. When they call recvpkt later,
+ * the recvpkt callback will call this function when it discovers
+ * new incoming connections
+ */
+ netfd.accept_fn = fn;
+ netfd.recv_security_ok = &bsd_recv_security_ok;
+ netfd.prefix_packet = &bsd_prefix_packet;
+ netfd.driver = &bsdudp_security_driver;
+
+
+ udp_addref(&netfd, &udp_netfd_read_callback);
+}
+
+/*
+ * Frees a handle allocated by the above
+ */
+static void
+bsdudp_close(
+ void *cookie)
+{
+ struct sec_handle *bh = cookie;
+
+ if(bh->proto_handle == NULL) {
+ return;
+ }
+
+ bsdudpprintf(("%s: bsdudp: close handle '%s'\n",
+ debug_prefix_time(NULL), bh->proto_handle));
+
+ udp_recvpkt_cancel(bh);
+ if(bh->next) {
+ bh->next->prev = bh->prev;
+ }
+ else {
+ netfd.bh_last = bh->prev;
+ }
+ if(bh->prev) {
+ bh->prev->next = bh->next;
+ }
+ else {
+ netfd.bh_first = bh->next;
+ }
+
+ amfree(bh->proto_handle);
+ amfree(bh->hostname);
+ amfree(bh);
+}
+
+#endif /* BSDUDP_SECURITY */ /* } */
+
* University of Maryland at College Park
*/
/*
- * $Id: clock.c,v 1.5 2002/04/08 00:16:18 jrjackson Exp $
+ * $Id: clock.c,v 1.7 2006/07/27 18:12:10 martinea Exp $
*
* timing functions
*/
#include "clock.h"
/* local functions */
-static struct timeval timesub P((struct timeval end, struct timeval start));
-static struct timeval timeadd P((struct timeval a, struct timeval b));
+static struct timeval timesub(struct timeval end, struct timeval start);
+static struct timeval timeadd(struct timeval a, struct timeval b);
-times_t times_zero = {{0,0}};
+times_t times_zero;
times_t start_time;
static int clock_running = 0;
-int clock_is_running()
+int
+clock_is_running(void)
{
return clock_running;
}
-void startclock()
+void
+startclock(void)
{
amanda_timezone dontcare;
amanda_gettimeofday(&start_time.r, &dontcare);
}
-times_t stopclock()
+times_t
+stopclock(void)
{
times_t diff;
struct timeval end_time;
return diff;
}
-times_t curclock()
+times_t
+curclock(void)
{
times_t diff;
struct timeval end_time;
return diff;
}
-times_t timesadd(a,b)
-times_t a,b;
+times_t
+timesadd(
+ times_t a,
+ times_t b)
{
times_t sum;
return sum;
}
-times_t timessub(a,b)
-times_t a,b;
+times_t
+timessub(
+ times_t a,
+ times_t b)
{
times_t dif;
return dif;
}
-char *times_str(t)
-times_t t;
+char *
+times_str(
+ times_t t)
{
static char str[10][NUM_STR_SIZE+10];
- static int n = 0;
+ static size_t n = 0;
char *s;
/* tv_sec/tv_usec are longs on some systems */
- snprintf(str[n], sizeof(str[n]),
- "rtime %d.%03d", (int)t.r.tv_sec, (int)t.r.tv_usec/1000);
+ snprintf(str[n], SIZEOF(str[n]), "rtime %lu.%03lu",
+ (unsigned long)t.r.tv_sec,
+ (unsigned long)t.r.tv_usec / 1000);
s = str[n++];
n %= am_countof(str);
return s;
}
-char *walltime_str(t)
-times_t t;
+char *
+walltime_str(
+ times_t t)
{
static char str[10][NUM_STR_SIZE+10];
- static int n = 0;
+ static size_t n = 0;
char *s;
/* tv_sec/tv_usec are longs on some systems */
- snprintf(str[n], sizeof(str[n]),
- "%d.%03d", (int)t.r.tv_sec, (int)t.r.tv_usec/1000);
+ snprintf(str[n], SIZEOF(str[n]), "%lu.%03lu",
+ (unsigned long)t.r.tv_sec,
+ (unsigned long)t.r.tv_usec/1000);
s = str[n++];
n %= am_countof(str);
return s;
}
-static struct timeval timesub(end,start)
-struct timeval end,start;
+static struct timeval
+timesub(
+ struct timeval end,
+ struct timeval start)
{
struct timeval diff;
if(end.tv_usec < start.tv_usec) { /* borrow 1 sec */
- end.tv_sec -= 1;
+ if (end.tv_sec > 0)
+ end.tv_sec -= 1;
end.tv_usec += 1000000;
}
diff.tv_usec = end.tv_usec - start.tv_usec;
return diff;
}
-static struct timeval timeadd(a,b)
-struct timeval a,b;
+static struct timeval
+timeadd(
+ struct timeval a,
+ struct timeval b)
{
struct timeval sum;
* University of Maryland at College Park
*/
/*
- * $Id: clock.h,v 1.5 2002/04/08 00:16:18 jrjackson Exp $
+ * $Id: clock.h,v 1.6 2006/05/25 01:47:11 johnfranks Exp $
*
* interface for timing functions
*/
# define amanda_gettimeofday(x, y) gettimeofday((x))
#endif
-void startclock P((void));
-times_t stopclock P((void));
-times_t curclock P((void));
-times_t timesadd P((times_t a, times_t b));
-times_t timessub P((times_t a, times_t b));
-char * times_str P((times_t t));
-char * walltime_str P((times_t t));
-int clock_is_running P((void));
+void startclock(void);
+times_t stopclock(void);
+times_t curclock(void);
+times_t timesadd(times_t a, times_t b);
+times_t timessub(times_t a, times_t b);
+char * times_str(times_t t);
+char * walltime_str(times_t t);
+int clock_is_running(void);
#endif /* CLOCK_H */
* University of Maryland at College Park
*/
/*
- * $Id: debug.c,v 1.36 2006/01/12 01:57:05 paddy_s Exp $
+ * $Id: debug.c,v 1.40 2006/07/26 11:49:32 martinea Exp $
*
* debug log subroutines
*/
static int db_fd = 2; /* default is stderr */
static FILE *db_file = NULL; /* stderr may not be a constant */
-static char *db_filename = NULL;
+static char *db_name = NULL; /* filename */
+static char *db_filename = NULL; /* /path/to/filename */
static pid_t debug_prefix_pid = 0;
+static char *get_debug_name(time_t t, int n);
+static void debug_setup_1(char *config, char *subdir);
+static void debug_setup_2(char *s, int fd, char *notation);
/*
* Format and write a debug message to the process debug file.
printf_arglist_function(void debug_printf, const char *, format)
{
va_list argp;
- int save_errno;
/*
* It is common in the code to call dbprintf to write out
* with errno (e.g. printf() or log()), so we make sure errno goes
* back out with the same value it came in with.
*/
- save_errno = errno;
+ if (debug != 0) {
+ int save_errno;
- if(db_file == NULL && db_fd == 2) {
- db_file = stderr;
- }
- if(db_file != NULL) {
- arglist_start(argp, format);
- vfprintf(db_file, format, argp);
- fflush(db_file);
- arglist_end(argp);
+ save_errno = errno;
+ if(db_file == NULL && db_fd == 2) {
+ db_file = stderr;
+ }
+ if(db_file != NULL) {
+ arglist_start(argp, format);
+ vfprintf(db_file, format, argp);
+ fflush(db_file);
+ arglist_end(argp);
+ }
+ errno = save_errno;
}
-
- errno = save_errno;
}
/*
* followed by a timestamp, an optional sequence number, and ".debug".
*/
static char *
-get_debug_name(t, n)
- time_t t;
- int n;
+get_debug_name(
+ time_t t,
+ int n)
{
char number[NUM_STR_SIZE];
char *ts;
if(n == 0) {
number[0] = '\0';
} else {
- snprintf(number, sizeof(number), "%03d", n - 1);
+ snprintf(number, SIZEOF(number), "%03d", n - 1);
}
result = vstralloc(get_pname(), ".", ts, number, ".debug", NULL);
amfree(ts);
static char *dbgdir = NULL;
static time_t curtime;
-static void debug_setup_1()
+static void
+debug_setup_1(char *config, char *subdir)
{
struct passwd *pwent;
char *pname;
DIR *d;
struct dirent *entry;
int do_rename;
- char *test_name = NULL;
+ char *test_name;
size_t test_name_len;
size_t d_name_len;
struct stat sbuf;
char *dbfilename = NULL;
+ char *sane_config = NULL;
int i;
+ memset(&sbuf, 0, SIZEOF(sbuf));
if(client_uid == (uid_t) -1 && (pwent = getpwnam(CLIENT_LOGIN)) != NULL) {
client_uid = pwent->pw_uid;
client_gid = pwent->pw_gid;
* Create the debug directory if it does not yet exist.
*/
amfree(dbgdir);
- dbgdir = stralloc2(AMANDA_DBGDIR, "/");
+ if (config)
+ sane_config = sanitise_filename(config);
+ if (sane_config && subdir)
+ dbgdir = vstralloc(AMANDA_DBGDIR, "/", subdir, "/", sane_config,
+ "/", NULL);
+ else if (sane_config)
+ dbgdir = vstralloc(AMANDA_DBGDIR, "/", sane_config, "/", NULL);
+ else if (subdir)
+ dbgdir = vstralloc(AMANDA_DBGDIR, "/", subdir, "/", NULL);
+ else
+ dbgdir = stralloc2(AMANDA_DBGDIR, "/");
if(mkpdir(dbgdir, 02700, client_uid, client_gid) == -1) {
error("create debug directory \"%s\": %s",
AMANDA_DBGDIR, strerror(errno));
+ /*NOTREACHED*/
}
+ amfree(sane_config);
/*
* Clean out old debug files. We also rename files with old style
if((d = opendir(AMANDA_DBGDIR)) == NULL) {
error("open debug directory \"%s\": %s",
AMANDA_DBGDIR, strerror(errno));
+ /*NOTREACHED*/
}
time(&curtime);
test_name = get_debug_name(curtime - (AMANDA_DEBUG_DAYS * 24 * 60 * 60), 0);
}
if(dbfilename == NULL) {
error("cannot rename old debug file \"%s\"", entry->d_name);
+ /*NOTREACHED*/
}
}
}
closedir(d);
}
-static void debug_setup_2(s, fd, notation)
- char *s;
- int fd;
- char *notation;
+static void
+debug_setup_2(
+ char * s,
+ int fd,
+ char * notation)
{
int saved_debug;
- int i;
+ int i, rc;
int fd_close[MIN_DB_FD+1];
amfree(db_filename);
db_filename = s;
s = NULL;
- (void) chown(db_filename, client_uid, client_gid);
+ if ((rc = chown(db_filename, client_uid, client_gid)) < 0) {
+ dbprintf(("chown(%s, %d, %d) failed. <%s>",
+ db_filename, client_uid, client_gid, strerror(errno)));
+ (void)rc;
+ }
amfree(dbgdir);
/*
* Move the file descriptor up high so it stays out of the way
* of other processing, e.g. sendbackup.
*/
- i = 0;
- fd_close[i++] = fd;
- while((db_fd = dup(fd)) < MIN_DB_FD) {
- fd_close[i++] = db_fd;
- }
- while(--i >= 0) {
- close(fd_close[i]);
+ if (fd >= 0) {
+ i = 0;
+ fd_close[i++] = fd;
+ while((db_fd = dup(fd)) < MIN_DB_FD) {
+ fd_close[i++] = db_fd;
+ }
+ while(--i >= 0) {
+ close(fd_close[i]);
+ }
+ db_file = fdopen(db_fd, "a");
}
- db_file = fdopen(db_fd, "a");
if (notation) {
/*
}
}
-void debug_open()
+void
+debug_open(char *subdir)
{
- char *dbfilename = NULL;
int fd = -1;
int i;
char *s = NULL;
/*
* Do initial setup.
*/
- debug_setup_1();
+ debug_setup_1(NULL, subdir);
/*
* Create the new file with a unique sequence number.
*/
- mask = umask(0037); /* Allow the group read bit through */
+ mask = (mode_t)umask((mode_t)0037); /* Allow the group read bit through */
for(i = 0; fd < 0; i++) {
- if ((dbfilename = get_debug_name(curtime, i)) == NULL) {
+ amfree(db_name);
+ if ((db_name = get_debug_name(curtime, i)) == NULL) {
error("Cannot create %s debug file", get_pname());
- /* NOTREACHED */
+ /*NOTREACHED*/
}
- if ((s = newvstralloc(s, dbgdir, dbfilename, NULL)) == NULL) {
+ if ((s = newvstralloc(s, dbgdir, db_name, NULL)) == NULL) {
error("Cannot allocate %s debug file name memory", get_pname());
- /* NOTREACHED */
- }
- amfree(dbfilename);
+ /*NOTREACHED*/
+ }
if ((fd = open(s, O_WRONLY|O_CREAT|O_EXCL|O_APPEND, 0640)) < 0) {
if (errno != EEXIST) {
error("Cannot create %s debug file: %s",
get_pname(), strerror(errno));
- /* NOTREACHED */
+ /*NOTREACHED*/
}
amfree(s);
}
debug_setup_2(s, fd, "start");
}
-void debug_reopen(dbfilename, notation)
- char *dbfilename;
- char *notation;
+void
+debug_reopen(
+ char * dbfilename,
+ char * notation)
{
char *s = NULL;
- int fd = -1;
+ int fd;
if (dbfilename == NULL) {
return;
/*
* Do initial setup.
*/
- debug_setup_1();
+ debug_setup_1(NULL, NULL);
/*
* Reopen the file.
}
if ((fd = open(s, O_RDWR|O_APPEND)) < 0) {
error("cannot reopen %s debug file %s", get_pname(), dbfilename);
+ /*NOTREACHED*/
}
/*
debug_setup_2(s, fd, notation);
}
-void debug_close()
+void
+debug_rename(
+ char *config,
+ char *subdir)
+{
+ int fd = -1;
+ int i;
+ char *s = NULL;
+ mode_t mask;
+
+ if (!db_filename)
+ return;
+
+ /*
+ * Do initial setup.
+ */
+ debug_setup_1(config, subdir);
+
+ s = newvstralloc(s, dbgdir, db_name, NULL);
+
+ if (strcmp(db_filename, s) == 0) {
+ amfree(s);
+ return;
+ }
+
+ mask = (mode_t)umask((mode_t)0037);
+ /* check if a file with the same name already exist */
+ if ((fd = open(s, O_WRONLY|O_CREAT|O_EXCL|O_APPEND, 0640)) < 0) {
+ for(i = 0; fd < 0; i++) {
+ amfree(db_name);
+ if ((db_name = get_debug_name(curtime, i)) == NULL) {
+ dbprintf(("Cannot create %s debug file", get_pname()));
+ break;
+ }
+
+ s = newvstralloc(s, dbgdir, db_name, NULL);
+ if ((fd = open(s, O_WRONLY|O_CREAT|O_EXCL|O_APPEND, 0640)) < 0) {
+ if (errno != EEXIST) {
+ dbprintf(("Cannot create %s debug file: %s", get_pname(),
+ strerror(errno)));
+ break;
+ }
+ }
+ }
+ }
+
+ if (fd >= 0) {
+ rename(db_filename, s);
+ }
+ (void)umask(mask); /* Restore mask */
+ close(fd);
+ /*
+ * Finish setup.
+ *
+ * Note: we release control of the string 's' points to.
+ */
+ debug_setup_2(s, -1, "rename");
+}
+
+void
+debug_close(void)
{
time_t curtime;
int save_debug;
int save_errno = errno;
db_file = NULL; /* prevent recursion */
- error("close debug file: %s", strerror(save_errno));
+ fprintf(stderr, "close debug file: %s", strerror(save_errno));
+ /*NOTREACHED*/
}
db_fd = -1;
db_file = NULL;
amfree(db_filename);
}
-int debug_fd()
+int
+debug_fd(void)
{
return db_fd;
}
-FILE *debug_fp()
+FILE *
+debug_fp(void)
{
return db_file;
}
-char *debug_fn()
+char *
+debug_fn(void)
{
return db_filename;
}
* time indicator.
*/
-void set_debug_prefix_pid(p)
- pid_t p;
+void
+set_debug_prefix_pid(
+ pid_t p)
{
debug_prefix_pid = p;
}
-char *debug_prefix(suffix)
- char *suffix;
+char *
+debug_prefix(
+ char * suffix)
{
int save_errno;
static char *s = NULL;
save_errno = errno;
s = newvstralloc(s, get_pname(), suffix, NULL);
if (debug_prefix_pid != (pid_t) 0) {
- snprintf(debug_pid, sizeof(debug_pid),
+ snprintf(debug_pid, SIZEOF(debug_pid),
"%ld",
(long) debug_prefix_pid);
s = newvstralloc(s, s, "[", debug_pid, "]", NULL);
return s;
}
-char *debug_prefix_time(suffix)
- char *suffix;
+char *
+debug_prefix_time(
+ char * suffix)
{
int save_errno;
static char *s = NULL;
* University of Maryland at College Park
*/
/*
- * $Id: dgram.c,v 1.29 2006/01/12 01:57:05 paddy_s Exp $
+ * $Id: dgram.c,v 1.32 2006/07/05 19:54:20 martinea Exp $
*
* library routines to marshall/send, recv/unmarshall UDP packets
*/
#include "dgram.h"
#include "util.h"
-void dgram_socket(dgram, socket)
-dgram_t *dgram;
-int socket;
+void
+dgram_socket(
+ dgram_t * dgram,
+ int socket)
{
if(socket < 0 || socket >= FD_SETSIZE) {
error("dgram_socket: socket %d out of range (0 .. %d)\n",
socket, FD_SETSIZE-1);
+ /*NOTREACHED*/
}
dgram->socket = socket;
}
-int dgram_bind(dgram, portp)
-dgram_t *dgram;
-int *portp;
+int
+dgram_bind(
+ dgram_t * dgram,
+ in_port_t * portp)
{
- int s;
+ int s, retries;
socklen_t len;
struct sockaddr_in name;
int save_errno;
+#if defined(USE_REUSEADDR)
+ const int on = 1;
+ int r;
+#endif
+ *portp = (in_port_t)0;
if((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
save_errno = errno;
dbprintf(("%s: dgram_bind: socket() failed: %s\n",
errno = save_errno;
return -1;
}
- if(s < 0 || s >= FD_SETSIZE) {
+ if(s < 0 || s >= (int)FD_SETSIZE) {
dbprintf(("%s: dgram_bind: socket out of range: %d\n",
debug_prefix(NULL),
s));
return -1;
}
- memset(&name, 0, sizeof(name));
- name.sin_family = AF_INET;
+ memset(&name, 0, SIZEOF(name));
+ name.sin_family = (sa_family_t)AF_INET;
name.sin_addr.s_addr = INADDR_ANY;
+#ifdef USE_REUSEADDR
+ r = setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
+ (void *)&on, (socklen_t)sizeof(on));
+ if (r < 0) {
+ dbprintf(("%s: dgram_bind: setsockopt(SO_REUSEADDR) failed: %s\n",
+ debug_prefix(NULL),
+ strerror(errno)));
+ }
+#endif
+
/*
* If a port range was specified, we try to get a port in that
* range first. Next, we try to get a reserved port. If that
* to get the desired port, and to make sure we return a port that
* is within the range it requires.
*/
+ for (retries = 0; ; retries++) {
#ifdef UDPPORTRANGE
- if (bind_portrange(s, &name, UDPPORTRANGE, "udp") == 0)
- goto out;
+ if (bind_portrange(s, &name, UDPPORTRANGE, "udp") == 0)
+ goto out;
+ dbprintf(("%s: dgram_bind: Could to bind to port in range: %d - %d.\n",
+ debug_prefix(NULL), UDPPORTRANGE));
#endif
- if (bind_portrange(s, &name, 512, IPPORT_RESERVED - 1, "udp") == 0)
- goto out;
+ if (bind_portrange(s, &name, (in_port_t)512,
+ (in_port_t)(IPPORT_RESERVED - 1), "udp") == 0)
+ goto out;
+ dbprintf(("%s: dgram_bind: Could to bind to port in range: 512 - %d.\n",
+ debug_prefix(NULL), IPPORT_RESERVED - 1));
+
+ name.sin_port = INADDR_ANY;
+ if (bind(s, (struct sockaddr *)&name, (socklen_t)sizeof(name)) == 0)
+ goto out;
+ dbprintf(("%s: dgram_bind: Could to bind to any port: %s\n",
+ debug_prefix(NULL), strerror(errno)));
+
+ if (retries >= BIND_CYCLE_RETRIES) {
+ dbprintf(("%s: dgram_bind: Giving up...\n", debug_prefix(NULL)));
+ break;
+ }
- name.sin_port = INADDR_ANY;
- if (bind(s, (struct sockaddr *)&name, (socklen_t)sizeof name) == -1) {
- save_errno = errno;
- dbprintf(("%s: dgram_bind: bind(INADDR_ANY) failed: %s\n",
+ dbprintf(("%s: dgram_bind: Retrying entire range after 10 second delay.\n",
+ debug_prefix(NULL)));
+ sleep(15);
+ }
+
+ save_errno = errno;
+ dbprintf(("%s: dgram_bind: bind(INADDR_ANY) failed: %s\n",
debug_prefix(NULL),
strerror(save_errno)));
- errno = save_errno;
- aclose(s);
- return -1;
- }
+ aclose(s);
+ errno = save_errno;
+ return -1;
out:
/* find out what name was actually used */
- len = (socklen_t) sizeof name;
+ len = (socklen_t)sizeof(name);
if(getsockname(s, (struct sockaddr *)&name, &len) == -1) {
save_errno = errno;
dbprintf(("%s: dgram_bind: getsockname() failed: %s\n",
aclose(s);
return -1;
}
- *portp = ntohs(name.sin_port);
+ *portp = (in_port_t)ntohs(name.sin_port);
dgram->socket = s;
dbprintf(("%s: dgram_bind: socket bound to %s.%d\n",
}
-int dgram_send_addr(addr, dgram)
-struct sockaddr_in addr;
-dgram_t *dgram;
+int
+dgram_send_addr(
+ struct sockaddr_in addr,
+ dgram_t * dgram)
{
- int s;
+ int s, rc;
int socket_opened;
struct sockaddr_in addr_save;
int save_errno;
int max_wait;
int wait_count;
+#if defined(USE_REUSEADDR)
+ const int on = 1;
+ int r;
+#endif
+ dbprintf(("%s: dgram_send_addr(addr=%p, dgram=%p)\n",
+ debug_prefix(NULL), &addr, dgram));
+ dump_sockaddr(&addr);
+ dbprintf(("%s: dgram_send_addr: %p->socket = %d\n",
+ debug_prefix(NULL), dgram, dgram->socket));
if(dgram->socket != -1) {
s = dgram->socket;
socket_opened = 0;
return -1;
}
socket_opened = 1;
+#ifdef USE_REUSEADDR
+ r = setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
+ (void *)&on, (socklen_t)sizeof(on));
+ if (r < 0) {
+ dbprintf(("%s: dgram_send_addr: setsockopt(SO_REUSEADDR) failed: %s\n",
+ debug_prefix(NULL),
+ strerror(errno)));
+ }
+#endif
}
+ memcpy(&addr_save, &addr, SIZEOF(addr));
if(s < 0 || s >= FD_SETSIZE) {
dbprintf(("%s: dgram_send_addr: socket out of range: %d\n",
debug_prefix(NULL),
s));
- if(socket_opened) {
- aclose(s);
- }
errno = EMFILE; /* out of range */
- return -1;
- }
-
- memcpy(&addr_save, &addr, sizeof(addr));
- max_wait = 300 / 5; /* five minutes */
- wait_count = 0;
- while(sendto(s,
+ rc = -1;
+ } else {
+ max_wait = 300 / 5; /* five minutes */
+ wait_count = 0;
+ rc = 0;
+ while(sendto(s,
dgram->data,
dgram->len,
0,
(struct sockaddr *)&addr,
- (socklen_t) sizeof(struct sockaddr_in)) == -1) {
+ (int)sizeof(struct sockaddr_in)) == -1) {
#ifdef ECONNREFUSED
- if(errno == ECONNREFUSED && wait_count++ < max_wait) {
- sleep(5);
- dbprintf(("%s: dgram_send_addr: sendto(%s.%d): retry %d after ECONNREFUSED\n",
+ if(errno == ECONNREFUSED && wait_count++ < max_wait) {
+ sleep(5);
+ dbprintf(("%s: dgram_send_addr: sendto(%s.%hu): retry %d after ECONNREFUSED\n",
debug_prefix_time(NULL),
inet_ntoa(addr_save.sin_addr),
- (int) ntohs(addr.sin_port),
+ (in_port_t)ntohs(addr.sin_port),
wait_count));
- continue;
- }
+ continue;
+ }
#endif
#ifdef EAGAIN
- if(errno == EAGAIN && wait_count++ < max_wait) {
- sleep(5);
- dbprintf(("%s: dgram_send_addr: sendto(%s.%d): retry %d after EAGAIN\n",
+ if(errno == EAGAIN && wait_count++ < max_wait) {
+ sleep(5);
+ dbprintf(("%s: dgram_send_addr: sendto(%s.%hu): retry %d after EAGAIN\n",
debug_prefix_time(NULL),
inet_ntoa(addr_save.sin_addr),
- (int) ntohs(addr.sin_port),
+ (in_port_t)ntohs(addr.sin_port),
wait_count));
- continue;
- }
+ continue;
+ }
#endif
- save_errno = errno;
- dbprintf(("%s: dgram_send_addr: sendto(%s.%d) failed: %s \n",
+ save_errno = errno;
+ dbprintf(("%s: dgram_send_addr: sendto(%s.%d) failed: %s \n",
debug_prefix_time(NULL),
inet_ntoa(addr_save.sin_addr),
(int) ntohs(addr.sin_port),
strerror(save_errno)));
- errno = save_errno;
- return -1;
+ errno = save_errno;
+ rc = -1;
+ break;
+ }
}
if(socket_opened) {
+ save_errno = errno;
if(close(s) == -1) {
- save_errno = errno;
dbprintf(("%s: dgram_send_addr: close(%s.%d): failed: %s\n",
debug_prefix(NULL),
inet_ntoa(addr_save.sin_addr),
(int) ntohs(addr.sin_port),
- strerror(save_errno)));
- errno = save_errno;
- return -1;
+ strerror(errno)));
+ /*
+ * Calling function should not care that the close failed.
+ * It does care about the send results though.
+ */
}
- s = -1;
+ errno = save_errno;
}
- return 0;
+ return rc;
}
-int dgram_send(hostname, port, dgram)
-char *hostname;
-int port;
-dgram_t *dgram;
+int
+dgram_send(
+ char * hostname,
+ in_port_t port,
+ dgram_t * dgram)
{
struct sockaddr_in name;
struct hostent *hp;
errno = save_errno;
return -1;
}
- memcpy(&name.sin_addr, hp->h_addr, hp->h_length);
- name.sin_family = AF_INET;
- name.sin_port = htons(port);
+ memcpy(&name.sin_addr, hp->h_addr, (size_t)hp->h_length);
+ name.sin_family = (sa_family_t)AF_INET;
+ name.sin_port = (in_port_t)htons(port);
return dgram_send_addr(name, dgram);
}
-int dgram_recv(dgram, timeout, fromaddr)
-dgram_t *dgram;
-int timeout;
-struct sockaddr_in *fromaddr;
+ssize_t
+dgram_recv(
+ dgram_t * dgram,
+ int timeout,
+ struct sockaddr_in *fromaddr)
{
- fd_set ready;
+ SELECT_ARG_TYPE ready;
struct timeval to;
ssize_t size;
int sock;
socklen_t addrlen;
- int nfound;
+ ssize_t nfound;
int save_errno;
sock = dgram->socket;
to.tv_sec = timeout;
to.tv_usec = 0;
- nfound = select(sock+1, (SELECT_ARG_TYPE *)&ready, NULL, NULL, &to);
+ dbprintf(("%s: dgram_recv(dgram=%p, timeout=%u, fromaddr=%p)\n",
+ debug_prefix_time(NULL), timeout, fromaddr));
+ dump_sockaddr(fromaddr);
+
+ nfound = (ssize_t)select(sock+1, &ready, NULL, NULL, &to);
if(nfound <= 0 || !FD_ISSET(sock, &ready)) {
save_errno = errno;
if(nfound < 0) {
return nfound;
}
- addrlen = (socklen_t) sizeof(struct sockaddr_in);
- size = recvfrom(sock, dgram->data, MAX_DGRAM, 0,
+ addrlen = (socklen_t)sizeof(struct sockaddr_in);
+ size = recvfrom(sock, dgram->data, (size_t)MAX_DGRAM, 0,
(struct sockaddr *)fromaddr, &addrlen);
if(size == -1) {
save_errno = errno;
errno = save_errno;
return -1;
}
- dgram->len = size;
+ dgram->len = (size_t)size;
dgram->data[size] = '\0';
dgram->cur = dgram->data;
return size;
}
-void dgram_zero(dgram)
-dgram_t *dgram;
+void
+dgram_zero(
+ dgram_t * dgram)
{
dgram->cur = dgram->data;
dgram->len = 0;
*(dgram->cur) = '\0';
}
-printf_arglist_function1(void dgram_cat, dgram_t *, dgram, const char *, fmt)
+printf_arglist_function1(int dgram_cat, dgram_t *, dgram, const char *, fmt)
{
- size_t bufsize;
+ ssize_t bufsize;
va_list argp;
+ int len;
assert(dgram != NULL);
assert(fmt != NULL);
- assert(dgram->len == dgram->cur - dgram->data);
- assert(dgram->len >= 0 && dgram->len < sizeof(dgram->data));
+ assert(dgram->len == (size_t)(dgram->cur - dgram->data));
+ assert(dgram->len < SIZEOF(dgram->data));
- bufsize = sizeof(dgram->data) - dgram->len;
+ bufsize = (ssize_t)(sizeof(dgram->data) - dgram->len);
if (bufsize <= 0)
- return;
+ return -1;
arglist_start(argp, fmt);
- dgram->len += vsnprintf(dgram->cur, bufsize, fmt, argp);
- dgram->cur = dgram->data + dgram->len;
+ len = vsnprintf(dgram->cur, (size_t)bufsize, fmt, argp);
arglist_end(argp);
+ if((ssize_t)len > bufsize) {
+ dgram->len = sizeof(dgram->data);
+ dgram->cur = dgram->data + dgram->len;
+ return -1;
+ }
+ else {
+ arglist_start(argp, fmt);
+ dgram->len += vsnprintf(dgram->cur, (size_t)bufsize, fmt, argp);
+ arglist_end(argp);
+ dgram->cur = dgram->data + dgram->len;
+ }
+ return 0;
}
-void dgram_eatline(dgram)
-dgram_t *dgram;
+void
+dgram_eatline(
+ dgram_t * dgram)
{
char *p = dgram->cur;
char *end = dgram->data + dgram->len;
- while(p < end && *p && *p != '\n') p++;
- if(*p == '\n') p++;
+ while(p < end && *p && *p != '\n')
+ p++;
+ if(*p == '\n')
+ p++;
dgram->cur = p;
}
* University of Maryland at College Park
*/
/*
- * $Id: dgram.h,v 1.13 2001/07/13 22:38:05 jrjackson Exp $
+ * $Id: dgram.h,v 1.15 2006/05/25 01:47:11 johnfranks Exp $
*
* interface for datagram module
*/
typedef struct dgram_s {
char *cur;
int socket;
- int len;
+ size_t len;
char data[MAX_DGRAM+1];
} dgram_t;
-int dgram_bind P((dgram_t *dgram, int *portp));
-void dgram_socket P((dgram_t *dgram, int sock));
-int dgram_send P((char *hostname, int port, dgram_t *dgram));
-int dgram_send_addr P((struct sockaddr_in addr, dgram_t *dgram));
-int dgram_recv P((dgram_t *dgram, int timeout, struct sockaddr_in *fromaddr));
-void dgram_zero P((dgram_t *dgram));
-void dgram_cat P((dgram_t *dgram, const char *fmt, ...))
+int dgram_bind(dgram_t *dgram, in_port_t *portp);
+void dgram_socket(dgram_t *dgram, int sock);
+int dgram_send(char *hostname, in_port_t port, dgram_t *dgram);
+int dgram_send_addr(struct sockaddr_in addr, dgram_t *dgram);
+ssize_t dgram_recv(dgram_t *dgram, int timeout, struct sockaddr_in *fromaddr);
+void dgram_zero(dgram_t *dgram);
+int dgram_cat(dgram_t *dgram, const char *fmt, ...)
__attribute__ ((format (printf, 2, 3)));
-void dgram_eatline P((dgram_t *dgram));
+void dgram_eatline(dgram_t *dgram);
#endif /* ! DGRAM_H */
* University of Maryland at College Park
*/
/*
- * $Id: error.c,v 1.18 2003/04/27 01:17:19 martinea Exp $
+ * $Id: error.c,v 1.19 2006/05/25 01:47:11 johnfranks Exp $
*
* error handling common to Amanda programs
*/
#define MAXFUNCS 8
-typedef void (*voidfunc) P((void));
+typedef void (*voidfunc)(void);
static voidfunc onerr[MAXFUNCS] =
{ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
static char *pname = "unknown";
-static void (*logerror) P((char *)) = NULL;
+static void output_error_message(char *msg);
-void set_pname(p)
-char *p;
+static void (*logerror)(char *) = NULL;
+
+void
+set_pname(
+ char * p)
{
pname = p;
}
-char *get_pname()
+char *
+get_pname(void)
{
return pname;
}
-void set_logerror(f)
-void (*f) P((char *));
+void
+set_logerror(
+ void (*f)(char *))
{
logerror = f;
}
-static void output_error_message(msg)
-char *msg;
+static void
+output_error_message(
+ char * msg)
{
/* print and/or log message */
#ifdef LOG_AUTH
openlog(get_pname(), LOG_PID, LOG_AUTH);
#else
- openlog(get_pname(), LOG_PID);
+ openlog(get_pname(), LOG_PID, 0);
#endif
syslog(LOG_NOTICE, "%s", msg);
closelog();
/* format and output the error message */
arglist_start(argp, format);
- vsnprintf(linebuf, sizeof(linebuf), format, argp);
+ vsnprintf(linebuf, SIZEOF(linebuf), format, argp);
arglist_end(argp);
output_error_message(linebuf);
/* format error message */
arglist_start(argp, format);
- vsnprintf(linebuf, sizeof(linebuf), format, argp);
+ vsnprintf(linebuf, SIZEOF(linebuf), format, argp);
arglist_end(argp);
output_error_message(linebuf);
}
-int onerror(errf)
-void (*errf) P((void));
/*
* Register function to be called when error is called. Up to MAXFUNCS
* functions can be registered. If there isn't room in the table, onerror
* The resemblance to atexit() is on purpose. I wouldn't need onerror()
* if everyone had atexit(). Bummer.
*/
+
+int
+onerror(
+ void (*errf)(void))
{
int i;
* file named AUTHORS, in the root directory of this distribution.
*/
/*
- * $Id: event.c,v 1.20 2005/10/02 15:31:07 martinea Exp $
+ * $Id: event.c,v 1.24 2006/06/16 10:55:05 martinea Exp $
*
* Event handler. Serializes different kinds of events to allow for
* a uniform interface, central state storage, and centralized
static struct sigtabent {
event_handle_t *handle; /* handle for this signal */
int score; /* number of signals recvd since last checked */
- void (*oldhandler) P((int));/* old handler (for unsetting) */
+ void (*oldhandler)(int);/* old handler (for unsetting) */
} sigtable[NSIG];
#ifdef EVENT_DEBUG
-static const char *event_type2str P((event_type_t));
+static const char *event_type2str(event_type_t);
#endif
#define fire(eh) (*(eh)->fn)((eh)->arg)
-static void signal_handler P((int));
-static event_handle_t *gethandle P((void));
-static void puthandle P((event_handle_t *));
+static void signal_handler(int);
+static event_handle_t *gethandle(void);
+static void puthandle(event_handle_t *);
+static int event_loop_wait (event_handle_t *, const int);
/*
* Add a new event. See the comment in event.h for what the arguments
* mean.
*/
event_handle_t *
-event_register(data, type, fn, arg)
- event_id_t data;
- event_type_t type;
- event_fn_t fn;
- void *arg;
+event_register(
+ event_id_t data,
+ event_type_t type,
+ event_fn_t fn,
+ void *arg)
{
event_handle_t *handle;
- switch (type) {
- case EV_READFD:
- case EV_WRITEFD:
+ if ((type == EV_READFD) || (type == EV_WRITEFD)) {
/* make sure we aren't given a high fd that will overflow a fd_set */
- assert(data < FD_SETSIZE);
- break;
-
- case EV_SIG:
+ if (data >= FD_SETSIZE) {
+ error("event_register: Invalid file descriptor %d", data);
+ /*NOTREACHED*/
+ }
+#if !defined(__lint) /* Global checking knows that these are never called */
+ } else if (type == EV_SIG) {
/* make sure signals are within range */
- assert(data < NSIG);
- /* make sure we don't double-register a signal */
- assert(sigtable[data].handle == NULL);
- break;
-
- case EV_TIME:
- case EV_WAIT:
- break;
-
- case EV_DEAD:
- default:
- /* callers can't register EV_DEAD */
- assert(0);
- break;
+ if (data >= NSIG) {
+ error("event_register: Invalid signal %d", data);
+ /*NOTREACHED*/
+ }
+ if (sigtable[data].handle != NULL) {
+ error("event_register: signal %d already registered", data);
+ /*NOTREACHED*/
+ }
+ } else if (type >= EV_DEAD) {
+ error("event_register: Invalid event type %d", type);
+ /*NOTREACHED*/
+#endif
}
handle = gethandle();
eventq_add(eventq, handle);
eventq.qlength++;
- eventprintf(("%s: event: register: %X data=%lu, type=%s\n", debug_prefix_time(NULL), (int)handle,
- handle->data, event_type2str(handle->type)));
+ eventprintf(("%s: event: register: %p->data=%lu, type=%s\n",
+ debug_prefix_time(NULL), handle, handle->data,
+ event_type2str(handle->type)));
return (handle);
}
* the event.
*/
void
-event_release(handle)
- event_handle_t *handle;
+event_release(
+ event_handle_t *handle)
{
assert(handle != NULL);
- eventprintf(("%s: event: release (mark): %X data=%lu, type=%s\n", debug_prefix_time(NULL),
- (int)handle, handle->data, event_type2str(handle->type)));
+ eventprintf(("%s: event: release (mark): %p data=%lu, type=%s\n",
+ debug_prefix_time(NULL), handle, handle->data,
+ event_type2str(handle->type)));
assert(handle->type != EV_DEAD);
/*
struct sigtabent *se = &sigtable[handle->data];
assert(se->handle == handle);
- signal(handle->data, se->oldhandler);
+ signal((int)handle->data, se->oldhandler);
se->handle = NULL;
se->score = 0;
}
* Fire all EV_WAIT events waiting on the specified id.
*/
int
-event_wakeup(id)
- event_id_t id;
+event_wakeup(
+ event_id_t id)
{
event_handle_t *eh;
int nwaken = 0;
- eventprintf(("%s: event: wakeup: enter (%lu)\n", debug_prefix_time(NULL), id));
-
- assert(id >= 0);
+ eventprintf(("%s: event: wakeup: enter (%lu)\n",
+ debug_prefix_time(NULL), id));
for (eh = eventq_first(eventq); eh != NULL; eh = eventq_next(eh)) {
if (eh->type == EV_WAIT && eh->data == id) {
- eventprintf(("%s: event: wakeup: %X id=%lu\n", debug_prefix_time(NULL), (int)eh, id));
+ eventprintf(("%s: event: wakeup: %p id=%lu\n",
+ debug_prefix_time(NULL), eh, id));
fire(eh);
nwaken++;
}
* we need to make sure we don't end up referencing a dead event handle.
*/
void
-event_loop(dontblock)
- const int dontblock;
+event_loop(
+ const int dontblock)
+{
+ event_loop_wait((event_handle_t *)NULL, dontblock);
+}
+
+
+
+int
+event_wait(
+ event_handle_t *eh)
+{
+ return event_loop_wait(eh, 0);
+}
+
+/*
+ * The event loop. We need to be specially careful here with adds and
+ * deletes. Since adds and deletes will often happen while this is running,
+ * we need to make sure we don't end up referencing a dead event handle.
+ */
+static int
+event_loop_wait(
+ event_handle_t *wait_eh,
+ const int dontblock)
{
#ifdef ASSERTIONS
static int entry = 0;
#endif
fd_set readfds, writefds, errfds, werrfds;
struct timeval timeout, *tvptr;
- int ntries, maxfd, rc, interval;
+ int ntries, maxfd, rc;
+ long interval;
time_t curtime;
event_handle_t *eh, *nexteh;
struct sigtabent *se;
+ int event_wait_fired = 0;
+ int see_event;
- eventprintf(("%s: event: loop: enter: dontblock=%d, qlength=%d\n", debug_prefix_time(NULL),
- dontblock, eventq.qlength));
+ eventprintf(("%s: event: loop: enter: dontblock=%d, qlength=%d, eh=%p\n",
+ debug_prefix_time(NULL),
+ dontblock, eventq.qlength, wait_eh));
/*
* If we have no events, we have nothing to do
*/
if (eventq.qlength == 0)
- return;
+ return 0;
/*
* We must not be entered twice
do {
#ifdef EVENT_DEBUG
- eventprintf(("%s: event: loop: dontblock=%d, qlength=%d\n", debug_prefix_time(NULL), dontblock,
- eventq.qlength));
+ eventprintf(("%s: event: loop: dontblock=%d, qlength=%d eh=%p\n",
+ debug_prefix_time(NULL), dontblock, eventq.qlength,
+ wait_eh));
for (eh = eventq_first(eventq); eh != NULL; eh = eventq_next(eh)) {
- eventprintf(("%s: %X: %s data=%lu fn=0x%x arg=0x%x\n", debug_prefix_time(NULL), (int)eh,
- event_type2str(eh->type), eh->data, (int)eh->fn, (int)eh->arg));
+ eventprintf(("%s: %p): %s data=%lu fn=%p arg=%p\n",
+ debug_prefix_time(NULL), eh,
+ event_type2str(eh->type), eh->data, eh->fn,
+ eh->arg));
}
#endif
/*
FD_ZERO(&errfds);
maxfd = 0;
+ see_event = (wait_eh == (event_handle_t *)NULL);
/*
* Run through each event handle and setup the events.
* We save our next pointer early in case we GC some dead
* Read fds just get set into the select bitmask
*/
case EV_READFD:
- FD_SET(eh->data, &readfds);
- FD_SET(eh->data, &errfds);
- maxfd = max(maxfd, eh->data);
+ FD_SET((int)eh->data, &readfds);
+ FD_SET((int)eh->data, &errfds);
+ maxfd = max(maxfd, (int)eh->data);
+ see_event |= (eh == wait_eh);
break;
/*
* Likewise with write fds
*/
case EV_WRITEFD:
- FD_SET(eh->data, &writefds);
- FD_SET(eh->data, &errfds);
- maxfd = max(maxfd, eh->data);
+ FD_SET((int)eh->data, &writefds);
+ FD_SET((int)eh->data, &errfds);
+ maxfd = max(maxfd, (int)eh->data);
+ see_event |= (eh == wait_eh);
break;
/*
*/
case EV_SIG:
se = &sigtable[eh->data];
+ see_event |= (eh == wait_eh);
if (se->handle == eh)
break;
assert(se->handle == NULL);
se->handle = eh;
se->score = 0;
- se->oldhandler = signal(eh->data, signal_handler);
+ /*@ignore@*/
+ se->oldhandler = signal((int)eh->data, signal_handler);
+ /*@end@*/
break;
/*
if (eh->lastfired == -1)
eh->lastfired = curtime;
- interval = eh->data - (curtime - eh->lastfired);
+ interval = (long)(eh->data - (curtime - eh->lastfired));
if (interval < 0)
interval = 0;
tvptr = &timeout;
timeout.tv_sec = interval;
}
+ see_event |= (eh == wait_eh);
break;
/*
* Wait events are processed immediately by event_wakeup()
*/
case EV_WAIT:
+ see_event |= (eh == wait_eh);
break;
/*
}
}
+ if(!see_event) {
+ assert(--entry == 0);
+ return 0;
+ }
+
/*
* Let 'er rip
*/
- eventprintf(("%s: event: select: dontblock=%d, maxfd=%d, timeout=%ld\n", debug_prefix_time(NULL),
- dontblock, maxfd, tvptr != NULL ? timeout.tv_sec : -1));
+ eventprintf((
+ "%s: event: select: dontblock=%d, maxfd=%d, timeout=%ld\n",
+ debug_prefix_time(NULL), dontblock, maxfd,
+ tvptr != NULL ? timeout.tv_sec : -1));
rc = select(maxfd + 1, &readfds, &writefds, &errfds, tvptr);
- eventprintf(("%s: event: select returns %d\n", debug_prefix_time(NULL), rc));
+ eventprintf(("%s: event: select returns %d\n",
+ debug_prefix_time(NULL), rc));
/*
* Select errors can mean many things. Interrupted events should
*/
if (rc < 0) {
if (errno != EINTR) {
- if (++ntries > 5)
+ if (++ntries > 5) {
error("select failed: %s", strerror(errno));
+ /*NOTREACHED*/
+ }
continue;
}
/* proceed if errno == EINTR, we may have caught a signal */
* that are being polled for both reading and writing have
* both of their poll events 'see' the error.
*/
- memcpy(&werrfds, &errfds, sizeof(werrfds));
+ memcpy(&werrfds, &errfds, SIZEOF(werrfds));
/*
* Now run through the events and fire the ones that are ready.
* Don't handle file descriptor events if the select failed.
*/
for (eh = eventq_first(eventq); eh != NULL; eh = eventq_next(eh)) {
+
switch (eh->type) {
/*
* Read fds: just fire the event if set in the bitmask
*/
case EV_READFD:
- if (FD_ISSET(eh->data, &readfds) ||
- FD_ISSET(eh->data, &errfds)) {
- FD_CLR(eh->data, &readfds);
- FD_CLR(eh->data, &errfds);
+ if (FD_ISSET((int)eh->data, &readfds) ||
+ FD_ISSET((int)eh->data, &errfds)) {
+ FD_CLR((int)eh->data, &readfds);
+ FD_CLR((int)eh->data, &errfds);
fire(eh);
+ if(eh == wait_eh) event_wait_fired = 1;
}
break;
* Write fds: same as Read fds
*/
case EV_WRITEFD:
- if (FD_ISSET(eh->data, &writefds) ||
- FD_ISSET(eh->data, &werrfds)) {
- FD_CLR(eh->data, &writefds);
- FD_CLR(eh->data, &werrfds);
+ if (FD_ISSET((int)eh->data, &writefds) ||
+ FD_ISSET((int)eh->data, &werrfds)) {
+ FD_CLR((int)eh->data, &writefds);
+ FD_CLR((int)eh->data, &werrfds);
fire(eh);
+ if(eh == wait_eh) event_wait_fired = 1;
}
break;
assert(se->handle == eh);
se->score = 0;
fire(eh);
+ if(eh == wait_eh) event_wait_fired = 1;
}
break;
case EV_TIME:
if (eh->lastfired == -1)
eh->lastfired = curtime;
- if (curtime - eh->lastfired >= eh->data) {
+ if ((curtime - eh->lastfired) >= (time_t)eh->data) {
eh->lastfired = curtime;
fire(eh);
+ if(eh == wait_eh) event_wait_fired = 1;
}
break;
break;
}
}
- } while (!dontblock && eventq.qlength > 0);
+ } while (!dontblock && eventq.qlength > 0 && event_wait_fired == 0);
assert(--entry == 0);
+
+ return (event_wait_fired == 1);
}
/*
* loop.
*/
static void
-signal_handler(signo)
- int signo;
+signal_handler(
+ int signo)
{
- assert(signo >= 0 && signo < sizeof(sigtable) / sizeof(sigtable[0]));
+ assert((signo >= 0) && ((size_t)signo < (size_t)(sizeof(sigtable) / sizeof(sigtable[0]))));
sigtable[signo].score++;
}
* alloc a new one.
*/
static event_handle_t *
-gethandle()
+gethandle(void)
{
event_handle_t *eh;
return (eh);
}
assert(cache.qlength == 0);
- return (alloc(sizeof(*eh)));
+ return (alloc(SIZEOF(*eh)));
}
/*
* Otherwise, free it.
*/
static void
-puthandle(eh)
- event_handle_t *eh;
+puthandle(
+ event_handle_t *eh)
{
if (cache.qlength > CACHEDEPTH) {
* Convert an event type into a string
*/
static const char *
-event_type2str(type)
- event_type_t type;
+event_type2str(
+ event_type_t type)
{
static const struct {
event_type_t type;
X(EV_DEAD),
#undef X
};
- int i;
+ size_t i;
- for (i = 0; i < sizeof(event_types) / sizeof(event_types[0]); i++)
+ for (i = 0; i < (size_t)(sizeof(event_types) / sizeof(event_types[0])); i++)
if (type == event_types[i].type)
return (event_types[i].name);
return ("BOGUS EVENT TYPE");
* file named AUTHORS, in the root directory of this distribution.
*/
/*
- * $Id: event.h,v 1.6 2005/11/30 22:35:11 martinea Exp $
+ * $Id: event.h,v 1.9 2006/06/16 10:55:05 martinea Exp $
*/
#ifndef EVENT_H
#define EVENT_H
* The function signature for functions that get called when an event
* fires.
*/
-typedef void (*event_fn_t) P((void *));
+typedef void (*event_fn_t)(void *);
/*
* Register an event handler.
* count on the time events being too accurate. They depend on the
* caller calling event_loop() often enough.
*/
-event_handle_t *event_register P((event_id_t, event_type_t,
- event_fn_t, void *));
+event_handle_t *event_register(event_id_t, event_type_t, event_fn_t, void *);
/*
* Release an event handler.
*/
-void event_release P((event_handle_t *));
+void event_release(event_handle_t *);
/*
* Wake up all EV_WAIT events waiting on a specific id
*/
-int event_wakeup P((event_id_t));
+int event_wakeup(event_id_t);
+
+/*
+ * Block until the event is terminated.
+ */
+int event_wait(event_handle_t *);
/*
* Process events. If the argument is nonzero, then the loop does
* not block.
*/
-void event_loop P((const int));
+void event_loop(const int);
#endif /* EVENT_H */
* Author: AMANDA core development group.
*/
/*
- * $Id: file.c,v 1.35 2006/03/09 16:51:41 martinea Exp $
+ * $Id: file.c,v 1.40 2006/07/19 17:41:15 martinea Exp $
*
* file and directory bashing routines
*/
#include "amanda.h"
#include "util.h"
-static int mk1dir P((const char *, int, uid_t, gid_t));
+void amanda_setup(int argc, char **argv, int setup_flags);
+static int mk1dir(const char *, mode_t, uid_t, gid_t);
+static void areads_getbuf(const char *s, int l, int fd);
uid_t client_uid = (uid_t) -1;
gid_t client_gid = (gid_t) -1;
** it will do nothing - only root is permitted to change the owner
** of a file.
*/
-static int mk1dir(dir, mode, uid, gid)
-const char *dir; /* directory to create */
-int mode; /* mode for new directory */
-uid_t uid; /* uid for new directory */
-gid_t gid; /* gid for new directory */
+static int
+mk1dir(
+ const char *dir, /* directory to create */
+ mode_t mode, /* mode for new directory */
+ uid_t uid, /* uid for new directory */
+ gid_t gid) /* gid for new directory */
{
int rc; /* return code */
- rc = 0; /* assume the best */
-
- if(mkdir(dir, mode) == 0) {
- chmod(dir, mode); /* mkdir() is affected by the umask */
- chown(dir, uid, gid); /* XXX - no-op on most systems? */
+ if((rc = mkdir(dir, mode)) == 0) {
+ if ((rc = chmod(dir, mode)) == 0) { /* mkdir() affected by the umask */
+ rc = chown(dir, uid, gid);
+ }
} else { /* maybe someone beat us to it */
int serrno;
serrno = errno;
- if(access(dir, F_OK) != 0) rc = -1;
+ if(access(dir, F_OK) != 0)
+ rc = -1;
errno = serrno; /* pass back the real error */
}
* the last element, but not the last element. So a (potential) file name
* may be passed to mkpdir and all the parents of that file will be created.
*/
-int mkpdir(file, mode, uid, gid)
-char *file; /* file to create parent directories for */
-int mode; /* mode for new directories */
-uid_t uid; /* uid for new directories */
-gid_t gid; /* gid for new directories */
+int
+mkpdir(
+ char * file, /* file to create parent directories for */
+ mode_t mode, /* mode for new directories */
+ uid_t uid, /* uid for new directories */
+ gid_t gid) /* gid for new directories */
{
- char *dir = NULL, *p;
+ char *dir;
+ char *p;
int rc; /* return code */
rc = 0;
dir = stralloc(file); /* make a copy we can play with */
-
p = strrchr(dir, '/');
if(p != dir && p != NULL) { /* got a '/' or a simple name */
*p = '\0';
** - stops deleting before topdir, ie: topdir will not be removed
** - if file is not under topdir this routine will not notice
*/
-int rmpdir(file, topdir)
-char *file; /* directory hierarchy to remove */
-char *topdir; /* where to stop removing */
+int
+rmpdir(
+ char * file, /* directory hierarchy to remove */
+ char * topdir) /* where to stop removing */
{
int rc;
- char *p, *dir = NULL;
+ char *p, *dir;
if(strcmp(file, topdir) == 0) return 0; /* all done */
dir = stralloc(file);
p = strrchr(dir, '/');
- if(p == dir) rc = 0; /* no /'s */
- else {
+ if (p == NULL || p == dir) {
+ rc = 0;
+ } else {
*p = '\0';
-
rc = rmpdir(dir, topdir);
}
*/
void
-amanda_setup (argc, argv, setup_flags)
- int argc;
- char **argv;
- int setup_flags;
+amanda_setup (
+ int argc,
+ char ** argv,
+ int setup_flags)
{
+ (void)argc; /* Quiet unused parameter warning */
+ (void)argv; /* Quiet unused parameter warning */
+ (void)setup_flags; /* Quiet unused parameter warning */
}
/*
*/
void
-safe_cd()
+safe_cd(void)
{
int cd_ok = 0;
struct stat sbuf;
if (client_uid != (uid_t) -1) {
#if defined(AMANDA_DBGDIR)
d = stralloc2(AMANDA_DBGDIR, "/.");
- (void) mkpdir(d, 02700, client_uid, client_gid);
+ (void) mkpdir(d, (mode_t)02700, client_uid, client_gid);
amfree(d);
#endif
d = stralloc2(AMANDA_TMPDIR, "/.");
- (void) mkpdir(d, 02700, client_uid, client_gid);
+ (void) mkpdir(d, (mode_t)02700, client_uid, client_gid);
amfree(d);
}
if(cd_ok) {
save_core(); /* save any old core file */
} else {
- (void) chdir("/"); /* assume this works */
+ if ((cd_ok = chdir("/")) == -1) {
+ (void)cd_ok; /* Quiet compiler warning if DEBUG disabled */
+ }
}
}
*/
void
-safe_fd(fd_start, fd_count)
- int fd_start;
- int fd_count;
+safe_fd(
+ int fd_start,
+ int fd_count)
{
int fd;
}
}
}
-
}
/*
*/
void
-save_core()
+save_core(void)
{
struct stat sbuf;
/*
** Sanitise a file name.
**
-** Convert all funny characters to '_' so that we can use,
+** Convert all '/' characters to '_' so that we can use,
** for example, disk names as part of file names.
** Notes:
** - there is a many-to-one mapping between input and output
-** XXX - We only look for '/' and ' ' at the moment. May
-** XXX - be we should also do all unprintables.
+** - Only / and '\0' are disallowed in filenames by POSIX...
*/
-char *sanitise_filename(inp)
-char *inp;
+char *
+sanitise_filename(
+ char * inp)
{
char *buf;
- int buf_size;
+ size_t buf_size;
char *s, *d;
int ch;
- buf_size = 2 * strlen(inp) + 1; /* worst case */
+ buf_size = strlen(inp) + 1; /* worst case */
buf = alloc(buf_size);
d = buf;
s = inp;
while((ch = *s++) != '\0') {
- if(ch == '_') {
- if(d >= buf + buf_size) {
- amfree(buf);
- return NULL; /* cannot happen */
- }
- *d++ = '_'; /* convert _ to __ to try */
- /* and ensure unique output */
- } else if(ch == '/' || isspace(ch)) {
+ if(ch == '/') {
ch = '_'; /* convert "bad" to "_" */
}
- if(d >= buf + buf_size) {
- amfree(buf);
- return NULL; /* cannot happen */
- }
- *d++ = ch;
- }
- if(d >= buf + buf_size) {
- amfree(buf);
- return NULL; /* cannot happen */
+ *d++ = (char)ch;
}
+ assert(d < buf + buf_size);
*d = '\0';
return buf;
*=====================================================================
* Get the next line of input from a stdio file.
*
- * char *agets (FILE *f)
+ * char *agets (FILE *stream)
*
- * entry: f = stdio stream to read
- * exit: returns a pointer to an alloc'd string or NULL at EOF
- * or error (errno will be zero on EOF).
+ * entry: stream - stream to read
+ * exit: returns a pointer to an alloc'd string or NULL
+ * at EOF or error. The functions ferror(stream) and
+ * feof(stream) should be checked by caller to determine
+ * stream status.
*
- * Notes: the newline, if read, is removed from the string
+ * Notes: the newline at the end of a line, if read, is removed from
+ * the string. Quoted newlines are left intact.
* the caller is responsible for free'ing the string
+ *
*=====================================================================
*/
+#define AGETS_LINE_INCR 128
+
char *
-debug_agets(s, l, file)
- const char *s;
- int l;
- FILE *file;
+debug_agets(
+ const char *sourcefile,
+ int lineno,
+ FILE * stream)
{
- char *line = NULL, *line_ptr;
- size_t line_size, size_save;
- int line_free, line_len;
- char *cp;
- char *f;
-
- malloc_enter(dbmalloc_caller_loc(s, l));
+ int ch;
+ char *line = alloc(AGETS_LINE_INCR);
+ size_t line_size = 0;
+ size_t loffset = 0;
+ int inquote = 0;
+ int escape = 0;
+
+ (void)sourcefile; /* Quiet unused parameter warning if not debugging */
+ (void)lineno; /* Quiet unused parameter warning if not debugging */
+
+ while ((ch = fgetc(stream)) != EOF) {
+ if (ch == '\n') {
+ if (!inquote) {
+ if (escape) {
+ escape = 0;
+ loffset--; /* Consume escape in buffer */
+ continue;
+ }
+ /* Reached end of line so exit without passing on LF */
+ break;
+ }
+ }
-#define AGETS_LINE_INCR 128
+ if (ch == '\\') {
+ escape = 1;
+ } else {
+ if (ch == '"') {
+ if (!escape)
+ inquote = !inquote;
+ }
+ escape = 0;
+ }
- line_size = AGETS_LINE_INCR;
- line = debug_alloc (s, l, line_size);
- line_free = line_size;
- line_ptr = line;
- line_len = 0;
+ if ((loffset + 1) >= line_size) {
+ char *tmpline;
- while ((f = fgets(line_ptr, line_free, file)) != NULL) {
- /*
- * Note that we only have to search what we just read, not
- * the whole buffer.
- */
- if ((cp = strchr (line_ptr, '\n')) != NULL) {
- line_len += cp - line_ptr;
- *cp = '\0'; /* zap the newline */
- break; /* got to end of line */
- }
- line_len += line_free - 1; /* bytes read minus '\0' */
- size_save = line_size;
- if (line_size < 256 * AGETS_LINE_INCR) {
- line_size *= 2;
- } else {
- line_size += 256 * AGETS_LINE_INCR;
+ /*
+ * Reallocate input line.
+ * alloc() never return NULL pointer.
+ */
+ tmpline = alloc(line_size + AGETS_LINE_INCR);
+ memcpy(tmpline, line, line_size);
+ amfree(line);
+ line = tmpline;
+ line_size = line_size + AGETS_LINE_INCR;
}
- cp = debug_alloc (s, l, line_size); /* get more space */
- memcpy (cp, line, size_save); /* copy old to new */
- free (line); /* and release the old */
- line = cp;
- line_ptr = line + size_save - 1; /* start at the null byte */
- line_free = line_size - line_len; /* and we get to use it */
+ line[loffset++] = (char)ch;
}
+
+ if ((ch == EOF) && (loffset == 0)) {
+ amfree(line); /* amfree zeros line... */
+ } else {
+ line[loffset] = '\0';
+ }
+
/*
- * Return what we got even if there was not a newline. Only
- * report done (NULL) when no data was processed.
+ * Return what we got even if there was not a newline.
+ * Only report done (NULL) when no data was processed.
*/
- if (f == NULL && line_len == 0) {
- amfree (line);
- line = NULL; /* redundant, but clear */
- if(!ferror(file)) {
- errno = 0; /* flag EOF vs error */
- }
- }
- malloc_leave(dbmalloc_caller_loc(s, l));
return line;
}
+
/*
*=====================================================================
* Find/create a buffer for a particular file descriptor for use with
* areads().
*
- * void areads_getbuf (const char *file, int line, int fd)
+ * void areads_getbuf (const char *file, size_t line, int fd)
*
* entry: file, line = caller source location
* fd = file descriptor to look up
static struct areads_buffer {
char *buffer;
char *endptr;
- ssize_t bufsize;
+ size_t bufsize;
} *areads_buffer = NULL;
static int areads_bufcount = 0;
-static ssize_t areads_bufsize = BUFSIZ; /* for the test program */
+static size_t areads_bufsize = BUFSIZ; /* for the test program */
static void
-areads_getbuf(s, l, fd)
- const char *s;
- int l;
- int fd;
+areads_getbuf(
+ const char *s,
+ int l,
+ int fd)
{
struct areads_buffer *new;
- ssize_t size;
+ size_t size;
assert(fd >= 0);
if(fd >= areads_bufcount) {
- size = (fd + 1) * sizeof(*areads_buffer);
+ size = (size_t)(fd + 1) * SIZEOF(*areads_buffer);
new = (struct areads_buffer *) debug_alloc(s, l, size);
memset((char *)new, 0, size);
if(areads_buffer) {
- size = areads_bufcount * sizeof(*areads_buffer);
+ size = areads_bufcount * SIZEOF(*areads_buffer);
memcpy(new, areads_buffer, size);
}
amfree(areads_buffer);
*/
ssize_t
-areads_dataready(fd)
- int fd;
+areads_dataready(
+ int fd)
{
ssize_t r = 0;
*/
void
-areads_relbuf(fd)
- int fd;
+areads_relbuf(
+ int fd)
{
if(fd >= 0 && fd < areads_bufcount) {
amfree(areads_buffer[fd].buffer);
*/
char *
-debug_areads (s, l, fd)
- const char *s;
- int l;
- int fd;
+debug_areads (
+ const char *s,
+ int l,
+ int fd)
{
char *nl;
char *line;
char *buffer;
char *endptr;
char *newbuf;
- ssize_t buflen;
- ssize_t size;
+ size_t buflen;
+ size_t size;
ssize_t r;
malloc_enter(dbmalloc_caller_loc(s, l));
areads_getbuf(s, l, fd);
buffer = areads_buffer[fd].buffer;
endptr = areads_buffer[fd].endptr;
- buflen = areads_buffer[fd].bufsize - (endptr - buffer);
+ buflen = areads_buffer[fd].bufsize - (size_t)(endptr - buffer);
while((nl = strchr(buffer, '\n')) == NULL) {
/*
* No newline yet, so get more data.
newbuf = debug_alloc(s, l, size + 1);
memcpy (newbuf, buffer, areads_buffer[fd].bufsize + 1);
amfree(areads_buffer[fd].buffer);
- buffer = NULL;
areads_buffer[fd].buffer = newbuf;
areads_buffer[fd].endptr = newbuf + areads_buffer[fd].bufsize;
areads_buffer[fd].bufsize = size;
buffer = areads_buffer[fd].buffer;
endptr = areads_buffer[fd].endptr;
- buflen = areads_buffer[fd].bufsize - (endptr - buffer);
+ buflen = areads_buffer[fd].bufsize - (size_t)(endptr - buffer);
}
if ((r = read(fd, endptr, buflen)) <= 0) {
if(r == 0) {
}
*nl++ = '\0';
line = stralloc(buffer);
- size = endptr - nl; /* data still left in buffer */
+ size = (size_t)(endptr - nl); /* data still left in buffer */
memmove(buffer, nl, size);
areads_buffer[fd].endptr = buffer + size;
areads_buffer[fd].endptr[0] = '\0';
#ifdef TEST
-int main(argc, argv)
- int argc;
- char **argv;
+int
+main(
+ int argc,
+ char ** argv)
{
int rc;
int fd;
set_pname("file test");
+ dbopen(NULL);
+
/* Don't die when child closes pipe */
signal(SIGPIPE, SIG_IGN);
}
fprintf(stderr, "Create parent directories of %s ...", name);
- rc = mkpdir(name, 02777, (uid_t)-1, (gid_t)-1);
+ rc = mkpdir(name, (mode_t)02777, (uid_t)-1, (gid_t)-1);
if (rc == 0)
fprintf(stderr, " done\n");
else {
* file named AUTHORS, in the root directory of this distribution.
*/
/*
- * $Id: fileheader.c,v 1.34 2006/03/09 16:51:41 martinea Exp $
+ * $Id: fileheader.c,v 1.40 2006/07/01 00:10:38 paddy_s Exp $
*/
#include "amanda.h"
#include "fileheader.h"
-static const char *filetype2str P((filetype_t));
-static filetype_t str2filetype P((const char *));
+static const char * filetype2str(filetype_t);
+static filetype_t str2filetype(const char *);
+static void strange_header(dumpfile_t *, const char *,
+ size_t, const char *, const char *);
void
-fh_init(file)
- dumpfile_t *file;
+fh_init(
+ dumpfile_t *file)
{
- memset(file, '\0', sizeof(*file));
+ memset(file, '\0', SIZEOF(*file));
file->blocksize = DISK_BLOCK_BYTES;
}
+static void
+strange_header(
+ dumpfile_t *file,
+ const char *buffer,
+ size_t buflen,
+ const char *expected,
+ const char *actual)
+{
+ if (actual == NULL)
+ actual = "<null>";
+ if (expected == NULL)
+ expected = "<null>";
+
+ fprintf(stderr, "%s: strange amanda header: \"%.*s\"\n", get_pname(),
+ (int)buflen, buffer);
+
+ fprintf(stderr, "%s: Expected: \"%s\" Actual: \"%s\"\n", get_pname(),
+ expected, actual);
+
+ file->type = F_WEIRD;
+}
+
+
void
-parse_file_header(buffer, file, buflen)
- const char *buffer;
- dumpfile_t *file;
- size_t buflen;
+parse_file_header(
+ const char *buffer,
+ dumpfile_t *file,
+ size_t buflen)
{
- char *buf, *line, *tok, *line1=NULL;
- int lsize;
+ char *buf, *line, *tok, *line1;
+ size_t lsize;
+ char *uqname;
+ int in_quotes;
+
/* put the buffer into a writable chunk of memory and nul-term it */
buf = alloc(buflen + 1);
memcpy(buf, buffer, buflen);
buf[buflen] = '\0';
-
fh_init(file);
- for(line=buf,lsize=0; *line != '\n' && lsize < buflen; line++) {lsize++;};
+ in_quotes = 0;
+ for (line = buf, lsize = 0; lsize < buflen; line++) {
+ if ((*line == '\n') && !in_quotes)
+ break;
+
+ if (*line == '"') {
+ in_quotes = !in_quotes;
+ } else if ((*line == '\\') && (*(line + 1) == '"')) {
+ line++;
+ lsize++;
+ }
+ lsize++;
+ }
*line = '\0';
- line1 = alloc(lsize+1);
- strncpy(line1,buf,lsize);
+ line1 = alloc(lsize + 1);
+ strncpy(line1, buf, lsize);
line1[lsize] = '\0';
*line = '\n';
tok = strtok(line1, " ");
- if (tok == NULL)
- goto weird_header;
+ if (tok == NULL) {
+ fprintf(stderr, "%s: Empty amanda header: buflen=" SIZE_T_FMT
+ " lsize=" SIZE_T_FMT "\n", get_pname(),
+ (SIZE_T_FMT_TYPE)buflen,
+ (SIZE_T_FMT_TYPE)lsize);
+ hexdump(buffer, lsize);
+ strange_header(file, buffer, buflen, "<Non-empty line>", tok);
+ goto out;
+ }
+
if (strcmp(tok, "NETDUMP:") != 0 && strcmp(tok, "AMANDA:") != 0) {
amfree(buf);
file->type = F_UNKNOWN;
}
tok = strtok(NULL, " ");
- if (tok == NULL)
- goto weird_header;
+ if (tok == NULL) {
+ strange_header(file, buffer, buflen, "<file type>", tok);
+ goto out;
+ }
file->type = str2filetype(tok);
-
+
switch (file->type) {
case F_TAPESTART:
tok = strtok(NULL, " ");
- if (tok == NULL || strcmp(tok, "DATE") != 0)
- goto weird_header;
+ if ((tok == NULL) || (strcmp(tok, "DATE") != 0)) {
+ strange_header(file, buffer, buflen, "DATE", tok);
+ goto out;
+ }
tok = strtok(NULL, " ");
- if (tok == NULL)
- goto weird_header;
- strncpy(file->datestamp, tok, sizeof(file->datestamp) - 1);
+ if (tok == NULL) {
+ strange_header(file, buffer, buflen, "<date stamp>", tok);
+ goto out;
+ }
+ strncpy(file->datestamp, tok, SIZEOF(file->datestamp) - 1);
tok = strtok(NULL, " ");
- if (tok == NULL || strcmp(tok, "TAPE") != 0)
- goto weird_header;
+ if ((tok == NULL) || (strcmp(tok, "TAPE") != 0)) {
+ strange_header(file, buffer, buflen, "TAPE", tok);
+ goto out;
+ }
tok = strtok(NULL, " ");
- if (tok == NULL)
- goto weird_header;
- strncpy(file->name, tok, sizeof(file->name) - 1);
+ if (tok == NULL) {
+ strange_header(file, buffer, buflen, "<file type>", tok);
+ goto out;
+ }
+ strncpy(file->name, tok, SIZEOF(file->name) - 1);
break;
case F_DUMPFILE:
case F_CONT_DUMPFILE:
case F_SPLIT_DUMPFILE:
tok = strtok(NULL, " ");
- if (tok == NULL)
- goto weird_header;
- strncpy(file->datestamp, tok, sizeof(file->datestamp) - 1);
+ if (tok == NULL) {
+ strange_header(file, buffer, buflen, "<date stamp>", tok);
+ goto out;
+ }
+ strncpy(file->datestamp, tok, SIZEOF(file->datestamp) - 1);
tok = strtok(NULL, " ");
- if (tok == NULL)
- goto weird_header;
- strncpy(file->name, tok, sizeof(file->name) - 1);
+ if (tok == NULL) {
+ strange_header(file, buffer, buflen, "<file name>", tok);
+ goto out;
+ }
+ strncpy(file->name, tok, SIZEOF(file->name) - 1);
- tok = strtok(NULL, " ");
- if (tok == NULL)
- goto weird_header;
- strncpy(file->disk, tok, sizeof(file->disk) - 1);
+ tok = strquotedstr();
+ if (tok == NULL) {
+ strange_header(file, buffer, buflen, "<disk name>", tok);
+ goto out;
+ }
+ uqname = unquote_string(tok);
+ strncpy(file->disk, uqname, SIZEOF(file->disk) - 1);
+ amfree(uqname);
- if(file->type == F_SPLIT_DUMPFILE){
+ if(file->type == F_SPLIT_DUMPFILE) {
tok = strtok(NULL, " ");
- if (tok == NULL || strcmp(tok, "part") != 0)
- goto weird_header;
+ if (tok == NULL || strcmp(tok, "part") != 0) {
+ strange_header(file, buffer, buflen, "part", tok);
+ goto out;
+ }
tok = strtok(NULL, "/");
- if (tok == NULL || sscanf(tok, "%d", &file->partnum) != 1)
- goto weird_header;
+ if ((tok == NULL) || (sscanf(tok, "%d", &file->partnum) != 1)) {
+ strange_header(file, buffer, buflen, "<part num param>", tok);
+ goto out;
+ }
- tok = strtok(NULL, " ");
- if (tok == NULL)
- goto weird_header;
/* If totalparts == -1, then the original dump was done in
streaming mode (no holding disk), thus we don't know how
many parts there are. */
- if(sscanf(tok, "%d", &file->totalparts) != 1){
- goto weird_header;
+ tok = strtok(NULL, " ");
+ if((tok == NULL) || (sscanf(tok, "%d", &file->totalparts) != 1)) {
+ strange_header(file, buffer, buflen, "<total parts param>", tok);
+ goto out;
}
}
-
tok = strtok(NULL, " ");
- if (tok == NULL || strcmp(tok, "lev") != 0)
- goto weird_header;
+ if ((tok == NULL) || (strcmp(tok, "lev") != 0)) {
+ strange_header(file, buffer, buflen, "lev", tok);
+ goto out;
+ }
tok = strtok(NULL, " ");
- if (tok == NULL || sscanf(tok, "%d", &file->dumplevel) != 1)
- goto weird_header;
+ if ((tok == NULL) || (sscanf(tok, "%d", &file->dumplevel) != 1)) {
+ strange_header(file, buffer, buflen, "<dump level param>", tok);
+ goto out;
+ }
tok = strtok(NULL, " ");
- if (tok == NULL || strcmp(tok, "comp") != 0)
- goto weird_header;
+ if ((tok == NULL) || (strcmp(tok, "comp") != 0)) {
+ strange_header(file, buffer, buflen, "comp", tok);
+ goto out;
+ }
tok = strtok(NULL, " ");
- if (tok == NULL)
- goto weird_header;
- strncpy(file->comp_suffix, tok, sizeof(file->comp_suffix) - 1);
+ if (tok == NULL) {
+ strange_header(file, buffer, buflen, "<comp param>", tok);
+ goto out;
+ }
+ strncpy(file->comp_suffix, tok, SIZEOF(file->comp_suffix) - 1);
file->compressed = strcmp(file->comp_suffix, "N");
/* compatibility with pre-2.2 amanda */
if (strcmp(file->comp_suffix, "C") == 0)
- strncpy(file->comp_suffix, ".Z", sizeof(file->comp_suffix) - 1);
+ strncpy(file->comp_suffix, ".Z", SIZEOF(file->comp_suffix) - 1);
tok = strtok(NULL, " ");
/* "program" is optional */
}
tok = strtok(NULL, " ");
- if (tok == NULL)
- goto weird_header;
- strncpy(file->program, tok, sizeof(file->program) - 1);
+ if (tok == NULL) {
+ strange_header(file, buffer, buflen, "<program name>", tok);
+ goto out;
+ }
+ strncpy(file->program, tok, SIZEOF(file->program) - 1);
if (file->program[0] == '\0')
- strncpy(file->program, "RESTORE", sizeof(file->program) - 1);
+ strncpy(file->program, "RESTORE", SIZEOF(file->program) - 1);
if ((tok = strtok(NULL, " ")) == NULL)
- break; /* reach the end of the buf */
+ break; /* reached the end of the buffer */
/* "encryption" is optional */
if (BSTRNCMP(tok, "crypt") == 0) {
tok = strtok(NULL, " ");
- if (tok == NULL)
- goto weird_header;
+ if (tok == NULL) {
+ strange_header(file, buffer, buflen, "<crypt param>", tok);
+ goto out;
+ }
strncpy(file->encrypt_suffix, tok,
- sizeof(file->encrypt_suffix) - 1);
+ SIZEOF(file->encrypt_suffix) - 1);
file->encrypted = BSTRNCMP(file->encrypt_suffix, "N");
if ((tok = strtok(NULL, " ")) == NULL)
break;
/* "srvcompprog" is optional */
if (BSTRNCMP(tok, "server_custom_compress") == 0) {
tok = strtok(NULL, " ");
- if (tok == NULL)
- goto weird_header;
- strncpy(file->srvcompprog, tok, sizeof(file->srvcompprog) - 1);
+ if (tok == NULL) {
+ strange_header(file, buffer, buflen,
+ "<server custom compress param>", tok);
+ goto out;
+ }
+ strncpy(file->srvcompprog, tok, SIZEOF(file->srvcompprog) - 1);
if ((tok = strtok(NULL, " ")) == NULL)
break;
}
/* "clntcompprog" is optional */
if (BSTRNCMP(tok, "client_custom_compress") == 0) {
tok = strtok(NULL, " ");
- if (tok == NULL)
- goto weird_header;
- strncpy(file->clntcompprog, tok, sizeof(file->clntcompprog) - 1);
+ if (tok == NULL) {
+ strange_header(file, buffer, buflen,
+ "<client custom compress param>", tok);
+ goto out;
+ }
+ strncpy(file->clntcompprog, tok, SIZEOF(file->clntcompprog) - 1);
if ((tok = strtok(NULL, " ")) == NULL)
break;
}
/* "srv_encrypt" is optional */
if (BSTRNCMP(tok, "server_encrypt") == 0) {
tok = strtok(NULL, " ");
- if (tok == NULL)
- goto weird_header;
- strncpy(file->srv_encrypt, tok, sizeof(file->srv_encrypt) - 1);
+ if (tok == NULL) {
+ strange_header(file, buffer, buflen,
+ "<server encrypt param>", tok);
+ goto out;
+ }
+ strncpy(file->srv_encrypt, tok, SIZEOF(file->srv_encrypt) - 1);
if ((tok = strtok(NULL, " ")) == NULL)
break;
}
/* "clnt_encrypt" is optional */
if (BSTRNCMP(tok, "client_encrypt") == 0) {
tok = strtok(NULL, " ");
- if (tok == NULL)
- goto weird_header;
- strncpy(file->clnt_encrypt, tok, sizeof(file->clnt_encrypt) - 1);
+ if (tok == NULL) {
+ strange_header(file, buffer, buflen,
+ "<client encrypt param>", tok);
+ goto out;
+ }
+ strncpy(file->clnt_encrypt, tok, SIZEOF(file->clnt_encrypt) - 1);
if ((tok = strtok(NULL, " ")) == NULL)
break;
}
/* "srv_decrypt_opt" is optional */
if (BSTRNCMP(tok, "server_decrypt_option") == 0) {
tok = strtok(NULL, " ");
- if (tok == NULL)
- goto weird_header;
+ if (tok == NULL) {
+ strange_header(file, buffer, buflen,
+ "<server decrypt param>", tok);
+ goto out;
+ }
strncpy(file->srv_decrypt_opt, tok,
- sizeof(file->srv_decrypt_opt) - 1);
+ SIZEOF(file->srv_decrypt_opt) - 1);
if ((tok = strtok(NULL, " ")) == NULL)
break;
}
/* "clnt_decrypt_opt" is optional */
if (BSTRNCMP(tok, "client_decrypt_option") == 0) {
tok = strtok(NULL, " ");
- if (tok == NULL)
- goto weird_header;
+ if (tok == NULL) {
+ strange_header(file, buffer, buflen,
+ "<client decrypt param>", tok);
+ goto out;
+ }
strncpy(file->clnt_decrypt_opt, tok,
- sizeof(file->clnt_decrypt_opt) - 1);
+ SIZEOF(file->clnt_decrypt_opt) - 1);
if ((tok = strtok(NULL, " ")) == NULL)
break;
}
case F_TAPEEND:
tok = strtok(NULL, " ");
/* DATE is optional */
- if (tok == NULL || strcmp(tok, "DATE") != 0) {
- amfree(buf);
- amfree(line1);
- return;
+ if (tok != NULL) {
+ if (strcmp(tok, "DATE") == 0) {
+ tok = strtok(NULL, " ");
+ if(tok == NULL)
+ file->datestamp[0] = '\0';
+ else
+ strncpy(file->datestamp, tok, SIZEOF(file->datestamp) - 1);
+ } else {
+ strange_header(file, buffer, buflen, "<DATE>", tok);
+ }
+ } else {
+ file->datestamp[0] = '\0';
}
- strncpy(file->datestamp, tok, sizeof(file->datestamp) - 1);
break;
default:
- goto weird_header;
+ strange_header(file, buffer, buflen,
+ "TAPESTART|DUMPFILE|CONT_DUMPFILE|SPLIT_DUMPFILE|TAPEEND", tok);
+ goto out;
}
- line = strtok(buf, "\n"); /* this is the first line */
+ (void)strtok(buf, "\n"); /* this is the first line */
/* iterate through the rest of the lines */
while ((line = strtok(NULL, "\n")) != NULL) {
#define SC "CONT_FILENAME="
- if (strncmp(line, SC, sizeof(SC) - 1) == 0) {
- line += sizeof(SC) - 1;
+ if (strncmp(line, SC, SIZEOF(SC) - 1) == 0) {
+ line += SIZEOF(SC) - 1;
strncpy(file->cont_filename, line,
- sizeof(file->cont_filename) - 1);
+ SIZEOF(file->cont_filename) - 1);
continue;
}
#undef SC
#define SC "PARTIAL="
- if (strncmp(line, SC, sizeof(SC) - 1) == 0) {
- line += sizeof(SC) - 1;
+ if (strncmp(line, SC, SIZEOF(SC) - 1) == 0) {
+ line += SIZEOF(SC) - 1;
file->is_partial = !strcasecmp(line, "yes");
continue;
}
#undef SC
#define SC "To restore, position tape at start of file and run:"
- if (strncmp(line, SC, sizeof(SC) - 1) == 0)
+ if (strncmp(line, SC, SIZEOF(SC) - 1) == 0)
continue;
#undef SC
#define SC "\tdd if=<tape> bs="
- if (strncmp(line, SC, sizeof(SC) - 1) == 0) {
- char *cmd1=NULL, *cmd2=NULL, *cmd3=NULL;
+ if (strncmp(line, SC, SIZEOF(SC) - 1) == 0) {
+ char *cmd1, *cmd2, *cmd3=NULL;
/* skip over dd command */
if ((cmd1 = strchr(line, '|')) == NULL) {
strncpy(file->recover_cmd, "BUG",
- sizeof(file->recover_cmd) - 1);
+ SIZEOF(file->recover_cmd) - 1);
continue;
}
*cmd1++ = '\0';
* one cmds: recover
*/
- if (cmd3 == NULL) {
+ if ( cmd3 == NULL) {
if (cmd2 == NULL) {
strncpy(file->recover_cmd, cmd1,
- sizeof(file->recover_cmd) - 1);
+ SIZEOF(file->recover_cmd) - 1);
} else {
snprintf(file->uncompress_cmd,
- sizeof(file->uncompress_cmd), "%s|", cmd1);
+ SIZEOF(file->uncompress_cmd), "%s|", cmd1);
strncpy(file->recover_cmd, cmd2,
- sizeof(file->recover_cmd) - 1);
+ SIZEOF(file->recover_cmd) - 1);
}
} else { /* cmd3 presents: decrypt | uncompress | recover */
snprintf(file->decrypt_cmd,
- sizeof(file->decrypt_cmd), "%s|", cmd1);
+ SIZEOF(file->decrypt_cmd), "%s|", cmd1);
snprintf(file->uncompress_cmd,
- sizeof(file->uncompress_cmd), "%s|", cmd2);
+ SIZEOF(file->uncompress_cmd), "%s|", cmd2);
strncpy(file->recover_cmd, cmd3,
- sizeof(file->recover_cmd) - 1);
+ SIZEOF(file->recover_cmd) - 1);
}
continue;
}
#undef SC
/* XXX complain about weird lines? */
}
- amfree(buf);
- amfree(line1);
- return;
-weird_header:
- fprintf(stderr, "%s: strange amanda header: \"%.*s\"\n", get_pname(),
- (int) buflen, buffer);
- file->type = F_WEIRD;
+out:
amfree(buf);
amfree(line1);
}
void
-build_header(buffer, file, buflen)
- char *buffer;
- const dumpfile_t *file;
- size_t buflen;
+dump_dumpfile_t(
+ const dumpfile_t *file)
+{
+ const char *pname = get_pname();
+
+ dbprintf(("%s: Contents of *(dumpfile_t *)%p:\n", pname, file));
+ dbprintf(("%s: type = %d (%s)\n", pname,
+ file->type, filetype2str(file->type)));
+ dbprintf(("%s: datestamp = '%s'\n", pname,
+ file->datestamp));
+ dbprintf(("%s: dumplevel = %d\n", pname, file->dumplevel));
+ dbprintf(("%s: compressed = %d\n", pname, file->compressed));
+ dbprintf(("%s: encrypted = %d\n", pname, file->encrypted));
+ dbprintf(("%s: comp_suffix = '%s'\n", pname,
+ file->comp_suffix));
+ dbprintf(("%s: encrypt_suffix = '%s'\n", pname,
+ file->encrypt_suffix));
+ dbprintf(("%s: name = '%s'\n", pname, file->name));
+ dbprintf(("%s: disk = '%s'\n", pname, file->disk));
+ dbprintf(("%s: program = '%s'\n", pname, file->program));
+ dbprintf(("%s: srvcompprog = '%s'\n", pname,
+ file->srvcompprog));
+ dbprintf(("%s: clntcompprog = '%s'\n", pname,
+ file->clntcompprog));
+ dbprintf(("%s: srv_encrypt = '%s'\n", pname,
+ file->srv_encrypt));
+ dbprintf(("%s: clnt_encrypt = '%s'\n", pname,
+ file->clnt_encrypt));
+ dbprintf(("%s: recover_cmd = '%s'\n", pname,
+ file->recover_cmd));
+ dbprintf(("%s: uncompress_cmd = '%s'\n", pname,
+ file->uncompress_cmd));
+ dbprintf(("%s: encrypt_cmd = '%s'\n", pname,
+ file->encrypt_cmd));
+ dbprintf(("%s: decrypt_cmd = '%s'\n", pname,
+ file->decrypt_cmd));
+ dbprintf(("%s: srv_decrypt_opt = '%s'\n", pname,
+ file->srv_decrypt_opt));
+ dbprintf(("%s: clnt_decrypt_opt = '%s'\n", pname,
+ file->clnt_decrypt_opt));
+ dbprintf(("%s: cont_filename = '%s'\n", pname,
+ file->cont_filename));
+ dbprintf(("%s: is_partial = %d\n", pname, file->is_partial));
+ dbprintf(("%s: partnum = %d\n", pname, file->partnum));
+ dbprintf(("%s: totalparts = %d\n", pname, file->totalparts));
+ dbprintf(("%s: blocksize = " SIZE_T_FMT "\n", pname,
+ (SIZE_T_FMT_TYPE)file->blocksize));
+}
+
+static void
+validate_name(
+ const char *name)
+{
+ if (strlen(name) == 0) {
+ error("Invalid name '%s'\n", name);
+ /*NOTREACHED*/
+ }
+}
+
+static void
+validate_datestamp(
+ const char *datestamp)
+{
+ if (strcmp(datestamp, "X") == 0) {
+ return;
+ }
+
+ if ((strlen(datestamp) == 8) && match("^[0-9]{8}$", datestamp)) {
+ return;
+ }
+ if ((strlen(datestamp) == 14) && match("^[0-9]{14}$", datestamp)) {
+ return;
+ }
+ error("Invalid datestamp '%s'\n", datestamp);
+ /*NOTREACHED*/
+}
+
+static void
+validate_parts(
+ const int partnum,
+ const int totalparts)
+{
+ if (partnum < 1) {
+ error("Invalid partnum (%d)\n", partnum);
+ /*NOTREACHED*/
+ }
+
+ if (partnum > totalparts && totalparts >= 0) {
+ error("Invalid partnum (%d) > totalparts (%d)\n",
+ partnum, totalparts);
+ /*NOTREACHED*/
+ }
+}
+
+void
+build_header(
+ char * buffer,
+ const dumpfile_t * file,
+ size_t buflen)
{
int n;
+ char *qname;
char split_data[128] = "";
+ dbprintf(("%s: Building type %d (%s) header of size " SIZE_T_FMT " using:\n",
+ get_pname(), file->type, filetype2str(file->type),
+ (SIZE_T_FMT_TYPE)buflen));
+ dump_dumpfile_t(file);
+
memset(buffer,'\0',buflen);
switch (file->type) {
case F_TAPESTART:
+ validate_name(file->name);
+ validate_datestamp(file->datestamp);
snprintf(buffer, buflen,
"AMANDA: TAPESTART DATE %s TAPE %s\n014\n",
file->datestamp, file->name);
break;
case F_SPLIT_DUMPFILE:
- snprintf(split_data, sizeof(split_data),
+ validate_parts(file->partnum, file->totalparts);
+ snprintf(split_data, SIZEOF(split_data),
" part %d/%d ", file->partnum, file->totalparts);
- /* FALLTHROUGH */
+ /*FALLTHROUGH*/
case F_CONT_DUMPFILE:
case F_DUMPFILE :
+ validate_name(file->name);
+ validate_datestamp(file->datestamp);
+ qname = quote_string(file->disk);
n = snprintf(buffer, buflen,
"AMANDA: %s %s %s %s %s lev %d comp %s program %s",
filetype2str(file->type),
- file->datestamp, file->name, file->disk,
+ file->datestamp, file->name, qname,
split_data,
file->dumplevel, file->comp_suffix, file->program);
+ amfree(qname);
if ( n ) {
buffer += n;
buflen -= n;
buffer += n;
buflen -= n;
- /* \014 == ^L */
+ /* \014 == ^L == form feed */
n = snprintf(buffer, buflen,
- "\tdd if=<tape> bs=%ldk skip=1 |%s %s %s\n\014\n",
- file->blocksize / 1024, file->decrypt_cmd, file->uncompress_cmd, file->recover_cmd);
- buffer += n;
- buflen -= n;
+ "\tdd if=<tape> bs=" SIZE_T_FMT "k skip=1 | %s %s %s\n\014\n",
+ (SIZE_T_FMT_TYPE)file->blocksize / 1024, file->decrypt_cmd,
+ file->uncompress_cmd, file->recover_cmd);
break;
case F_TAPEEND:
+ validate_datestamp(file->datestamp);
snprintf(buffer, buflen, "AMANDA: TAPEEND DATE %s\n\014\n",
file->datestamp);
break;
case F_UNKNOWN:
+ case F_EMPTY:
case F_WEIRD:
- break;
+ default:
+ error("Invalid header type: %d (%s)",
+ file->type, filetype2str(file->type));
+ /*NOTREACHED*/
}
}
* Prints the contents of the file structure.
*/
void
-print_header(outf, file)
- FILE *outf;
- const dumpfile_t *file;
+print_header(
+ FILE * outf,
+ const dumpfile_t * file)
{
+ char *qdisk;
char number[NUM_STR_SIZE*2];
+
switch(file->type) {
+ case F_EMPTY:
+ fprintf(outf, "EMPTY file\n");
+ break;
+
case F_UNKNOWN:
fprintf(outf, "UNKNOWN file\n");
break;
+
case F_WEIRD:
fprintf(outf, "WEIRD file\n");
break;
+
case F_TAPESTART:
fprintf(outf, "start of tape: date %s label %s\n",
file->datestamp, file->name);
break;
+
case F_DUMPFILE:
case F_CONT_DUMPFILE:
+ qdisk = quote_string(file->disk);
fprintf(outf, "%s: date %s host %s disk %s lev %d comp %s",
filetype2str(file->type), file->datestamp, file->name,
- file->disk, file->dumplevel, file->comp_suffix);
+ qdisk, file->dumplevel, file->comp_suffix);
if (*file->program)
fprintf(outf, " program %s",file->program);
if (strcmp(file->encrypt_suffix, "enc") == 0)
if (*file->clnt_decrypt_opt)
fprintf(outf, " client_decrypt_option %s", file->clnt_decrypt_opt);
fprintf(outf, "\n");
+ amfree(qdisk);
break;
+
case F_SPLIT_DUMPFILE:
if(file->totalparts > 0){
- snprintf(number, sizeof(number), "%d", file->totalparts);
+ snprintf(number, SIZEOF(number), "%d", file->totalparts);
}
- else snprintf(number, sizeof(number), "UNKNOWN");
+ else snprintf(number, SIZEOF(number), "UNKNOWN");
+ qdisk = quote_string(file->disk);
fprintf(outf, "split dumpfile: date %s host %s disk %s part %d/%s lev %d comp %s",
- file->datestamp, file->name, file->disk, file->partnum,
+ file->datestamp, file->name, qdisk, file->partnum,
number, file->dumplevel, file->comp_suffix);
if (*file->program)
fprintf(outf, " program %s",file->program);
if (*file->clnt_decrypt_opt)
fprintf(outf, " client_decrypt_option %s", file->clnt_decrypt_opt);
fprintf(outf, "\n");
+ amfree(qdisk);
break;
+
case F_TAPEEND:
fprintf(outf, "end of tape: date %s\n", file->datestamp);
break;
}
int
-known_compress_type(file)
- const dumpfile_t *file;
+known_compress_type(
+ const dumpfile_t * file)
{
if(strcmp(file->comp_suffix, ".Z") == 0)
return 1;
{ F_CONT_DUMPFILE, "CONT_FILE" },
{ F_SPLIT_DUMPFILE, "SPLIT_FILE" }
};
-#define NFILETYPES (sizeof(filetypetab) / sizeof(filetypetab[0]))
+#define NFILETYPES (size_t)(sizeof(filetypetab) / sizeof(filetypetab[0]))
static const char *
-filetype2str(type)
- filetype_t type;
+filetype2str(
+ filetype_t type)
{
int i;
- for (i = 0; i < NFILETYPES; i++)
+ for (i = 0; i < (int)NFILETYPES; i++)
if (filetypetab[i].type == type)
return (filetypetab[i].str);
return ("UNKNOWN");
}
static filetype_t
-str2filetype(str)
- const char *str;
+str2filetype(
+ const char *str)
{
int i;
- for (i = 0; i < NFILETYPES; i++)
+ for (i = 0; i < (int)NFILETYPES; i++)
if (strcmp(filetypetab[i].str, str) == 0)
return (filetypetab[i].type);
return (F_UNKNOWN);
* file named AUTHORS, in the root directory of this distribution.
*/
/*
- * $Id: fileheader.h,v 1.15 2005/12/09 03:22:52 paddy_s Exp $
+ * $Id: fileheader.h,v 1.16 2006/05/25 01:47:12 johnfranks Exp $
*
*/
typedef char string_t[STRMAX];
typedef enum {
F_UNKNOWN, F_WEIRD, F_TAPESTART, F_TAPEEND,
- F_DUMPFILE, F_CONT_DUMPFILE, F_SPLIT_DUMPFILE
+ F_DUMPFILE, F_CONT_DUMPFILE, F_SPLIT_DUMPFILE, F_EMPTY
} filetype_t;
typedef struct file_s {
int is_partial;
int partnum;
int totalparts; /* -1 == UNKNOWN */
- long blocksize;
+ size_t blocksize;
} dumpfile_t;
/* local functions */
-void fh_init P((dumpfile_t *file));
-void parse_file_header P((const char *buffer, dumpfile_t *file, size_t buflen));
-void build_header P((char *buffer,
- const dumpfile_t *file,
- size_t buflen));
-void print_header P((FILE *outf, const dumpfile_t *file));
-int known_compress_type P((const dumpfile_t *file));
+void fh_init(dumpfile_t *file);
+void parse_file_header(const char *buffer, dumpfile_t *file, size_t buflen);
+void build_header(char *buffer, const dumpfile_t *file, size_t buflen);
+void print_header(FILE *outf, const dumpfile_t *file);
+int known_compress_type(const dumpfile_t *file);
+void dump_dumpfile_t(const dumpfile_t *file);
#endif /* !FILEHEADER_H */
* file named AUTHORS, in the root directory of this distribution.
*/
/*
- * $Id: genversion.c,v 1.31 2003/10/07 17:09:46 martinea Exp $
+ * $Id: genversion.c,v 1.36 2006/07/13 03:22:20 paddy_s Exp $
*
* dump the current Amanda version info
*/
#define LMARGIN 6
#define RMARGIN 70
-static int linelen;
+static size_t linelen;
#define startline(title) printf(" \"%-*s", LMARGIN, title); linelen = 0
#define endline() printf("\\n\",\n")
-static void prstr P((const char *));
-static void prvar P((const char *, const char *));
-int main P((void));
+static void prstr(const char *);
+static void prvar(const char *, const char *);
+static void prundefvar(const char *var);
+static void prnum(const char *var, long val);
+
+int main(int, char **);
/* Print a string */
static void
-prstr(string)
- const char *string;
+prstr(
+ const char *string)
{
size_t len = strlen(string) + 1;
/* Print a text variable */
static void
-prvar(var, val)
- const char *var, *val;
+prvar(
+ const char *var,
+ const char *val)
{
size_t new_len;
new_len = strlen(var)
- + sizeof("=\\\"")
+ + SIZEOF("=\\\"")
+ strlen(val)
- + sizeof("\\\"")
+ + SIZEOF("\\\"")
+ 1;
if(new_len > buf_len) {
free(buf);
buf_len = new_len;
- buf = malloc(new_len); /* let it die if malloc() fails */
+ buf = malloc(new_len);
+ if (!buf) {
+ fprintf(stderr, "genversion: Not enough memory");
+ abort();
+ /*NOTREACHED*/
+ }
}
- sprintf(buf, "%s=\\\"%s\\\"", var, val); /* safe */
+ snprintf(buf, buf_len, "%s=\\\"%s\\\"", var, val); /* safe */
prstr(buf);
}
/* Print a undef variable */
static void
-prundefvar(var)
- const char *var;
+prundefvar(
+ const char *var)
{
size_t new_len;
new_len = strlen(var)
- + sizeof("=UNDEF")
+ + SIZEOF("=UNDEF")
+ 1;
if(new_len > buf_len) {
free(buf);
buf_len = new_len;
buf = malloc(new_len); /* let it die if malloc() fails */
+ if (!buf) {
+ fprintf(stderr, "genversion: Not enough memory");
+ abort();
+ /*NOTREACHED*/
+ }
}
- sprintf(buf, "%s=UNDEF", var); /* safe */
+ snprintf(buf, buf_len, "%s=UNDEF", var); /* safe */
prstr(buf);
}
/* Print a numeric variable */
static void
-prnum(var, val)
- const char *var;
- long val;
+prnum(
+ const char *var,
+ long val)
{
static char number[NUM_STR_SIZE];
size_t new_len;
- snprintf(number, sizeof(number), "%ld", val);
+ snprintf(number, SIZEOF(number), "%ld", val);
new_len = strlen(var)
- + sizeof("=")
+ + SIZEOF("=")
+ strlen(number)
+ 1;
if(new_len > buf_len) {
free(buf);
buf_len = new_len;
buf = malloc(new_len); /* let it die if malloc() fails */
+ if (!buf) {
+ fprintf(stderr, "genversion: Not enough memory");
+ abort();
+ /*NOTREACHED*/
+ }
}
- sprintf(buf, "%s=%s", var, number); /* safe */
+ snprintf(buf, buf_len, "%s=%s", var, number); /* safe */
prstr(buf);
}
int
-main()
+main(
+ int argc,
+ char ** argv)
{
const char *v;
char *verstr;
size_t v_len;
+ (void)argc; /* Quiet unused parameter warning */
+ (void)argv; /* Quiet unused parameter warning */
+
printf("/* version.c - generated by genversion.c - DO NOT EDIT! */\n");
printf("const char * const version_info[] = {\n");
startline("build:");
v = version();
- v_len = sizeof("Amanda-") + strlen(v) + 1;
+ v_len = SIZEOF("Amanda-") + strlen(v) + 1;
verstr = malloc(v_len);
- sprintf(verstr, "Amanda-%s", v); /* safe */
+ if (!verstr) {
+ fprintf(stderr, "genversion: Not enough memory");
+ abort();
+ /*NOTREACHED*/
+ }
+ snprintf(verstr, v_len, "Amanda-%s", v); /* safe */
prvar("VERSION", verstr);
free(verstr);
prvar("DEFAULT_SERVER", DEFAULT_SERVER);
prvar("DEFAULT_CONFIG", DEFAULT_CONFIG);
prvar("DEFAULT_TAPE_SERVER", DEFAULT_TAPE_SERVER);
+
+#ifdef DEFAULT_TAPE_DEVICE
prvar("DEFAULT_TAPE_DEVICE", DEFAULT_TAPE_DEVICE);
+#endif
#ifdef AIX_BACKUP
prstr("AIX_BACKUP");
printf(" 0\n};\n");
- exit(0);
+ return (0); /* exit */
}
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*/
-/* $Id: getcwd.c,v 1.4 2002/02/11 01:32:10 jrjackson Exp $ */
+/* $Id: getcwd.c,v 1.5 2006/05/25 01:47:12 johnfranks Exp $ */
#ifndef lint
-static char rcsid[] = "$Header: /cvsroot/amanda/amanda/common-src/getcwd.c,v 1.4 2002/02/11 01:32:10 jrjackson Exp $ SPRITE (Berkeley)";
+static char rcsid[] = "$Header: /cvsroot/amanda/amanda/common-src/getcwd.c,v 1.5 2006/05/25 01:47:12 johnfranks Exp $ SPRITE (Berkeley)";
#endif /* not lint */
-#include <stdio.h>
-#include <errno.h>
-#include <sys/param.h>
+#include "amanda.h"
extern char *getwd();
extern int errno;
*/
/*
- * $Id: krb4-security.c,v 1.9.2.1 2006/04/11 11:11:16 martinea Exp $
+ * $Id: krb4-security.c,v 1.18 2006/07/13 03:22:20 paddy_s Exp $
*
* krb4-security.c - helper functions for kerberos v4 security.
*/
#include "packet.h"
#include "queue.h"
#include "security.h"
+#include "security-util.h"
#include "protocol.h"
#include "stream.h"
#include "version.h"
#endif /* HAVE_ON_EXIT */
#endif /* ! HAVE_ATEXIT */
-int krb_set_lifetime P((int));
-int kuserok P((AUTH_DAT *, char *));
+int krb_set_lifetime(int);
+int kuserok(AUTH_DAT *, char *);
/*
* This is the private handle data
* The rest is used for the async recvpkt/recvpkt_cancel
* interface.
*/
- void (*fn) P((void *, pkt_t *, security_status_t));
+ void (*fn)(void *, pkt_t *, security_status_t);
/* func to call when packet recvd */
void *arg; /* argument to pass function */
event_handle_t *ev_timeout; /* timeout handle for recv */
int socket; /* fd for server-side accepts */
event_handle_t *ev_read; /* read event handle */
char databuf[MAX_TAPE_BLOCK_BYTES]; /* read buffer */
- void (*fn) P((void *, void *, int)); /* read event fn */
+ int len; /* */
+ void (*fn)(void *, void *, ssize_t);/* read event fn */
void *arg; /* arg for previous */
};
/*
* Interface functions
*/
-static void krb4_connect P((const char *,
- char *(*)(char *, void *),
- void (*)(void *, security_handle_t *, security_status_t), void *));
-static void krb4_accept P((int, int, void (*)(security_handle_t *, pkt_t *)));
-static void krb4_close P((void *));
-static int krb4_sendpkt P((void *, pkt_t *));
-static void krb4_recvpkt P((void *,
- void (*)(void *, pkt_t *, security_status_t), void *, int));
-static void krb4_recvpkt_cancel P((void *));
-
-static void *krb4_stream_server P((void *));
-static int krb4_stream_accept P((void *));
-static void *krb4_stream_client P((void *, int));
-static void krb4_stream_close P((void *));
-static int krb4_stream_auth P((void *));
-static int krb4_stream_id P((void *));
-static int krb4_stream_write P((void *, const void *, size_t));
-static void krb4_stream_read P((void *, void (*)(void *, void *, int),
- void *));
-static void krb4_stream_read_cancel P((void *));
+static void krb4_connect(const char *, char *(*)(char *, void *),
+ void (*)(void *, security_handle_t *, security_status_t),
+ void *, void *);
+static void krb4_accept(const struct security_driver *, int, int, void (*)(security_handle_t *, pkt_t *));
+static void krb4_close(void *);
+static int krb4_sendpkt(void *, pkt_t *);
+static void krb4_recvpkt(void *, void (*)(void *, pkt_t *, security_status_t),
+ void *, int);
+static void krb4_recvpkt_cancel(void *);
+static void * krb4_stream_server(void *);
+static int krb4_stream_accept(void *);
+static void * krb4_stream_client(void *, int);
+static void krb4_stream_close(void *);
+static int krb4_stream_auth(void *);
+static int krb4_stream_id(void *);
+static int krb4_stream_write(void *, const void *, size_t);
+static void krb4_stream_read(void *, void (*)(void *, void *, int), void *);
+static int krb4_stream_read_sync(void *, void **);
+static void krb4_stream_read_cancel(void *);
/*
krb4_stream_id,
krb4_stream_write,
krb4_stream_read,
+ krb4_stream_read_sync,
krb4_stream_read_cancel,
+ sec_close_connection_none,
};
/*
#define handleq_first() TAILQ_FIRST(&handleq.tailq)
#define handleq_next(kh) TAILQ_NEXT(kh, tq)
-
+
/*
* This is the event manager's handle for our netfd
* created. If NULL, no new handles are created.
* It is passed the new handle and the received pkt
*/
-static void (*accept_fn) P((security_handle_t *, pkt_t *));
+static void (*accept_fn)(security_handle_t *, pkt_t *);
/*
*/
union mutual {
char pad[8];
- unsigned long cksum;
+ long cksum;
};
/*
* Private functions
*/
-static unsigned long krb4_cksum P((const char *));
-static void krb4_getinst P((const char *, char *, size_t));
-static void host2key P((const char *, const char *, des_cblock *));
-static void init P((void));
-static void inithandle P((struct krb4_handle *, struct hostent *, int,
- const char *));
-static void get_tgt P((void));
-static void killtickets P((void));
-static void recvpkt_callback P((void *));
-static void recvpkt_timeout P((void *));
-static int recv_security_ok P((struct krb4_handle *, pkt_t *));
-static void stream_read_callback P((void *));
-static int net_write P((int, const void *, size_t));
-static int net_read P((int, void *, size_t, int));
-
-static int add_ticket P((struct krb4_handle *, const pkt_t *, dgram_t *));
-static void add_mutual_auth P((struct krb4_handle *, dgram_t *));
-static int check_ticket P((struct krb4_handle *, const pkt_t *,
- const char *, unsigned long));
-static int check_mutual_auth P((struct krb4_handle *, const char *));
-
-static const char *pkthdr2str P((const struct krb4_handle *, const pkt_t *));
-static int str2pkthdr P((const char *, pkt_t *, char *, size_t, int *));
-
-static const char *bin2astr P((const unsigned char *, int));
-static void astr2bin P((const char *, unsigned char *, int *));
-
-static void encrypt_data P((void *, int, des_cblock *));
-static void decrypt_data P((void *, int, des_cblock *));
+static unsigned long krb4_cksum(const char *);
+static void krb4_getinst(const char *, char *, size_t);
+static void host2key(const char *, const char *, des_cblock *);
+static void init(void);
+static void inithandle(struct krb4_handle *, struct hostent *, int,
+ const char *);
+static void get_tgt(void);
+static void killtickets(void);
+static void recvpkt_callback(void *);
+static void recvpkt_timeout(void *);
+static int recv_security_ok(struct krb4_handle *, pkt_t *);
+static void stream_read_callback(void *);
+static void stream_read_sync_callback(void *);
+static int net_write(int, const void *, size_t);
+static int net_read(int, void *, size_t, int);
+
+static int add_ticket(struct krb4_handle *, const pkt_t *, dgram_t *);
+static void add_mutual_auth(struct krb4_handle *, dgram_t *);
+static int check_ticket(struct krb4_handle *, const pkt_t *,
+ const char *, unsigned long);
+static int check_mutual_auth(struct krb4_handle *, const char *);
+
+static const char *pkthdr2str(const struct krb4_handle *, const pkt_t *);
+static int str2pkthdr(const char *, pkt_t *, char *, size_t, int *);
+
+static const char *bin2astr(const unsigned char *, int);
+static void astr2bin(const unsigned char *, unsigned char *, int *);
+
+static void encrypt_data(void *, size_t, des_cblock *);
+static void decrypt_data(void *, size_t, des_cblock *);
#define HOSTNAME_INSTANCE inst
* Setup some things about krb4. This should only be called once.
*/
static void
-init()
+init(void)
{
char tktfile[256];
int port;
return;
beenhere = 1;
- gethostname(hostname, sizeof(hostname) - 1);
- hostname[sizeof(hostname) - 1] = '\0';
+ gethostname(hostname, SIZEOF(hostname) - 1);
+ hostname[SIZEOF(hostname) - 1] = '\0';
if (atexit(killtickets) < 0)
error("could not setup krb4 exit handler: %s", strerror(errno));
* This file also needs to be removed so that no extra tickets are
* hanging around.
*/
- snprintf(tktfile, sizeof(tktfile), "/tmp/tkt%ld-%ld.amanda",
+ snprintf(tktfile, SIZEOF(tktfile), "/tmp/tkt%ld-%ld.amanda",
(long)getuid(), (long)getpid());
ticketfilename = stralloc(tktfile);
unlink(ticketfilename);
* Get a ticket granting ticket and stuff it in the cache
*/
static void
-get_tgt()
+get_tgt(void)
{
char realm[REALM_SZ];
int rc;
- strncpy(realm, krb_realmofhost(hostname), sizeof(realm) - 1);
- realm[sizeof(realm) - 1] = '\0';
+ strncpy(realm, krb_realmofhost(hostname), SIZEOF(realm) - 1);
+ realm[SIZEOF(realm) - 1] = '\0';
rc = krb_get_svc_in_tkt(SERVER_HOST_PRINCIPLE, SERVER_HOST_INSTANCE,
realm, "krbtgt", realm, TICKET_LIFETIME, SERVER_HOST_KEY_FILE);
* up a network "connection".
*/
static void
-krb4_connect(hostname, conf_fn, fn, arg)
- const char *hostname;
- char *(*conf_fn) P((char *, void *));
- void (*fn) P((void *, security_handle_t *, security_status_t));
- void *arg;
+krb4_connect(
+ const char *hostname,
+ char * (*conf_fn)(char *, void *),
+ void (*fn)(void *, security_handle_t *, security_status_t),
+ void * arg,
+ void * datap)
{
struct krb4_handle *kh;
char handle[32];
*/
init();
- kh = alloc(sizeof(*kh));
+ kh = alloc(SIZEOF(*kh));
security_handleinit(&kh->sech, &krb4_security_driver);
if ((he = gethostbyname(hostname)) == NULL) {
return;
}
if ((se = getservbyname(KAMANDA_SERVICE_NAME, "udp")) == NULL)
- port = htons(KAMANDA_SERVICE_DEFAULT);
+ port = (int)htons(KAMANDA_SERVICE_DEFAULT);
else
port = se->s_port;
- snprintf(handle, sizeof(handle), "%ld", (long)time(NULL));
- inithandle(kh, he, port, handle);
+ snprintf(handle, SIZEOF(handle), "%ld", (long)time(NULL));
+ inithandle(kh, he, (int)port, handle);
(*fn)(arg, &kh->sech, S_OK);
}
* Setup to handle new incoming connections
*/
static void
-krb4_accept(in, out, fn)
- int in, out;
- void (*fn) P((security_handle_t *, pkt_t *));
+krb4_accept(
+ const struct security_driver *driver,
+ int in,
+ int out,
+ void (*fn)(security_handle_t *, pkt_t *))
{
/*
accept_fn = fn;
if (ev_netfd == NULL)
- ev_netfd = event_register(netfd.socket, EV_READFD,
- recvpkt_callback, NULL);
+ ev_netfd = event_register((event_id_t)netfd.socket, EV_READFD,
+ recvpkt_callback, NULL);
}
/*
* Given a hostname and a port, setup a krb4_handle
*/
static void
-inithandle(kh, he, port, handle)
- struct krb4_handle *kh;
- struct hostent *he;
- int port;
- const char *handle;
+inithandle(
+ struct krb4_handle *kh,
+ struct hostent * he,
+ int port,
+ const char * handle)
{
/*
* Get the instance and realm for this host
* (krb_realmofhost always returns something)
*/
- krb4_getinst(he->h_name, kh->inst, sizeof(kh->inst));
- strncpy(kh->realm, krb_realmofhost(he->h_name), sizeof(kh->realm) - 1);
- kh->realm[sizeof(kh->realm) - 1] = '\0';
+ krb4_getinst(he->h_name, kh->inst, SIZEOF(kh->inst));
+ strncpy(kh->realm, krb_realmofhost(he->h_name), SIZEOF(kh->realm) - 1);
+ kh->realm[SIZEOF(kh->realm) - 1] = '\0';
/*
* Save a copy of the hostname
*/
- strncpy(kh->hostname, he->h_name, sizeof(kh->hostname) - 1);
- kh->hostname[sizeof(kh->hostname) - 1] = '\0';
+ strncpy(kh->hostname, he->h_name, SIZEOF(kh->hostname) - 1);
+ kh->hostname[SIZEOF(kh->hostname) - 1] = '\0';
/*
* We have no checksum or session key at this point
*/
kh->cksum = 0;
- memset(kh->session_key, 0, sizeof(kh->session_key));
+ memset(kh->session_key, 0, SIZEOF(kh->session_key));
/*
* Setup our peer info. We don't do anything with the sequence yet,
* so just leave it at 0.
*/
- kh->peer.sin_family = AF_INET;
- kh->peer.sin_port = port;
+ kh->peer.sin_family = (sa_family_t)AF_INET;
+ kh->peer.sin_port = (in_port_t)port;
kh->peer.sin_addr = *(struct in_addr *)he->h_addr;
- strncpy(kh->proto_handle, handle, sizeof(kh->proto_handle) - 1);
- kh->proto_handle[sizeof(kh->proto_handle) - 1] = '\0';
+ strncpy(kh->proto_handle, handle, SIZEOF(kh->proto_handle) - 1);
+ kh->proto_handle[SIZEOF(kh->proto_handle) - 1] = '\0';
kh->sequence = 0;
kh->fn = NULL;
kh->arg = NULL;
* frees a handle allocated by the above
*/
static void
-krb4_close(inst)
- void *inst;
+krb4_close(
+ void * inst)
{
krb4_recvpkt_cancel(inst);
/*
* Transmit a packet. Add security information first.
*/
-static int
-krb4_sendpkt(cookie, pkt)
- void *cookie;
- pkt_t *pkt;
+static ssize_t
+krb4_sendpkt(
+ void * cookie,
+ pkt_t * pkt)
{
struct krb4_handle *kh = cookie;
* it has been read.
*/
static void
-krb4_recvpkt(cookie, fn, arg, timeout)
- void *cookie, *arg;
- void (*fn) P((void *, pkt_t *, security_status_t));
- int timeout;
+krb4_recvpkt(
+ void * cookie,
+ void (*fn)(void *, pkt_t *, security_status_t),
+ void * arg,
+ int timeout)
{
struct krb4_handle *kh = cookie;
*/
if (ev_netfd == NULL) {
assert(handleq.qlength == 0);
- ev_netfd = event_register(netfd.socket, EV_READFD,
- recvpkt_callback, NULL);
+ ev_netfd = event_register((event_id_t)netfd.socket, EV_READFD,
+ recvpkt_callback, NULL);
}
/*
if (timeout < 0)
kh->ev_timeout = NULL;
else
- kh->ev_timeout = event_register(timeout, EV_TIME, recvpkt_timeout, kh);
+ kh->ev_timeout = event_register((event_id_t)timeout, EV_TIME,
+ recvpkt_timeout, kh);
kh->fn = fn;
kh->arg = arg;
}
* for our network fd.
*/
static void
-krb4_recvpkt_cancel(cookie)
- void *cookie;
+krb4_recvpkt_cancel(
+ void * cookie)
{
struct krb4_handle *kh = cookie;
* socket for receiving a connection.
*/
static void *
-krb4_stream_server(h)
- void *h;
+krb4_stream_server(
+ void * h)
{
struct krb4_handle *kh = h;
struct krb4_stream *ks;
assert(kh != NULL);
- ks = alloc(sizeof(*ks));
+ ks = alloc(SIZEOF(*ks));
security_streaminit(&ks->secstr, &krb4_security_driver);
- ks->socket = stream_server(&ks->port, STREAM_BUFSIZE, STREAM_BUFSIZE);
+ ks->socket = stream_server(&ks->port, STREAM_BUFSIZE, STREAM_BUFSIZE, 1);
if (ks->socket < 0) {
security_seterror(&kh->sech,
"can't create server stream: %s", strerror(errno));
* Accept an incoming connection on a stream_server socket
*/
static int
-krb4_stream_accept(s)
- void *s;
+krb4_stream_accept(
+ void * s)
{
struct krb4_stream *ks = s;
struct krb4_handle *kh;
assert(ks->socket >= 0);
assert(ks->fd == -1);
- ks->fd = stream_accept(ks->socket, 30, -1, -1);
+ ks->fd = stream_accept(ks->socket, 30, STREAM_BUFSIZE, STREAM_BUFSIZE);
if (ks->fd < 0) {
security_stream_seterror(&ks->secstr,
"can't accept new stream connection: %s", strerror(errno));
* Return a connected stream.
*/
static void *
-krb4_stream_client(h, id)
- void *h;
- int id;
+krb4_stream_client(
+ void * h,
+ int id)
{
struct krb4_handle *kh = h;
struct krb4_stream *ks;
assert(kh != NULL);
- if (id < 0) {
- security_seterror(&kh->sech,
- "%d: invalid security stream id", id);
- return (NULL);
- }
-
- ks = alloc(sizeof(*ks));
+ ks = alloc(SIZEOF(*ks));
security_streaminit(&ks->secstr, &krb4_security_driver);
ks->fd = stream_client(kh->hostname, id, STREAM_BUFSIZE, STREAM_BUFSIZE,
&ks->port, 0);
* Close and unallocate resources for a stream.
*/
static void
-krb4_stream_close(s)
- void *s;
+krb4_stream_close(
+ void * s)
{
struct krb4_stream *ks = s;
* into byte arrays and send those.
*/
static int
-krb4_stream_auth(s)
- void *s;
+krb4_stream_auth(
+ void * s)
{
struct krb4_stream *ks = s;
struct krb4_handle *kh;
assert(fd >= 0);
/* make sure our timeval is what we're expecting, see above */
- assert(sizeof(struct timeval) == 8);
+ assert(SIZEOF(struct timeval) == 8);
/*
* Get the current time, put it in network byte order, encrypt it
* and present it to the other side.
*/
gettimeofday(&local, &tz);
- enc.tv_sec = htonl(local.tv_sec);
- enc.tv_usec = htonl(local.tv_usec);
- encrypt_data(&enc, sizeof(enc), &kh->session_key);
- if (net_write(fd, &enc, sizeof(enc)) < 0) {
+ enc.tv_sec = (long)htonl((uint32_t)local.tv_sec);
+ enc.tv_usec = (long)htonl((uint32_t)local.tv_usec);
+ encrypt_data(&enc, SIZEOF(enc), &kh->session_key);
+ if (net_write(fd, &enc, SIZEOF(enc)) < 0) {
security_stream_seterror(&ks->secstr,
"krb4 stream handshake write error: %s", strerror(errno));
return (-1);
* and useconds by one. Reencrypt, and present to the other side.
* Timeout in 10 seconds.
*/
- if (net_read(fd, &enc, sizeof(enc), 60) < 0) {
+ if (net_read(fd, &enc, SIZEOF(enc), 60) < 0) {
security_stream_seterror(&ks->secstr,
"krb4 stream handshake read error: %s", strerror(errno));
return (-1);
}
- decrypt_data(&enc, sizeof(enc), &kh->session_key);
+ decrypt_data(&enc, SIZEOF(enc), &kh->session_key);
/* XXX do timestamp checking here */
- enc.tv_sec = htonl(ntohl(enc.tv_sec) + 1);
- enc.tv_usec = htonl(ntohl(enc.tv_usec) + 1);
- encrypt_data(&enc, sizeof(enc), &kh->session_key);
+ enc.tv_sec = (long)htonl(ntohl((uint32_t)enc.tv_sec) + 1);
+ enc.tv_usec =(long)htonl(ntohl((uint32_t)enc.tv_usec) + 1);
+ encrypt_data(&enc, SIZEOF(enc), &kh->session_key);
- if (net_write(fd, &enc, sizeof(enc)) < 0) {
+ if (net_write(fd, &enc, SIZEOF(enc)) < 0) {
security_stream_seterror(&ks->secstr,
"krb4 stream handshake write error: %s", strerror(errno));
return (-1);
* If they incremented it properly, then succeed.
* Timeout in 10 seconds.
*/
- if (net_read(fd, &enc, sizeof(enc), 60) < 0) {
+ if (net_read(fd, &enc, SIZEOF(enc), 60) < 0) {
security_stream_seterror(&ks->secstr,
"krb4 stream handshake read error: %s", strerror(errno));
return (-1);
}
- decrypt_data(&enc, sizeof(enc), &kh->session_key);
- if (ntohl(enc.tv_sec) == local.tv_sec + 1 &&
- ntohl(enc.tv_usec) == local.tv_usec + 1)
+ decrypt_data(&enc, SIZEOF(enc), &kh->session_key);
+ if ((ntohl((uint32_t)enc.tv_sec) == (uint32_t)(local.tv_sec + 1)) &&
+ (ntohl((uint32_t)enc.tv_usec) == (uint32_t)(local.tv_usec + 1)))
return (0);
security_stream_seterror(&ks->secstr,
"krb4 handshake failed: sent %ld,%ld - recv %ld,%ld",
(long)(local.tv_sec + 1), (long)(local.tv_usec + 1),
- (long)ntohl(enc.tv_sec), (long)ntohl(enc.tv_usec));
+ (long)ntohl((uint32_t)enc.tv_sec),
+ (long)ntohl((uint32_t)enc.tv_usec));
return (-1);
}
* port.
*/
static int
-krb4_stream_id(s)
- void *s;
+krb4_stream_id(
+ void * s)
{
struct krb4_stream *ks = s;
* Write a chunk of data to a stream. Blocks until completion.
*/
static int
-krb4_stream_write(s, buf, size)
- void *s;
- const void *buf;
- size_t size;
+krb4_stream_write(
+ void * s,
+ const void *buf,
+ size_t size)
{
struct krb4_stream *ks = s;
struct krb4_handle *kh = ks->krb4_handle;
* function and arg when completed.
*/
static void
-krb4_stream_read(s, fn, arg)
- void *s, *arg;
- void (*fn) P((void *, void *, int));
+krb4_stream_read(
+ void * s,
+ void (*fn)(void *, void *, ssize_t),
+ void * arg)
{
struct krb4_stream *ks = s;
if (ks->ev_read != NULL)
event_release(ks->ev_read);
- ks->ev_read = event_register(ks->fd, EV_READFD, stream_read_callback, ks);
+ ks->ev_read = event_register((event_id_t)ks->fd, EV_READFD,
+ stream_read_callback, ks);
ks->fn = fn;
ks->arg = arg;
}
+/*
+ * Write a chunk of data to a stream. Blocks until completion.
+ */
+static ssize_t
+krb4_stream_read_sync(
+ void * s,
+ void ** buf)
+{
+ struct krb4_stream *ks = s;
+
+ (void)buf; /* Quiet unused variable warning */
+ assert(ks != NULL);
+
+ if (ks->ev_read != NULL)
+ event_release(ks->ev_read);
+
+ ks->ev_read = event_register((event_id_t)ks->fd, EV_READFD,
+ stream_read_sync_callback, ks);
+ event_wait(ks->ev_read);
+ return((ssize_t)ks->len);
+}
+
+/*
+ * Callback for krb4_stream_read_sync
+ */
+static void
+stream_read_sync_callback(
+ void * arg)
+{
+ struct krb4_stream *ks = arg;
+ ssize_t n;
+
+ assert(ks != NULL);
+ assert(ks->fd != -1);
+
+ /*
+ * Remove the event first, and then call the callback.
+ * We remove it first because we don't want to get in their
+ * way if they reschedule it.
+ */
+ krb4_stream_read_cancel(ks);
+ n = read(ks->fd, ks->databuf, sizeof(ks->databuf));
+ if (n < 0)
+ security_stream_seterror(&ks->secstr,
+ strerror(errno));
+ ks->len = (int)n;
+}
+
/*
* Cancel a previous stream read request. It's ok if we didn't have a read
* scheduled.
*/
static void
-krb4_stream_read_cancel(s)
- void *s;
+krb4_stream_read_cancel(
+ void * s)
{
struct krb4_stream *ks = s;
* Callback for krb4_stream_read
*/
static void
-stream_read_callback(arg)
- void *arg;
+stream_read_callback(
+ void * arg)
{
struct krb4_stream *ks = arg;
- int n;
+ ssize_t n;
assert(ks != NULL);
assert(ks->fd != -1);
* way if they reschedule it.
*/
krb4_stream_read_cancel(ks);
- n = read(ks->fd, ks->databuf, sizeof(ks->databuf));
+ n = read(ks->fd, ks->databuf, SIZEOF(ks->databuf));
if (n < 0)
security_stream_seterror(&ks->secstr,
strerror(errno));
* and does the real callback if so.
*/
static void
-recvpkt_callback(cookie)
- void *cookie;
+recvpkt_callback(
+ void * cookie)
{
char handle[32];
struct sockaddr_in peer;
int sequence;
struct krb4_handle *kh;
struct hostent *he;
- void (*fn) P((void *, pkt_t *, security_status_t));
+ void (*fn)(void *, pkt_t *, security_status_t);
void *arg;
assert(cookie == NULL);
dgram_zero(&netfd);
if (dgram_recv(&netfd, 0, &peer) < 0)
return;
- if (str2pkthdr(netfd.cur, &pkt, handle, sizeof(handle), &sequence) < 0)
+ if (str2pkthdr(netfd.cur, &pkt, handle, SIZEOF(handle), &sequence) < 0)
return;
for (kh = handleq_first(); kh != NULL; kh = handleq_next(kh)) {
if (strcmp(kh->proto_handle, handle) == 0 &&
memcmp(&kh->peer.sin_addr, &peer.sin_addr,
- sizeof(peer.sin_addr)) == 0 &&
+ SIZEOF(peer.sin_addr)) == 0 &&
kh->peer.sin_port == peer.sin_port) {
kh->sequence = sequence;
if (accept_fn == NULL)
return;
- he = gethostbyaddr((void *)&peer.sin_addr, sizeof(peer.sin_addr), AF_INET);
+ he = gethostbyaddr((void *)&peer.sin_addr, SIZEOF(peer.sin_addr), AF_INET);
if (he == NULL)
return;
- kh = alloc(sizeof(*kh));
+ kh = alloc(SIZEOF(*kh));
security_handleinit(&kh->sech, &krb4_security_driver);
- inithandle(kh, he, peer.sin_port, handle);
+ inithandle(kh, he, (int)peer.sin_port, handle);
/*
* Check the security of the packet. If it is bad, then pass NULL
* This is called when a handle times out before receiving a packet.
*/
static void
-recvpkt_timeout(cookie)
- void *cookie;
+recvpkt_timeout(
+ void * cookie)
{
struct krb4_handle *kh = cookie;
- void (*fn) P((void *, pkt_t *, security_status_t));
+ void (*fn)(void *, pkt_t *, security_status_t);
void *arg;
assert(kh != NULL);
* Add a ticket to the message
*/
static int
-add_ticket(kh, pkt, msg)
- struct krb4_handle *kh;
- const pkt_t *pkt;
- dgram_t *msg;
+add_ticket(
+ struct krb4_handle *kh,
+ const pkt_t * pkt,
+ dgram_t * msg)
{
char inst[INST_SZ];
KTEXT_ST ticket;
char *security;
int rc;
- kh->cksum = krb4_cksum(pkt->body);
+ kh->cksum = (long)krb4_cksum(pkt->body);
#if CLIENT_HOST_INSTANCE == HOSTNAME_INSTANCE
/*
* User requested that all instances be based on the target
* hostname.
*/
- strncpy(inst, kh->inst, sizeof(inst) - 1);
+ strncpy(inst, kh->inst, SIZEOF(inst) - 1);
#else
/*
* User requested a fixed instance.
*/
- strncpy(inst, CLIENT_HOST_INSTANCE, sizeof(inst) - 1);
+ strncpy(inst, CLIENT_HOST_INSTANCE, SIZEOF(inst) - 1);
#endif
- inst[sizeof(inst) - 1] = '\0';
+ inst[SIZEOF(inst) - 1] = '\0';
/*
* Get a ticket with the user-defined service and instance,
* the req, + 1
*/
static void
-add_mutual_auth(kh, msg)
- struct krb4_handle *kh;
- dgram_t *msg;
+add_mutual_auth(
+ struct krb4_handle *kh,
+ dgram_t * msg)
{
union mutual mutual;
char *security;
assert(kh->cksum != 0);
assert(kh->session_key[0] != '\0');
- memset(&mutual, 0, sizeof(mutual));
- mutual.cksum = htonl(kh->cksum + 1);
- encrypt_data(&mutual, sizeof(mutual), &kh->session_key);
+ memset(&mutual, 0, SIZEOF(mutual));
+ mutual.cksum = (unsigned long)htonl((uint32_t)kh->cksum + 1);
+ encrypt_data(&mutual, SIZEOF(mutual), &kh->session_key);
security = vstralloc("SECURITY MUTUAL-AUTH ",
- bin2astr(mutual.pad, sizeof(mutual.pad)), "\n", NULL);
+ bin2astr((unsigned char *)mutual.pad,
+ (int)sizeof(mutual.pad)), "\n", NULL);
dgram_cat(msg, security);
amfree(security);
}
* passed packet.
*/
static int
-recv_security_ok(kh, pkt)
- struct krb4_handle *kh;
- pkt_t *pkt;
+recv_security_ok(
+ struct krb4_handle *kh,
+ pkt_t * pkt)
{
char *tok, *security, *body;
unsigned long cksum;
* Increment the cur pointer past it to the data section after
* parsing is finished.
*/
- if (strncmp(pkt->body, "SECURITY", sizeof("SECURITY") - 1) == 0) {
+ if (strncmp(pkt->body, "SECURITY", SIZEOF("SECURITY") - 1) == 0) {
tok = strtok(pkt->body, " ");
assert(strcmp(tok, "SECURITY") == 0);
/* security info goes until the newline */
}
/*
- * Get a checksum of the non-security parts of the body
+ * Get a checksum of the non-security parts of the body
*/
cksum = krb4_cksum(body);
* Check the ticket in a REQ packet for authenticity
*/
static int
-check_ticket(kh, pkt, ticket_str, cksum)
- struct krb4_handle *kh;
- const pkt_t *pkt;
- const char *ticket_str;
- unsigned long cksum;
+check_ticket(
+ struct krb4_handle *kh,
+ const pkt_t * pkt,
+ const char * ticket_str,
+ unsigned long cksum)
{
char inst[INST_SZ];
KTEXT_ST ticket;
assert(pkt != NULL);
assert(ticket_str != NULL);
- ticket.length = sizeof(ticket.dat);
- astr2bin(ticket_str, ticket.dat, &ticket.length);
+ ticket.length = (int)sizeof(ticket.dat);
+ astr2bin((unsigned char *)ticket_str, ticket.dat, &ticket.length);
assert(ticket.length > 0);
/* get a copy of the instance into writable memory */
#if CLIENT_HOST_INSTANCE == HOSTNAME_INSTANCE
- strncpy(inst, krb_get_phost(hostname), sizeof(inst) - 1);
+ strncpy(inst, krb_get_phost(hostname), SIZEOF(inst) - 1);
#else
- strncpy(inst, CLIENT_HOST_INSTANCE, sizeof(inst) - 1);
+ strncpy(inst, CLIENT_HOST_INSTANCE, SIZEOF(inst) - 1);
#endif
- inst[sizeof(inst) - 1] = '\0';
+ inst[SIZEOF(inst) - 1] = '\0';
/* get the checksum out of the ticket */
rc = krb_rd_req(&ticket, CLIENT_HOST_PRINCIPLE, inst,
kh->hostname, (long)auth.checksum, cksum);
return (-1);
}
- kh->cksum = cksum;
- memcpy(kh->session_key, auth.session, sizeof(kh->session_key));
+ kh->cksum = (unsigned long)cksum;
+ memcpy(kh->session_key, auth.session, SIZEOF(kh->session_key));
/*
* If FORCE_USERID is set, then we need to specifically
* the same checksum as our request + 1.
*/
static int
-check_mutual_auth(kh, mutual_auth_str)
- struct krb4_handle *kh;
- const char *mutual_auth_str;
+check_mutual_auth(
+ struct krb4_handle *kh,
+ const char * mutual_auth_str)
{
union mutual mutual;
int len;
assert(kh->cksum != 0);
/* convert the encoded string into binary data */
- len = sizeof(mutual);
- astr2bin(mutual_auth_str, (unsigned char *)&mutual, &len);
+ len = (int)sizeof(mutual);
+ astr2bin((unsigned char *)mutual_auth_str, (unsigned char *)&mutual, &len);
/* unencrypt the string using the key in the ticket file */
host2key(kh->hostname, kh->inst, &kh->session_key);
- decrypt_data(&mutual, len, &kh->session_key);
- mutual.cksum = ntohl(mutual.cksum);
+ decrypt_data(&mutual, (size_t)len, &kh->session_key);
+ mutual.cksum = (unsigned long)ntohl((uint32_t)mutual.cksum);
/* the data must be the same as our request cksum + 1 */
- if (mutual.cksum != kh->cksum + 1) {
+ if (mutual.cksum != (kh->cksum + 1)) {
security_seterror(&kh->sech,
"krb4 checksum mismatch from %s (remote=%lu, local=%lu)",
kh->hostname, mutual.cksum, kh->cksum + 1);
* Convert a pkt_t into a header string for our packet
*/
static const char *
-pkthdr2str(kh, pkt)
- const struct krb4_handle *kh;
- const pkt_t *pkt;
+pkthdr2str(
+ const struct krb4_handle * kh,
+ const pkt_t * pkt)
{
static char retbuf[256];
assert(kh != NULL);
assert(pkt != NULL);
- snprintf(retbuf, sizeof(retbuf), "Amanda %d.%d %s HANDLE %s SEQ %d\n",
+ snprintf(retbuf, SIZEOF(retbuf), "Amanda %d.%d %s HANDLE %s SEQ %d\n",
VERSION_MAJOR, VERSION_MINOR, pkt_type2str(pkt->type),
kh->proto_handle, kh->sequence);
* Returns negative on parse error.
*/
static int
-str2pkthdr(origstr, pkt, handle, handlesize, sequence)
- const char *origstr;
- pkt_t *pkt;
- char *handle;
- size_t handlesize;
- int *sequence;
+str2pkthdr(
+ const char *origstr,
+ pkt_t * pkt,
+ char * handle,
+ size_t handlesize,
+ int * sequence)
{
char *str;
const char *tok;
}
static void
-host2key(hostname, inst, key)
- const char *hostname, *inst;
- des_cblock *key;
+host2key(
+ const char *hostname,
+ const char *inst,
+ des_cblock *key)
{
char realm[256];
CREDENTIALS cred;
- strncpy(realm, krb_realmofhost((char *)hostname), sizeof(realm) - 1);
- realm[sizeof(realm) - 1] = '\0';
+ strncpy(realm, krb_realmofhost((char *)hostname), SIZEOF(realm) - 1);
+ realm[SIZEOF(realm) - 1] = '\0';
#if CLIENT_HOST_INSTANCE != HOSTNAME_INSTANCE
inst = CLIENT_HOST_INSTANCE
#endif
krb_get_cred(CLIENT_HOST_PRINCIPLE, (char *)inst, realm, &cred);
- memcpy(key, cred.session, sizeof(des_cblock));
+ memcpy(key, cred.session, SIZEOF(des_cblock));
}
* Convert a chunk of data into a string.
*/
static const char *
-bin2astr(buf, len)
- const unsigned char *buf;
- int len;
+bin2astr(
+ const unsigned char *buf,
+ int len)
{
static const char tohex[] = "0123456789ABCDEF";
static char *str = NULL;
char *q;
const unsigned char *p;
- int slen, i;
+ size_t slen;
+ int i;
/*
* calculate output string len
* We quote everything, so each input byte == 3 output chars, plus
* two more for quotes
*/
- slen = (len * 3) + 2;
+ slen = ((size_t)len * 3) + 2;
/* allocate string and fill it in */
if (str != NULL)
*q = '\0';
/* make sure we didn't overrun our allocated buffer */
- assert(q - str == slen);
+ assert((size_t)(q - str) == slen);
return (str);
}
* Convert an encoded string into a block of data bytes
*/
static void
-astr2bin(astr, buf, lenp)
- const char *astr;
- unsigned char *buf;
- int *lenp;
+astr2bin(
+ const unsigned char *astr,
+ unsigned char * buf,
+ int * lenp)
{
- const char *p;
+ const unsigned char *p;
unsigned char *q;
#define fromhex(h) (isdigit((int)h) ? (h) - '0' : (h) - 'A' + 10)
*q++ = (fromhex(p[1]) << 4) + fromhex(p[2]);
p += 3;
}
- if (q - buf >= *lenp)
+ if ((int)(q - buf) >= *lenp)
break;
}
*lenp = q - buf;
}
static unsigned long
-krb4_cksum(str)
- const char *str;
+krb4_cksum(
+ const char *str)
{
des_cblock seed;
- memset(seed, 0, sizeof(seed));
+ memset(seed, 0, SIZEOF(seed));
/*
* The first arg is an unsigned char * in some krb4 implementations,
* and in others, it's a des_cblock *. Just make it void here
* to shut them all up.
*/
- return (quad_cksum((void *)str, NULL, strlen(str), 1, &seed));
+ return (quad_cksum((void *)str, NULL, (long)strlen(str), 1, &seed));
}
static void
-krb4_getinst(hname, inst, size)
- const char *hname;
- char *inst;
- size_t size;
+krb4_getinst(
+ const char *hname,
+ char * inst,
+ size_t size)
{
/*
}
static void
-encrypt_data(data, length, key)
- void *data;
- int length;
- des_cblock *key;
+encrypt_data(
+ void * data,
+ size_t length,
+ des_cblock *key)
{
des_key_schedule sched;
* arrays should be outlawed.
*/
des_key_sched((void *)key, sched);
- des_pcbc_encrypt(data, data, length, sched, key, DES_ENCRYPT);
+ des_pcbc_encrypt(data, data, (long)length, sched, key, DES_ENCRYPT);
}
static void
-decrypt_data(data, length, key)
- void *data;
- int length;
- des_cblock *key;
+decrypt_data(
+ void * data,
+ size_t length,
+ des_cblock *key)
{
des_key_schedule sched;
des_key_sched((void *)key, sched);
- des_pcbc_encrypt(data, data, length, sched, key, DES_DECRYPT);
+ des_pcbc_encrypt(data, data, (long)length, sched, key, DES_DECRYPT);
}
/*
* like write(), but always writes out the entire buffer.
*/
static int
-net_write(fd, vbuf, size)
- int fd;
- const void *vbuf;
- size_t size;
+net_write(
+ int fd,
+ const void *vbuf,
+ size_t size)
{
const char *buf = vbuf; /* so we can do ptr arith */
- int n;
+ ssize_t n;
while (size > 0) {
n = write(fd, buf, size);
* Like read(), but waits until the entire buffer has been filled.
*/
static int
-net_read(fd, vbuf, size, timeout)
- int fd;
- void *vbuf;
- size_t size;
- int timeout;
+net_read(
+ int fd,
+ void * vbuf,
+ size_t size,
+ int timeout)
{
char *buf = vbuf; /* ptr arith */
- int n, neof = 0;
+ ssize_t n;
+ int neof = 0;
fd_set readfds;
struct timeval tv;
/* debug routines */
static void
-print_hex(str,buf,len)
-const char *str;
-const unsigned char *buf;
-int len;
+print_hex(
+ const char * str,
+ const unsigned char * buf,
+ size_t len)
{
int i;
}
static void
-print_ticket(str, tktp)
-const char *str;
-KTEXT tktp;
+print_ticket(
+ const char *str,
+ KTEXT tktp)
{
dbprintf(("%s: length %d chk %lX\n", str, tktp->length, tktp->mbz));
print_hex("ticket data", tktp->dat, tktp->length);
}
static void
-print_auth(authp)
-AUTH_DAT *authp;
+print_auth(
+ AUTH_DAT *authp)
{
printf("\nAuth Data:\n");
printf(" Principal \"%s\" Instance \"%s\" Realm \"%s\"\n",
authp->pname, authp->pinst, authp->prealm);
printf(" cksum %d life %d keylen %ld\n", authp->checksum,
- authp->life, sizeof(authp->session));
- print_hex("session key", authp->session, sizeof(authp->session));
+ authp->life, SIZEOF(authp->session));
+ print_hex("session key", authp->session, SIZEOF(authp->session));
fflush(stdout);
}
static void
-print_credentials(credp)
-CREDENTIALS *credp;
+print_credentials(
+ CREDENTIALS *credp)
{
printf("\nCredentials:\n");
printf(" service \"%s\" instance \"%s\" realm \"%s\" life %d kvno %d\n",
credp->service, credp->instance, credp->realm, credp->lifetime,
credp->kvno);
- print_hex("session key", credp->session, sizeof(credp->session));
+ print_hex("session key", credp->session, SIZEOF(credp->session));
print_hex("ticket", credp->ticket_st.dat, credp->ticket_st.length);
fflush(stdout);
}
#endif
#else
-void krb4_security_dummy (void) {}
+
+void krb4_security_dummy(void);
+
+void
+krb4_security_dummy(void)
+{
+}
+
#endif /* KRB4_SECURITY */
*/
/*
- * $Id: krb5-security.c,v 1.12 2006/02/21 04:13:55 ktill Exp $
+ * $Id: krb5-security.c,v 1.22 2006/06/16 10:55:05 martinea Exp $
*
* krb5-security.c - kerberos V5 security module
*/
#include "config.h"
#ifdef KRB5_SECURITY
#include "amanda.h"
+#include "util.h"
#include "arglist.h"
#include "event.h"
#include "packet.h"
#include "queue.h"
#include "security.h"
+#include "security-util.h"
#include "stream.h"
#include "version.h"
struct krb5_stream *ks; /* virtual stream we xmit over */
union {
- void (*recvpkt) P((void *, pkt_t *, security_status_t));
+ void (*recvpkt)(void *, pkt_t *, security_status_t);
/* func to call when packet recvd */
- void (*connect) P((void *, security_handle_t *, security_status_t));
+ void (*connect)(void *, security_handle_t *, security_status_t);
/* func to call when connected */
} fn;
void *arg; /* argument to pass function */
+ void *datap; /* argument to pass function */
event_handle_t *ev_wait; /* wait handle for connects */
- char *(*conf_fn) P((char *, void *)); /* used to get config info */
+ char *(*conf_fn)(char *, void *); /* used to get config info */
event_handle_t *ev_timeout; /* timeout handle for recv */
};
struct krb5_conn *kc; /* physical connection */
int handle; /* protocol handle */
event_handle_t *ev_read; /* read (EV_WAIT) event handle */
- void (*fn) P((void *, void *, int)); /* read event fn */
+ void (*fn)(void *, void *, ssize_t);/* read event fn */
void *arg; /* arg for previous */
+ char buf[KRB5_STREAM_BUFSIZE];
+ ssize_t len;
};
/*
* Interface functions
*/
-static int krb5_sendpkt P((void *, pkt_t *));
-static int krb5_stream_accept P((void *));
-static int krb5_stream_auth P((void *));
-static int krb5_stream_id P((void *));
-static int krb5_stream_write P((void *, const void *, size_t));
-static void *krb5_stream_client P((void *, int));
-static void *krb5_stream_server P((void *));
-static void krb5_accept P((int, int,
- void (*)(security_handle_t *, pkt_t *)));
-static void krb5_close P((void *));
-static void krb5_connect P((const char *,
- char *(*)(char *, void *),
- void (*)(void *, security_handle_t *, security_status_t), void *));
-static void krb5_recvpkt P((void *,
- void (*)(void *, pkt_t *, security_status_t), void *, int));
-static void krb5_recvpkt_cancel P((void *));
-static void krb5_stream_close P((void *));
-static void krb5_stream_read P((void *, void (*)(void *, void *, int),
- void *));
-static void krb5_stream_read_cancel P((void *));
+static ssize_t krb5_sendpkt(void *, pkt_t *);
+static int krb5_stream_accept(void *);
+static int krb5_stream_auth(void *);
+static int krb5_stream_id(void *);
+static int krb5_stream_write(void *, const void *, size_t);
+static void * krb5_stream_client(void *, int);
+static void * krb5_stream_server(void *);
+static void krb5_accept(const struct security_driver *, int, int,
+ void (*)(security_handle_t *, pkt_t *));
+static void krb5_close(void *);
+static void krb5_connect(const char *, char *(*)(char *, void *),
+ void (*)(void *, security_handle_t *, security_status_t),
+ void *, void *);
+static void krb5_recvpkt(void *, void (*)(void *, pkt_t *, security_status_t),
+ void *, int);
+static void krb5_recvpkt_cancel(void *);
+static void krb5_stream_close(void *);
+static void krb5_stream_read(void *, void (*)(void *, void *, ssize_t), void *);
+static ssize_t krb5_stream_read_sync(void *, void **);
+static void krb5_stream_read_cancel(void *);
/*
* This is our interface to the outside world.
krb5_stream_id,
krb5_stream_write,
krb5_stream_read,
+ krb5_stream_read_sync,
krb5_stream_read_cancel,
+ sec_close_connection_none,
};
/*
static struct {
TAILQ_HEAD(, krb5_conn) tailq;
int qlength;
-} connq = {
- TAILQ_HEAD_INITIALIZER(connq.tailq), 0
+} krb5_connq = {
+ TAILQ_HEAD_INITIALIZER(krb5_connq.tailq), 0
};
-#define connq_first() TAILQ_FIRST(&connq.tailq)
-#define connq_next(kc) TAILQ_NEXT(kc, tq)
-#define connq_append(kc) do { \
- TAILQ_INSERT_TAIL(&connq.tailq, kc, tq); \
- connq.qlength++; \
+#define krb5_connq_first() TAILQ_FIRST(&krb5_connq.tailq)
+#define krb5_connq_next(kc) TAILQ_NEXT(kc, tq)
+#define krb5_connq_append(kc) do { \
+ TAILQ_INSERT_TAIL(&krb5_connq.tailq, kc, tq); \
+ krb5_connq.qlength++; \
} while (0)
-#define connq_remove(kc) do { \
- assert(connq.qlength > 0); \
- TAILQ_REMOVE(&connq.tailq, kc, tq); \
- connq.qlength--; \
+#define krb5_connq_remove(kc) do { \
+ assert(krb5_connq.qlength > 0); \
+ TAILQ_REMOVE(&krb5_connq.tailq, kc, tq); \
+ krb5_connq.qlength--; \
} while (0)
static int newhandle = 1;
* created. If NULL, no new handles are created.
* It is passed the new handle and the received pkt
*/
-static void (*accept_fn) P((security_handle_t *, pkt_t *));
+static void (*accept_fn)(security_handle_t *, pkt_t *);
/*
* Local functions
*/
-static void init P((void));
+static void init(void);
#ifdef BROKEN_MEMORY_CCACHE
-static void cleanup P((void));
+static void cleanup(void);
#endif
-static const char *get_tgt P((char *, char *));
-static void open_callback P((void *));
-static void connect_callback P((void *));
-static void connect_timeout P((void *));
-static int send_token P((struct krb5_conn *, int, const gss_buffer_desc *));
-static int recv_token P((struct krb5_conn *, int *, gss_buffer_desc *, int));
-static void recvpkt_callback P((void *, void *, ssize_t));
-static void recvpkt_timeout P((void *));
-static void stream_read_callback P((void *));
-static int gss_server P((struct krb5_conn *));
-static int gss_client P((struct krb5_handle *));
-static const char *gss_error P((OM_uint32, OM_uint32));
+static const char *get_tgt(char *, char *);
+static void open_callback(void *);
+static void connect_callback(void *);
+static void connect_timeout(void *);
+static int send_token(struct krb5_conn *, int, const gss_buffer_desc *);
+static ssize_t recv_token(struct krb5_conn *, int *, gss_buffer_desc *, int);
+static void recvpkt_callback(void *, void *, ssize_t);
+static void recvpkt_timeout(void *);
+static void stream_read_callback(void *);
+static void stream_read_sync_callback2(void *, void *, ssize_t);
+static int gss_server(struct krb5_conn *);
+static int gss_client(struct krb5_handle *);
+static const char *gss_error(OM_uint32, OM_uint32);
#ifdef AMANDA_KRB5_ENCRYPT
-static int kdecrypt P((struct krb5_stream *, gss_buffer_desc *,
- gss_buffer_desc *));
-static int kencrypt P((struct krb5_stream *, gss_buffer_desc *,
- gss_buffer_desc *));
+static int kdecrypt(struct krb5_stream *, gss_buffer_desc *, gss_buffer_desc *);
+static int kencrypt(struct krb5_stream *, gss_buffer_desc *, gss_buffer_desc *);
#endif
-static struct krb5_conn *conn_get P((const char *));
-static void conn_put P((struct krb5_conn *));
-static void conn_read P((struct krb5_conn *));
-static void conn_read_cancel P((struct krb5_conn *));
-static void conn_read_callback P((void *));
-static int conn_run_frameq P((struct krb5_conn *, struct krb5_stream *));
-static int net_writev P((int, struct iovec *, int));
-static ssize_t net_read P((struct krb5_conn *, void *, size_t, int));
-static int net_read_fillbuf P((struct krb5_conn *, int));
-static char *krb5_checkuser(char *, char *, char *);
-static void parse_pkt P((pkt_t *, const void *, size_t));
+static struct krb5_conn *conn_get(const char *);
+static void conn_put(struct krb5_conn *);
+static void conn_read(struct krb5_conn *);
+static void conn_read_cancel(struct krb5_conn *);
+static void conn_read_callback(void *);
+static int conn_run_frameq(struct krb5_conn *, struct krb5_stream *);
+static char * krb5_checkuser(char *, char *, char *);
/*
* up a network "connection".
*/
static void
-krb5_connect(hostname, conf_fn, fn, arg)
- const char *hostname;
- char *(*conf_fn) P((char *, void *));
- void (*fn) P((void *, security_handle_t *, security_status_t));
- void *arg;
+krb5_connect(
+ const char *hostname,
+ char * (*conf_fn)(char *, void *),
+ void (*fn)(void *, security_handle_t *, security_status_t),
+ void * arg,
+ void * datap)
{
struct krb5_handle *kh;
struct hostent *he;
struct servent *se;
- int port, fd;
+ int fd;
+ int port;
const char *err;
char *keytab_name = NULL;
char *principal_name = NULL;
*/
init();
- kh = alloc(sizeof(*kh));
+ kh = alloc(SIZEOF(*kh));
security_handleinit(&kh->sech, &krb5_security_driver);
kh->hostname = NULL;
kh->ks = NULL;
keytab_name = AMANDA_KEYTAB;
#else
if(conf_fn) {
- keytab_name = conf_fn("krb5keytab", arg);
+ keytab_name = conf_fn("krb5keytab", datap);
}
#endif
#ifdef AMANDA_PRINCIPAL
principal_name = AMANDA_PRINCIPAL;
#else
if(conf_fn) {
- principal_name = conf_fn("krb5principal", arg);
+ principal_name = conf_fn("krb5principal", datap);
}
#endif
kh->fn.connect = fn;
kh->conf_fn = conf_fn;
kh->arg = arg;
+ kh->datap = datap;
kh->hostname = stralloc(he->h_name);
kh->ks = krb5_stream_client(kh, newhandle++);
* We need to open a new connection. See if we have too
* many connections open.
*/
- if (connq.qlength > AMANDA_KRB5_MAXCONN) {
+ if (krb5_connq.qlength > AMANDA_KRB5_MAXCONN) {
k5printf(("krb5_connect: too many conections (%d), delaying %s\n",
- connq.qlength, kh->hostname));
+ krb5_connq.qlength, kh->hostname));
krb5_stream_close(kh->ks);
kh->ev_wait = event_register((event_id_t)open_callback,
EV_WAIT, open_callback, kh);
* so we will know when the socket comes alive.
* We also register a timeout.
*/
- kh->ev_wait = event_register(fd, EV_WRITEFD, connect_callback, kh);
- kh->ev_timeout = event_register(GSS_TIMEOUT, EV_TIME, connect_timeout, kh);
+ kh->ev_wait = event_register((event_id_t)fd, EV_WRITEFD,
+ connect_callback, kh);
+ kh->ev_timeout = event_register((event_id_t)GSS_TIMEOUT, EV_TIME,
+ connect_timeout, kh);
return;
* we can open more.
*/
static void
-open_callback(cookie)
- void *cookie;
+open_callback(
+ void * cookie)
{
struct krb5_handle *kh = cookie;
k5printf(("krb5: open_callback: possible connections available, retry %s\n",
kh->hostname));
- krb5_connect(kh->hostname, kh->conf_fn, kh->fn.connect, kh->arg);
+ krb5_connect(kh->hostname, kh->conf_fn, kh->fn.connect, kh->arg,kh->datap);
amfree(kh->hostname);
amfree(kh);
}
* to be authenticated.
*/
static void
-connect_callback(cookie)
- void *cookie;
+connect_callback(
+ void * cookie)
{
struct krb5_handle *kh = cookie;
* Called if a connection times out before completion.
*/
static void
-connect_timeout(cookie)
- void *cookie;
+connect_timeout(
+ void * cookie)
{
struct krb5_handle *kh = cookie;
* Setup to handle new incoming connections
*/
static void
-krb5_accept(in, out, fn)
- int in, out;
- void (*fn) P((security_handle_t *, pkt_t *));
+krb5_accept(
+ const struct security_driver *driver,
+ int in,
+ int out,
+ void (*fn)(security_handle_t *, pkt_t *))
{
struct sockaddr_in sin;
- size_t len;
+ socklen_t len;
struct krb5_conn *kc;
struct hostent *he;
*/
init();
- len = sizeof(sin);
+ /* shut up compiler */
+ driver=driver;
+ out=out;
+
+ len = SIZEOF(sin);
if (getpeername(in, (struct sockaddr *)&sin, &len) < 0)
return;
- he = gethostbyaddr((void *)&sin.sin_addr, sizeof(sin.sin_addr), AF_INET);
+ he = gethostbyaddr((void *)&sin.sin_addr, SIZEOF(sin.sin_addr), AF_INET);
if (he == NULL)
return;
* for the lack of a connection (kc->fd == -1) and set one up.
*/
static struct krb5_conn *
-conn_get(hostname)
- const char *hostname;
+conn_get(
+ const char * hostname)
{
struct krb5_conn *kc;
k5printf(("krb5: conn_get: %s\n", hostname));
- for (kc = connq_first(); kc != NULL; kc = connq_next(kc)) {
+ for (kc = krb5_connq_first(); kc != NULL; kc = krb5_connq_next(kc)) {
if (strcasecmp(hostname, kc->hostname) == 0)
break;
}
* We can't be creating a new handle if we are the client
*/
assert(accept_fn == NULL);
- kc = alloc(sizeof(*kc));
+ kc = alloc(SIZEOF(*kc));
kc->fd = -1;
kc->readbuf.left = 0;
kc->readbuf.size = 0;
kc->state = unauthed;
kc->ev_read = NULL;
- strncpy(kc->hostname, hostname, sizeof(kc->hostname) - 1);
- kc->hostname[sizeof(kc->hostname) - 1] = '\0';
+ strncpy(kc->hostname, hostname, SIZEOF(kc->hostname) - 1);
+ kc->hostname[SIZEOF(kc->hostname) - 1] = '\0';
kc->errmsg = NULL;
kc->gss_context = GSS_C_NO_CONTEXT;
/*
*/
kc->refcnt = 2;
TAILQ_INIT(&kc->frameq);
- connq_append(kc);
+ krb5_connq_append(kc);
return (kc);
}
* reference.
*/
static void
-conn_put(kc)
- struct krb5_conn *kc;
+conn_put(
+ struct krb5_conn * kc)
{
OM_uint32 min_stat;
struct krb5_frame *kf;
amfree(kf->tok.value);
amfree(kf);
}
- connq_remove(kc);
+ krb5_connq_remove(kc);
amfree(kc);
/* signal that a connection is available */
event_wakeup((event_id_t)open_callback);
* already receiving read events.
*/
static void
-conn_read(kc)
- struct krb5_conn *kc;
+conn_read(
+ struct krb5_conn *kc)
{
if (kc->ev_read != NULL) {
}
k5printf(("krb5: conn_read registering event handler for %s\n",
kc->hostname));
- kc->ev_read = event_register(kc->fd, EV_READFD, conn_read_callback, kc);
+ kc->ev_read = event_register((event_id_t)kc->fd, EV_READFD, conn_read_callback, kc);
kc->ev_read_refcnt = 1;
}
static void
-conn_read_cancel(kc)
- struct krb5_conn *kc;
+conn_read_cancel(
+ struct krb5_conn * kc)
{
if (--kc->ev_read_refcnt > 0) {
* frees a handle allocated by the above
*/
static void
-krb5_close(inst)
- void *inst;
+krb5_close(
+ void * inst)
{
struct krb5_handle *kh = inst;
/*
* Transmit a packet. Encrypt first.
*/
-static int
-krb5_sendpkt(cookie, pkt)
- void *cookie;
- pkt_t *pkt;
+static ssize_t
+krb5_sendpkt(
+ void * cookie,
+ pkt_t * pkt)
{
struct krb5_handle *kh = cookie;
gss_buffer_desc tok;
int rval;
- unsigned char c, *buf;
+ unsigned char *buf;
assert(kh != NULL);
assert(pkt != NULL);
k5printf(("krb5: sendpkt: enter\n"));
if (pkt->body[0] == '\0') {
- c = (unsigned char)pkt->type;
tok.length = 1;
- tok.value = &c;
+ tok.value = alloc(SIZEOF(pkt->type));
+ memcpy(tok.value, &pkt->type, sizeof(unsigned char));
} else {
tok.length = strlen(pkt->body) + 2;
tok.value = alloc(tok.length);
buf = tok.value;
*buf++ = (unsigned char)pkt->type;
- strncpy(buf, pkt->body, tok.length - 2);
+ strncpy((char *)buf, pkt->body, tok.length - 2);
buf[tok.length - 2] = '\0';
}
rval = krb5_stream_write(kh->ks, tok.value, tok.length);
if (rval < 0)
security_seterror(&kh->sech, security_stream_geterror(&kh->ks->secstr));
- if (tok.length > 1)
- amfree(tok.value);
+ /*@ignore@*/
+ amfree(tok.value);
+ /*@end@*/
return (rval);
}
* it has been read.
*/
static void
-krb5_recvpkt(cookie, fn, arg, timeout)
- void *cookie, *arg;
- void (*fn) P((void *, pkt_t *, security_status_t));
- int timeout;
+krb5_recvpkt(
+ void * cookie,
+ void (*fn)(void *, pkt_t *, security_status_t),
+ void * arg,
+ int timeout)
{
struct krb5_handle *kh = cookie;
if (timeout < 0)
kh->ev_timeout = NULL;
else
- kh->ev_timeout = event_register(timeout, EV_TIME, recvpkt_timeout, kh);
+ kh->ev_timeout = event_register((event_id_t)timeout, EV_TIME,
+ recvpkt_timeout, kh);
kh->fn.recvpkt = fn;
kh->arg = arg;
* Remove a async receive request from the queue
*/
static void
-krb5_recvpkt_cancel(cookie)
- void *cookie;
+krb5_recvpkt_cancel(
+ void * cookie)
{
struct krb5_handle *kh = cookie;
* net is for it.
*/
static void
-recvpkt_callback(cookie, buf, bufsize)
- void *cookie, *buf;
- ssize_t bufsize;
+recvpkt_callback(
+ void *cookie,
+ void *buf,
+ ssize_t bufsize)
{
pkt_t pkt;
struct krb5_handle *kh = cookie;
(*kh->fn.recvpkt)(kh->arg, NULL, S_ERROR);
return;
default:
- parse_pkt(&pkt, buf, bufsize);
+ parse_pkt(&pkt, buf, (size_t)bufsize);
k5printf(("krb5: received %s pkt (%d) from %s, contains:\n\n\"%s\"\n\n",
pkt_type2str(pkt.type), pkt.type, kh->hostname, pkt.body));
(*kh->fn.recvpkt)(kh->arg, &pkt, S_OK);
* This is called when a handle times out before receiving a packet.
*/
static void
-recvpkt_timeout(cookie)
- void *cookie;
+recvpkt_timeout(
+ void * cookie)
{
struct krb5_handle *kh = cookie;
* object and allocate a new handle for it.
*/
static void *
-krb5_stream_server(h)
- void *h;
+krb5_stream_server(
+ void * h)
{
struct krb5_handle *kh = h;
struct krb5_stream *ks;
assert(kh != NULL);
- ks = alloc(sizeof(*ks));
+ ks = alloc(SIZEOF(*ks));
security_streaminit(&ks->secstr, &krb5_security_driver);
ks->kc = conn_get(kh->hostname);
/*
* so as not to conflict with the amanda server's handle numbers,
* we start at 5000 and work down
*/
- ks->handle = 5000 - newhandle++;
+ ks->handle = (int)(5000 - newhandle++);
ks->ev_read = NULL;
k5printf(("krb5: stream_server: created stream %d\n", ks->handle));
return (ks);
* Nothing needed for krb5.
*/
static int
-krb5_stream_accept(s)
- void *s;
+krb5_stream_accept(
+ void * s)
{
+ /* shut up compiler */
+ s = s;
+
return (0);
}
* with the supplied handle.
*/
static void *
-krb5_stream_client(h, id)
- void *h;
- int id;
+krb5_stream_client(
+ void * h,
+ int id)
{
struct krb5_handle *kh = h;
struct krb5_stream *ks;
return (NULL);
}
- ks = alloc(sizeof(*ks));
+ ks = alloc(SIZEOF(*ks));
security_streaminit(&ks->secstr, &krb5_security_driver);
- ks->handle = id;
+ ks->handle = (int)id;
ks->ev_read = NULL;
ks->kc = conn_get(kh->hostname);
* Close and unallocate resources for a stream.
*/
static void
-krb5_stream_close(s)
- void *s;
+krb5_stream_close(
+ void * s)
{
struct krb5_stream *ks = s;
* on startup.
*/
static int
-krb5_stream_auth(s)
- void *s;
+krb5_stream_auth(
+ void * s)
{
+ /* shut up compiler */
+ s = s;
return (0);
}
* port.
*/
static int
-krb5_stream_id(s)
- void *s;
+krb5_stream_id(
+ void * s)
{
struct krb5_stream *ks = s;
* Write a chunk of data to a stream. Blocks until completion.
*/
static int
-krb5_stream_write(s, buf, size)
- void *s;
- const void *buf;
- size_t size;
+krb5_stream_write(
+ void * s,
+ const void *buf,
+ size_t size)
{
struct krb5_stream *ks = s;
gss_buffer_desc tok;
* function and arg when completed.
*/
static void
-krb5_stream_read(s, fn, arg)
- void *s, *arg;
- void (*fn) P((void *, void *, int));
+krb5_stream_read(
+ void * s,
+ void (*fn)(void *, void *, ssize_t),
+ void * arg)
{
struct krb5_stream *ks = s;
}
}
+/*
+ * Submit a request to read some data. Calls back with the given
+ * function and arg when completed.
+ */
+static ssize_t
+krb5_stream_read_sync(
+ void * s,
+ void **buf)
+{
+ struct krb5_stream *ks = s;
+
+ assert(ks != NULL);
+
+ /*
+ * Only one read request can be active per stream.
+ */
+ ks->fn = stream_read_sync_callback2;
+ ks->arg = ks;
+
+ /*
+ * First see if there's any queued frames for this stream.
+ * If so, we're done.
+ */
+ if (conn_run_frameq(ks->kc, ks) > 0)
+ return ks->len;
+
+ if (ks->ev_read != NULL)
+ event_release(ks->ev_read);
+
+ ks->ev_read = event_register((event_id_t)ks->kc, EV_WAIT,
+ stream_read_callback, ks);
+ conn_read(ks->kc);
+ event_wait(ks->ev_read);
+ buf = (void **)&ks->buf;
+ return ks->len;
+}
+
+
+/*
+ * Callback for krb5_stream_read_sync
+ */
+static void
+stream_read_sync_callback2(
+ void * arg,
+ void * buf,
+ ssize_t size)
+{
+ struct krb5_stream *ks = arg;
+
+ assert(ks != NULL);
+
+ k5printf(("krb5: stream_read_sync_callback2: handle %d\n", ks->handle));
+
+ memcpy(ks->buf, buf, (size_t)size);
+ ks->len = size;
+}
+
/*
* Cancel a previous stream read request. It's ok if we didn't have a read
* scheduled.
*/
static void
-krb5_stream_read_cancel(s)
- void *s;
+krb5_stream_read_cancel(
+ void * s)
{
struct krb5_stream *ks = s;
* Callback for krb5_stream_read
*/
static void
-stream_read_callback(arg)
- void *arg;
+stream_read_callback(
+ void * arg)
{
struct krb5_stream *ks = arg;
* Returns 1 if a frame was found and processed.
*/
static int
-conn_run_frameq(kc, ks)
- struct krb5_conn *kc;
- struct krb5_stream *ks;
+conn_run_frameq(
+ /*@keep@*/ struct krb5_conn * kc,
+ /*@keep@*/ struct krb5_stream * ks)
{
struct krb5_frame *kf, *nextkf;
gss_buffer_desc *enctok, *dectok;
{
k5printf(("krb5: stream_read_callback: read %d bytes from %s:%d\n",
dectok->length, ks->kc->hostname, ks->handle));
- (*ks->fn)(ks->arg, dectok->value, dectok->length);
+ (*ks->fn)(ks->arg, dectok->value, (ssize_t)dectok->length);
#ifdef AMANDA_KRB5_ENCRYPT
gss_release_buffer(&min_stat, dectok);
#endif
* and does the real callback if so.
*/
static void
-conn_read_callback(cookie)
- void *cookie;
+conn_read_callback(
+ void * cookie)
{
struct krb5_conn *kc = cookie;
struct krb5_handle *kh;
k5printf(("krb5: conn_read_callback\n"));
- kf = alloc(sizeof(*kf));
+ kf = alloc(SIZEOF(*kf));
TAILQ_INSERT_TAIL(&kc->frameq, kf, tq);
/* Read the data off the wire. If we get errors, shut down. */
return;
}
- kh = alloc(sizeof(*kh));
+ kh = alloc(SIZEOF(*kh));
security_handleinit(&kh->sech, &krb5_security_driver);
kh->hostname = stralloc(kc->hostname);
kh->ks = krb5_stream_client(kh, kf->handle);
* Negotiate a krb5 gss context from the client end.
*/
static int
-gss_client(kh)
- struct krb5_handle *kh;
+gss_client(
+ struct krb5_handle *kh)
{
struct krb5_stream *ks = kh->ks;
struct krb5_conn *kc = ks->kc;
send_tok.length = strlen(send_tok.value) + 1;
maj_stat = gss_import_name(&min_stat, &send_tok, GSS_C_NULL_OID,
&gss_name);
- if (maj_stat != GSS_S_COMPLETE) {
+ if (maj_stat != (OM_uint32)GSS_S_COMPLETE) {
security_seterror(&kh->sech, "can't import name %s: %s",
(char *)send_tok.value, gss_error(maj_stat, min_stat));
amfree(send_tok.value);
* and only if the server has another token to send us.
*/
+ recv_tok.value = NULL;
for (recv_tok.length = 0;;) {
min_stat = 0;
maj_stat = gss_init_sec_context(&min_stat,
&kc->gss_context,
gss_name,
GSS_C_NULL_OID,
- GSS_C_MUTUAL_FLAG|GSS_C_REPLAY_FLAG,
+ (OM_uint32)GSS_C_MUTUAL_FLAG|GSS_C_REPLAY_FLAG,
0, NULL, /* no channel bindings */
(recv_tok.length == 0 ? GSS_C_NO_BUFFER : &recv_tok),
NULL, /* ignore mech type */
recv_tok.length = 0;
}
- if (maj_stat != GSS_S_COMPLETE && maj_stat != GSS_S_CONTINUE_NEEDED) {
+ if (maj_stat != (OM_uint32)GSS_S_COMPLETE && maj_stat != (OM_uint32)GSS_S_CONTINUE_NEEDED) {
security_seterror(&kh->sech,
"error getting gss context: %s",
gss_error(maj_stat, min_stat));
/*
* If we need to continue, then register for more packets
*/
- if (maj_stat != GSS_S_CONTINUE_NEEDED)
+ if (maj_stat != (OM_uint32)GSS_S_CONTINUE_NEEDED)
break;
if ((rc = recv_token(kc, NULL, &recv_tok, GSS_TIMEOUT)) <= 0) {
* Negotiate a krb5 gss context from the server end.
*/
static int
-gss_server(kc)
- struct krb5_conn *kc;
+gss_server(
+ struct krb5_conn * kc)
{
OM_uint32 maj_stat, min_stat, ret_flags;
gss_buffer_desc send_tok, recv_tok;
*/
euid = geteuid();
if (getuid() != 0) {
- snprintf(errbuf, sizeof(errbuf),
+ snprintf(errbuf, SIZEOF(errbuf),
"real uid is %ld, needs to be 0 to read krb5 host key",
(long)getuid());
goto out;
}
if (seteuid(0) < 0) {
- snprintf(errbuf, sizeof(errbuf),
+ snprintf(errbuf, SIZEOF(errbuf),
"can't seteuid to uid 0: %s", strerror(errno));
goto out;
}
}
maj_stat = gss_import_name(&min_stat, &send_tok, GSS_C_NULL_OID,
&gss_name);
- if (maj_stat != GSS_S_COMPLETE) {
+ if (maj_stat != (OM_uint32)GSS_S_COMPLETE) {
seteuid(euid);
- snprintf(errbuf, sizeof(errbuf),
+ snprintf(errbuf, SIZEOF(errbuf),
"can't import name %s: %s", (char *)send_tok.value,
gss_error(maj_stat, min_stat));
amfree(send_tok.value);
maj_stat = gss_acquire_cred(&min_stat, gss_name, 0,
GSS_C_NULL_OID_SET, GSS_C_ACCEPT, &gss_creds, NULL, NULL);
- if (maj_stat != GSS_S_COMPLETE) {
- snprintf(errbuf, sizeof(errbuf),
+ if (maj_stat != (OM_uint32)GSS_S_COMPLETE) {
+ snprintf(errbuf, SIZEOF(errbuf),
"can't acquire creds for host key host/%s: %s", hostname,
gss_error(maj_stat, min_stat));
gss_release_name(&min_stat, &gss_name);
for (recv_tok.length = 0;;) {
if ((rc = recv_token(kc, NULL, &recv_tok, GSS_TIMEOUT)) <= 0) {
if (rc < 0) {
- snprintf(errbuf, sizeof(errbuf),
+ snprintf(errbuf, SIZEOF(errbuf),
"recv error in gss loop: %s", kc->errmsg);
amfree(kc->errmsg);
} else
- snprintf(errbuf, sizeof(errbuf), "EOF in gss loop");
+ snprintf(errbuf, SIZEOF(errbuf), "EOF in gss loop");
goto out;
}
gss_creds, &recv_tok, GSS_C_NO_CHANNEL_BINDINGS,
&gss_name, &doid, &send_tok, &ret_flags, NULL, NULL);
- if (maj_stat != GSS_S_COMPLETE &&
- maj_stat != GSS_S_CONTINUE_NEEDED) {
- snprintf(errbuf, sizeof(errbuf),
+ if (maj_stat != (OM_uint32)GSS_S_COMPLETE &&
+ maj_stat != (OM_uint32)GSS_S_CONTINUE_NEEDED) {
+ snprintf(errbuf, SIZEOF(errbuf),
"error accepting context: %s", gss_error(maj_stat, min_stat));
amfree(recv_tok.value);
goto out;
amfree(recv_tok.value);
if (send_tok.length > 0 && send_token(kc, 0, &send_tok) < 0) {
- strncpy(errbuf, kc->errmsg, sizeof(errbuf) - 1);
- errbuf[sizeof(errbuf) - 1] = '\0';
+ strncpy(errbuf, kc->errmsg, SIZEOF(errbuf) - 1);
+ errbuf[SIZEOF(errbuf) - 1] = '\0';
amfree(kc->errmsg);
gss_release_buffer(&min_stat, &send_tok);
goto out;
* If we need to get more from the client, then register for
* more packets.
*/
- if (maj_stat != GSS_S_CONTINUE_NEEDED)
+ if (maj_stat != (OM_uint32)GSS_S_CONTINUE_NEEDED)
break;
}
maj_stat = gss_display_name(&min_stat, gss_name, &send_tok, &doid);
- if (maj_stat != GSS_S_COMPLETE) {
- snprintf(errbuf, sizeof(errbuf),
+ if (maj_stat != (OM_uint32)GSS_S_COMPLETE) {
+ snprintf(errbuf, SIZEOF(errbuf),
"can't display gss name: %s", gss_error(maj_stat, min_stat));
gss_release_name(&min_stat, &gss_name);
goto out;
/* get rid of the realm */
if ((p = strchr(send_tok.value, '@')) == NULL) {
- snprintf(errbuf, sizeof(errbuf),
+ snprintf(errbuf, SIZEOF(errbuf),
"malformed gss name: %s", (char *)send_tok.value);
amfree(send_tok.value);
goto out;
* If the principal doesn't match, complain
*/
if ((msg = krb5_checkuser(kc->hostname, send_tok.value, realm)) != NULL) {
- snprintf(errbuf, sizeof(errbuf),
+ snprintf(errbuf, SIZEOF(errbuf),
"access not allowed from %s: %s", (char *)send_tok.value, msg);
amfree(send_tok.value);
goto out;
* Setup some things about krb5. This should only be called once.
*/
static void
-init()
+init(void)
{
static int beenhere = 0;
struct hostent *he;
char *p;
- int krb5_setenv P((const char *, const char *, int));
if (beenhere)
return;
beenhere = 1;
#ifndef BROKEN_MEMORY_CCACHE
- krb5_setenv(KRB5_ENV_CCNAME, "MEMORY:amanda_ccache", 1);
+ setenv(KRB5_ENV_CCNAME, "MEMORY:amanda_ccache", 1);
#else
/*
* MEMORY ccaches seem buggy and cause a lot of internal heap
atexit(cleanup);
{
char ccache[64];
- snprintf(ccache, sizeof(ccache), "FILE:/tmp/amanda_ccache.%ld.%ld",
+ snprintf(ccache, SIZEOF(ccache), "FILE:/tmp/amanda_ccache.%ld.%ld",
(long)geteuid(), (long)getpid());
- krb5_setenv(KRB5_ENV_CCNAME, ccache, 1);
+ setenv(KRB5_ENV_CCNAME, ccache, 1);
}
#endif
- gethostname(hostname, sizeof(hostname) - 1);
- hostname[sizeof(hostname) - 1] = '\0';
+ gethostname(hostname, SIZEOF(hostname) - 1);
+ hostname[SIZEOF(hostname) - 1] = '\0';
/*
* In case it isn't fully qualified, do a DNS lookup.
*/
if ((he = gethostbyname(hostname)) != NULL)
- strncpy(hostname, he->h_name, sizeof(hostname) - 1);
+ strncpy(hostname, he->h_name, SIZEOF(hostname) - 1);
/*
* Lowercase the results. We assume all host/ principals will be
#ifdef BROKEN_MEMORY_CCACHE
static void
-cleanup()
+cleanup(void)
{
#ifdef KDESTROY_VIA_UNLINK
char ccache[64];
- snprintf(ccache, sizeof(ccache), "/tmp/amanda_ccache.%ld.%ld",
+ snprintf(ccache, SIZEOF(ccache), "/tmp/amanda_ccache.%ld.%ld",
(long)geteuid(), (long)getpid());
unlink(ccache);
#else
* Get a ticket granting ticket and stuff it in the cache
*/
static const char *
-get_tgt(keytab_name, principal_name)
- char *keytab_name, *principal_name;
+get_tgt(
+ char * keytab_name,
+ char * principal_name)
{
krb5_context context;
krb5_error_code ret;
return (error);
}
- krb5_init_ets(context);
+ /*krb5_init_ets(context);*/
if(!keytab_name) {
error = vstralloc("error -- no krb5 keytab defined", NULL);
return (error);
}
- memset(&creds, 0, sizeof(creds));
+ memset(&creds, 0, SIZEOF(creds));
creds.times.starttime = 0;
creds.times.endtime = now + AMANDA_TKT_LIFETIME;
/*
* get rid of tickets
*/
-kdestroy()
+static void
+kdestroy(void)
{
krb5_context context;
krb5_ccache ccache;
return;
}
-static void
-parse_pkt(pkt, buf, bufsize)
- pkt_t *pkt;
- const void *buf;
- size_t bufsize;
-{
- const unsigned char *bufp = buf;
-
- k5printf(("krb5: parse_pkt: parsing buffer of %d bytes\n", bufsize));
-
- pkt->type = (pktype_t)*bufp++;
- bufsize--;
-
- if (bufsize == 0) {
- pkt->body[0] = '\0';
- } else {
- if (bufsize > sizeof(pkt->body) - 1)
- bufsize = sizeof(pkt->body) - 1;
- memcpy(pkt->body, bufp, bufsize);
- pkt->body[sizeof(pkt->body) - 1] = '\0';
- }
-
- k5printf(("krb5: parse_pkt: %s (%d): \"%s\"\n", pkt_type2str(pkt->type),
- pkt->type, pkt->body));
-}
-
-
/*
* Formats an error from the gss api
*/
static const char *
-gss_error(major, minor)
- OM_uint32 major, minor;
+gss_error(
+ OM_uint32 major,
+ OM_uint32 minor)
{
static gss_buffer_desc msg;
OM_uint32 min_stat, msg_ctx;
* Encryption must be done by the caller.
*/
static int
-send_token(kc, handle, tok)
- struct krb5_conn *kc;
- int handle;
- const gss_buffer_desc *tok;
+send_token(
+ struct krb5_conn * kc,
+ int handle,
+ const gss_buffer_desc * tok)
{
OM_uint32 netlength, nethandle;
struct iovec iov[3];
* 32 bit handle (network byte order)
* data
*/
- netlength = htonl(tok->length);
+ netlength = (OM_uint32)htonl(tok->length);
iov[0].iov_base = (void *)&netlength;
- iov[0].iov_len = sizeof(netlength);
+ iov[0].iov_len = SIZEOF(netlength);
- nethandle = htonl(handle);
+ nethandle = (OM_uint32)htonl((uint32_t)handle);
iov[1].iov_base = (void *)&nethandle;
- iov[1].iov_len = sizeof(nethandle);
+ iov[1].iov_len = SIZEOF(nethandle);
iov[2].iov_base = (void *)tok->value;
iov[2].iov_len = tok->length;
return (0);
}
-static int
-recv_token(kc, handle, gtok, timeout)
- struct krb5_conn *kc;
- int *handle;
- gss_buffer_desc *gtok;
- int timeout;
+static ssize_t
+recv_token(
+ struct krb5_conn * kc,
+ int * handle,
+ gss_buffer_desc * gtok,
+ int timeout)
{
- OM_uint32 netint;
+ OM_uint32 netint[2];
assert(kc->fd >= 0);
assert(gtok != NULL);
k5printf(("krb5: recv_token: reading from %s\n", kc->hostname));
- switch (net_read(kc, &netint, sizeof(netint), timeout)) {
+ switch (net_read(kc->fd, &netint, SIZEOF(netint), timeout)) {
case -1:
kc->errmsg = newvstralloc(kc->errmsg, "recv error: ", strerror(errno),
NULL);
default:
break;
}
- gtok->length = ntohl(netint);
+ gtok->length = ntohl(netint[0]);
if (gtok->length > AMANDA_MAX_TOK_SIZE) {
kc->errmsg = newstralloc(kc->errmsg, "recv error: buffer too large");
return (-1);
}
- switch (net_read(kc, &netint, sizeof(netint), timeout)) {
- case -1:
- kc->errmsg = newvstralloc(kc->errmsg, "recv error: ", strerror(errno),
- NULL);
- k5printf(("krb5 recv_token error return: %s\n", kc->errmsg));
- return (-1);
- case 0:
- gtok->length = 0;
- return (0);
- default:
- break;
- }
if (handle != NULL)
- *handle = ntohl(netint);
+ *handle = ntohl(netint[1]);
gtok->value = alloc(gtok->length);
- switch (net_read(kc, gtok->value, gtok->length, timeout)) {
+ switch (net_read(kc->fd, gtok->value, gtok->length, timeout)) {
case -1:
kc->errmsg = newvstralloc(kc->errmsg, "recv error: ", strerror(errno),
NULL);
k5printf(("krb5: recv_token: read %d bytes from %s\n", gtok->length,
kc->hostname));
- return (gtok->length);
+ return ((ssize_t)gtok->length);
}
#ifdef AMANDA_KRB5_ENCRYPT
static int
-kencrypt(ks, tok, enctok)
- struct krb5_stream *ks;
- gss_buffer_desc *tok, *enctok;
+kencrypt(
+ struct krb5_stream *ks,
+ gss_buffer_desc * tok,
+ gss_buffer_desc * enctok)
{
int conf_state;
OM_uint32 maj_stat, min_stat;
assert(ks->kc->gss_context != GSS_C_NO_CONTEXT);
maj_stat = gss_seal(&min_stat, ks->kc->gss_context, 1,
GSS_C_QOP_DEFAULT, tok, &conf_state, enctok);
- if (maj_stat != GSS_S_COMPLETE || conf_state == 0) {
+ if (maj_stat != (OM_uint32)GSS_S_COMPLETE || conf_state == 0) {
security_stream_seterror(&ks->secstr,
"krb5 encryption failed to %s: %s",
ks->kc->hostname, gss_error(maj_stat, min_stat));
}
static int
-kdecrypt(ks, enctok, tok)
- struct krb5_stream *ks;
- gss_buffer_desc *enctok, *tok;
+kdecrypt(
+ struct krb5_stream *ks,
+ gss_buffer_desc * enctok,
+ gss_buffer_desc * tok)
{
OM_uint32 maj_stat, min_stat;
int conf_state, qop_state;
assert(ks->kc->gss_context != GSS_C_NO_CONTEXT);
maj_stat = gss_unseal(&min_stat, ks->kc->gss_context, enctok, tok,
&conf_state, &qop_state);
- if (maj_stat != GSS_S_COMPLETE) {
+ if (maj_stat != (OM_uint32)GSS_S_COMPLETE) {
security_stream_seterror(&ks->secstr, "krb5 decrypt error from %s: %s",
ks->kc->hostname, gss_error(maj_stat, min_stat));
return (-1);
}
#endif
-/*
- * Writes out the entire iovec
- */
-static int
-net_writev(fd, iov, iovcnt)
- int fd, iovcnt;
- struct iovec *iov;
-{
- int delta, n, total;
-
- assert(iov != NULL);
-
- total = 0;
- while (iovcnt > 0) {
- /*
- * Write the iovec
- */
- total += n = writev(fd, iov, iovcnt);
- if (n < 0)
- return (-1);
- if (n == 0) {
- errno = EIO;
- return (-1);
- }
- /*
- * Iterate through each iov. Figure out what we still need
- * to write out.
- */
- for (; n > 0; iovcnt--, iov++) {
- /* 'delta' is the bytes written from this iovec */
- delta = n < iov->iov_len ? n : iov->iov_len;
- /* subtract from the total num bytes written */
- n -= delta;
- assert(n >= 0);
- /* subtract from this iovec */
- iov->iov_len -= delta;
- (char *)iov->iov_base += delta;
- /* if this iovec isn't empty, run the writev again */
- if (iov->iov_len > 0)
- break;
- }
- }
- return (total);
-}
-
-/*
- * Like read(), but waits until the entire buffer has been filled.
- */
-static ssize_t
-net_read(kc, vbuf, origsize, timeout)
- struct krb5_conn *kc;
- void *vbuf;
- size_t origsize;
- int timeout;
-{
- char *buf = vbuf, *off; /* ptr arith */
- int nread;
- size_t size = origsize;
-
- while (size > 0) {
- if (kc->readbuf.left == 0) {
- if (net_read_fillbuf(kc, timeout) < 0)
- return (-1);
- if (kc->readbuf.size == 0)
- return (0);
- }
- nread = min(kc->readbuf.left, size);
- off = kc->readbuf.buf + kc->readbuf.size - kc->readbuf.left;
- memcpy(buf, off, nread);
-
- buf += nread;
- size -= nread;
- kc->readbuf.left -= nread;
- }
- return ((ssize_t)origsize);
-}
-
-/*
- * net_read likes to do a lot of little reads. Buffer it.
- */
-static int
-net_read_fillbuf(kc, timeout)
- struct krb5_conn *kc;
- int timeout;
-{
- fd_set readfds;
- struct timeval tv;
-
- FD_ZERO(&readfds);
- FD_SET(kc->fd, &readfds);
- tv.tv_sec = timeout;
- tv.tv_usec = 0;
- switch (select(kc->fd + 1, &readfds, NULL, NULL, &tv)) {
- case 0:
- errno = ETIMEDOUT;
- /* FALLTHROUGH */
- case -1:
- return (-1);
- case 1:
- assert(FD_ISSET(kc->fd, &readfds));
- break;
- default:
- assert(0);
- break;
- }
- kc->readbuf.left = 0;
- kc->readbuf.size = read(kc->fd, kc->readbuf.buf,
- sizeof(kc->readbuf.buf));
-k5printf(("net_read_fillbuf: read %d characters w/ errno %d\n", kc->readbuf.size, errno));
- if (kc->readbuf.size < 0)
- return (-1);
- kc->readbuf.left = kc->readbuf.size;
- return (0);
-}
-
/*
* hackish, but you can #undef AMANDA_PRINCIPAL here, and you can both
* hardcode a principal in your build and use the .k5amandahosts. This is
* hardcoded, then we don't check the realm
*/
static char *
-krb5_checkuser(host, name, realm)
- char *host, *name, *realm;
+krb5_checkuser( char * host,
+ char * name,
+ char * realm)
{
#ifdef AMANDA_PRINCIPAL
if(strcmp(name, AMANDA_PRINCIPAL) == 0) {
if(strcmp(name, CLIENT_LOGIN) != 0) {
result = vstralloc(name, " does not match ",
CLIENT_LOGIN, NULL);
- goto common_exit;
+ return result;
}
result = NULL;
goto common_exit;
k5printf(("opening ptmp: %s\n", (ptmp)?ptmp: "NULL!"));
if((fp = fopen(ptmp, "r")) == NULL) {
result = vstralloc("can not open ", ptmp, NULL);
- goto common_exit;
+ return result;
}
k5printf(("opened ptmp\n"));
if (fstat(fileno(fp), &sbuf) != 0) {
result = vstralloc("cannot fstat ", ptmp, ": ", strerror(errno), NULL);
goto common_exit;
-
}
if (sbuf.st_uid != localuid) {
- snprintf(n1, sizeof(n1), "%ld", (long) sbuf.st_uid);
- snprintf(n2, sizeof(n2), "%ld", (long) localuid);
+ snprintf(n1, SIZEOF(n1), "%ld", (long) sbuf.st_uid);
+ snprintf(n2, SIZEOF(n2), "%ld", (long) localuid);
result = vstralloc(ptmp, ": ",
"owned by id ", n1,
", should be ", n2,
goto common_exit;
}
- while((line = agets(fp)) != NULL) {
+ while ((line = agets(fp)) != NULL) {
+ if (line[0] == '\0') {
+ amfree(line);
+ continue;
+ }
+
#if defined(SHOW_SECURITY_DETAIL) /* { */
k5printf(("%s: processing line: <%s>\n", debug_prefix(NULL), line));
#endif /* } */
continue;
}
result = NULL;
+ amfree(line);
goto common_exit;
}
-
amfree(line);
}
-
result = vstralloc("no match in ", ptmp, NULL);
common_exit:
- if(fp)
- afclose(fp);
- if(line)
- amfree(line);
+ afclose(fp);
return(result);
#endif /* AMANDA_PRINCIPAL */
}
#else
-void krb5_security_dummy (void) {}
+
+void krb5_security_dummy(void);
+
+void
+krb5_security_dummy(void)
+{
+}
+
#endif /* KRB5_SECURITY */
* file named AUTHORS, in the root directory of this distribution.
*/
/*
- * $Id: match.c,v 1.21 2005/10/11 01:17:00 vectro Exp $
+ * $Id: match.c,v 1.23 2006/05/25 01:47:12 johnfranks Exp $
*
* functions for checking and matching regular expressions
*/
#include "amanda.h"
#include "regex.h"
-char *validate_regexp(regex)
-char *regex;
+static int match_word(const char *glob, const char *word, const char separator);
+
+char *
+validate_regexp(
+ const char * regex)
{
regex_t regc;
int result;
if ((result = regcomp(®c, regex,
REG_EXTENDED|REG_NOSUB|REG_NEWLINE)) != 0) {
- regerror(result, ®c, errmsg, sizeof(errmsg));
+ regerror(result, ®c, errmsg, SIZEOF(errmsg));
return errmsg;
}
return NULL;
}
-char *clean_regex(regex)
-char *regex;
+char *
+clean_regex(
+ const char * regex)
{
char *result;
int j;
result[j++]='\\';
result[j++]=regex[i];
}
- result[j++] = '\0';
+ result[j] = '\0';
return result;
}
-int match(regex, str)
-char *regex, *str;
+int
+match(
+ const char * regex,
+ const char * str)
{
regex_t regc;
int result;
if((result = regcomp(®c, regex,
REG_EXTENDED|REG_NOSUB|REG_NEWLINE)) != 0) {
- regerror(result, ®c, errmsg, sizeof(errmsg));
+ regerror(result, ®c, errmsg, SIZEOF(errmsg));
error("regex \"%s\": %s", regex, errmsg);
+ /*NOTREACHED*/
}
if((result = regexec(®c, str, 0, 0, 0)) != 0
&& result != REG_NOMATCH) {
- regerror(result, ®c, errmsg, sizeof(errmsg));
+ regerror(result, ®c, errmsg, SIZEOF(errmsg));
error("regex \"%s\": %s", regex, errmsg);
+ /*NOTREACHED*/
}
regfree(®c);
return result == 0;
}
-char *validate_glob(glob)
-char *glob;
+char *
+validate_glob(
+ const char * glob)
{
- char *regex = NULL;
+ char *regex;
regex_t regc;
int result;
static char errmsg[STR_SIZE];
regex = glob_to_regex(glob);
if ((result = regcomp(®c, regex,
REG_EXTENDED|REG_NOSUB|REG_NEWLINE)) != 0) {
- regerror(result, ®c, errmsg, sizeof(errmsg));
+ regerror(result, ®c, errmsg, SIZEOF(errmsg));
amfree(regex);
return errmsg;
}
return NULL;
}
-int match_glob(glob, str)
-char *glob, *str;
+int
+match_glob(
+ const char * glob,
+ const char * str)
{
- char *regex = NULL;
+ char *regex;
regex_t regc;
int result;
char errmsg[STR_SIZE];
regex = glob_to_regex(glob);
if((result = regcomp(®c, regex,
REG_EXTENDED|REG_NOSUB|REG_NEWLINE)) != 0) {
- regerror(result, ®c, errmsg, sizeof(errmsg));
+ regerror(result, ®c, errmsg, SIZEOF(errmsg));
error("glob \"%s\" -> regex \"%s\": %s", glob, regex, errmsg);
+ /*NOTREACHED*/
}
if((result = regexec(®c, str, 0, 0, 0)) != 0
&& result != REG_NOMATCH) {
- regerror(result, ®c, errmsg, sizeof(errmsg));
+ regerror(result, ®c, errmsg, SIZEOF(errmsg));
error("glob \"%s\" -> regex \"%s\": %s", glob, regex, errmsg);
+ /*NOTREACHED*/
}
regfree(®c);
return result == 0;
}
-char *glob_to_regex(glob)
-char *glob;
+char *
+glob_to_regex(
+ const char * glob)
{
char *regex;
char *r;
last_ch = '\0';
for (ch = *glob++; ch != '\0'; last_ch = ch, ch = *glob++) {
if (last_ch == '\\') {
- *r++ = ch;
+ *r++ = (char)ch;
ch = '\0'; /* so last_ch != '\\' next time */
} else if (last_ch == '[' && ch == '!') {
*r++ = '^';
} else if (ch == '\\') {
- *r++ = ch;
+ *r++ = (char)ch;
} else if (ch == '*' || ch == '?') {
*r++ = '[';
*r++ = '^';
|| ch == '$'
|| ch == '|') {
*r++ = '\\';
- *r++ = ch;
+ *r++ = (char)ch;
} else {
- *r++ = ch;
+ *r++ = (char)ch;
}
}
if (last_ch != '\\') {
}
-int match_tar(glob, str)
-char *glob, *str;
+int
+match_tar(
+ const char * glob,
+ const char * str)
{
- char *regex = NULL;
+ char *regex;
regex_t regc;
int result;
char errmsg[STR_SIZE];
regex = tar_to_regex(glob);
if((result = regcomp(®c, regex,
REG_EXTENDED|REG_NOSUB|REG_NEWLINE)) != 0) {
- regerror(result, ®c, errmsg, sizeof(errmsg));
+ regerror(result, ®c, errmsg, SIZEOF(errmsg));
error("glob \"%s\" -> regex \"%s\": %s", glob, regex, errmsg);
+ /*NOTREACHED*/
}
if((result = regexec(®c, str, 0, 0, 0)) != 0
&& result != REG_NOMATCH) {
- regerror(result, ®c, errmsg, sizeof(errmsg));
+ regerror(result, ®c, errmsg, SIZEOF(errmsg));
error("glob \"%s\" -> regex \"%s\": %s", glob, regex, errmsg);
+ /*NOTREACHED*/
}
regfree(®c);
return result == 0;
}
-char *tar_to_regex(glob)
-char *glob;
+char *
+tar_to_regex(
+ const char * glob)
{
char *regex;
char *r;
last_ch = '\0';
for (ch = *glob++; ch != '\0'; last_ch = ch, ch = *glob++) {
if (last_ch == '\\') {
- *r++ = ch;
+ *r++ = (char)ch;
ch = '\0'; /* so last_ch != '\\' next time */
} else if (last_ch == '[' && ch == '!') {
*r++ = '^';
} else if (ch == '\\') {
- *r++ = ch;
+ *r++ = (char)ch;
} else if (ch == '*') {
*r++ = '.';
*r++ = '*';
|| ch == '$'
|| ch == '|') {
*r++ = '\\';
- *r++ = ch;
+ *r++ = (char)ch;
} else {
- *r++ = ch;
+ *r++ = (char)ch;
}
}
if (last_ch != '\\') {
}
-int match_word(glob, word, separator)
-char *glob, *word;
-char separator;
+static int
+match_word(
+ const char * glob,
+ const char * word,
+ const char separator)
{
char *regex;
char *r;
size_t lenword;
char *nword;
char *nglob;
- char *g, *w;
+ char *g;
+ const char *w;
int i;
lenword = strlen(word);
for (ch = *g++; ch != '\0'; last_ch = ch, ch = *g++) {
next_ch = *g;
if (last_ch == '\\') {
- *r++ = ch;
+ *r++ = (char)ch;
ch = '\0'; /* so last_ch != '\\' next time */
} else if (last_ch == '[' && ch == '!') {
*r++ = '^';
} else if (ch == '\\') {
- *r++ = ch;
+ *r++ = (char)ch;
} else if (ch == '*' || ch == '?') {
if(ch == '*' && next_ch == '*') {
*r++ = '.';
*r++ = '\\';
*r++ = separator;
}
- *r++ = ch;
+ *r++ = (char)ch;
} else if ( ch == '('
|| ch == ')'
|| ch == '{'
|| ch == '$'
|| ch == '|') {
*r++ = '\\';
- *r++ = ch;
+ *r++ = (char)ch;
} else {
- *r++ = ch;
+ *r++ = (char)ch;
}
}
if(last_ch != '\\') {
}
-int match_host(glob, host)
-char *glob, *host;
+int
+match_host(
+ const char * glob,
+ const char * host)
{
char *lglob, *lhost;
- char *c, *d;
+ char *c;
+ const char *d;
int i;
lglob = (char *)alloc(strlen(glob)+1);
c = lglob, d=glob;
while( *d != '\0')
- *c++ = tolower(*d++);
+ *c++ = (char)tolower(*d++);
*c = *d;
lhost = (char *)alloc(strlen(host)+1);
c = lhost, d=host;
while( *d != '\0')
- *c++ = tolower(*d++);
+ *c++ = (char)tolower(*d++);
*c = *d;
- i = match_word(lglob, lhost, '.');
+ i = match_word(lglob, lhost, (int)'.');
amfree(lglob);
amfree(lhost);
return i;
}
-int match_disk(glob, disk)
-char *glob, *disk;
+int
+match_disk(
+ const char * glob,
+ const char * disk)
{
return match_word(glob, disk, '/');
}
-int match_datestamp(dateexp, datestamp)
-char *dateexp, *datestamp;
+int
+match_datestamp(
+ const char * dateexp,
+ const char * datestamp)
{
char *dash;
size_t len, len_suffix;
- int len_prefix;
+ size_t len_prefix;
char firstdate[100], lastdate[100];
char mydateexp[100];
int match_exact;
if(strlen(dateexp) >= 100 || strlen(dateexp) < 1) {
error("Illegal datestamp expression %s",dateexp);
+ /*NOTREACHED*/
}
if(dateexp[0] == '^') {
if((dash = strchr(mydateexp,'-'))) {
if(match_exact == 1) {
error("Illegal datestamp expression %s",dateexp);
+ /*NOTREACHED*/
}
- len = dash - mydateexp;
+ len = (size_t)(dash - mydateexp);
len_suffix = strlen(dash) - 1;
len_prefix = len - len_suffix;
- if(len_prefix < 0) {
- error("Illegal datestamp expression %s",dateexp);
- }
-
dash++;
strncpy(firstdate, mydateexp, len);
firstdate[len] = '\0';
}
-int match_level(levelexp, level)
-char *levelexp, *level;
+int
+match_level(
+ const char * levelexp,
+ const char * level)
{
char *dash;
size_t len, len_suffix;
- int len_prefix;
+ size_t len_prefix;
char lowend[100], highend[100];
char mylevelexp[100];
int match_exact;
if(strlen(levelexp) >= 100 || strlen(levelexp) < 1) {
error("Illegal level expression %s",levelexp);
+ /*NOTREACHED*/
}
if(levelexp[0] == '^') {
if((dash = strchr(mylevelexp,'-'))) {
if(match_exact == 1) {
error("Illegal level expression %s",levelexp);
+ /*NOTREACHED*/
}
- len = dash - mylevelexp;
+ len = (size_t)(dash - mylevelexp);
len_suffix = strlen(dash) - 1;
len_prefix = len - len_suffix;
- if(len_prefix < 0) {
- error("Illegal level expression %s",levelexp);
- }
-
dash++;
strncpy(lowend, mylevelexp, len);
lowend[len] = '\0';
* SUCH DAMAGE. */
/*static char *sccsid = "from: @(#)ctime.c 5.26 (Berkeley) 2/23/91";*/
-/*static char *rcsid = "$Id: mktime.c,v 1.4 1998/03/18 10:00:49 amcore Exp $";*/
+/*static char *rcsid = "$Id: mktime.c,v 1.5 2006/05/25 01:47:12 johnfranks Exp $";*/
/*
* This implementation of mktime is lifted straight from the NetBSD (BSD 4.4)
* by hand. Sorry about that.
*/
+#include "amanda.h"
+
#ifndef DSTMINUTES
#define DSTMINUTES 60
#endif
#define TM_YEAR_BASE 1900
#define isleap(y) ((((y) % 4) == 0 && ((y) % 100) != 0) || ((y) % 400) == 0)
-#include <sys/types.h>
-#include <time.h>
-
-extern time_t time();
-
static int mon_lengths[2][MONSPERYEAR] = {
{ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
{ 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
* file named AUTHORS, in the root directory of this distribution.
*/
/*
- * $Id: packet.c,v 1.6 2004/02/13 14:00:35 martinea Exp $
+ * $Id: packet.c,v 1.8 2006/05/25 01:47:12 johnfranks Exp $
*
* Routines for modifying the amanda protocol packet type
*/
{ "ACK", P_ACK },
{ "NAK", P_NAK }
};
-#define NPKTYPES (sizeof(pktypes) / sizeof(pktypes[0]))
+#define NPKTYPES (int)(SIZEOF(pktypes) / SIZEOF(pktypes[0]))
/*
* Initialize a packet
printf_arglist_function2(void pkt_init, pkt_t *, pkt, pktype_t, type,
const char *, fmt)
{
- va_list argp;
+ va_list argp;
assert(pkt != NULL);
assert(strcmp(pkt_type2str(type), "BOGUS") != 0);
assert(fmt != NULL);
pkt->type = type;
-
+ pkt->packet_size = 1000;
+ pkt->body = alloc(pkt->packet_size);
arglist_start(argp, fmt);
- vsnprintf(pkt->body, sizeof(pkt->body), fmt, argp);
+ while (vsnprintf(pkt->body, pkt->packet_size, fmt, argp) >=
+ (int)(pkt->packet_size - 1)) {
+ pkt->packet_size *= 2;
+ amfree(pkt->body);
+ pkt->body = alloc(pkt->packet_size);
+ }
arglist_end(argp);
+ pkt->size = strlen(pkt->body);
}
/*
*/
printf_arglist_function1(void pkt_cat, pkt_t *, pkt, const char *, fmt)
{
- size_t len, bufsize;
- va_list argp;
+ size_t len;
+ va_list argp;
+ char * pktbody;
assert(pkt != NULL);
assert(fmt != NULL);
len = strlen(pkt->body);
- assert(len < sizeof(pkt->body));
-
- bufsize = sizeof(pkt->body) - len;
- if (bufsize <= 0)
- return;
arglist_start(argp, fmt);
- vsnprintf(pkt->body + len, bufsize, fmt, argp);
+ while (vsnprintf(pkt->body + len, pkt->packet_size - len, fmt,argp) >=
+ (int)(pkt->packet_size - len - 1)) {
+ pkt->packet_size *= 2;
+ pktbody = alloc(pkt->packet_size);
+ strncpy(pktbody, pkt->body, len);
+ pktbody[len] = '\0';
+ amfree(pkt->body);
+ pkt->body = pktbody;
+ arglist_end(argp);
+ arglist_start(argp, fmt);
+ }
arglist_end(argp);
+ pkt->size = strlen(pkt->body);
}
/*
* Converts a string into a packet type
*/
pktype_t
-pkt_str2type(typestr)
- const char *typestr;
+pkt_str2type(
+ const char *typestr)
{
int i;
assert(typestr != NULL);
- for (i = 0; i < NPKTYPES; i++)
+ for (i = 0; i < (int)NPKTYPES; i++)
if (strcmp(typestr, pktypes[i].name) == 0)
return (pktypes[i].type);
return ((pktype_t)-1);
* Converts a packet type into a string
*/
const char *
-pkt_type2str(type)
- pktype_t type;
+pkt_type2str(
+ pktype_t type)
{
int i;
- for (i = 0; i < NPKTYPES; i++)
+ for (i = 0; i < (int)NPKTYPES; i++)
if (pktypes[i].type == type)
return (pktypes[i].name);
return ("BOGUS");
* file named AUTHORS, in the root directory of this distribution.
*/
/*
- * $Id: packet.h,v 1.6 2004/02/13 14:00:35 martinea Exp $
+ * $Id: packet.h,v 1.8 2006/05/25 01:47:12 johnfranks Exp $
*
* interfaces for modifying amanda protocol packet type
*/
#ifndef PACKET_H
#define PACKET_H
-/*
- * We limit our body length to 50k.
- */
-#define MAX_PACKET (50*1024)
-
typedef enum { P_REQ = 0, P_REP = 1, P_PREP = 2, P_ACK = 3, P_NAK = 4 } pktype_t;
typedef struct {
- pktype_t type; /* type of packet */
- char body[MAX_PACKET]; /* body of packet */
+ pktype_t type; /* type of packet */
+ char * body; /* body of packet */
+ size_t size;
+ size_t packet_size;
} pkt_t;
/*
* Initialize a packet
*/
-void pkt_init P((pkt_t *, pktype_t, const char *, ...))
+void pkt_init(pkt_t *, pktype_t, const char *, ...)
__attribute__ ((format (printf, 3, 4)));
/*
* Append data to a packet
*/
-void pkt_cat P((pkt_t *, const char *, ...))
+void pkt_cat(pkt_t *, const char *, ...)
__attribute__ ((format (printf, 2, 3)));
/*
* Convert the packet type to and from a string
*/
-const char *pkt_type2str P((pktype_t));
-pktype_t pkt_str2type P((const char *));
+const char *pkt_type2str(pktype_t);
+pktype_t pkt_str2type(const char *);
#endif /* PACKET_H */
#include "pipespawn.h"
#include "arglist.h"
#include "clock.h"
+#include "util.h"
char skip_argument[1];
+pid_t pipespawnv_passwd(char *prog, int pipedef,
+ int *stdinfd, int *stdoutfd, int *stderrfd,
+ char **my_argv);
+
+
/*
* this used to be a function in it's own write but became a wrapper around
* pipespawnv to eliminate redundancy...
*/
-#ifdef STDC_HEADERS
-int pipespawn(char *prog, int pipedef, int *stdinfd, int *stdoutfd,
- int *stderrfd, ...)
-#else
-int pipespawn(prog, pipedef, stdinfd, stdoutfd, stderrfd, va_alist)
-char *prog;
-int pipedef;
-int *stdinfd, *stdoutfd, *stderrfd;
-va_dcl
-#endif
+pid_t
+pipespawn(
+ char * prog,
+ int pipedef,
+ int * stdinfd,
+ int * stdoutfd,
+ int * stderrfd,
+ ...)
{
va_list ap;
- int argc = 0, pid, i;
+ int argc = 0, i;
+ pid_t pid;
char **argv;
/* count args */
* Create the argument vector.
*/
arglist_start(ap, stderrfd);
- argv = (char **)alloc((argc + 1) * sizeof(*argv));
+ argv = (char **)alloc((argc + 1) * SIZEOF(*argv));
i = 0;
while((argv[i] = arglist_val(ap, char *)) != NULL) {
if (argv[i] != skip_argument) {
}
arglist_end(ap);
- pid = pipespawnv_passwd(prog, pipedef, stdinfd, stdoutfd, stderrfd, NULL, NULL, argv);
+ pid = pipespawnv_passwd(prog, pipedef, stdinfd, stdoutfd, stderrfd, argv);
amfree(argv);
return pid;
}
-int pipespawnv(prog, pipedef, stdinfd, stdoutfd, stderrfd, my_argv)
-char *prog;
-int pipedef;
-int *stdinfd, *stdoutfd, *stderrfd;
-char **my_argv;
+pid_t
+pipespawnv(
+ char * prog,
+ int pipedef,
+ int * stdinfd,
+ int * stdoutfd,
+ int * stderrfd,
+ char ** my_argv)
{
return pipespawnv_passwd(prog, pipedef, stdinfd, stdoutfd, stderrfd,
- NULL, NULL, my_argv);
+ my_argv);
}
-int pipespawnv_passwd(prog, pipedef, stdinfd, stdoutfd, stderrfd, passwdvar, passwdfd, my_argv)
-char *prog;
-int pipedef;
-int *stdinfd, *stdoutfd, *stderrfd;
-char *passwdvar;
-int *passwdfd;
-char **my_argv;
+pid_t
+pipespawnv_passwd(
+ char * prog,
+ int pipedef,
+ int * stdinfd,
+ int * stdoutfd,
+ int * stderrfd,
+ char ** my_argv)
{
int argc;
- int pid, i, inpipe[2], outpipe[2], errpipe[2], passwdpipe[2];
+ pid_t pid;
+ int i, inpipe[2], outpipe[2], errpipe[2], passwdpipe[2];
char number[NUM_STR_SIZE];
char **arg;
char *e;
- int ch;
char **env;
char **newenv;
+ char *passwdvar = NULL;
+ int *passwdfd = NULL;
/*
* Log the command line and count the args.
dbprintf(("%s: argument list:", debug_prefix(NULL)));
if ((pipedef & PASSWD_PIPE) != 0) {
passwdvar = *my_argv++;
- passwdfd = (int *)*my_argv++;
+ passwdfd = (int *)*my_argv++;
}
+ memset(inpipe, -1, SIZEOF(inpipe));
+ memset(outpipe, -1, SIZEOF(outpipe));
+ memset(errpipe, -1, SIZEOF(errpipe));
+ memset(passwdpipe, -1, SIZEOF(passwdpipe));
argc = 0;
for(arg = my_argv; *arg != NULL; arg++) {
- if (*arg == skip_argument) {
- continue;
- }
- argc++;
- dbprintf((" "));
- for(i = 0; (ch = (*arg)[i]) != '\0' && isprint(ch) && ch != ' '; i++) {}
- if(ch != '\0' || i == 0) {
- dbprintf(("\""));
- }
- dbprintf(("%s", *arg));
- if(ch != '\0' || i == 0) {
- dbprintf(("\""));
+ char *quoted;
+
+ if (*arg != skip_argument) {
+ argc++;
+ quoted = quote_string(*arg);
+ dbprintf((" %s", quoted));
+ amfree(quoted);
}
}
dbprintf(("\n"));
if ((pipedef & STDIN_PIPE) != 0) {
if(pipe(inpipe) == -1) {
error("error [open pipe to %s: %s]", prog, strerror(errno));
+ /*NOTREACHED*/
}
}
if ((pipedef & STDOUT_PIPE) != 0) {
if(pipe(outpipe) == -1) {
error("error [open pipe to %s: %s]", prog, strerror(errno));
+ /*NOTREACHED*/
}
}
if ((pipedef & STDERR_PIPE) != 0) {
if(pipe(errpipe) == -1) {
error("error [open pipe to %s: %s]", prog, strerror(errno));
+ /*NOTREACHED*/
}
}
if ((pipedef & PASSWD_PIPE) != 0) {
if(pipe(passwdpipe) == -1) {
error("error [open pipe to %s: %s]", prog, strerror(errno));
+ /*NOTREACHED*/
}
}
case -1:
e = strerror(errno);
error("error [fork %s: %s]", prog, e);
+ /*NOTREACHED*/
+
default: /* parent process */
if ((pipedef & STDIN_PIPE) != 0) {
aclose(inpipe[0]); /* close input side of pipe */
*/
if(dup2(inpipe[0], 0) == -1) {
error("error [spawn %s: dup2 in: %s]", prog, strerror(errno));
+ /*NOTREACHED*/
}
if(dup2(outpipe[1], 1) == -1) {
error("error [spawn %s: dup2 out: %s]", prog, strerror(errno));
+ /*NOTREACHED*/
}
if(dup2(errpipe[1], 2) == -1) {
error("error [spawn %s: dup2 err: %s]", prog, strerror(errno));
+ /*NOTREACHED*/
}
/*
*/
env = safe_env();
if ((pipedef & PASSWD_PIPE) != 0) {
- for(i = 0; env[i] != NULL; i++) {}
- newenv = (char **)alloc((i + 1 + 1) * sizeof(*newenv));
- snprintf(number, sizeof(number), "%d", passwdpipe[0]);
+ for (i = 0; env[i] != NULL; i++)
+ (void)i; /* make lint happy and do nothing */
+ newenv = (char **)alloc((i + 1 + 1) * SIZEOF(*newenv));
+ snprintf(number, SIZEOF(number), "%d", passwdpipe[0]);
newenv[0] = vstralloc(passwdvar, "=", number, NULL);
- for(i = 0; (newenv[i + 1] = env[i]) != NULL; i++) {}
+ for(i = 0; env[i] != NULL; i++)
+ newenv[i + 1] = env[i];
+ newenv[i + 1] = NULL;
amfree(env);
env = newenv;
}
execve(prog, my_argv, env);
e = strerror(errno);
error("error [exec %s: %s]", prog, e);
- /* NOTREACHED */
+ /*NOTREACHED*/
}
return pid;
}
#define STDERR_PIPE (1 << 2)
#define PASSWD_PIPE (1 << 3)
-int pipespawn P((char *prog, int pipedef,
+pid_t pipespawn(char *prog, int pipedef,
int *stdinfd, int *stdoutfd, int *stderrfd,
- ...));
-int pipespawnv P((char *prog, int pipedef,
+ ...);
+pid_t pipespawnv(char *prog, int pipedef,
int *stdinfd, int *stdoutfd, int *stderrfd,
- char **my_argv));
-int pipespawnv_passwd P((char *prog, int pipedef,
- int *stdinfd, int *stdoutfd, int *stderrfd,
- char *passwdvar, int *passwdfd,
- char **my_argv));
-
+ char **my_argv);
#endif /* PIPESPAWN_H */
* file named AUTHORS, in the root directory of this distribution.
*/
/*
- * $Id: protocol.c,v 1.39 2006/02/28 16:36:13 martinea Exp $
+ * $Id: protocol.c,v 1.45 2006/05/25 17:07:31 martinea Exp $
*
* implements amanda protocol
*/
* Valid actions that can be passed to the state machine
*/
typedef enum {
- A_START, A_TIMEOUT, A_ERROR, A_RCVDATA, A_CONTPEND, A_PENDING,
- A_CONTINUE, A_FINISH, A_ABORT
-} action_t;
+ PA_START,
+ PA_TIMEOUT,
+ PA_ERROR,
+ PA_RCVDATA,
+ PA_CONTPEND,
+ PA_PENDING,
+ PA_CONTINUE,
+ PA_FINISH,
+ PA_ABORT
+} p_action_t;
/*
* The current state type. States are represented as function
* vectors.
*/
struct proto;
-typedef action_t (*pstate_t) P((struct proto *, action_t, pkt_t *));
+typedef p_action_t (*pstate_t)(struct proto *, p_action_t, pkt_t *);
/*
* This is a request structure that is wrapped around a packet while it
pkt_t req; /* the actual wire request */
protocol_sendreq_callback continuation; /* call when req dies/finishes */
void *datap; /* opaque cookie passed to above */
- char *(*conf_fn) P((char *, void *));/* configuration function */
+ char *(*conf_fn)(char *, void *); /* configuration function */
} proto_t;
#define CONNECT_TRIES 3 /* num retries after connect errors */
#define DROP_DEAD_TIME(t) (CURTIME - (t) > (60 * 60))
/* get the size of an array */
-#define ASIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
+#define ASIZE(arr) (int)(sizeof(arr) / sizeof((arr)[0]))
/*
* Initialization time
/* local functions */
#ifdef PROTO_DEBUG
-static const char *action2str P((action_t));
-static const char *pstate2str P((pstate_t));
+static const char *action2str(p_action_t);
+static const char *pstate2str(pstate_t);
#endif
-static void connect_callback P((void *, security_handle_t *,
- security_status_t));
-static void connect_wait_callback P((void *));
-static void recvpkt_callback P((void *, pkt_t *, security_status_t));
+static void connect_callback(void *, security_handle_t *, security_status_t);
+static void connect_wait_callback(void *);
+static void recvpkt_callback(void *, pkt_t *, security_status_t);
-static action_t s_sendreq P((proto_t *, action_t, pkt_t *));
-static action_t s_ackwait P((proto_t *, action_t, pkt_t *));
-static action_t s_repwait P((proto_t *, action_t, pkt_t *));
-static void state_machine P((proto_t *, action_t, pkt_t *));
+static p_action_t s_sendreq(proto_t *, p_action_t, pkt_t *);
+static p_action_t s_ackwait(proto_t *, p_action_t, pkt_t *);
+static p_action_t s_repwait(proto_t *, p_action_t, pkt_t *);
+static void state_machine(proto_t *, p_action_t, pkt_t *);
/*
* -------------------
* Initialize globals.
*/
void
-protocol_init()
+protocol_init(void)
{
proto_init_time = time(NULL);
* for transmission.
*/
void
-protocol_sendreq(hostname, security_driver, conf_fn, req, repwait, continuation, datap)
- const char *hostname;
- const security_driver_t *security_driver;
- char *(*conf_fn) P((char *, void *));
- const char *req;
- time_t repwait;
- protocol_sendreq_callback continuation;
- void *datap;
+protocol_sendreq(
+ const char * hostname,
+ const security_driver_t * security_driver,
+ char * (*conf_fn)(char *, void *),
+ const char * req,
+ time_t repwait,
+ protocol_sendreq_callback continuation,
+ void * datap)
{
proto_t *p;
- p = alloc(sizeof(proto_t));
+ p = alloc(SIZEOF(proto_t));
p->state = s_sendreq;
p->hostname = stralloc(hostname);
p->security_driver = security_driver;
p->datap = datap;
#ifdef PROTO_DEBUG
- dbprintf(("%s: security_connect: host %s -> p %X\n",
- debug_prefix_time(": protocol"), hostname, (int)p));
+ dbprintf(("%s: security_connect: host %s -> p %p\n",
+ debug_prefix_time(": protocol"), hostname, p));
#endif
- security_connect(p->security_driver, p->hostname, conf_fn, connect_callback, p);
+ security_connect(p->security_driver, p->hostname, conf_fn, connect_callback,
+ p, p->datap);
}
/*
* be had via security_geterror on the handle.
*/
static void
-connect_callback(cookie, security_handle, status)
- void *cookie;
- security_handle_t *security_handle;
- security_status_t status;
+connect_callback(
+ void * cookie,
+ security_handle_t * security_handle,
+ security_status_t status)
{
proto_t *p = cookie;
p->security_handle = security_handle;
#ifdef PROTO_DEBUG
- dbprintf(("%s: connect_callback: p %X\n",
- debug_prefix_time(": protocol"), (int)p));
+ dbprintf(("%s: connect_callback: p %p\n",
+ debug_prefix_time(": protocol"), p));
#endif
switch (status) {
case S_OK:
- state_machine(p, A_START, NULL);
+ state_machine(p, PA_START, NULL);
break;
case S_TIMEOUT:
* an error back to the caller.
*/
if (--p->connecttries == 0) {
- state_machine(p, A_ABORT, NULL);
+ state_machine(p, PA_ABORT, NULL);
} else {
#ifdef PROTO_DEBUG
- dbprintf(("%s: connect_callback: p %X: retrying %s\n",
- debug_prefix_time(": protocol"), (int)p, p->hostname));
+ dbprintf(("%s: connect_callback: p %p: retrying %s\n",
+ debug_prefix_time(": protocol"), p, p->hostname));
#endif
security_close(p->security_handle);
/* XXX overload p->security handle to hold the event handle */
* initial connection attempts failed.
*/
static void
-connect_wait_callback(cookie)
- void *cookie;
+connect_wait_callback(
+ void * cookie)
{
proto_t *p = cookie;
event_release((event_handle_t *)p->security_handle);
security_connect(p->security_driver, p->hostname, p->conf_fn,
- connect_callback, p);
+ connect_callback, p, p->datap);
}
* requests if they plan on doing a lot of work.
*/
void
-protocol_check()
+protocol_check(void)
{
/* arg == 1 means don't block */
* and are just waiting for all of the answers to come back.
*/
void
-protocol_run()
+protocol_run(void)
{
/* arg == 0 means block forever until no more events are left */
* with timeouts and successfull replies.
*/
static void
-state_machine(p, action, pkt)
- proto_t *p;
- action_t action;
- pkt_t *pkt;
+state_machine(
+ proto_t * p,
+ p_action_t action,
+ pkt_t * pkt)
{
pstate_t curstate;
- action_t retaction;
+ p_action_t retaction;
#ifdef PROTO_DEBUG
- dbprintf(("%s: state_machine: initial: p %X action %s pkt %X\n",
+ dbprintf(("%s: state_machine: initial: p %p action %s pkt %p\n",
debug_prefix_time(": protocol"),
- (int)p, action2str(action), NULL));
+ p, action2str(action), NULL));
#endif
assert(p != NULL);
- assert(action == A_RCVDATA || pkt == NULL);
+ assert(action == PA_RCVDATA || pkt == NULL);
assert(p->state != NULL);
for (;;) {
#ifdef PROTO_DEBUG
- dbprintf(("%s: state_machine: p %X state %s action %s\n",
+ dbprintf(("%s: state_machine: p %p state %s action %s\n",
debug_prefix_time(": protocol"),
- (int)p, pstate2str(p->state), action2str(action)));
+ p, pstate2str(p->state), action2str(action)));
if (pkt != NULL) {
dbprintf(("%s: pkt: %s (t %d) orig REQ (t %d cur %d)\n",
debug_prefix(": protocol"),
* is in.
*
* We keep track of the last state we were in so we can make
- * sure states which return A_CONTINUE really have transitioned
+ * sure states which return PA_CONTINUE really have transitioned
* the request to a new state.
*/
curstate = p->state;
- if (action == A_ABORT)
+ if (action == PA_ABORT)
/*
* If the passed action indicates a terminal error, then we
* need to move to abort right away.
*/
- retaction = A_ABORT;
+ retaction = PA_ABORT;
else
/*
* Else we run the state and perform the action it
retaction = (*curstate)(p, action, pkt);
#ifdef PROTO_DEBUG
- dbprintf(("%s: state_machine: p %X state %s returned %s\n",
+ dbprintf(("%s: state_machine: p %p state %s returned %s\n",
debug_prefix_time(": protocol"),
- (int)p, pstate2str(p->state), action2str(retaction)));
+ p, pstate2str(p->state), action2str(retaction)));
#endif
/*
* The state function is expected to return one of the following
- * action_t's.
+ * p_action_t's.
*/
switch (retaction) {
* Setup to receive another pkt, and wait for the recv event
* to occur.
*/
- case A_CONTPEND:
+ case PA_CONTPEND:
(*p->continuation)(p->datap, pkt, p->security_handle);
/* FALLTHROUGH */
- case A_PENDING:
+ case PA_PENDING:
#ifdef PROTO_DEBUG
- dbprintf(("%s: state_machine: p %X state %s: timeout %d\n",
+ dbprintf(("%s: state_machine: p %p state %s: timeout %d\n",
debug_prefix_time(": protocol"),
- (int)p, pstate2str(p->state), (int)p->timeout));
+ p, pstate2str(p->state), (int)p->timeout));
#endif
/*
* Get the security layer to register a receive event for this
* seconds.
*/
security_recvpkt(p->security_handle, recvpkt_callback, p,
- p->timeout);
+ (int)p->timeout);
return;
/*
* Request has moved to another state. Loop and run it again.
*/
- case A_CONTINUE:
+ case PA_CONTINUE:
assert(p->state != curstate);
#ifdef PROTO_DEBUG
- dbprintf(("%s: state_machine: p %X: moved from %s to %s\n",
+ dbprintf(("%s: state_machine: p %p: moved from %s to %s\n",
debug_prefix_time(": protocol"),
- (unsigned int)p, pstate2str(curstate),
+ p, pstate2str(curstate),
pstate2str(p->state)));
#endif
continue;
* pkt to NULL to indicate failure to the callback, and then
* fall through to the common finish code.
*
- * Note that remote failures finish via A_FINISH, because they did
+ * Note that remote failures finish via PA_FINISH, because they did
* complete successfully locally.
*/
- case A_ABORT:
+ case PA_ABORT:
pkt = NULL;
/* FALLTHROUGH */
* Free up resources the request has used, call the continuation
* function specified by the caller and quit.
*/
- case A_FINISH:
+ case PA_FINISH:
(*p->continuation)(p->datap, pkt, p->security_handle);
security_close(p->security_handle);
amfree(p->hostname);
+ amfree(p->req.body);
amfree(p);
return;
assert(0);
break; /* in case asserts are turned off */
}
- /* NOTREACHED */
+ /*NOTREACHED*/
}
- /* NOTREACHED */
+ /*NOTREACHED*/
}
/*
* moves to the acknowledgement wait state. We return from the state
* machine at this point, and let the request be received from the network.
*/
-static action_t
-s_sendreq(p, action, pkt)
- proto_t *p;
- action_t action;
- pkt_t *pkt;
+static p_action_t
+s_sendreq(
+ proto_t * p,
+ p_action_t action,
+ pkt_t * pkt)
{
assert(p != NULL);
+ (void)action; /* Quiet unused parameter warning */
+ (void)pkt; /* Quiet unused parameter warning */
if (security_sendpkt(p->security_handle, &p->req) < 0) {
/* XXX should retry */
security_seterror(p->security_handle, "error sending REQ: %s",
security_geterror(p->security_handle));
- return (A_ABORT);
+ return (PA_ABORT);
}
/*
*/
p->state = s_ackwait;
p->timeout = ACK_WAIT;
- return (A_PENDING);
+ return (PA_PENDING);
}
/*
* The acknowledge wait state. We can enter here two ways:
*
* - the caller has received a packet, located the request for
- * that packet, and called us with an action of A_RCVDATA.
+ * that packet, and called us with an action of PA_RCVDATA.
*
* - the caller has determined that a request has timed out,
- * and has called us with A_TIMEOUT.
+ * and has called us with PA_TIMEOUT.
*
* Here we process the acknowledgment, which usually means that
* the client has agreed to our request and is working on it.
* It will later send a reply when finished.
*/
-static action_t
-s_ackwait(p, action, pkt)
- proto_t *p;
- action_t action;
- pkt_t *pkt;
+static p_action_t
+s_ackwait(
+ proto_t * p,
+ p_action_t action,
+ pkt_t * pkt)
{
assert(p != NULL);
* fail this request. Otherwise, move to the send state
* to retry the request.
*/
- if (action == A_TIMEOUT) {
+ if (action == PA_TIMEOUT) {
assert(pkt == NULL);
if (--p->acktries == 0) {
security_seterror(p->security_handle, "timeout waiting for ACK");
- return (A_ABORT);
+ return (PA_ABORT);
}
p->state = s_sendreq;
- return (A_CONTINUE);
+ return (PA_CONTINUE);
}
- assert(action == A_RCVDATA);
+ assert(action == PA_RCVDATA);
assert(pkt != NULL);
/*
case P_ACK:
p->state = s_repwait;
p->timeout = p->repwait;
- return (A_PENDING);
+ return (PA_PENDING);
/*
* Received a NAK. The request failed, so free up the
* resources associated with it and return.
*
- * This should NOT return A_ABORT because it is not a local failure.
+ * This should NOT return PA_ABORT because it is not a local failure.
*/
case P_NAK:
- return (A_FINISH);
+ return (PA_FINISH);
/*
* The client skipped the ACK, and replied right away.
case P_REP:
case P_PREP:
p->state = s_repwait;
- return (A_CONTINUE);
+ return (PA_CONTINUE);
/*
* Unexpected packet. Requeue this request and hope
* we get what we want later.
*/
default:
- return (A_PENDING);
+ return (PA_PENDING);
}
}
/*
* The reply wait state. We enter here much like we do with s_ackwait.
*/
-static action_t
-s_repwait(p, action, pkt)
- proto_t *p;
- action_t action;
- pkt_t *pkt;
+static p_action_t
+s_repwait(
+ proto_t * p,
+ p_action_t action,
+ pkt_t * pkt)
{
pkt_t ack;
/*
* Timeout waiting for a reply.
*/
- if (action == A_TIMEOUT) {
+ if (action == PA_TIMEOUT) {
assert(pkt == NULL);
/*
*/
if (p->reqtries == 0 || DROP_DEAD_TIME(p->origtime)) {
security_seterror(p->security_handle, "timeout waiting for REP");
- return (A_ABORT);
+ return (PA_ABORT);
}
/*
p->reqtries--;
p->state = s_sendreq;
p->acktries = ACK_TRIES;
- return (A_CONTINUE);
+ return (PA_CONTINUE);
}
- assert(action == A_RCVDATA);
+ assert(action == PA_RCVDATA);
/*
* We've received some data. If we didn't get a reply,
* the reply, cleanup this packet, and return.
*/
if (pkt->type != P_REP && pkt->type != P_PREP)
- return (A_PENDING);
+ return (PA_PENDING);
if(pkt->type == P_REP) {
pkt_init(&ack, P_ACK, "");
if (security_sendpkt(p->security_handle, &ack) < 0) {
/* XXX should retry */
+ amfree(ack.body);
security_seterror(p->security_handle, "error sending ACK: %s",
security_geterror(p->security_handle));
- return (A_ABORT);
+ return (PA_ABORT);
}
- return (A_FINISH);
+ amfree(ack.body);
+ return (PA_FINISH);
}
else if(pkt->type == P_PREP) {
p->timeout = p->repwait - CURTIME + p->curtime + 1;
- return (A_CONTPEND);
+ return (PA_CONTPEND);
}
/* should never go here, shut up compiler warning */
- return (A_FINISH);
+ return (PA_FINISH);
}
/*
* event callback that receives a packet
*/
static void
-recvpkt_callback(cookie, pkt, status)
- void *cookie;
- pkt_t *pkt;
- security_status_t status;
+recvpkt_callback(
+ void * cookie,
+ pkt_t * pkt,
+ security_status_t status)
{
proto_t *p = cookie;
switch (status) {
case S_OK:
- state_machine(p, A_RCVDATA, pkt);
+ state_machine(p, PA_RCVDATA, pkt);
break;
case S_TIMEOUT:
- state_machine(p, A_TIMEOUT, NULL);
+ state_machine(p, PA_TIMEOUT, NULL);
break;
case S_ERROR:
- state_machine(p, A_ABORT, NULL);
+ state_machine(p, PA_ABORT, NULL);
break;
default:
assert(0);
* Convert a pstate_t into a printable form.
*/
static const char *
-pstate2str(pstate)
- pstate_t pstate;
+pstate2str(
+ pstate_t pstate)
{
static const struct {
pstate_t type;
}
/*
- * Convert an action_t into a printable form
+ * Convert an p_action_t into a printable form
*/
static const char *
-action2str(action)
- action_t action;
+action2str(
+ p_action_t action)
{
static const struct {
- action_t type;
+ p_action_t type;
const char name[12];
} actions[] = {
#define X(s) { s, stringize(s) }
- X(A_START),
- X(A_TIMEOUT),
- X(A_ERROR),
- X(A_RCVDATA),
- X(A_CONTPEND),
- X(A_PENDING),
- X(A_CONTINUE),
- X(A_FINISH),
- X(A_ABORT),
+ X(PA_START),
+ X(PA_TIMEOUT),
+ X(PA_ERROR),
+ X(PA_RCVDATA),
+ X(PA_CONTPEND),
+ X(PA_PENDING),
+ X(PA_CONTINUE),
+ X(PA_FINISH),
+ X(PA_ABORT),
#undef X
};
int i;
* file named AUTHORS, in the root directory of this distribution.
*/
/*
- * $Id: protocol.h,v 1.10 2003/04/26 02:02:18 kovert Exp $
+ * $Id: protocol.h,v 1.11 2006/05/25 01:47:12 johnfranks Exp $
*
* server-side interfaces for amanda protocol state machine
*/
#include "security.h"
-void protocol_init P((void));
-typedef void (*protocol_sendreq_callback) P((void *, pkt_t *,
- security_handle_t *));
-void protocol_sendreq P((const char *, const security_driver_t *,
- char *(*) P((char *, void *)),
- const char *,
- time_t, protocol_sendreq_callback, void *));
-void protocol_check P((void));
-void protocol_run P((void));
+void protocol_init(void);
+typedef void (*protocol_sendreq_callback)(void *, pkt_t *,
+ security_handle_t *);
+void protocol_sendreq(const char *, const security_driver_t *,
+ char *(*)(char *, void *), const char *, time_t,
+ protocol_sendreq_callback, void *);
+void protocol_check(void);
+void protocol_run(void);
#endif /* PROTOCOL_H */
* Authors: the Amanda Development Team. Its members are listed in a
* file named AUTHORS, in the root directory of this distribution.
*/
-/* $Id: regcomp.c,v 1.3 1998/07/04 00:18:51 oliva Exp $
+/* $Id: regcomp.c,v 1.4 2006/05/25 01:47:12 johnfranks Exp $
*
* wrapper file for Henry Spencer's regcomp.c
*/
+#include "amanda.h"
#include "amregex.h"
#include "../regex-src/regcomp.c"
*/
/*
- * $Id: rsh-security.c,v 1.18.2.1 2006/04/11 11:11:16 martinea Exp $
+ * $Id: rsh-security.c,v 1.31 2006/08/21 20:17:10 martinea Exp $
*
* rsh-security.c - security and transport over rsh or a rsh-like command.
*
*/
#include "amanda.h"
+#include "util.h"
#include "event.h"
#include "packet.h"
#include "queue.h"
#include "security.h"
+#include "security-util.h"
#include "stream.h"
#include "version.h"
/*
* Arguments to rsh. This should also be configurable
*/
-#define RSH_ARGS "-l", CLIENT_LOGIN
+/*#define RSH_ARGS */
/*
* Number of seconds rsh has to start up
#define H_TAKEN -1 /* rsh_conn->tok was already read */
#define H_EOF -2 /* this connection has been shut down */
-/*
- * This is a rsh connection to a host. We should only have
- * one connection per host.
- */
-struct rsh_conn {
- int read, write; /* pipes to rsh */
- pid_t pid; /* pid of rsh process */
- char pkt[NETWORK_BLOCK_BYTES]; /* last pkt read */
- unsigned long pktlen; /* len of above */
- struct { /* buffer read() calls */
- char buf[STREAM_BUFSIZE]; /* buffer */
- size_t left; /* unread data */
- ssize_t size; /* size of last read */
- } readbuf;
- event_handle_t *ev_read; /* read (EV_READFD) handle */
- int ev_read_refcnt; /* number of readers */
- char hostname[MAX_HOSTNAME_LENGTH+1]; /* host we're talking to */
- char *errmsg; /* error passed up */
- int refcnt; /* number of handles using */
- int handle; /* last proto handle read */
- TAILQ_ENTRY(rsh_conn) tq; /* queue handle */
-};
-
-
-struct rsh_stream;
-
-/*
- * This is the private handle data.
- */
-struct rsh_handle {
- security_handle_t sech; /* MUST be first */
- char *hostname; /* ptr to rc->hostname */
- struct rsh_stream *rs; /* virtual stream we xmit over */
-
- union {
- void (*recvpkt) P((void *, pkt_t *, security_status_t));
- /* func to call when packet recvd */
- void (*connect) P((void *, security_handle_t *, security_status_t));
- /* func to call when connected */
- } fn;
- void *arg; /* argument to pass function */
- event_handle_t *ev_timeout; /* timeout handle for recv */
-};
-
-/*
- * This is the internal security_stream data for rsh.
- */
-struct rsh_stream {
- security_stream_t secstr; /* MUST be first */
- struct rsh_conn *rc; /* physical connection */
- int handle; /* protocol handle */
- event_handle_t *ev_read; /* read (EV_WAIT) event handle */
- void (*fn) P((void *, void *, ssize_t)); /* read event fn */
- void *arg; /* arg for previous */
-};
-
/*
* Interface functions
*/
-static int rsh_sendpkt P((void *, pkt_t *));
-static int rsh_stream_accept P((void *));
-static int rsh_stream_auth P((void *));
-static int rsh_stream_id P((void *));
-static int rsh_stream_write P((void *, const void *, size_t));
-static void *rsh_stream_client P((void *, int));
-static void *rsh_stream_server P((void *));
-static void rsh_accept P((int, int,
- void (*)(security_handle_t *, pkt_t *)));
-static void rsh_close P((void *));
-static void rsh_connect P((const char *,
- char *(*)(char *, void *),
- void (*)(void *, security_handle_t *, security_status_t), void *));
-static void rsh_recvpkt P((void *,
- void (*)(void *, pkt_t *, security_status_t), void *, int));
-static void rsh_recvpkt_cancel P((void *));
-static void rsh_stream_close P((void *));
-static void rsh_stream_read P((void *, void (*)(void *, void *, ssize_t),
- void *));
-static void rsh_stream_read_cancel P((void *));
+static void rsh_connect(const char *, char *(*)(char *, void *),
+ void (*)(void *, security_handle_t *, security_status_t),
+ void *, void *);
/*
* This is our interface to the outside world.
const security_driver_t rsh_security_driver = {
"RSH",
rsh_connect,
- rsh_accept,
- rsh_close,
- rsh_sendpkt,
- rsh_recvpkt,
- rsh_recvpkt_cancel,
- rsh_stream_server,
- rsh_stream_accept,
- rsh_stream_client,
- rsh_stream_close,
- rsh_stream_auth,
- rsh_stream_id,
- rsh_stream_write,
- rsh_stream_read,
- rsh_stream_read_cancel,
-};
-
-/*
- * This is a queue of open connections
- */
-static struct {
- TAILQ_HEAD(, rsh_conn) tailq;
- int qlength;
-} connq = {
- TAILQ_HEAD_INITIALIZER(connq.tailq), 0
+ sec_accept,
+ sec_close,
+ stream_sendpkt,
+ stream_recvpkt,
+ stream_recvpkt_cancel,
+ tcpma_stream_server,
+ tcpma_stream_accept,
+ tcpma_stream_client,
+ tcpma_stream_close,
+ sec_stream_auth,
+ sec_stream_id,
+ tcpm_stream_write,
+ tcpm_stream_read,
+ tcpm_stream_read_sync,
+ tcpm_stream_read_cancel,
+ tcpm_close_connection,
};
-#define connq_first() TAILQ_FIRST(&connq.tailq)
-#define connq_next(rc) TAILQ_NEXT(rc, tq)
-#define connq_append(rc) do { \
- TAILQ_INSERT_TAIL(&connq.tailq, rc, tq); \
- connq.qlength++; \
-} while (0)
-#define connq_remove(rc) do { \
- assert(connq.qlength > 0); \
- TAILQ_REMOVE(&connq.tailq, rc, tq); \
- connq.qlength--; \
-} while (0)
static int newhandle = 1;
-/*
- * This is a function that should be called if a new security_handle_t is
- * created. If NULL, no new handles are created.
- * It is passed the new handle and the received pkt
- */
-static void (*accept_fn) P((security_handle_t *, pkt_t *));
-
/*
* Local functions
*/
-static void connect_callback P((void *));
-static void connect_timeout P((void *));
-static int send_token P((struct rsh_conn *, int, const void *, size_t));
-static int recv_token P((struct rsh_conn *, int));
-static void recvpkt_callback P((void *, void *, ssize_t));
-static void recvpkt_timeout P((void *));
-static void stream_read_callback P((void *));
-
-static int runrsh P((struct rsh_conn *));
-static struct rsh_conn *conn_get P((const char *));
-static void conn_put P((struct rsh_conn *));
-static void conn_read P((struct rsh_conn *));
-static void conn_read_cancel P((struct rsh_conn *));
-static void conn_read_callback P((void *));
-static int net_writev P((int, struct iovec *, int));
-static ssize_t net_read P((struct rsh_conn *, void *, size_t, int));
-static int net_read_fillbuf P((struct rsh_conn *, int, int));
-static void parse_pkt P((pkt_t *, const void *, size_t));
+static int runrsh(struct tcp_conn *, const char *, const char *);
/*
* up a network "connection".
*/
static void
-rsh_connect(hostname, conf_fn, fn, arg)
- const char *hostname;
- char *(*conf_fn) P((char *, void *));
- void (*fn) P((void *, security_handle_t *, security_status_t));
- void *arg;
-{
- struct rsh_handle *rh;
+rsh_connect(
+ const char * hostname,
+ char * (*conf_fn)(char *, void *),
+ void (*fn)(void *, security_handle_t *, security_status_t),
+ void * arg,
+ void * datap)
+{
+ struct sec_handle *rh;
struct hostent *he;
+ char *amandad_path=NULL, *client_username=NULL;
assert(fn != NULL);
assert(hostname != NULL);
- rshprintf(("rsh_connect: %s\n", hostname));
+ rshprintf(("%s: rsh: rsh_connect: %s\n", debug_prefix_time(NULL),
+ hostname));
- rh = alloc(sizeof(*rh));
+ rh = alloc(SIZEOF(*rh));
security_handleinit(&rh->sech, &rsh_security_driver);
rh->hostname = NULL;
rh->rs = NULL;
(*fn)(arg, &rh->sech, S_ERROR);
return;
}
- rh->hostname = he->h_name; /* will be replaced */
- rh->rs = rsh_stream_client(rh, newhandle++);
+ rh->hostname = stralloc(he->h_name); /* will be replaced */
+ rh->rs = tcpma_stream_client(rh, newhandle++);
if (rh->rs == NULL)
goto error;
- rh->hostname = rh->rs->rc->hostname;
+ amfree(rh->hostname);
+ rh->hostname = stralloc(rh->rs->rc->hostname);
- if (rh->rs->rc->pid < 0) {
- /*
- * We need to open a new connection.
- *
- * XXX need to eventually limit number of outgoing connections here.
- */
- if (runrsh(rh->rs->rc) < 0) {
- security_seterror(&rh->sech,
- "can't connect to %s: %s", hostname, rh->rs->rc->errmsg);
+ /*
+ * We need to open a new connection.
+ *
+ * XXX need to eventually limit number of outgoing connections here.
+ */
+ if(conf_fn) {
+ amandad_path = conf_fn("amandad_path", datap);
+ client_username = conf_fn("client_username", datap);
+ }
+ if(rh->rc->read == -1) {
+ if (runrsh(rh->rs->rc, amandad_path, client_username) < 0) {
+ security_seterror(&rh->sech, "can't connect to %s: %s",
+ hostname, rh->rs->rc->errmsg);
goto error;
}
+ rh->rc->refcnt++;
}
+
/*
* The socket will be opened async so hosts that are down won't
* block everything. We need to register a write event
*/
rh->fn.connect = fn;
rh->arg = arg;
- rh->rs->ev_read = event_register(rh->rs->rc->write, EV_WRITEFD,
- connect_callback, rh);
- rh->ev_timeout = event_register(CONNECT_TIMEOUT, EV_TIME,
- connect_timeout, rh);
+ rh->rs->ev_read = event_register((event_id_t)rh->rs->rc->write, EV_WRITEFD,
+ sec_connect_callback, rh);
+ rh->ev_timeout = event_register((event_id_t)CONNECT_TIMEOUT, EV_TIME,
+ sec_connect_timeout, rh);
return;
(*fn)(arg, &rh->sech, S_ERROR);
}
-/*
- * Called when a rsh connection is finished connecting and is ready
- * to be authenticated.
- */
-static void
-connect_callback(cookie)
- void *cookie;
-{
- struct rsh_handle *rh = cookie;
-
- event_release(rh->rs->ev_read);
- rh->rs->ev_read = NULL;
- event_release(rh->ev_timeout);
- rh->ev_timeout = NULL;
-
- (*rh->fn.connect)(rh->arg, &rh->sech, S_OK);
-}
-
-/*
- * Called if a connection times out before completion.
- */
-static void
-connect_timeout(cookie)
- void *cookie;
-{
- struct rsh_handle *rh = cookie;
-
- event_release(rh->rs->ev_read);
- rh->rs->ev_read = NULL;
- event_release(rh->ev_timeout);
- rh->ev_timeout = NULL;
-
- (*rh->fn.connect)(rh->arg, &rh->sech, S_TIMEOUT);
-}
-
-/*
- * Setup to handle new incoming connections
- */
-static void
-rsh_accept(in, out, fn)
- int in, out;
- void (*fn) P((security_handle_t *, pkt_t *));
-{
- struct rsh_conn *rc;
-
- rc = conn_get("unknown");
- rc->read = in;
- rc->write = out;
- accept_fn = fn;
- conn_read(rc);
-}
-
-/*
- * Locate an existing connection to the given host, or create a new,
- * unconnected entry if none exists. The caller is expected to check
- * for the lack of a connection (rc->read == -1) and set one up.
- */
-static struct rsh_conn *
-conn_get(hostname)
- const char *hostname;
-{
- struct rsh_conn *rc;
-
- rshprintf(("rsh: conn_get: %s\n", hostname));
-
- for (rc = connq_first(); rc != NULL; rc = connq_next(rc)) {
- if (strcasecmp(hostname, rc->hostname) == 0)
- break;
- }
-
- if (rc != NULL) {
- rc->refcnt++;
- rshprintf(("rsh: conn_get: exists, refcnt to %s is now %d\n",
- rc->hostname, rc->refcnt));
- return (rc);
- }
-
- rshprintf(("rsh: conn_get: creating new handle\n"));
- /*
- * We can't be creating a new handle if we are the client
- */
- assert(accept_fn == NULL);
- rc = alloc(sizeof(*rc));
- rc->read = rc->write = -1;
- rc->pid = -1;
- rc->readbuf.left = 0;
- rc->readbuf.size = 0;
- rc->ev_read = NULL;
- strncpy(rc->hostname, hostname, sizeof(rc->hostname) - 1);
- rc->hostname[sizeof(rc->hostname) - 1] = '\0';
- rc->errmsg = NULL;
- rc->refcnt = 1;
- rc->handle = -1;
- connq_append(rc);
- return (rc);
-}
-
-/*
- * Delete a reference to a connection, and close it if it is the last
- * reference.
- */
-static void
-conn_put(rc)
- struct rsh_conn *rc;
-{
- amwait_t status;
-
- assert(rc->refcnt > 0);
- if (--rc->refcnt > 0) {
- rshprintf(("rsh: conn_put: decrementing refcnt for %s to %d\n",
- rc->hostname, rc->refcnt));
- return;
- }
- rshprintf(("rsh: conn_put: closing connection to %s\n", rc->hostname));
- if (rc->read != -1)
- aclose(rc->read);
- if (rc->write != -1)
- aclose(rc->write);
- if (rc->pid != -1) {
- waitpid(rc->pid, &status, WNOHANG);
- }
- if (rc->ev_read != NULL)
- event_release(rc->ev_read);
- if (rc->errmsg != NULL)
- amfree(rc->errmsg);
- connq_remove(rc);
- amfree(rc);
-}
-
-/*
- * Turn on read events for a conn. Or, increase a refcnt if we are
- * already receiving read events.
- */
-static void
-conn_read(rc)
- struct rsh_conn *rc;
-{
-
- if (rc->ev_read != NULL) {
- rc->ev_read_refcnt++;
- rshprintf(("rsh: conn_read: incremented refcnt to %d for %s\n",
- rc->ev_read_refcnt, rc->hostname));
- return;
- }
- rshprintf(("rsh: conn_read registering event handler for %s\n",
- rc->hostname));
- rc->ev_read = event_register(rc->read, EV_READFD, conn_read_callback, rc);
- rc->ev_read_refcnt = 1;
-}
-
-static void
-conn_read_cancel(rc)
- struct rsh_conn *rc;
-{
-
- if (--rc->ev_read_refcnt > 0) {
- rshprintf(("rsh: conn_read_cancel: decremented refcnt to %d for %s\n",
- rc->ev_read_refcnt, rc->hostname));
- return;
- }
- rshprintf(("rsh: conn_read_cancel: releasing event handler for %s\n",
- rc->hostname));
- event_release(rc->ev_read);
- rc->ev_read = NULL;
-}
-
-/*
- * frees a handle allocated by the above
- */
-static void
-rsh_close(inst)
- void *inst;
-{
- struct rsh_handle *rh = inst;
-
- assert(rh != NULL);
-
- rshprintf(("rsh: closing handle to %s\n", rh->hostname));
-
- if (rh->rs != NULL) {
- /* This may be null if we get here on an error */
- rsh_recvpkt_cancel(rh);
- security_stream_close(&rh->rs->secstr);
- }
- /* keep us from getting here again */
- rh->sech.driver = NULL;
- amfree(rh);
-}
-
/*
* Forks a rsh to the host listed in rc->hostname
* Returns negative on error, with an errmsg in rc->errmsg.
*/
static int
-runrsh(rc)
- struct rsh_conn *rc;
+runrsh(
+ struct tcp_conn * rc,
+ const char * amandad_path,
+ const char * client_username)
{
int rpipe[2], wpipe[2];
- char *amandad_path;
+ char *xamandad_path = (char *)amandad_path;
+ char *xclient_username = (char *)client_username;
+ memset(rpipe, -1, SIZEOF(rpipe));
+ memset(wpipe, -1, SIZEOF(wpipe));
if (pipe(rpipe) < 0 || pipe(wpipe) < 0) {
- rc->errmsg = newvstralloc("pipe: ", strerror(errno), NULL);
+ rc->errmsg = newvstralloc(rc->errmsg, "pipe: ", strerror(errno), NULL);
return (-1);
}
+
switch (rc->pid = fork()) {
case -1:
- rc->errmsg = newvstralloc("fork: ", strerror(errno), NULL);
+ rc->errmsg = newvstralloc(rc->errmsg, "fork: ", strerror(errno), NULL);
aclose(rpipe[0]);
aclose(rpipe[1]);
aclose(wpipe[0]);
case 0:
dup2(wpipe[0], 0);
dup2(rpipe[1], 1);
- dup2(rpipe[1], 2);
break;
default:
rc->read = rpipe[0];
safe_fd(-1, 0);
- amandad_path = vstralloc(libexecdir, "/", "amandad", versionsuffix(),
- NULL);
- execlp(RSH_PATH, RSH_PATH, RSH_ARGS, rc->hostname, amandad_path,
- "-auth=rsh", NULL);
+ if(!xamandad_path || strlen(xamandad_path) <= 1)
+ xamandad_path = vstralloc(libexecdir, "/", "amandad",
+ versionsuffix(), NULL);
+ if(!xclient_username || strlen(xclient_username) <= 1)
+ xclient_username = CLIENT_LOGIN;
+
+ execlp(RSH_PATH, RSH_PATH, "-l", xclient_username,
+ rc->hostname, xamandad_path, "-auth=rsh", "amdump", "amindexd",
+ "amidxtaped", (char *)NULL);
error("error: couldn't exec %s: %s", RSH_PATH, strerror(errno));
- /* should nerver go here, shut up compiler warning */
+ /* should never go here, shut up compiler warning */
return(-1);
}
-/*
- * Transmit a packet.
- */
-static int
-rsh_sendpkt(cookie, pkt)
- void *cookie;
- pkt_t *pkt;
-{
- char buf[sizeof(pkt_t)];
- struct rsh_handle *rh = cookie;
- size_t len;
-
- assert(rh != NULL);
- assert(pkt != NULL);
-
- rshprintf(("rsh: sendpkt: enter\n"));
-
- len = strlen(pkt->body) + 2;
- buf[0] = (char)pkt->type;
- strcpy(&buf[1], pkt->body);
-
- rshprintf(("rsh: sendpkt: %s (%d) pkt_t (len %d) contains:\n\n\"%s\"\n\n",
- pkt_type2str(pkt->type), pkt->type, strlen(pkt->body), pkt->body));
-
- if (rsh_stream_write(rh->rs, buf, len) < 0) {
- security_seterror(&rh->sech, security_stream_geterror(&rh->rs->secstr));
- return (-1);
- }
- return (0);
-}
-
-/*
- * Set up to receive a packet asyncronously, and call back when
- * it has been read.
- */
-static void
-rsh_recvpkt(cookie, fn, arg, timeout)
- void *cookie, *arg;
- void (*fn) P((void *, pkt_t *, security_status_t));
- int timeout;
-{
- struct rsh_handle *rh = cookie;
-
- assert(rh != NULL);
-
- rshprintf(("rsh: recvpkt registered for %s\n", rh->hostname));
-
- /*
- * Reset any pending timeout on this handle
- */
- if (rh->ev_timeout != NULL)
- event_release(rh->ev_timeout);
-
- /*
- * Negative timeouts mean no timeout
- */
- if (timeout < 0)
- rh->ev_timeout = NULL;
- else
- rh->ev_timeout = event_register(timeout, EV_TIME, recvpkt_timeout, rh);
-
- rh->fn.recvpkt = fn;
- rh->arg = arg;
- rsh_stream_read(rh->rs, recvpkt_callback, rh);
-}
-
-/*
- * Remove a async receive request from the queue
- */
-static void
-rsh_recvpkt_cancel(cookie)
- void *cookie;
-{
- struct rsh_handle *rh = cookie;
-
- rshprintf(("rsh: cancelling recvpkt for %s\n", rh->hostname));
-
- assert(rh != NULL);
-
- rsh_stream_read_cancel(rh->rs);
- if (rh->ev_timeout != NULL) {
- event_release(rh->ev_timeout);
- rh->ev_timeout = NULL;
- }
-}
-
-/*
- * This is called when a handle is woken up because data read off of the
- * net is for it.
- */
-static void
-recvpkt_callback(cookie, buf, bufsize)
- void *cookie, *buf;
- ssize_t bufsize;
-{
- pkt_t pkt;
- struct rsh_handle *rh = cookie;
-
- assert(rh != NULL);
-
- /*
- * We need to cancel the recvpkt request before calling
- * the callback because the callback may reschedule us.
- */
- rsh_recvpkt_cancel(rh);
-
- switch (bufsize) {
- case 0:
- security_seterror(&rh->sech,
- "EOF on read from %s", rh->hostname);
- (*rh->fn.recvpkt)(rh->arg, NULL, S_ERROR);
- return;
- case -1:
- security_seterror(&rh->sech, security_stream_geterror(&rh->rs->secstr));
- (*rh->fn.recvpkt)(rh->arg, NULL, S_ERROR);
- return;
- default:
- break;
- }
-
- parse_pkt(&pkt, buf, bufsize);
- rshprintf(("rsh: received %s packet (%d) from %s, contains:\n\n\"%s\"\n\n",
- pkt_type2str(pkt.type), pkt.type, rh->hostname, pkt.body));
- (*rh->fn.recvpkt)(rh->arg, &pkt, S_OK);
-}
-
-/*
- * This is called when a handle times out before receiving a packet.
- */
-static void
-recvpkt_timeout(cookie)
- void *cookie;
-{
- struct rsh_handle *rh = cookie;
-
- assert(rh != NULL);
-
- rshprintf(("rsh: recvpkt timeout for %s\n", rh->hostname));
-
- rsh_recvpkt_cancel(rh);
- (*rh->fn.recvpkt)(rh->arg, NULL, S_TIMEOUT);
-}
-
-/*
- * Create the server end of a stream. For rsh, this means setup a stream
- * object and allocate a new handle for it.
- */
-static void *
-rsh_stream_server(h)
- void *h;
-{
- struct rsh_handle *rh = h;
- struct rsh_stream *rs;
-
- assert(rh != NULL);
-
- rs = alloc(sizeof(*rs));
- security_streaminit(&rs->secstr, &rsh_security_driver);
- rs->rc = conn_get(rh->hostname);
- /*
- * Stream should already be setup!
- */
- if (rs->rc->read < 0) {
- conn_put(rs->rc);
- amfree(rs);
- security_seterror(&rh->sech, "lost connection to %s", rh->hostname);
- return (NULL);
- }
- rh->hostname = rs->rc->hostname;
- /*
- * so as not to conflict with the amanda server's handle numbers,
- * we start at 5000 and work down
- */
- rs->handle = 5000 - newhandle++;
- rs->ev_read = NULL;
- rshprintf(("rsh: stream_server: created stream %d\n", rs->handle));
- return (rs);
-}
-
-/*
- * Accept an incoming connection on a stream_server socket
- * Nothing needed for rsh.
- */
-static int
-rsh_stream_accept(s)
- void *s;
-{
-
- return (0);
-}
-
-/*
- * Return a connected stream. For rsh, this means setup a stream
- * with the supplied handle.
- */
-static void *
-rsh_stream_client(h, id)
- void *h;
- int id;
-{
- struct rsh_handle *rh = h;
- struct rsh_stream *rs;
-
- assert(rh != NULL);
-
- if (id <= 0) {
- security_seterror(&rh->sech,
- "%d: invalid security stream id", id);
- return (NULL);
- }
-
- rs = alloc(sizeof(*rs));
- security_streaminit(&rs->secstr, &rsh_security_driver);
- rs->handle = id;
- rs->ev_read = NULL;
- rs->rc = conn_get(rh->hostname);
-
- rshprintf(("rsh: stream_client: connected to stream %d\n", id));
-
- return (rs);
-}
-
-/*
- * Close and unallocate resources for a stream.
- */
-static void
-rsh_stream_close(s)
- void *s;
-{
- struct rsh_stream *rs = s;
-
- assert(rs != NULL);
-
- rshprintf(("rsh: stream_close: closing stream %d\n", rs->handle));
-
- rsh_stream_read_cancel(rs);
- conn_put(rs->rc);
- amfree(rs);
-}
-
-/*
- * Authenticate a stream
- * Nothing needed for rsh. The connection is authenticated by rshd
- * on startup.
- */
-static int
-rsh_stream_auth(s)
- void *s;
-{
-
- return (0);
-}
-
-/*
- * Returns the stream id for this stream. This is just the local
- * port.
- */
-static int
-rsh_stream_id(s)
- void *s;
-{
- struct rsh_stream *rs = s;
-
- assert(rs != NULL);
-
- return (rs->handle);
-}
-
-/*
- * Write a chunk of data to a stream. Blocks until completion.
- */
-static int
-rsh_stream_write(s, buf, size)
- void *s;
- const void *buf;
- size_t size;
-{
- struct rsh_stream *rs = s;
-
- assert(rs != NULL);
-
- rshprintf(("rsh: stream_write: writing %d bytes to %s:%d\n", size,
- rs->rc->hostname, rs->handle));
-
- if (send_token(rs->rc, rs->handle, buf, size) < 0) {
- security_stream_seterror(&rs->secstr, rs->rc->errmsg);
- return (-1);
- }
- return (0);
-}
-
-/*
- * Submit a request to read some data. Calls back with the given
- * function and arg when completed.
- */
-static void
-rsh_stream_read(s, fn, arg)
- void *s, *arg;
- void (*fn) P((void *, void *, ssize_t));
-{
- struct rsh_stream *rs = s;
-
- assert(rs != NULL);
-
- /*
- * Only one read request can be active per stream.
- */
- if (rs->ev_read == NULL) {
- rs->ev_read = event_register((event_id_t)rs->rc, EV_WAIT,
- stream_read_callback, rs);
- conn_read(rs->rc);
- }
- rs->fn = fn;
- rs->arg = arg;
-}
-
-/*
- * Cancel a previous stream read request. It's ok if we didn't have a read
- * scheduled.
- */
-static void
-rsh_stream_read_cancel(s)
- void *s;
-{
- struct rsh_stream *rs = s;
-
- assert(rs != NULL);
-
- if (rs->ev_read != NULL) {
- event_release(rs->ev_read);
- rs->ev_read = NULL;
- conn_read_cancel(rs->rc);
- }
-}
-
-/*
- * Callback for rsh_stream_read
- */
-static void
-stream_read_callback(arg)
- void *arg;
-{
- struct rsh_stream *rs = arg;
- assert(rs != NULL);
-
- rshprintf(("rsh: stream_read_callback: handle %d\n", rs->handle));
-
- /*
- * Make sure this was for us. If it was, then blow away the handle
- * so it doesn't get claimed twice. Otherwise, leave it alone.
- *
- * If the handle is EOF, pass that up to our callback.
- */
- if (rs->rc->handle == rs->handle) {
- rshprintf(("rsh: stream_read_callback: it was for us\n"));
- rs->rc->handle = H_TAKEN;
- } else if (rs->rc->handle != H_EOF) {
- rshprintf(("rsh: stream_read_callback: not for us\n"));
- return;
- }
-
- /*
- * Remove the event first, and then call the callback.
- * We remove it first because we don't want to get in their
- * way if they reschedule it.
- */
- rsh_stream_read_cancel(rs);
-
- if (rs->rc->pktlen == 0) {
- rshprintf(("rsh: stream_read_callback: EOF\n"));
- (*rs->fn)(rs->arg, NULL, 0);
- return;
- }
- rshprintf(("rsh: stream_read_callback: read %ld bytes from %s:%d\n",
- rs->rc->pktlen, rs->rc->hostname, rs->handle));
- (*rs->fn)(rs->arg, rs->rc->pkt, rs->rc->pktlen);
-}
-
-/*
- * The callback for the netfd for the event handler
- * Determines if this packet is for this security handle,
- * and does the real callback if so.
- */
-static void
-conn_read_callback(cookie)
- void *cookie;
-{
- struct rsh_conn *rc = cookie;
- struct rsh_handle *rh;
- pkt_t pkt;
- int rval;
-
- assert(cookie != NULL);
-
- rshprintf(("rsh: conn_read_callback\n"));
-
- /* Read the data off the wire. If we get errors, shut down. */
- rval = recv_token(rc, 60);
- rshprintf(("rsh: conn_read_callback: recv_token returned %d\n", rval));
- if (rval <= 0) {
- rc->pktlen = 0;
- rc->handle = H_EOF;
- rval = event_wakeup((event_id_t)rc);
- rshprintf(("rsh: conn_read_callback: event_wakeup return %d\n", rval));
- /* delete our 'accept' reference */
- if (accept_fn != NULL)
- conn_put(rc);
- accept_fn = NULL;
- return;
- }
-
- /* If there are events waiting on this handle, we're done */
- rval = event_wakeup((event_id_t)rc);
- rshprintf(("rsh: conn_read_callback: event_wakeup return %d\n", rval));
- if (rval > 0)
- return;
-
- /* If there is no accept fn registered, then drop the packet */
- if (accept_fn == NULL)
- return;
-
- rh = alloc(sizeof(*rh));
- security_handleinit(&rh->sech, &rsh_security_driver);
- rh->hostname = rc->hostname;
- rh->rs = rsh_stream_client(rh, rc->handle);
- rh->ev_timeout = NULL;
-
- rshprintf(("rsh: new connection\n"));
- parse_pkt(&pkt, rc->pkt, rc->pktlen);
- rshprintf(("rsh: calling accept_fn\n"));
- (*accept_fn)(&rh->sech, &pkt);
-}
-
-static void
-parse_pkt(pkt, buf, bufsize)
- pkt_t *pkt;
- const void *buf;
- size_t bufsize;
-{
- const unsigned char *bufp = buf;
-
- rshprintf(("rsh: parse_pkt: parsing buffer of %d bytes\n", bufsize));
-
- pkt->type = (pktype_t)*bufp++;
- bufsize--;
-
- if (bufsize == 0) {
- pkt->body[0] = '\0';
- } else {
- if (bufsize > sizeof(pkt->body) - 1)
- bufsize = sizeof(pkt->body) - 1;
- memcpy(pkt->body, bufp, bufsize);
- pkt->body[sizeof(pkt->body) - 1] = '\0';
- }
-
- rshprintf(("rsh: parse_pkt: %s (%d): \"%s\"\n", pkt_type2str(pkt->type),
- pkt->type, pkt->body));
-}
-
-
-/*
- * Transmits a chunk of data over a rsh_handle, adding
- * the necessary headers to allow the remote end to decode it.
- */
-static int
-send_token(rc, handle, buf, len)
- struct rsh_conn *rc;
- int handle;
- const void *buf;
- size_t len;
-{
- unsigned int netlength, nethandle;
- struct iovec iov[3];
-
- rshprintf(("rsh: send_token: writing %d bytes to %s\n", len,
- rc->hostname));
-
- assert(sizeof(netlength) == 4);
-
- /*
- * Format is:
- * 32 bit length (network byte order)
- * 32 bit handle (network byte order)
- * data
- */
- netlength = htonl(len);
- iov[0].iov_base = (void *)&netlength;
- iov[0].iov_len = sizeof(netlength);
-
- nethandle = htonl(handle);
- iov[1].iov_base = (void *)&nethandle;
- iov[1].iov_len = sizeof(nethandle);
-
- iov[2].iov_base = (void *)buf;
- iov[2].iov_len = len;
-
- if (net_writev(rc->write, iov, 3) < 0) {
- rc->errmsg = newvstralloc(rc->errmsg, "rsh write error to ",
- rc->hostname, ": ", strerror(errno), NULL);
- return (-1);
- }
- return (0);
-}
-
-static int
-recv_token(rc, timeout)
- struct rsh_conn *rc;
- int timeout;
-{
- unsigned int netint;
-
- assert(sizeof(netint) == 4);
-
- assert(rc->read >= 0);
-
- rshprintf(("rsh: recv_token: reading from %s\n", rc->hostname));
-
- switch (net_read(rc, &netint, sizeof(netint), timeout)) {
- case -1:
- rc->errmsg = newvstralloc(rc->errmsg, "recv error: ", strerror(errno),
- NULL);
- return (-1);
- case 0:
- rc->pktlen = 0;
- return (0);
- default:
- break;
- }
- rc->pktlen = ntohl(netint);
- if (rc->pktlen > sizeof(rc->pkt)) {
- rc->errmsg = newstralloc(rc->errmsg, "recv error: huge packet");
- return (-1);
- }
-
- switch (net_read(rc, &netint, sizeof(netint), timeout)) {
- case -1:
- rc->errmsg = newvstralloc(rc->errmsg, "recv error: ", strerror(errno),
- NULL);
- return (-1);
- case 0:
- rc->pktlen = 0;
- return (0);
- default:
- break;
- }
- rc->handle = ntohl(netint);
-
- switch (net_read(rc, rc->pkt, rc->pktlen, timeout)) {
- case -1:
- rc->errmsg = newvstralloc(rc->errmsg, "recv error: ", strerror(errno),
- NULL);
- return (-1);
- case 0:
- rc->pktlen = 0;
- break;
- default:
- break;
- }
-
- rshprintf(("rsh: recv_token: read %ld bytes from %s\n", rc->pktlen,
- rc->hostname));
- return (rc->pktlen);
-}
-
-/*
- * Writes out the entire iovec
- */
-static int
-net_writev(fd, iov, iovcnt)
- int fd, iovcnt;
- struct iovec *iov;
-{
- int delta, n, total;
-
- assert(iov != NULL);
-
- total = 0;
- while (iovcnt > 0) {
- /*
- * Write the iovec
- */
- total += n = writev(fd, iov, iovcnt);
- if (n < 0)
- return (-1);
- if (n == 0) {
- errno = EIO;
- return (-1);
- }
- /*
- * Iterate through each iov. Figure out what we still need
- * to write out.
- */
- for (; n > 0; iovcnt--, iov++) {
- /* 'delta' is the bytes written from this iovec */
- delta = n < iov->iov_len ? n : iov->iov_len;
- /* subtract from the total num bytes written */
- n -= delta;
- assert(n >= 0);
- /* subtract from this iovec */
- iov->iov_len -= delta;
- iov->iov_base = (char *)iov->iov_base + delta;
- /* if this iovec isn't empty, run the writev again */
- if (iov->iov_len > 0)
- break;
- }
- }
- return (total);
-}
-
-/*
- * Like read(), but waits until the entire buffer has been filled.
- */
-static ssize_t
-net_read(rc, vbuf, origsize, timeout)
- struct rsh_conn *rc;
- void *vbuf;
- size_t origsize;
- int timeout;
-{
- char *buf = vbuf, *off; /* ptr arith */
- int nread;
- size_t size = origsize;
-
- while (size > 0) {
- if (rc->readbuf.left == 0) {
- if (net_read_fillbuf(rc, timeout, size) < 0)
- return (-1);
- if (rc->readbuf.size == 0)
- return (0);
- }
- nread = min(rc->readbuf.left, size);
- off = rc->readbuf.buf + rc->readbuf.size - rc->readbuf.left;
- memcpy(buf, off, nread);
-
- buf += nread;
- size -= nread;
- rc->readbuf.left -= nread;
- }
- return ((ssize_t)origsize);
-}
-
-/*
- * net_read likes to do a lot of little reads. Buffer it.
- */
-static int
-net_read_fillbuf(rc, timeout, size)
- struct rsh_conn *rc;
- int timeout;
- int size;
-{
- fd_set readfds;
- struct timeval tv;
- if(size > sizeof(rc->readbuf.buf)) size = sizeof(rc->readbuf.buf);
-
- FD_ZERO(&readfds);
- FD_SET(rc->read, &readfds);
- tv.tv_sec = timeout;
- tv.tv_usec = 0;
- switch (select(rc->read + 1, &readfds, NULL, NULL, &tv)) {
- case 0:
- errno = ETIMEDOUT;
- /* FALLTHROUGH */
- case -1:
- return (-1);
- case 1:
- assert(FD_ISSET(rc->read, &readfds));
- break;
- default:
- assert(0);
- break;
- }
- rc->readbuf.left = 0;
- rc->readbuf.size = read(rc->read, rc->readbuf.buf, size);
- if (rc->readbuf.size < 0)
- return (-1);
- rc->readbuf.left = rc->readbuf.size;
- return (0);
-}
-
#endif /* RSH_SECURITY */
--- /dev/null
+/*
+ * Amanda, The Advanced Maryland Automatic Network Disk Archiver
+ * Copyright (c) 1999 University of Maryland
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of U.M. not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. U.M. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: the Amanda Development Team. Its members are listed in a
+ * file named AUTHORS, in the root directory of this distribution.
+ */
+
+/*
+ * $Id: security-util.c,v 1.25 2006/07/22 12:04:47 martinea Exp $
+ *
+ * sec-security.c - security and transport over sec or a sec-like command.
+ *
+ * XXX still need to check for initial keyword on connect so we can skip
+ * over shell garbage and other stuff that sec might want to spew out.
+ */
+
+#include "amanda.h"
+#include "util.h"
+#include "event.h"
+#include "packet.h"
+#include "queue.h"
+#include "security.h"
+#include "security-util.h"
+#include "stream.h"
+#include "version.h"
+
+/* #define SEC_DEBUG */
+#define SHOW_SECURITY_DETAIL
+
+#ifdef SEC_DEBUG
+# define secprintf(x) dbprintf(x)
+#else
+# ifdef __lint
+# define secprintf(x) (void)(x)
+# else
+# define secprintf(x)
+# endif
+#endif
+
+/*
+ * Magic values for sec_conn->handle
+ */
+#define H_TAKEN -1 /* sec_conn->tok was already read */
+#define H_EOF -2 /* this connection has been shut down */
+
+/*
+ * This is a queue of open connections
+ */
+struct connq_s connq = {
+ TAILQ_HEAD_INITIALIZER(connq.tailq), 0
+};
+static int newhandle = 1;
+static int newevent = 1;
+
+/*
+ * Local functions
+ */
+static void recvpkt_callback(void *, void *, ssize_t);
+static void stream_read_callback(void *);
+static void stream_read_sync_callback(void *);
+
+static void sec_tcp_conn_read_cancel(struct tcp_conn *);
+static void sec_tcp_conn_read_callback(void *);
+
+
+/*
+ * Authenticate a stream
+ * Nothing needed for sec. The connection is authenticated by secd
+ * on startup.
+ */
+int
+sec_stream_auth(
+ void * s)
+{
+ (void)s; /* Quiet unused parameter warning */
+ return (0);
+}
+
+/*
+ * Returns the stream id for this stream. This is just the local
+ * port.
+ */
+int
+sec_stream_id(
+ void * s)
+{
+ struct sec_stream *rs = s;
+
+ assert(rs != NULL);
+
+ return (rs->handle);
+}
+
+/*
+ * Setup to handle new incoming connections
+ */
+void
+sec_accept(
+ const security_driver_t *driver,
+ int in,
+ int out,
+ void (*fn)(security_handle_t *, pkt_t *))
+{
+ struct tcp_conn *rc;
+
+ rc = sec_tcp_conn_get("unknown",0);
+ rc->read = in;
+ rc->write = out;
+ rc->accept_fn = fn;
+ rc->driver = driver;
+ sec_tcp_conn_read(rc);
+}
+
+/*
+ * frees a handle allocated by the above
+ */
+void
+sec_close(
+ void * inst)
+{
+ struct sec_handle *rh = inst;
+
+ assert(rh != NULL);
+
+ secprintf(("%s: sec: closing handle to %s\n", debug_prefix_time(NULL),
+ rh->hostname));
+
+ if (rh->rs != NULL) {
+ /* This may be null if we get here on an error */
+ stream_recvpkt_cancel(rh);
+ security_stream_close(&rh->rs->secstr);
+ }
+ /* keep us from getting here again */
+ rh->sech.driver = NULL;
+ amfree(rh->hostname);
+ amfree(rh);
+}
+
+/*
+ * Called when a sec connection is finished connecting and is ready
+ * to be authenticated.
+ */
+void
+sec_connect_callback(
+ void * cookie)
+{
+ struct sec_handle *rh = cookie;
+
+ event_release(rh->rs->ev_read);
+ rh->rs->ev_read = NULL;
+ event_release(rh->ev_timeout);
+ rh->ev_timeout = NULL;
+
+ (*rh->fn.connect)(rh->arg, &rh->sech, S_OK);
+}
+
+/*
+ * Called if a connection times out before completion.
+ */
+void
+sec_connect_timeout(
+ void * cookie)
+{
+ struct sec_handle *rh = cookie;
+
+ event_release(rh->rs->ev_read);
+ rh->rs->ev_read = NULL;
+ event_release(rh->ev_timeout);
+ rh->ev_timeout = NULL;
+
+ (*rh->fn.connect)(rh->arg, &rh->sech, S_TIMEOUT);
+}
+
+void
+sec_close_connection_none(
+ void *h,
+ char *hostname)
+{
+ h = h;
+ hostname = hostname;
+
+ return;
+}
+
+
+
+/*
+ * Transmit a packet.
+ */
+ssize_t
+stream_sendpkt(
+ void * cookie,
+ pkt_t * pkt)
+{
+ char *buf;
+ struct sec_handle *rh = cookie;
+ size_t len;
+ char *s;
+
+ assert(rh != NULL);
+ assert(pkt != NULL);
+
+ secprintf(("%s: sec: stream_sendpkt: enter\n", debug_prefix_time(NULL)));
+
+ if (rh->rc->prefix_packet)
+ s = rh->rc->prefix_packet(rh, pkt);
+ else
+ s = "";
+ len = strlen(pkt->body) + strlen(s) + 2;
+ buf = alloc(len);
+ buf[0] = (char)pkt->type;
+ strncpy(&buf[1], s, len - 1);
+ strncpy(&buf[1 + strlen(s)], pkt->body, (len - strlen(s) - 1));
+ if (strlen(s) > 0)
+ amfree(s);
+
+ secprintf((
+ "%s: sec: stream_sendpkt: %s (%d) pkt_t (len %d) contains:\n\n\"%s\"\n\n",
+ debug_prefix_time(NULL), pkt_type2str(pkt->type), pkt->type,
+ strlen(pkt->body), pkt->body));
+
+ if (security_stream_write(&rh->rs->secstr, buf, len) < 0) {
+ security_seterror(&rh->sech, security_stream_geterror(&rh->rs->secstr));
+ return (-1);
+ }
+ amfree(buf);
+ return (0);
+}
+
+/*
+ * Set up to receive a packet asyncronously, and call back when
+ * it has been read.
+ */
+void
+stream_recvpkt(
+ void * cookie,
+ void (*fn)(void *, pkt_t *, security_status_t),
+ void * arg,
+ int timeout)
+{
+ struct sec_handle *rh = cookie;
+
+ assert(rh != NULL);
+
+ secprintf(("%s: sec: recvpkt registered for %s\n",
+ debug_prefix_time(NULL), rh->hostname));
+
+ /*
+ * Reset any pending timeout on this handle
+ */
+ if (rh->ev_timeout != NULL)
+ event_release(rh->ev_timeout);
+
+ /*
+ * Negative timeouts mean no timeout
+ */
+ if (timeout < 0) {
+ rh->ev_timeout = NULL;
+ } else {
+ rh->ev_timeout = event_register((event_id_t)timeout, EV_TIME,
+ stream_recvpkt_timeout, rh);
+ }
+ rh->fn.recvpkt = fn;
+ rh->arg = arg;
+ security_stream_read(&rh->rs->secstr, recvpkt_callback, rh);
+}
+
+/*
+ * This is called when a handle times out before receiving a packet.
+ */
+void
+stream_recvpkt_timeout(
+ void * cookie)
+{
+ struct sec_handle *rh = cookie;
+
+ assert(rh != NULL);
+
+ secprintf(("%s: sec: recvpkt timeout for %s\n",
+ debug_prefix_time(NULL), rh->hostname));
+
+ stream_recvpkt_cancel(rh);
+ (*rh->fn.recvpkt)(rh->arg, NULL, S_TIMEOUT);
+}
+
+/*
+ * Remove a async receive request from the queue
+ */
+void
+stream_recvpkt_cancel(
+ void * cookie)
+{
+ struct sec_handle *rh = cookie;
+
+ secprintf(("%s: sec: cancelling recvpkt for %s\n",
+ debug_prefix_time(NULL), rh->hostname));
+
+ assert(rh != NULL);
+
+ security_stream_read_cancel(&rh->rs->secstr);
+ if (rh->ev_timeout != NULL) {
+ event_release(rh->ev_timeout);
+ rh->ev_timeout = NULL;
+ }
+}
+
+/*
+ * Write a chunk of data to a stream. Blocks until completion.
+ */
+int
+tcpm_stream_write(
+ void * s,
+ const void *buf,
+ size_t size)
+{
+ struct sec_stream *rs = s;
+
+ assert(rs != NULL);
+ assert(rs->rc != NULL);
+
+ secprintf(("%s: sec: stream_write: writing %d bytes to %s:%d %d\n",
+ debug_prefix_time(NULL), size, rs->rc->hostname, rs->handle,
+ rs->rc->write));
+
+ if (tcpm_send_token(rs->rc->write, rs->handle, &rs->rc->errmsg,
+ buf, size)) {
+ security_stream_seterror(&rs->secstr, rs->rc->errmsg);
+ return (-1);
+ }
+ return (0);
+}
+
+/*
+ * Submit a request to read some data. Calls back with the given
+ * function and arg when completed.
+ */
+void
+tcpm_stream_read(
+ void * s,
+ void (*fn)(void *, void *, ssize_t),
+ void * arg)
+{
+ struct sec_stream *rs = s;
+
+ assert(rs != NULL);
+
+ /*
+ * Only one read request can be active per stream.
+ */
+ if (rs->ev_read == NULL) {
+ rs->ev_read = event_register((event_id_t)rs->rc, EV_WAIT,
+ stream_read_callback, rs);
+ sec_tcp_conn_read(rs->rc);
+ }
+ rs->fn = fn;
+ rs->arg = arg;
+}
+
+/*
+ * Write a chunk of data to a stream. Blocks until completion.
+ */
+ssize_t
+tcpm_stream_read_sync(
+ void * s,
+ void ** buf)
+{
+ struct sec_stream *rs = s;
+
+ assert(rs != NULL);
+
+ /*
+ * Only one read request can be active per stream.
+ */
+ if (rs->ev_read != NULL) {
+ return -1;
+ }
+ rs->ev_read = event_register((event_id_t)rs->rc, EV_WAIT,
+ stream_read_sync_callback, rs);
+ sec_tcp_conn_read(rs->rc);
+ event_wait(rs->ev_read);
+ *buf = rs->rc->pkt;
+ return (rs->rc->pktlen);
+}
+
+/*
+ * Cancel a previous stream read request. It's ok if we didn't have a read
+ * scheduled.
+ */
+void
+tcpm_stream_read_cancel(
+ void * s)
+{
+ struct sec_stream *rs = s;
+
+ assert(rs != NULL);
+
+ if (rs->ev_read != NULL) {
+ event_release(rs->ev_read);
+ rs->ev_read = NULL;
+ sec_tcp_conn_read_cancel(rs->rc);
+ }
+}
+
+/*
+ * Transmits a chunk of data over a rsh_handle, adding
+ * the necessary headers to allow the remote end to decode it.
+ */
+ssize_t
+tcpm_send_token(
+ int fd,
+ int handle,
+ char ** errmsg,
+ const void *buf,
+ size_t len)
+{
+ uint32_t nethandle;
+ uint32_t netlength;
+ struct iovec iov[3];
+ int nb_iov = 3;
+
+ assert(SIZEOF(netlength) == 4);
+
+ /*
+ * Format is:
+ * 32 bit length (network byte order)
+ * 32 bit handle (network byte order)
+ * data
+ */
+ netlength = htonl(len);
+ iov[0].iov_base = (void *)&netlength;
+ iov[0].iov_len = SIZEOF(netlength);
+
+ nethandle = htonl((uint32_t)handle);
+ iov[1].iov_base = (void *)&nethandle;
+ iov[1].iov_len = SIZEOF(nethandle);
+
+ if(len == 0) {
+ nb_iov = 2;
+ }
+ else {
+ iov[2].iov_base = (void *)buf;
+ iov[2].iov_len = len;
+ nb_iov = 3;
+ }
+
+ if (net_writev(fd, iov, nb_iov) < 0) {
+ if (errmsg)
+ *errmsg = newvstralloc(*errmsg, "write error to ",
+ ": ", strerror(errno), NULL);
+ return (-1);
+ }
+ return (0);
+}
+
+/*
+ * return -1 on error
+ * return 0 on EOF: *handle = H_EOF && *size = 0 if socket closed
+ * return 0 on EOF: *handle = handle && *size = 0 if stream closed
+ * return size : *handle = handle && *size = size for data read
+ */
+
+ssize_t
+tcpm_recv_token(
+ int fd,
+ int * handle,
+ char ** errmsg,
+ char ** buf,
+ ssize_t * size,
+ int timeout)
+{
+ unsigned int netint[2];
+
+ assert(SIZEOF(netint) == 8);
+
+ switch (net_read(fd, &netint, SIZEOF(netint), timeout)) {
+ case -1:
+ if (errmsg)
+ *errmsg = newvstralloc(*errmsg, "recv error: ", strerror(errno),
+ NULL);
+ secprintf(("%s: tcpm_recv_token: A return(-1)\n",
+ debug_prefix_time(NULL)));
+ return (-1);
+ case 0:
+ *size = 0;
+ *handle = H_EOF;
+ *errmsg = newvstralloc(*errmsg, "SOCKET_EOF", NULL);
+ secprintf(("%s: tcpm_recv_token: A return(0)\n",
+ debug_prefix_time(NULL)));
+ return (0);
+ default:
+ break;
+ }
+
+ *size = (ssize_t)ntohl(netint[0]);
+ if (*size > NETWORK_BLOCK_BYTES) {
+ *errmsg = newvstralloc(*errmsg, "tcpm_recv_token: invalid size",
+ NULL);
+ dbprintf(("%s: tcpm_recv_token: invalid size %d\n",
+ debug_prefix_time(NULL), *size));
+ *size = -1;
+ return -1;
+ }
+ amfree(*buf);
+ *buf = alloc((size_t)*size);
+ *handle = (int)ntohl(netint[1]);
+
+ if(*size == 0) {
+ secprintf(("%s: tcpm_recv_token: read EOF from %d\n",
+ debug_prefix_time(NULL), *handle));
+ *errmsg = newvstralloc(*errmsg, "EOF",
+ NULL);
+ return 0;
+ }
+ switch (net_read(fd, *buf, (size_t)*size, timeout)) {
+ case -1:
+ if (errmsg)
+ *errmsg = newvstralloc(*errmsg, "recv error: ", strerror(errno),
+ NULL);
+ secprintf(("%s: tcpm_recv_token: B return(-1)\n",
+ debug_prefix_time(NULL)));
+ return (-1);
+ case 0:
+ *size = 0;
+ *errmsg = newvstralloc(*errmsg, "SOCKET_EOF", NULL);
+ secprintf(("%s: tcpm_recv_token: B return(0)\n",
+ debug_prefix_time(NULL)));
+ return (0);
+ default:
+ break;
+ }
+
+ secprintf(("%s: tcpm_recv_token: read %ld bytes from %d\n",
+ debug_prefix_time(NULL), *size, *handle));
+ return((*size));
+}
+
+void
+tcpm_close_connection(
+ void *h,
+ char *hostname)
+{
+ struct sec_handle *rh = h;
+
+ hostname = hostname;
+
+ if(rh->rc->toclose == 0) {
+ rh->rc->toclose = 1;
+ sec_tcp_conn_put(rh->rc);
+ }
+}
+
+
+
+/*
+ * Accept an incoming connection on a stream_server socket
+ * Nothing needed for tcpma.
+ */
+int
+tcpma_stream_accept(
+ void * s)
+{
+ (void)s; /* Quiet unused parameter warning */
+
+ return (0);
+}
+
+/*
+ * Return a connected stream. For sec, this means setup a stream
+ * with the supplied handle.
+ */
+void *
+tcpma_stream_client(
+ void * h,
+ int id)
+{
+ struct sec_handle *rh = h;
+ struct sec_stream *rs;
+
+ assert(rh != NULL);
+
+ if (id <= 0) {
+ security_seterror(&rh->sech,
+ "%hd: invalid security stream id", id);
+ return (NULL);
+ }
+
+ rs = alloc(SIZEOF(*rs));
+ security_streaminit(&rs->secstr, rh->sech.driver);
+ rs->handle = id;
+ rs->ev_read = NULL;
+ rs->closed_by_me = 0;
+ rs->closed_by_network = 0;
+ if (rh->rc) {
+ rs->rc = rh->rc;
+ rh->rc->refcnt++;
+ }
+ else {
+ rs->rc = sec_tcp_conn_get(rh->hostname, 0);
+ rs->rc->driver = rh->sech.driver;
+ rh->rc = rs->rc;
+ }
+
+ secprintf(("%s: sec: stream_client: connected to stream %hd\n",
+ debug_prefix_time(NULL), id));
+
+ return (rs);
+}
+
+/*
+ * Create the server end of a stream. For sec, this means setup a stream
+ * object and allocate a new handle for it.
+ */
+void *
+tcpma_stream_server(
+ void * h)
+{
+ struct sec_handle *rh = h;
+ struct sec_stream *rs;
+
+ assert(rh != NULL);
+
+ rs = alloc(SIZEOF(*rs));
+ security_streaminit(&rs->secstr, rh->sech.driver);
+ rs->closed_by_me = 0;
+ rs->closed_by_network = 0;
+ if (rh->rc) {
+ rs->rc = rh->rc;
+ rs->rc->refcnt++;
+ }
+ else {
+ rs->rc = sec_tcp_conn_get(rh->hostname, 0);
+ rs->rc->driver = rh->sech.driver;
+ rh->rc = rs->rc;
+ }
+ /*
+ * Stream should already be setup!
+ */
+ if (rs->rc->read < 0) {
+ sec_tcp_conn_put(rs->rc);
+ amfree(rs);
+ security_seterror(&rh->sech, "lost connection to %s", rh->hostname);
+ return (NULL);
+ }
+ assert(strcmp(rh->hostname, rs->rc->hostname) == 0);
+ //amfree(rh->hostname);
+ //rh->hostname = stralloc(rs->rc->hostname);
+ /*
+ * so as not to conflict with the amanda server's handle numbers,
+ * we start at 500000 and work down
+ */
+ rs->handle = 500000 - newhandle++;
+ rs->ev_read = NULL;
+ secprintf(("%s: sec: stream_server: created stream %d\n",
+ debug_prefix_time(NULL), rs->handle));
+ return (rs);
+}
+
+/*
+ * Close and unallocate resources for a stream.
+ */
+void
+tcpma_stream_close(
+ void * s)
+{
+ struct sec_stream *rs = s;
+ char buf = 0;
+
+ assert(rs != NULL);
+
+ secprintf(("%s: sec: tcpma_stream_close: closing stream %d\n",
+ debug_prefix_time(NULL), rs->handle));
+
+ if(rs->closed_by_network == 0 && rs->rc->write != -1)
+ tcpm_stream_write(rs, &buf, 0);
+ security_stream_read_cancel(&rs->secstr);
+ if(rs->closed_by_network == 0)
+ sec_tcp_conn_put(rs->rc);
+ amfree(rs);
+}
+
+/*
+ * Create the server end of a stream. For bsdudp, this means setup a tcp
+ * socket for receiving a connection.
+ */
+void *
+tcp1_stream_server(
+ void * h)
+{
+ struct sec_stream *rs = NULL;
+ struct sec_handle *rh = h;
+
+ assert(rh != NULL);
+
+ rs = alloc(SIZEOF(*rs));
+ security_streaminit(&rs->secstr, rh->sech.driver);
+ rs->closed_by_me = 0;
+ rs->closed_by_network = 0;
+ if (rh->rc) {
+ rs->rc = rh->rc;
+ rs->handle = 500000 - newhandle++;
+ rs->rc->refcnt++;
+ rs->socket = 0; /* the socket is already opened */
+ }
+ else {
+ rh->rc = sec_tcp_conn_get(rh->hostname, 1);
+ rh->rc->driver = rh->sech.driver;
+ rs->rc = rh->rc;
+ rs->socket = stream_server(&rs->port, STREAM_BUFSIZE,
+ STREAM_BUFSIZE, 0);
+ if (rs->socket < 0) {
+ security_seterror(&rh->sech,
+ "can't create server stream: %s", strerror(errno));
+ amfree(rs);
+ return (NULL);
+ }
+ rh->rc->read = rs->socket;
+ rh->rc->write = rs->socket;
+ rs->handle = (int)rs->port;
+ }
+ rs->fd = -1;
+ rs->ev_read = NULL;
+ return (rs);
+}
+
+/*
+ * Accepts a new connection on unconnected streams. Assumes it is ok to
+ * block on accept()
+ */
+int
+tcp1_stream_accept(
+ void * s)
+{
+ struct sec_stream *bs = s;
+
+ assert(bs != NULL);
+ assert(bs->socket != -1);
+ assert(bs->fd < 0);
+
+ if (bs->socket > 0) {
+ bs->fd = stream_accept(bs->socket, 30, STREAM_BUFSIZE, STREAM_BUFSIZE);
+ if (bs->fd < 0) {
+ security_stream_seterror(&bs->secstr,
+ "can't accept new stream connection: %s",
+ strerror(errno));
+ return (-1);
+ }
+ bs->rc->read = bs->fd;
+ bs->rc->write = bs->fd;
+ }
+ return (0);
+}
+
+/*
+ * Return a connected stream
+ */
+void *
+tcp1_stream_client(
+ void * h,
+ int id)
+{
+ struct sec_stream *rs = NULL;
+ struct sec_handle *rh = h;
+
+ assert(rh != NULL);
+
+ rs = alloc(SIZEOF(*rs));
+ security_streaminit(&rs->secstr, rh->sech.driver);
+ rs->handle = id;
+ rs->ev_read = NULL;
+ rs->closed_by_me = 0;
+ rs->closed_by_network = 0;
+ if (rh->rc) {
+ rs->rc = rh->rc;
+ rh->rc->refcnt++;
+ }
+ else {
+ rh->rc = sec_tcp_conn_get(rh->hostname, 1);
+ rs->rc = rh->rc;
+ rh->rc->read = stream_client(rh->hostname, (in_port_t)id,
+ STREAM_BUFSIZE, STREAM_BUFSIZE, &rs->port, 0);
+ if (rh->rc->read < 0) {
+ security_seterror(&rh->sech,
+ "can't connect stream to %s port %d: %s",
+ rh->hostname, id, strerror(errno));
+ amfree(rs);
+ return (NULL);
+ }
+ rh->rc->write = rh->rc->read;
+ }
+ rs->socket = -1; /* we're a client */
+ rh->rs = rs;
+ return (rs);
+}
+
+int
+tcp_stream_write(
+ void * s,
+ const void *buf,
+ size_t size)
+{
+ struct sec_stream *rs = s;
+
+ assert(rs != NULL);
+
+ if (fullwrite(rs->fd, buf, size) < 0) {
+ security_stream_seterror(&rs->secstr,
+ "write error on stream %d: %s", rs->port, strerror(errno));
+ return (-1);
+ }
+ return (0);
+}
+
+char *
+bsd_prefix_packet(
+ void * h,
+ pkt_t * pkt)
+{
+ struct sec_handle *rh = h;
+ struct passwd *pwd;
+ char *buf;
+
+ if (pkt->type != P_REQ)
+ return "";
+
+ if ((pwd = getpwuid(getuid())) == NULL) {
+ security_seterror(&rh->sech,
+ "can't get login name for my uid %ld",
+ (long)getuid());
+ return(NULL);
+ }
+ buf = alloc(16+strlen(pwd->pw_name));
+ strncpy(buf, "SECURITY USER ", (16 + strlen(pwd->pw_name)));
+ strncpy(&buf[14], pwd->pw_name, (16 + strlen(pwd->pw_name) - 14));
+ buf[14 + strlen(pwd->pw_name)] = '\n';
+ buf[15 + strlen(pwd->pw_name)] = '\0';
+
+ return (buf);
+}
+
+
+/*
+ * Check the security of a received packet. Returns negative on security
+ * violation, or returns 0 if ok. Removes the security info from the pkt_t.
+ */
+int
+bsd_recv_security_ok(
+ struct sec_handle * rh,
+ pkt_t * pkt)
+{
+ char *tok, *security, *body, *result;
+ char *service = NULL, *serviceX, *serviceY;
+ char *security_line;
+ size_t len;
+
+ /*
+ * Now, find the SECURITY line in the body, and parse it out
+ * into an argv.
+ */
+ if (strncmp(pkt->body, "SECURITY ", SIZEOF("SECURITY ") - 1) == 0) {
+ security = pkt->body;
+ len = 0;
+ while(*security != '\n' && len < pkt->size) {
+ security++;
+ len++;
+ }
+ if(*security == '\n') {
+ body = security+1;
+ *security = '\0';
+ security_line = stralloc(pkt->body);
+ security = pkt->body + strlen("SECURITY ");
+ } else {
+ body = pkt->body;
+ security_line = NULL;
+ security = NULL;
+ }
+ } else {
+ body = pkt->body;
+ security_line = NULL;
+ security = NULL;
+ }
+
+ /*
+ * Now, find the SERVICE line in the body, and parse it out
+ * into an argv.
+ */
+ if (strncmp(body, "SERVICE", SIZEOF("SERVICE") - 1) == 0) {
+ serviceX = stralloc(body + strlen("SERVICE "));
+ serviceY = strtok(serviceX, "\n");
+ if (serviceY)
+ service = stralloc(serviceY);
+ amfree(serviceX);
+ }
+
+ /*
+ * We need to do different things depending on which type of packet
+ * this is.
+ */
+ switch (pkt->type) {
+ case P_REQ:
+ /*
+ * Request packets must come from a reserved port
+ */
+ if (ntohs(rh->peer.sin_port) >= IPPORT_RESERVED) {
+ security_seterror(&rh->sech,
+ "host %s: port %d not secure", rh->hostname,
+ ntohs(rh->peer.sin_port));
+ amfree(service);
+ amfree(security_line);
+ return (-1);
+ }
+
+ if (!service) {
+ security_seterror(&rh->sech,
+ "packet as no SERVICE line");
+ amfree(security_line);
+ return (-1);
+ }
+
+ /*
+ * Request packets contain a remote username. We need to check
+ * that we allow it in.
+ *
+ * They will look like:
+ * SECURITY USER [username]
+ */
+
+ /* there must be some security info */
+ if (security == NULL) {
+ security_seterror(&rh->sech,
+ "no bsd SECURITY for P_REQ");
+ amfree(service);
+ return (-1);
+ }
+
+ /* second word must be USER */
+ if ((tok = strtok(security, " ")) == NULL) {
+ security_seterror(&rh->sech,
+ "SECURITY line: %s", security_line);
+ amfree(service);
+ amfree(security_line);
+ return (-1); /* default errmsg */
+ }
+ if (strcmp(tok, "USER") != 0) {
+ security_seterror(&rh->sech,
+ "REQ SECURITY line parse error, expecting USER, got %s", tok);
+ amfree(service);
+ amfree(security_line);
+ return (-1);
+ }
+
+ /* the third word is the username */
+ if ((tok = strtok(NULL, "")) == NULL) {
+ security_seterror(&rh->sech,
+ "SECURITY line: %s", security_line);
+ amfree(security_line);
+ return (-1); /* default errmsg */
+ }
+ if ((result = check_user(rh, tok, service)) != NULL) {
+ security_seterror(&rh->sech, "%s", result);
+ amfree(service);
+ amfree(result);
+ amfree(security_line);
+ return (-1);
+ }
+
+ /* we're good to go */
+ break;
+ default:
+ break;
+ }
+ amfree(service);
+ amfree(security_line);
+
+ /*
+ * If there is security info at the front of the packet, we need to
+ * shift the rest of the data up and nuke it.
+ */
+ if (body != pkt->body)
+ memmove(pkt->body, body, strlen(body) + 1);
+ return (0);
+}
+
+/*
+ * Transmit a packet. Add security information first.
+ */
+ssize_t
+udpbsd_sendpkt(
+ void * cookie,
+ pkt_t * pkt)
+{
+ struct sec_handle *rh = cookie;
+ struct passwd *pwd;
+
+ assert(rh != NULL);
+ assert(pkt != NULL);
+
+ secprintf(("%s: udpbsd_sendpkt: enter\n", get_pname()));
+ /*
+ * Initialize this datagram, and add the header
+ */
+ dgram_zero(&rh->udp->dgram);
+ dgram_cat(&rh->udp->dgram, pkthdr2str(rh, pkt));
+
+ /*
+ * Add the security info. This depends on which kind of packet we're
+ * sending.
+ */
+ switch (pkt->type) {
+ case P_REQ:
+ /*
+ * Requests get sent with our username in the body
+ */
+ if ((pwd = getpwuid(geteuid())) == NULL) {
+ security_seterror(&rh->sech,
+ "can't get login name for my uid %ld", (long)getuid());
+ return (-1);
+ }
+ dgram_cat(&rh->udp->dgram, "SECURITY USER %s\n", pwd->pw_name);
+ break;
+
+ default:
+ break;
+ }
+
+ /*
+ * Add the body, and send it
+ */
+ dgram_cat(&rh->udp->dgram, pkt->body);
+
+ secprintf((
+ "%s: sec: udpbsd_sendpkt: %s (%d) pkt_t (len %d) contains:\n\n\"%s\"\n\n",
+ debug_prefix_time(NULL), pkt_type2str(pkt->type), pkt->type,
+ strlen(pkt->body), pkt->body));
+
+ if (dgram_send_addr(rh->peer, &rh->udp->dgram) != 0) {
+ security_seterror(&rh->sech,
+ "send %s to %s failed: %s", pkt_type2str(pkt->type),
+ rh->hostname, strerror(errno));
+ return (-1);
+ }
+ return (0);
+}
+
+void
+udp_close(
+ void * cookie)
+{
+ struct sec_handle *rh = cookie;
+
+ if (rh->proto_handle == NULL) {
+ return;
+ }
+
+ secprintf(("%s: udp: close handle '%s'\n",
+ debug_prefix_time(NULL), rh->proto_handle));
+
+ udp_recvpkt_cancel(rh);
+ if (rh->next) {
+ rh->next->prev = rh->prev;
+ }
+ else {
+ rh->udp->bh_last = rh->prev;
+ }
+ if (rh->prev) {
+ rh->prev->next = rh->next;
+ }
+ else {
+ rh->udp->bh_first = rh->next;
+ }
+
+ amfree(rh->proto_handle);
+ amfree(rh->hostname);
+ amfree(rh);
+}
+
+/*
+ * Set up to receive a packet asynchronously, and call back when it has
+ * been read.
+ */
+void
+udp_recvpkt(
+ void * cookie,
+ void (*fn)(void *, pkt_t *, security_status_t),
+ void * arg,
+ int timeout)
+{
+ struct sec_handle *rh = cookie;
+
+ secprintf(("%s: udp_recvpkt(cookie=%p, fn=%p, arg=%p, timeout=%u)\n",
+ debug_prefix(NULL), cookie, fn, arg, timeout));
+ assert(rh != NULL);
+ assert(fn != NULL);
+
+
+ /*
+ * Subsequent recvpkt calls override previous ones
+ */
+ if (rh->ev_read == NULL) {
+ udp_addref(rh->udp, &udp_netfd_read_callback);
+ rh->ev_read = event_register(rh->event_id, EV_WAIT,
+ udp_recvpkt_callback, rh);
+ }
+ if (rh->ev_timeout != NULL)
+ event_release(rh->ev_timeout);
+ if (timeout < 0)
+ rh->ev_timeout = NULL;
+ else
+ rh->ev_timeout = event_register((event_id_t)timeout, EV_TIME,
+ udp_recvpkt_timeout, rh);
+ rh->fn.recvpkt = fn;
+ rh->arg = arg;
+}
+
+/*
+ * Remove a async receive request on this handle from the queue.
+ * If it is the last one to be removed, then remove the event
+ * handler for our network fd
+ */
+void
+udp_recvpkt_cancel(
+ void * cookie)
+{
+ struct sec_handle *rh = cookie;
+
+ assert(rh != NULL);
+
+ if (rh->ev_read != NULL) {
+ udp_delref(rh->udp);
+ event_release(rh->ev_read);
+ rh->ev_read = NULL;
+ }
+
+ if (rh->ev_timeout != NULL) {
+ event_release(rh->ev_timeout);
+ rh->ev_timeout = NULL;
+ }
+}
+
+/*
+ * This is called when a handle is woken up because data read off of the
+ * net is for it.
+ */
+void
+udp_recvpkt_callback(
+ void * cookie)
+{
+ struct sec_handle *rh = cookie;
+ void (*fn)(void *, pkt_t *, security_status_t);
+ void *arg;
+
+ secprintf(("%s: udp: receive handle '%s' netfd '%s'\n",
+ debug_prefix_time(NULL), rh->proto_handle, rh->udp->handle));
+ assert(rh != NULL);
+
+ if (strcmp(rh->proto_handle, rh->udp->handle) != 0) assert(1);
+ /* if it didn't come from the same host/port, forget it */
+ if (memcmp(&rh->peer.sin_addr, &rh->udp->peer.sin_addr,
+ SIZEOF(rh->udp->peer.sin_addr)) != 0 ||
+ rh->peer.sin_port != rh->udp->peer.sin_port) {
+ amfree(rh->udp->handle);
+ //rh->udp->handle = NULL;
+ return;
+ }
+
+ /*
+ * We need to cancel the recvpkt request before calling the callback
+ * because the callback may reschedule us.
+ */
+ fn = rh->fn.recvpkt;
+ arg = rh->arg;
+ udp_recvpkt_cancel(rh);
+
+ /*
+ * Check the security of the packet. If it is bad, then pass NULL
+ * to the packet handling function instead of a packet.
+ */
+ if (rh->udp->recv_security_ok &&
+ rh->udp->recv_security_ok(rh, &rh->udp->pkt) < 0)
+ (*fn)(arg, NULL, S_ERROR);
+ else
+ (*fn)(arg, &rh->udp->pkt, S_OK);
+}
+
+/*
+ * This is called when a handle times out before receiving a packet.
+ */
+void
+udp_recvpkt_timeout(
+ void * cookie)
+{
+ struct sec_handle *rh = cookie;
+ void (*fn)(void *, pkt_t *, security_status_t);
+ void *arg;
+
+ assert(rh != NULL);
+
+ assert(rh->ev_timeout != NULL);
+ fn = rh->fn.recvpkt;
+ arg = rh->arg;
+ udp_recvpkt_cancel(rh);
+ (*fn)(arg, NULL, S_TIMEOUT);
+}
+
+/*
+ * Given a hostname and a port, setup a udp_handle
+ */
+int
+udp_inithandle(
+ udp_handle_t * udp,
+ struct sec_handle * rh,
+ struct hostent * he,
+ in_port_t port,
+ char * handle,
+ int sequence)
+{
+ int i;
+
+ /*
+ * Save the hostname and port info
+ */
+ secprintf(("%s: udp_inithandle port %hd handle %s sequence %d\n",
+ debug_prefix_time(NULL), ntohs(port),
+ handle, sequence));
+ assert(he != NULL);
+
+ rh->hostname = stralloc(he->h_name);
+ memcpy(&rh->peer.sin_addr, he->h_addr, SIZEOF(rh->peer.sin_addr));
+ rh->peer.sin_port = port;
+ rh->peer.sin_family = (sa_family_t)AF_INET;
+
+ /*
+ * Do a forward lookup of the hostname. This is unnecessary if we
+ * are initiating the connection, but is very serious if we are
+ * receiving. We want to make sure the hostname
+ * resolves back to the remote ip for security reasons.
+ */
+ if ((he = gethostbyname(rh->hostname)) == NULL) {
+ secprintf(("%s: udp: bb\n", debug_prefix_time(NULL)));
+ security_seterror(&rh->sech,
+ "%s: could not resolve hostname", rh->hostname);
+ return (-1);
+ }
+
+ /*
+ * Make sure the hostname matches. This should always work.
+ */
+ if (strncasecmp(rh->hostname, he->h_name, strlen(rh->hostname)) != 0) {
+ secprintf(("%s: udp: cc\n", debug_prefix_time(NULL)));
+ security_seterror(&rh->sech,
+ "%s: did not resolve to itself, it resolv to",
+ rh->hostname, he->h_name);
+ return (-1);
+ }
+
+ /*
+ * Now look for a matching ip address.
+ */
+ for (i = 0; he->h_addr_list[i] != NULL; i++) {
+ if (memcmp(&rh->peer.sin_addr, he->h_addr_list[i],
+ SIZEOF(struct in_addr)) == 0) {
+ break;
+ }
+ }
+
+ /*
+ * If we didn't find it, try the aliases. This is a workaround for
+ * Solaris if DNS goes over NIS.
+ */
+ if (he->h_addr_list[i] == NULL) {
+ const char *ipstr = inet_ntoa(rh->peer.sin_addr);
+ for (i = 0; he->h_aliases[i] != NULL; i++) {
+ if (strcmp(he->h_aliases[i], ipstr) == 0)
+ break;
+ }
+ /*
+ * No aliases either. Failure. Someone is fooling with us or
+ * DNS is messed up.
+ */
+ if (he->h_aliases[i] == NULL) {
+ security_seterror(&rh->sech,
+ "DNS check failed: no matching ip address for %s",
+ rh->hostname);
+ return (-1);
+ }
+ }
+
+ rh->prev = udp->bh_last;
+ if (udp->bh_last) {
+ rh->prev->next = rh;
+ }
+ if (!udp->bh_first) {
+ udp->bh_first = rh;
+ }
+ rh->next = NULL;
+ udp->bh_last = rh;
+
+ rh->sequence = sequence;
+ rh->event_id = (event_id_t)newevent++;
+ amfree(rh->proto_handle);
+ rh->proto_handle = stralloc(handle);
+ rh->fn.connect = NULL;
+ rh->arg = NULL;
+ rh->ev_read = NULL;
+ rh->ev_timeout = NULL;
+
+ secprintf(("%s: udp: adding handle '%s'\n",
+ debug_prefix_time(NULL), rh->proto_handle));
+
+ return(0);
+}
+
+
+/*
+ * Callback for received packets. This is the function bsd_recvpkt
+ * registers with the event handler. It is called when the event handler
+ * realizes that data is waiting to be read on the network socket.
+ */
+void
+udp_netfd_read_callback(
+ void * cookie)
+{
+ struct udp_handle *udp = cookie;
+ struct sec_handle *rh;
+ struct hostent *he;
+ int a;
+
+ secprintf(("%s: udp_netfd_read_callback(cookie=%p)\n",
+ debug_prefix(NULL), cookie));
+ assert(udp != NULL);
+
+#ifndef TEST /* { */
+ /*
+ * Receive the packet.
+ */
+ dgram_zero(&udp->dgram);
+ if (dgram_recv(&udp->dgram, 0, &udp->peer) < 0)
+ return;
+#endif /* !TEST */ /* } */
+
+ /*
+ * Parse the packet.
+ */
+ if (str2pkthdr(udp) < 0)
+ return;
+
+ /*
+ * If there are events waiting on this handle, we're done
+ */
+ rh = udp->bh_first;
+ while(rh != NULL && (strcmp(rh->proto_handle, udp->handle) != 0 ||
+ rh->sequence != udp->sequence ||
+ rh->peer.sin_addr.s_addr != udp->peer.sin_addr.s_addr ||
+ rh->peer.sin_port != udp->peer.sin_port)) {
+ rh = rh->next;
+ }
+ if (rh && event_wakeup(rh->event_id) > 0)
+ return;
+
+ /*
+ * If we didn't find a handle, then check for a new incoming packet.
+ * If no accept handler was setup, then just return.
+ */
+ if (udp->accept_fn == NULL)
+ return;
+
+ he = gethostbyaddr((void *)&udp->peer.sin_addr,
+ (socklen_t)sizeof(udp->peer.sin_addr), AF_INET);
+ if (he == NULL)
+ return;
+ rh = alloc(SIZEOF(*rh));
+ rh->proto_handle=NULL;
+ rh->udp = udp;
+ rh->rc = NULL;
+ security_handleinit(&rh->sech, udp->driver);
+ a = udp_inithandle(udp, rh,
+ he,
+ udp->peer.sin_port,
+ udp->handle,
+ udp->sequence);
+ if (a < 0) {
+ secprintf(("%s: bsd: closeX handle '%s'\n",
+ debug_prefix_time(NULL), rh->proto_handle));
+
+ amfree(rh);
+ return;
+ }
+ /*
+ * Check the security of the packet. If it is bad, then pass NULL
+ * to the accept function instead of a packet.
+ */
+ if (rh->udp->recv_security_ok(rh, &udp->pkt) < 0)
+ (*udp->accept_fn)(&rh->sech, NULL);
+ else
+ (*udp->accept_fn)(&rh->sech, &udp->pkt);
+}
+
+/*
+ * Locate an existing connection to the given host, or create a new,
+ * unconnected entry if none exists. The caller is expected to check
+ * for the lack of a connection (rc->read == -1) and set one up.
+ */
+struct tcp_conn *
+sec_tcp_conn_get(
+ const char *hostname,
+ int want_new)
+{
+ struct tcp_conn *rc;
+
+ secprintf(("%s: sec_tcp_conn_get: %s\n", debug_prefix_time(NULL), hostname));
+
+ if (want_new == 0) {
+ for (rc = connq_first(); rc != NULL; rc = connq_next(rc)) {
+ if (strcasecmp(hostname, rc->hostname) == 0)
+ break;
+ }
+
+ if (rc != NULL) {
+ rc->refcnt++;
+ secprintf(("%s: sec_tcp_conn_get: exists, refcnt to %s is now %d\n",
+ debug_prefix_time(NULL),
+ rc->hostname, rc->refcnt));
+ return (rc);
+ }
+ }
+
+ secprintf(("%s: sec_tcp_conn_get: creating new handle\n",
+ debug_prefix_time(NULL)));
+ /*
+ * We can't be creating a new handle if we are the client
+ */
+ rc = alloc(SIZEOF(*rc));
+ rc->read = rc->write = -1;
+ rc->driver = NULL;
+ rc->pid = -1;
+ rc->ev_read = NULL;
+ rc->toclose = 0;
+ rc->donotclose = 0;
+ strncpy(rc->hostname, hostname, SIZEOF(rc->hostname) - 1);
+ rc->hostname[SIZEOF(rc->hostname) - 1] = '\0';
+ rc->errmsg = NULL;
+ rc->refcnt = 1;
+ rc->handle = -1;
+ rc->pkt = NULL;
+ rc->accept_fn = NULL;
+ rc->recv_security_ok = NULL;
+ rc->prefix_packet = NULL;
+ connq_append(rc);
+ return (rc);
+}
+
+/*
+ * Delete a reference to a connection, and close it if it is the last
+ * reference.
+ */
+void
+sec_tcp_conn_put(
+ struct tcp_conn * rc)
+{
+ amwait_t status;
+
+ assert(rc->refcnt > 0);
+ --rc->refcnt;
+ secprintf(("%s: sec_tcp_conn_put: decrementing refcnt for %s to %d\n",
+ debug_prefix_time(NULL),
+ rc->hostname, rc->refcnt));
+ if (rc->refcnt > 0) {
+ return;
+ }
+ secprintf(("%s: sec_tcp_conn_put: closing connection to %s\n",
+ debug_prefix_time(NULL), rc->hostname));
+ if (rc->read != -1)
+ aclose(rc->read);
+ if (rc->write != -1)
+ aclose(rc->write);
+ if (rc->pid != -1) {
+ waitpid(rc->pid, &status, WNOHANG);
+ }
+ if (rc->ev_read != NULL)
+ event_release(rc->ev_read);
+ if (rc->errmsg != NULL)
+ amfree(rc->errmsg);
+ connq_remove(rc);
+ amfree(rc->pkt);
+ if(!rc->donotclose)
+ amfree(rc); /* someone might still use it */
+ /* eg. in sec_tcp_conn_read_callback if */
+ /* event_wakeup call us. */
+}
+
+/*
+ * Turn on read events for a conn. Or, increase a ev_read_refcnt if we are
+ * already receiving read events.
+ */
+void
+sec_tcp_conn_read(
+ struct tcp_conn * rc)
+{
+ assert (rc != NULL);
+
+ if (rc->ev_read != NULL) {
+ rc->ev_read_refcnt++;
+ secprintf((
+ "%s: sec: conn_read: incremented ev_read_refcnt to %d for %s\n",
+ debug_prefix_time(NULL), rc->ev_read_refcnt, rc->hostname));
+ return;
+ }
+ secprintf(("%s: sec: conn_read registering event handler for %s\n",
+ debug_prefix_time(NULL), rc->hostname));
+ rc->ev_read = event_register((event_id_t)rc->read, EV_READFD,
+ sec_tcp_conn_read_callback, rc);
+ rc->ev_read_refcnt = 1;
+}
+
+static void
+sec_tcp_conn_read_cancel(
+ struct tcp_conn * rc)
+{
+
+ --rc->ev_read_refcnt;
+ secprintf((
+ "%s: sec: conn_read_cancel: decremented ev_read_refcnt to %d for %s\n",
+ debug_prefix_time(NULL),
+ rc->ev_read_refcnt, rc->hostname));
+ if (rc->ev_read_refcnt > 0) {
+ return;
+ }
+ secprintf(("%s: sec: conn_read_cancel: releasing event handler for %s\n",
+ debug_prefix_time(NULL), rc->hostname));
+ event_release(rc->ev_read);
+ rc->ev_read = NULL;
+}
+
+/*
+ * This is called when a handle is woken up because data read off of the
+ * net is for it.
+ */
+static void
+recvpkt_callback(
+ void * cookie,
+ void * buf,
+ ssize_t bufsize)
+{
+ pkt_t pkt;
+ struct sec_handle *rh = cookie;
+
+ assert(rh != NULL);
+
+ secprintf(("%s: sec: recvpkt_callback: %d\n",
+ debug_prefix_time(NULL), bufsize));
+ /*
+ * We need to cancel the recvpkt request before calling
+ * the callback because the callback may reschedule us.
+ */
+ stream_recvpkt_cancel(rh);
+
+ switch (bufsize) {
+ case 0:
+ security_seterror(&rh->sech,
+ "EOF on read from %s", rh->hostname);
+ (*rh->fn.recvpkt)(rh->arg, NULL, S_ERROR);
+ return;
+ case -1:
+ security_seterror(&rh->sech, security_stream_geterror(&rh->rs->secstr));
+ (*rh->fn.recvpkt)(rh->arg, NULL, S_ERROR);
+ return;
+ default:
+ break;
+ }
+
+ parse_pkt(&pkt, buf, (size_t)bufsize);
+ secprintf((
+ "%s: sec: received %s packet (%d) from %s, contains:\n\n\"%s\"\n\n",
+ debug_prefix_time(NULL), pkt_type2str(pkt.type), pkt.type,
+ rh->hostname, pkt.body));
+ if (rh->rc->recv_security_ok && (rh->rc->recv_security_ok)(rh, &pkt) < 0)
+ (*rh->fn.recvpkt)(rh->arg, NULL, S_ERROR);
+ else
+ (*rh->fn.recvpkt)(rh->arg, &pkt, S_OK);
+ amfree(pkt.body);
+}
+
+/*
+ * Callback for tcpm_stream_read_sync
+ */
+static void
+stream_read_sync_callback(
+ void * s)
+{
+ struct sec_stream *rs = s;
+ assert(rs != NULL);
+
+ secprintf(("%s: sec: stream_read_callback_sync: handle %d\n",
+ debug_prefix_time(NULL), rs->handle));
+
+ /*
+ * Make sure this was for us. If it was, then blow away the handle
+ * so it doesn't get claimed twice. Otherwise, leave it alone.
+ *
+ * If the handle is EOF, pass that up to our callback.
+ */
+ if (rs->rc->handle == rs->handle) {
+ secprintf(("%s: sec: stream_read_callback_sync: it was for us\n",
+ debug_prefix_time(NULL)));
+ rs->rc->handle = H_TAKEN;
+ } else if (rs->rc->handle != H_EOF) {
+ secprintf(("%s: sec: stream_read_callback_sync: not for us\n",
+ debug_prefix_time(NULL)));
+ return;
+ }
+
+ /*
+ * Remove the event first, and then call the callback.
+ * We remove it first because we don't want to get in their
+ * way if they reschedule it.
+ */
+ tcpm_stream_read_cancel(rs);
+
+ if (rs->rc->pktlen <= 0) {
+ secprintf(("%s: sec: stream_read_sync_callback: %s\n",
+ debug_prefix_time(NULL), rs->rc->errmsg));
+ security_stream_seterror(&rs->secstr, rs->rc->errmsg);
+ if(rs->closed_by_me == 0 && rs->closed_by_network == 0)
+ sec_tcp_conn_put(rs->rc);
+ rs->closed_by_network = 1;
+ return;
+ }
+ secprintf((
+ "%s: sec: stream_read_callback_sync: read %ld bytes from %s:%d\n",
+ debug_prefix_time(NULL),
+ rs->rc->pktlen, rs->rc->hostname, rs->handle));
+}
+
+/*
+ * Callback for tcpm_stream_read
+ */
+static void
+stream_read_callback(
+ void * arg)
+{
+ struct sec_stream *rs = arg;
+ assert(rs != NULL);
+
+ secprintf(("%s: sec: stream_read_callback: handle %d\n",
+ debug_prefix_time(NULL), rs->handle));
+
+ /*
+ * Make sure this was for us. If it was, then blow away the handle
+ * so it doesn't get claimed twice. Otherwise, leave it alone.
+ *
+ * If the handle is EOF, pass that up to our callback.
+ */
+ if (rs->rc->handle == rs->handle) {
+ secprintf(("%s: sec: stream_read_callback: it was for us\n",
+ debug_prefix_time(NULL)));
+ rs->rc->handle = H_TAKEN;
+ } else if (rs->rc->handle != H_EOF) {
+ secprintf(("%s: sec: stream_read_callback: not for us\n",
+ debug_prefix_time(NULL)));
+ return;
+ }
+
+ /*
+ * Remove the event first, and then call the callback.
+ * We remove it first because we don't want to get in their
+ * way if they reschedule it.
+ */
+ tcpm_stream_read_cancel(rs);
+
+ if (rs->rc->pktlen <= 0) {
+ secprintf(("%s: sec: stream_read_callback: %s\n",
+ debug_prefix_time(NULL), rs->rc->errmsg));
+ security_stream_seterror(&rs->secstr, rs->rc->errmsg);
+ if(rs->closed_by_me == 0 && rs->closed_by_network == 0)
+ sec_tcp_conn_put(rs->rc);
+ rs->closed_by_network = 1;
+ (*rs->fn)(rs->arg, NULL, rs->rc->pktlen);
+ return;
+ }
+ secprintf(("%s: sec: stream_read_callback: read %ld bytes from %s:%d\n",
+ debug_prefix_time(NULL),
+ rs->rc->pktlen, rs->rc->hostname, rs->handle));
+ (*rs->fn)(rs->arg, rs->rc->pkt, rs->rc->pktlen);
+ secprintf(("%s: sec: after callback stream_read_callback\n",
+ debug_prefix_time(NULL)));
+}
+
+/*
+ * The callback for the netfd for the event handler
+ * Determines if this packet is for this security handle,
+ * and does the real callback if so.
+ */
+static void
+sec_tcp_conn_read_callback(
+ void * cookie)
+{
+ struct tcp_conn * rc = cookie;
+ struct sec_handle * rh;
+ pkt_t pkt;
+ ssize_t rval;
+ int revent;
+
+ assert(cookie != NULL);
+
+ secprintf(("%s: sec: conn_read_callback\n", debug_prefix_time(NULL)));
+
+ /* Read the data off the wire. If we get errors, shut down. */
+ rval = tcpm_recv_token(rc->read, &rc->handle, &rc->errmsg, &rc->pkt,
+ &rc->pktlen, 60);
+ secprintf(("%s: sec: conn_read_callback: tcpm_recv_token returned %d\n",
+ debug_prefix_time(NULL), rval));
+ if (rval < 0 || rc->handle == H_EOF) {
+ rc->pktlen = rval;
+ rc->handle = H_EOF;
+ revent = event_wakeup((event_id_t)rc);
+ secprintf(("%s: sec: conn_read_callback: event_wakeup return %d\n",
+ debug_prefix_time(NULL), revent));
+ /* delete our 'accept' reference */
+ if (rc->accept_fn != NULL) {
+ if(rc->refcnt != 1) {
+ dbprintf(("STRANGE, rc->refcnt should be 1"));
+ rc->refcnt=1;
+ }
+ rc->accept_fn = NULL;
+ sec_tcp_conn_put(rc);
+ }
+ return;
+ }
+
+ if(rval == 0) {
+ rc->pktlen = 0;
+ revent = event_wakeup((event_id_t)rc);
+ secprintf(("%s: 0 sec: conn_read_callback: event_wakeup return %d\n",
+ debug_prefix_time(NULL), revent));
+ return;
+ }
+
+ /* If there are events waiting on this handle, we're done */
+ rc->donotclose = 1;
+ revent = event_wakeup((event_id_t)rc);
+ secprintf(("%s: sec: conn_read_callback: event_wakeup return %d\n",
+ debug_prefix_time(NULL), rval));
+ rc->donotclose = 0;
+ if (rc->handle == H_TAKEN || rc->pktlen == 0) {
+ if(rc->refcnt == 0) amfree(rc);
+ return;
+ }
+
+ assert(rc->refcnt > 0);
+
+ /* If there is no accept fn registered, then drop the packet */
+ if (rc->accept_fn == NULL)
+ return;
+
+ rh = alloc(SIZEOF(*rh));
+ security_handleinit(&rh->sech, rc->driver);
+ rh->hostname = stralloc(rc->hostname);
+ rh->ev_timeout = NULL;
+ rh->rc = rc;
+ rh->peer = rc->peer;
+ rh->rs = tcpma_stream_client(rh, rc->handle);
+
+ secprintf(("%s: sec: new connection\n", debug_prefix_time(NULL)));
+ pkt.body = NULL;
+ parse_pkt(&pkt, rc->pkt, (size_t)rc->pktlen);
+ secprintf(("%s: sec: calling accept_fn\n", debug_prefix_time(NULL)));
+ if (rh->rc->recv_security_ok && (rh->rc->recv_security_ok)(rh, &pkt) < 0)
+ (*rc->accept_fn)(&rh->sech, NULL);
+ else
+ (*rc->accept_fn)(&rh->sech, &pkt);
+ amfree(pkt.body);
+}
+
+void
+parse_pkt(
+ pkt_t * pkt,
+ const void *buf,
+ size_t bufsize)
+{
+ const unsigned char *bufp = buf;
+
+ secprintf(("%s: sec: parse_pkt: parsing buffer of %d bytes\n",
+ debug_prefix_time(NULL), bufsize));
+
+ pkt->type = (pktype_t)*bufp++;
+ bufsize--;
+
+ pkt->packet_size = bufsize+1;
+ pkt->body = alloc(pkt->packet_size);
+ if (bufsize == 0) {
+ pkt->body[0] = '\0';
+ } else {
+ memcpy(pkt->body, bufp, bufsize);
+ pkt->body[pkt->packet_size - 1] = '\0';
+ }
+ pkt->size = strlen(pkt->body);
+
+ secprintf(("%s: sec: parse_pkt: %s (%d): \"%s\"\n",
+ debug_prefix_time(NULL), pkt_type2str(pkt->type),
+ pkt->type, pkt->body));
+}
+
+/*
+ * Convert a packet header into a string
+ */
+const char *
+pkthdr2str(
+ const struct sec_handle * rh,
+ const pkt_t * pkt)
+{
+ static char retbuf[256];
+
+ assert(rh != NULL);
+ assert(pkt != NULL);
+
+ snprintf(retbuf, SIZEOF(retbuf), "Amanda %d.%d %s HANDLE %s SEQ %d\n",
+ VERSION_MAJOR, VERSION_MINOR, pkt_type2str(pkt->type),
+ rh->proto_handle, rh->sequence);
+
+ secprintf(("%s: bsd: pkthdr2str handle '%s'\n",
+ debug_prefix_time(NULL), rh->proto_handle));
+
+ /* check for truncation. If only we had asprintf()... */
+ assert(retbuf[strlen(retbuf) - 1] == '\n');
+
+ return (retbuf);
+}
+
+/*
+ * Parses out the header line in 'str' into the pkt and handle
+ * Returns negative on parse error.
+ */
+int
+str2pkthdr(
+ udp_handle_t * udp)
+{
+ char *str;
+ const char *tok;
+ pkt_t *pkt;
+
+ pkt = &udp->pkt;
+
+ assert(udp->dgram.cur != NULL);
+ str = stralloc(udp->dgram.cur);
+
+ /* "Amanda %d.%d <ACK,NAK,...> HANDLE %s SEQ %d\n" */
+
+ /* Read in "Amanda" */
+ if ((tok = strtok(str, " ")) == NULL || strcmp(tok, "Amanda") != 0)
+ goto parse_error;
+
+ /* nothing is done with the major/minor numbers currently */
+ if ((tok = strtok(NULL, " ")) == NULL || strchr(tok, '.') == NULL)
+ goto parse_error;
+
+ /* Read in the packet type */
+ if ((tok = strtok(NULL, " ")) == NULL)
+ goto parse_error;
+ amfree(pkt->body);
+ pkt_init(pkt, pkt_str2type(tok), "");
+ if (pkt->type == (pktype_t)-1)
+ goto parse_error;
+
+ /* Read in "HANDLE" */
+ if ((tok = strtok(NULL, " ")) == NULL || strcmp(tok, "HANDLE") != 0)
+ goto parse_error;
+
+ /* parse the handle */
+ if ((tok = strtok(NULL, " ")) == NULL)
+ goto parse_error;
+ amfree(udp->handle);
+ udp->handle = stralloc(tok);
+
+ /* Read in "SEQ" */
+ if ((tok = strtok(NULL, " ")) == NULL || strcmp(tok, "SEQ") != 0)
+ goto parse_error;
+
+ /* parse the sequence number */
+ if ((tok = strtok(NULL, "\n")) == NULL)
+ goto parse_error;
+ udp->sequence = atoi(tok);
+
+ /* Save the body, if any */
+ if ((tok = strtok(NULL, "")) != NULL)
+ pkt_cat(pkt, "%s", tok);
+
+ amfree(str);
+ return (0);
+
+parse_error:
+#if 0 /* XXX we have no way of passing this back up */
+ security_seterror(&rh->sech,
+ "parse error in packet header : '%s'", origstr);
+#endif
+ amfree(str);
+ return (-1);
+}
+
+char *
+check_user(
+ struct sec_handle * rh,
+ const char * remoteuser,
+ const char * service)
+{
+ struct passwd *pwd;
+ char *r;
+ char *result = NULL;
+ char *localuser = NULL;
+
+ /* lookup our local user name */
+ if ((pwd = getpwnam(CLIENT_LOGIN)) == NULL) {
+ return vstralloc("getpwnam(", CLIENT_LOGIN, ") fails", NULL);
+ }
+
+ /*
+ * Make a copy of the user name in case getpw* is called by
+ * any of the lower level routines.
+ */
+ localuser = stralloc(pwd->pw_name);
+
+#ifndef USE_AMANDAHOSTS
+ r = check_user_ruserok(rh->hostname, pwd, remoteuser);
+#else
+ r = check_user_amandahosts(rh->hostname, rh->peer.sin_addr, pwd, remoteuser, service);
+#endif
+ if (r != NULL) {
+ result = vstralloc("user ", remoteuser, " from ", rh->hostname,
+ " is not allowed to execute the service ",
+ service, ": ", r, NULL);
+ amfree(r);
+ }
+ amfree(localuser);
+ return result;
+}
+
+/*
+ * See if a remote user is allowed in. This version uses ruserok()
+ * and friends.
+ *
+ * Returns 0 on success, or negative on error.
+ */
+char *
+check_user_ruserok(
+ const char * host,
+ struct passwd * pwd,
+ const char * remoteuser)
+{
+ int saved_stderr;
+ int fd[2];
+ FILE *fError;
+ amwait_t exitcode;
+ pid_t ruserok_pid;
+ pid_t pid;
+ char *es;
+ char *result;
+ int ok;
+ char number[NUM_STR_SIZE];
+ uid_t myuid = getuid();
+
+ /*
+ * note that some versions of ruserok (eg SunOS 3.2) look in
+ * "./.rhosts" rather than "~CLIENT_LOGIN/.rhosts", so we have to
+ * chdir ourselves. Sigh.
+ *
+ * And, believe it or not, some ruserok()'s try an initgroup just
+ * for the hell of it. Since we probably aren't root at this point
+ * it'll fail, and initgroup "helpfully" will blatt "Setgroups: Not owner"
+ * into our stderr output even though the initgroup failure is not a
+ * problem and is expected. Thanks a lot. Not.
+ */
+ if (pipe(fd) != 0) {
+ return stralloc2("pipe() fails: ", strerror(errno));
+ }
+ if ((ruserok_pid = fork()) < 0) {
+ return stralloc2("fork() fails: ", strerror(errno));
+ } else if (ruserok_pid == 0) {
+ int ec;
+
+ close(fd[0]);
+ fError = fdopen(fd[1], "w");
+ if (!fError) {
+ error("Can't fdopen: %s", strerror(errno));
+ /*NOTREACHED*/
+ }
+ /* pamper braindead ruserok's */
+ if (chdir(pwd->pw_dir) != 0) {
+ fprintf(fError, "chdir(%s) failed: %s",
+ pwd->pw_dir, strerror(errno));
+ fclose(fError);
+ exit(1);
+ }
+
+#if defined(SHOW_SECURITY_DETAIL) /* { */
+ {
+ char *dir = stralloc(pwd->pw_dir);
+
+ secprintf(("%s: bsd: calling ruserok(%s, %d, %s, %s)\n",
+ debug_prefix_time(NULL),
+ host, ((myuid == 0) ? 1 : 0), remoteuser, pwd->pw_name));
+ if (myuid == 0) {
+ secprintf(("%s: bsd: because you are running as root, ",
+ debug_prefix(NULL)));
+ secprintf(("/etc/hosts.equiv will not be used\n"));
+ } else {
+ show_stat_info("/etc/hosts.equiv", NULL);
+ }
+ show_stat_info(dir, "/.rhosts");
+ amfree(dir);
+ }
+#endif /* } */
+
+ saved_stderr = dup(2);
+ close(2);
+ if (open("/dev/null", O_RDWR) == -1) {
+ secprintf(("%s: Could not open /dev/null: %s\n",
+ debug_prefix(NULL), strerror(errno)));
+ ec = 1;
+ } else {
+ ok = ruserok(host, myuid == 0, remoteuser, CLIENT_LOGIN);
+ if (ok < 0) {
+ ec = 1;
+ } else {
+ ec = 0;
+ }
+ }
+ (void)dup2(saved_stderr,2);
+ close(saved_stderr);
+ exit(ec);
+ }
+ close(fd[1]);
+ fError = fdopen(fd[0], "r");
+ if (!fError) {
+ error("Can't fdopen: %s", strerror(errno));
+ /*NOTREACHED*/
+ }
+
+ result = NULL;
+ while ((es = agets(fError)) != NULL) {
+ if (*es == 0) {
+ amfree(es);
+ continue;
+ }
+ if (result == NULL) {
+ result = stralloc("");
+ } else {
+ strappend(result, ": ");
+ }
+ strappend(result, es);
+ amfree(es);
+ }
+ close(fd[0]);
+
+ pid = wait(&exitcode);
+ while (pid != ruserok_pid) {
+ if ((pid == (pid_t) -1) && (errno != EINTR)) {
+ amfree(result);
+ return stralloc2("ruserok wait failed: %s", strerror(errno));
+ }
+ pid = wait(&exitcode);
+ }
+ if (WIFSIGNALED(exitcode)) {
+ amfree(result);
+ snprintf(number, SIZEOF(number), "%d", WTERMSIG(exitcode));
+ return stralloc2("ruserok child got signal ", number);
+ }
+ if (WEXITSTATUS(exitcode) == 0) {
+ amfree(result);
+ } else if (result == NULL) {
+ result = stralloc("ruserok failed");
+ }
+
+ return result;
+}
+
+/*
+ * Check to see if a user is allowed in. This version uses .amandahosts
+ * Returns -1 on failure, or 0 on success.
+ */
+char *
+check_user_amandahosts(
+ const char * host,
+ struct in_addr addr,
+ struct passwd * pwd,
+ const char * remoteuser,
+ const char * service)
+{
+ char *line = NULL;
+ char *filehost;
+ const char *fileuser;
+ char *ptmp = NULL;
+ char *result = NULL;
+ FILE *fp = NULL;
+ int found;
+ struct stat sbuf;
+ char n1[NUM_STR_SIZE];
+ char n2[NUM_STR_SIZE];
+ int hostmatch;
+ int usermatch;
+ char *aservice = NULL;
+
+ secprintf(("check_user_amandahosts(host=%s, pwd=%p, "
+ "remoteuser=%s, service=%s)\n",
+ host, pwd, remoteuser, service));
+
+ ptmp = stralloc2(pwd->pw_dir, "/.amandahosts");
+#if defined(SHOW_SECURITY_DETAIL) /* { */
+ show_stat_info(ptmp, "");;
+#endif /* } */
+ if ((fp = fopen(ptmp, "r")) == NULL) {
+ result = vstralloc("cannot open ", ptmp, ": ", strerror(errno), NULL);
+ amfree(ptmp);
+ return result;
+ }
+
+ /*
+ * Make sure the file is owned by the Amanda user and does not
+ * have any group/other access allowed.
+ */
+ if (fstat(fileno(fp), &sbuf) != 0) {
+ result = vstralloc("cannot fstat ", ptmp, ": ", strerror(errno), NULL);
+ goto common_exit;
+ }
+ if (sbuf.st_uid != pwd->pw_uid) {
+ snprintf(n1, SIZEOF(n1), "%ld", (long)sbuf.st_uid);
+ snprintf(n2, SIZEOF(n2), "%ld", (long)pwd->pw_uid);
+ result = vstralloc(ptmp, ": ",
+ "owned by id ", n1,
+ ", should be ", n2,
+ NULL);
+ goto common_exit;
+ }
+ if ((sbuf.st_mode & 077) != 0) {
+ result = stralloc2(ptmp,
+ ": incorrect permissions; file must be accessible only by its owner");
+ goto common_exit;
+ }
+
+ /*
+ * Now, scan the file for the host/user/service.
+ */
+ found = 0;
+ while ((line = agets(fp)) != NULL) {
+ if (*line == 0) {
+ amfree(line);
+ continue;
+ }
+
+#if defined(SHOW_SECURITY_DETAIL) /* { */
+ secprintf(("%s: bsd: processing line: <%s>\n", debug_prefix(NULL), line));
+#endif /* } */
+ /* get the host out of the file */
+ if ((filehost = strtok(line, " \t")) == NULL) {
+ amfree(line);
+ continue;
+ }
+
+ /* get the username. If no user specified, then use the local user */
+ if ((fileuser = strtok(NULL, " \t")) == NULL) {
+ fileuser = pwd->pw_name;
+ }
+
+ hostmatch = (strcasecmp(filehost, host) == 0);
+ /* ok if addr=127.0.0.1 and
+ * either localhost or localhost.domain is in .amandahost */
+ if ( !hostmatch ) {
+ if (strcmp(inet_ntoa(addr), "127.0.0.1")== 0 &&
+ (strcasecmp(filehost, "localhost")== 0 ||
+ strcasecmp(filehost, "localhost.localdomain")== 0))
+ {
+ hostmatch = 1;
+ }
+ }
+ usermatch = (strcasecmp(fileuser, remoteuser) == 0);
+#if defined(SHOW_SECURITY_DETAIL) /* { */
+ secprintf(("%s: bsd: comparing \"%s\" with\n", debug_prefix(NULL), filehost));
+ secprintf(("%s: bsd: \"%s\" (%s)\n", host,
+ debug_prefix(NULL), hostmatch ? "match" : "no match"));
+ secprintf(("%s: bsd: and \"%s\" with\n", fileuser, debug_prefix(NULL)));
+ secprintf(("%s: bsd: \"%s\" (%s)\n", remoteuser,
+ debug_prefix(NULL), usermatch ? "match" : "no match"));
+#endif /* } */
+ /* compare */
+ if (!hostmatch || !usermatch) {
+ amfree(line);
+ continue;
+ }
+
+ if (!service) {
+ /* success */
+ amfree(line);
+ found = 1;
+ break;
+ }
+
+ /* get the services. If no service specified, then use
+ * noop/selfcheck/sendsize/sendbackup
+ */
+ aservice = strtok(NULL, " \t,");
+ if (!aservice) {
+ if (strcmp(service,"noop") == 0 ||
+ strcmp(service,"selfcheck") == 0 ||
+ strcmp(service,"sendsize") == 0 ||
+ strcmp(service,"sendbackup") == 0) {
+ /* success */
+ found = 1;
+ amfree(line);
+ break;
+ }
+ else {
+ amfree(line);
+ break;
+ }
+ }
+
+ do {
+ if (strcmp(aservice,service) == 0) {
+ found = 1;
+ break;
+ }
+ if (strcmp(aservice, "amdump") == 0 &&
+ (strcmp(service, "noop") == 0 ||
+ strcmp(service, "selfcheck") == 0 ||
+ strcmp(service, "sendsize") == 0 ||
+ strcmp(service, "sendbackup") == 0)) {
+ found = 1;
+ break;
+ }
+ } while((aservice = strtok(NULL, " \t,")) != NULL);
+
+ if (aservice && strcmp(aservice, service) == 0) {
+ /* success */
+ found = 1;
+ amfree(line);
+ break;
+ }
+ amfree(line);
+ }
+ if (! found) {
+ if (strcmp(service, "amindexd") == 0 ||
+ strcmp(service, "amidxtaped") == 0) {
+ result = vstralloc("Please add \"amindexd amidxtaped\" to "
+ "the line in ", ptmp, NULL);
+ } else if (strcmp(service, "amdump") == 0 ||
+ strcmp(service, "noop") == 0 ||
+ strcmp(service, "selfcheck") == 0 ||
+ strcmp(service, "sendsize") == 0 ||
+ strcmp(service, "sendbackup") == 0) {
+ result = vstralloc("Please add \"amdump\" to the line in ",
+ ptmp, NULL);
+ } else {
+ result = vstralloc(ptmp, ": ",
+ "invalid service ", service, NULL);
+ }
+ }
+
+common_exit:
+
+ afclose(fp);
+ amfree(ptmp);
+
+ return result;
+}
+
+/* return 1 on success, 0 on failure */
+int
+check_security(
+ struct sockaddr_in *addr,
+ char * str,
+ unsigned long cksum,
+ char ** errstr)
+{
+ char * remotehost = NULL, *remoteuser = NULL;
+ char * bad_bsd = NULL;
+ struct hostent * hp;
+ struct passwd * pwptr;
+ uid_t myuid;
+ int i;
+ int j;
+ char * s;
+ char * fp;
+ int ch;
+
+ (void)cksum; /* Quiet unused parameter warning */
+
+ secprintf(("%s: check_security(addr=%p, str='%s', cksum=%ul, errstr=%p\n",
+ debug_prefix(NULL), addr, str, cksum, errstr));
+ dump_sockaddr(addr);
+
+ *errstr = NULL;
+
+ /* what host is making the request? */
+
+ hp = gethostbyaddr((char *)&addr->sin_addr, SIZEOF(addr->sin_addr),
+ AF_INET);
+ if (hp == NULL) {
+ /* XXX include remote address in message */
+ *errstr = vstralloc("[",
+ "addr ", inet_ntoa(addr->sin_addr), ": ",
+ "hostname lookup failed",
+ "]", NULL);
+ return 0;
+ }
+ remotehost = stralloc(hp->h_name);
+
+ /* Now let's get the hostent for that hostname */
+ hp = gethostbyname( remotehost );
+ if (hp == NULL) {
+ /* XXX include remote hostname in message */
+ *errstr = vstralloc("[",
+ "host ", remotehost, ": ",
+ "hostname lookup failed",
+ "]", NULL);
+ amfree(remotehost);
+ return 0;
+ }
+
+ /* Verify that the hostnames match -- they should theoretically */
+ if (strncasecmp( remotehost, hp->h_name, strlen(remotehost)+1 ) != 0 ) {
+ *errstr = vstralloc("[",
+ "hostnames do not match: ",
+ remotehost, " ", hp->h_name,
+ "]", NULL);
+ amfree(remotehost);
+ return 0;
+ }
+
+ /* Now let's verify that the ip which gave us this hostname
+ * is really an ip for this hostname; or is someone trying to
+ * break in? (THIS IS THE CRUCIAL STEP)
+ */
+ for (i = 0; hp->h_addr_list[i]; i++) {
+ if (memcmp(hp->h_addr_list[i],
+ (char *) &addr->sin_addr, SIZEOF(addr->sin_addr)) == 0)
+ break; /* name is good, keep it */
+ }
+
+ /* If we did not find it, your DNS is messed up or someone is trying
+ * to pull a fast one on you. :(
+ */
+
+ /* Check even the aliases list. Work around for Solaris if dns goes over NIS */
+
+ if (!hp->h_addr_list[i] ) {
+ for (j = 0; hp->h_aliases[j] !=0 ; j++) {
+ if (strcmp(hp->h_aliases[j],inet_ntoa(addr->sin_addr)) == 0)
+ break; /* name is good, keep it */
+ }
+ if (!hp->h_aliases[j] ) {
+ *errstr = vstralloc("[",
+ "ip address ", inet_ntoa(addr->sin_addr),
+ " is not in the ip list for ", remotehost,
+ "]",
+ NULL);
+ amfree(remotehost);
+ return 0;
+ }
+ }
+
+ /* next, make sure the remote port is a "reserved" one */
+
+ if (ntohs(addr->sin_port) >= IPPORT_RESERVED) {
+ char number[NUM_STR_SIZE];
+
+ snprintf(number, SIZEOF(number), "%hd", (short)ntohs(addr->sin_port));
+ *errstr = vstralloc("[",
+ "host ", remotehost, ": ",
+ "port ", number, " not secure",
+ "]", NULL);
+ amfree(remotehost);
+ return 0;
+ }
+
+ /* extract the remote user name from the message */
+
+ s = str;
+ ch = *s++;
+
+ bad_bsd = vstralloc("[",
+ "host ", remotehost, ": ",
+ "bad bsd security line",
+ "]", NULL);
+
+#define sc "USER "
+ if (strncmp(s - 1, sc, SIZEOF(sc)-1) != 0) {
+ *errstr = bad_bsd;
+ bad_bsd = NULL;
+ amfree(remotehost);
+ return 0;
+ }
+ s += SIZEOF(sc)-1;
+ ch = s[-1];
+#undef sc
+
+ skip_whitespace(s, ch);
+ if (ch == '\0') {
+ *errstr = bad_bsd;
+ bad_bsd = NULL;
+ amfree(remotehost);
+ return 0;
+ }
+ fp = s - 1;
+ skip_non_whitespace(s, ch);
+ s[-1] = '\0';
+ remoteuser = stralloc(fp);
+ s[-1] = (char)ch;
+ amfree(bad_bsd);
+
+ /* lookup our local user name */
+
+ myuid = getuid();
+ if ((pwptr = getpwuid(myuid)) == NULL)
+ error("error [getpwuid(%d) fails]", myuid);
+
+ secprintf(("%s: bsd security: remote host %s user %s local user %s\n",
+ debug_prefix(NULL), remotehost, remoteuser, pwptr->pw_name));
+
+#ifndef USE_AMANDAHOSTS
+ s = check_user_ruserok(remotehost, pwptr, remoteuser);
+#else
+ s = check_user_amandahosts(remotehost, addr->sin_addr, pwptr, remoteuser, NULL);
+#endif
+
+ if (s != NULL) {
+ *errstr = vstralloc("[",
+ "access as ", pwptr->pw_name, " not allowed",
+ " from ", remoteuser, "@", remotehost,
+ ": ", s, "]", NULL);
+ }
+ amfree(s);
+ amfree(remotehost);
+ amfree(remoteuser);
+ return *errstr == NULL;
+}
+
+/*
+ * Writes out the entire iovec
+ */
+ssize_t
+net_writev(
+ int fd,
+ struct iovec * iov,
+ int iovcnt)
+{
+ ssize_t delta, n, total;
+
+ assert(iov != NULL);
+
+ total = 0;
+ while (iovcnt > 0) {
+ /*
+ * Write the iovec
+ */
+ n = writev(fd, iov, iovcnt);
+ if (n < 0) {
+ if (errno != EINTR)
+ return (-1);
+ secprintf(("%s: net_writev got EINTR\n",
+ debug_prefix(NULL)));
+ }
+ else if (n == 0) {
+ errno = EIO;
+ return (-1);
+ } else {
+ total += n;
+ /*
+ * Iterate through each iov. Figure out what we still need
+ * to write out.
+ */
+ for (; n > 0; iovcnt--, iov++) {
+ /* 'delta' is the bytes written from this iovec */
+ delta = ((size_t)n < iov->iov_len) ? n : (ssize_t)iov->iov_len;
+ /* subtract from the total num bytes written */
+ n -= delta;
+ assert(n >= 0);
+ /* subtract from this iovec */
+ iov->iov_len -= delta;
+ iov->iov_base = (char *)iov->iov_base + delta;
+ /* if this iovec isn't empty, run the writev again */
+ if (iov->iov_len > 0)
+ break;
+ }
+ }
+ }
+ return (total);
+}
+
+/*
+ * Like read(), but waits until the entire buffer has been filled.
+ */
+ssize_t
+net_read(
+ int fd,
+ void * vbuf,
+ size_t origsize,
+ int timeout)
+{
+ char *buf = vbuf; /* ptr arith */
+ ssize_t nread;
+ size_t size = origsize;
+
+ secprintf(("%s: net_read: begin %d\n", debug_prefix_time(NULL), origsize));
+
+ while (size > 0) {
+ secprintf(("%s: net_read: while %d\n",
+ debug_prefix_time(NULL), size));
+ nread = net_read_fillbuf(fd, timeout, buf, size);
+ if (nread < 0) {
+ secprintf(("%s: db: net_read: end return(-1)\n",
+ debug_prefix_time(NULL)));
+ return (-1);
+ }
+ if (nread == 0) {
+ secprintf(("%s: net_read: end return(0)\n",
+ debug_prefix_time(NULL)));
+ return (0);
+ }
+ buf += nread;
+ size -= nread;
+ }
+ secprintf(("%s: net_read: end %d\n",
+ debug_prefix_time(NULL), origsize));
+ return ((ssize_t)origsize);
+}
+
+/*
+ * net_read likes to do a lot of little reads. Buffer it.
+ */
+ssize_t
+net_read_fillbuf(
+ int fd,
+ int timeout,
+ void * buf,
+ size_t size)
+{
+ fd_set readfds;
+ struct timeval tv;
+ ssize_t nread;
+
+ secprintf(("%s: net_read_fillbuf: begin\n", debug_prefix_time(NULL)));
+ FD_ZERO(&readfds);
+ FD_SET(fd, &readfds);
+ tv.tv_sec = timeout;
+ tv.tv_usec = 0;
+ switch (select(fd + 1, &readfds, NULL, NULL, &tv)) {
+ case 0:
+ errno = ETIMEDOUT;
+ /* FALLTHROUGH */
+ case -1:
+ secprintf(("%s: net_read_fillbuf: case -1\n",
+ debug_prefix_time(NULL)));
+ return (-1);
+ case 1:
+ secprintf(("%s: net_read_fillbuf: case 1\n",
+ debug_prefix_time(NULL)));
+ assert(FD_ISSET(fd, &readfds));
+ break;
+ default:
+ secprintf(("%s: net_read_fillbuf: case default\n",
+ debug_prefix_time(NULL)));
+ assert(0);
+ break;
+ }
+ nread = read(fd, buf, size);
+ if (nread < 0)
+ return (-1);
+ secprintf(("%s: net_read_fillbuf: end %d\n",
+ debug_prefix_time(NULL), nread));
+ return (nread);
+}
+
+
+/*
+ * Display stat() information about a file.
+ */
+
+void
+show_stat_info(
+ char * a,
+ char * b)
+{
+ char *name = vstralloc(a, b, NULL);
+ struct stat sbuf;
+ struct passwd *pwptr;
+ char *owner;
+ struct group *grptr;
+ char *group;
+
+ if (stat(name, &sbuf) != 0) {
+ secprintf(("%s: bsd: cannot stat %s: %s\n",
+ debug_prefix_time(NULL), name, strerror(errno)));
+ amfree(name);
+ return;
+ }
+ if ((pwptr = getpwuid(sbuf.st_uid)) == NULL) {
+ owner = alloc(NUM_STR_SIZE + 1);
+ snprintf(owner, NUM_STR_SIZE, "%ld", (long)sbuf.st_uid);
+ } else {
+ owner = stralloc(pwptr->pw_name);
+ }
+ if ((grptr = getgrgid(sbuf.st_gid)) == NULL) {
+ group = alloc(NUM_STR_SIZE + 1);
+ snprintf(owner, NUM_STR_SIZE, "%ld", (long)sbuf.st_gid);
+ } else {
+ group = stralloc(grptr->gr_name);
+ }
+ secprintf(("%s: bsd: processing file: %s\n", debug_prefix(NULL), name));
+ secprintf(("%s: bsd: owner=%s group=%s mode=%03o\n",
+ debug_prefix(NULL), owner, group, (int) (sbuf.st_mode & 0777)));
+ amfree(name);
+ amfree(owner);
+ amfree(group);
+}
--- /dev/null
+#ifndef _SECURITY_UTIL_H
+#define _SECURITY_UTIL_H
+
+/*
+ * Amanda, The Advanced Maryland Automatic Network Disk Archiver
+ * Copyright (c) 1999 University of Maryland
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of U.M. not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. U.M. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: the Amanda Development Team. Its members are listed in a
+ * file named AUTHORS, in the root directory of this distribution.
+ */
+
+/*
+ * $Id: security-util.h,v 1.5 2006/07/01 00:10:38 paddy_s Exp $
+ *
+ */
+
+#include "stream.h"
+#include "dgram.h"
+#include "queue.h"
+
+struct sec_handle;
+
+/*
+ * This is a sec connection to a host. We should only have
+ * one connection per host.
+ */
+struct tcp_conn {
+ const struct security_driver *driver; /* MUST be first */
+ int read, write; /* pipes to sec */
+ pid_t pid; /* pid of sec process */
+ char * pkt; /* last pkt read */
+ ssize_t pktlen; /* len of above */
+ event_handle_t * ev_read; /* read (EV_READFD) handle */
+ int ev_read_refcnt; /* number of readers */
+ char hostname[MAX_HOSTNAME_LENGTH+1];
+ /* host we're talking to */
+ char * errmsg; /* error passed up */
+ int refcnt; /* number of handles using */
+ int handle; /* last proto handle read */
+ void (*accept_fn)(security_handle_t *, pkt_t *);
+ struct sockaddr_in peer;
+ TAILQ_ENTRY(tcp_conn) tq; /* queue handle */
+ int (*recv_security_ok)(struct sec_handle *, pkt_t *);
+ char * (*prefix_packet)(void *, pkt_t *);
+ int toclose;
+ int donotclose;
+};
+
+
+struct sec_stream;
+
+/*
+ * This is the private handle data.
+ */
+struct sec_handle {
+ security_handle_t sech; /* MUST be first */
+ char * hostname; /* ptr to rc->hostname */
+ struct sec_stream * rs; /* virtual stream we xmit over */
+ struct tcp_conn * rc; /* */
+ union {
+ void (*recvpkt)(void *, pkt_t *, security_status_t);
+ /* func to call when packet recvd */
+ void (*connect)(void *, security_handle_t *, security_status_t);
+ /* func to call when connected */
+ } fn;
+ void * arg; /* argument to pass function */
+ event_handle_t * ev_timeout; /* timeout handle for recv */
+ struct sockaddr_in peer;
+ int sequence;
+ event_id_t event_id;
+ char * proto_handle;
+ event_handle_t * ev_read;
+ struct sec_handle * prev;
+ struct sec_handle * next;
+ struct udp_handle * udp;
+ void (*accept_fn)(security_handle_t *, pkt_t *);
+ int (*recv_security_ok)(struct sec_handle *, pkt_t *);
+};
+
+/*
+ * This is the internal security_stream data for sec.
+ */
+struct sec_stream {
+ security_stream_t secstr; /* MUST be first */
+ struct tcp_conn * rc; /* physical connection */
+ int handle; /* protocol handle */
+ event_handle_t * ev_read; /* read (EV_WAIT) event handle */
+ void (*fn)(void *, void *, ssize_t); /* read event fn */
+ void * arg; /* arg for previous */
+ int fd;
+ char databuf[NETWORK_BLOCK_BYTES];
+ ssize_t len;
+ int socket;
+ in_port_t port;
+ int closed_by_me;
+ int closed_by_network;
+};
+
+struct connq_s {
+ TAILQ_HEAD(, tcp_conn) tailq;
+ int qlength;
+};
+extern struct connq_s connq;
+
+#define connq_first() TAILQ_FIRST(&connq.tailq)
+#define connq_next(rc) TAILQ_NEXT(rc, tq)
+#define connq_append(rc) do { \
+ TAILQ_INSERT_TAIL(&connq.tailq, rc, tq); \
+ connq.qlength++; \
+} while (0)
+#define connq_remove(rc) do { \
+ assert(connq.qlength > 0); \
+ TAILQ_REMOVE(&connq.tailq, rc, tq); \
+ connq.qlength--; \
+} while (0)
+
+/*
+ * This is data local to the datagram socket. We have one datagram
+ * per process per auth.
+ */
+typedef struct udp_handle {
+ const struct security_driver *driver; /* MUST be first */
+ dgram_t dgram; /* datagram to read/write from */
+ struct sockaddr_in peer; /* who sent it to us */
+ pkt_t pkt; /* parsed form of dgram */
+ char *handle; /* handle from recvd packet */
+ int sequence; /* seq no of packet */
+ event_handle_t *ev_read; /* read event handle from dgram */
+ int refcnt; /* number of handles blocked for reading */
+ struct sec_handle *bh_first, *bh_last;
+ void (*accept_fn)(security_handle_t *, pkt_t *);
+ int (*recv_security_ok)(struct sec_handle *, pkt_t *);
+ char *(*prefix_packet)(void *, pkt_t *);
+} udp_handle_t;
+
+/*
+ * We register one event handler for our network fd which takes
+ * care of all of our async requests. When all async requests
+ * have either been satisfied or cancelled, we unregister our
+ * network event handler.
+ */
+#define udp_addref(udp, netfd_read_callback) do { \
+ if ((udp)->refcnt++ == 0) { \
+ assert((udp)->ev_read == NULL); \
+ (udp)->ev_read = event_register((event_id_t)(udp)->dgram.socket,\
+ EV_READFD, netfd_read_callback, (udp)); \
+ } \
+ assert((udp)->refcnt > 0); \
+} while (0)
+
+/*
+ * If this is the last request to be removed, then remove the
+ * reader event from the netfd.
+ */
+#define udp_delref(udp) do { \
+ assert((udp)->refcnt > 0); \
+ if (--(udp)->refcnt == 0) { \
+ assert((udp)->ev_read != NULL); \
+ event_release((udp)->ev_read); \
+ (udp)->ev_read = NULL; \
+ } \
+} while (0)
+
+
+int sec_stream_auth(void *);
+int sec_stream_id(void *);
+void sec_accept(const security_driver_t *, int, int,
+ void (*)(security_handle_t *, pkt_t *));
+void sec_close(void *);
+void sec_connect_callback(void *);
+void sec_connect_timeout(void *);
+void sec_close_connection_none(void *, char *);
+
+ssize_t stream_sendpkt(void *, pkt_t *);
+void stream_recvpkt(void *,
+ void (*)(void *, pkt_t *, security_status_t),
+ void *, int);
+void stream_recvpkt_timeout(void *);
+void stream_recvpkt_cancel(void *);
+
+int tcpm_stream_write(void *, const void *, size_t);
+void tcpm_stream_read(void *, void (*)(void *, void *, ssize_t), void *);
+ssize_t tcpm_stream_read_sync(void *, void **);
+void tcpm_stream_read_cancel(void *);
+ssize_t tcpm_send_token(int, int, char **, const void *, size_t);
+ssize_t tcpm_recv_token(int, int *, char **, char **, ssize_t *, int);
+void tcpm_close_connection(void *, char *);
+
+int tcpma_stream_accept(void *);
+void * tcpma_stream_client(void *, int);
+void * tcpma_stream_server(void *);
+void tcpma_stream_close(void *);
+
+void * tcp1_stream_server(void *);
+int tcp1_stream_accept(void *);
+void * tcp1_stream_client(void *, int);
+
+int tcp_stream_write(void *, const void *, size_t);
+
+char * bsd_prefix_packet(void *, pkt_t *);
+int bsd_recv_security_ok(struct sec_handle *, pkt_t *);
+
+ssize_t udpbsd_sendpkt(void *, pkt_t *);
+void udp_close(void *);
+void udp_recvpkt(void *, void (*)(void *, pkt_t *, security_status_t),
+ void *, int);
+void udp_recvpkt_cancel(void *);
+void udp_recvpkt_callback(void *);
+void udp_recvpkt_timeout(void *);
+int udp_inithandle(udp_handle_t *, struct sec_handle *, struct hostent *,
+ in_port_t, char *, int);
+void udp_netfd_read_callback(void *);
+
+struct tcp_conn *sec_tcp_conn_get(const char *, int);
+void sec_tcp_conn_put(struct tcp_conn *);
+void sec_tcp_conn_read(struct tcp_conn *);
+void parse_pkt(pkt_t *, const void *, size_t);
+const char *pkthdr2str(const struct sec_handle *, const pkt_t *);
+int str2pkthdr(udp_handle_t *);
+char * check_user(struct sec_handle *, const char *, const char *);
+
+char * check_user_ruserok (const char *host,
+ struct passwd *pwd,
+ const char *user);
+char * check_user_amandahosts(const char *host,
+ struct in_addr addr,
+ struct passwd *pwd,
+ const char *user,
+ const char *service);
+
+ssize_t net_writev(int, struct iovec *, int);
+ssize_t net_read(int, void *, size_t, int);
+ssize_t net_read_fillbuf(int, int, void *, size_t);
+void show_stat_info(char *a, char *b);
+
+#endif /* _SECURITY_INFO_H */
* file named AUTHORS, in the root directory of this distribution.
*/
/*
- * $Id: security.c,v 1.26 2004/03/16 19:09:39 martinea Exp $
+ * $Id: security.c,v 1.28 2006/05/25 01:47:12 johnfranks Exp $
*
* Security driver interface for the Amanda backup system.
*/
#ifdef SSH_SECURITY
extern const security_driver_t ssh_security_driver;
#endif
+#ifdef BSDTCP_SECURITY
+extern const security_driver_t bsdtcp_security_driver;
+#endif
+#ifdef BSDUDP_SECURITY
+extern const security_driver_t bsdudp_security_driver;
+#endif
static const security_driver_t *drivers[] = {
#ifdef BSD_SECURITY
#ifdef SSH_SECURITY
&ssh_security_driver,
#endif
+#ifdef BSDTCP_SECURITY
+ &bsdtcp_security_driver,
+#endif
+#ifdef BSDUDP_SECURITY
+ &bsdudp_security_driver,
+#endif
};
-#define NDRIVERS (sizeof(drivers) / sizeof(drivers[0]))
+#define NDRIVERS (size_t)(sizeof(drivers) / sizeof(drivers[0]))
/*
* Given a name of a security type, returns the driver structure
*/
const security_driver_t *
-security_getdriver(name)
- const char *name;
+security_getdriver(
+ const char * name)
{
- int i;
+ size_t i;
assert(name != NULL);
- for (i = 0; i < NDRIVERS; i++)
- if (strcasecmp(name, drivers[i]->name) == 0)
+ for (i = 0; i < NDRIVERS; i++) {
+ if (strcasecmp(name, drivers[i]->name) == 0) {
+ dbprintf(("security_getdriver(name=%s) returns %p\n",
+ name, drivers[i]));
return (drivers[i]);
+ }
+ }
+ dbprintf(("security_getdriver(name=%s) returns NULL\n", name));
return (NULL);
}
* For the drivers: initialize the common part of a security_handle_t
*/
void
-security_handleinit(handle, driver)
- security_handle_t *handle;
- const security_driver_t *driver;
+security_handleinit(
+ security_handle_t * handle,
+ const security_driver_t * driver)
{
-
+ dbprintf(("security_handleinit(handle=%p, driver=%p (%s))\n",
+ handle, driver, driver->name));
handle->driver = driver;
handle->error = stralloc("unknown protocol error");
}
assert(handle->error != NULL);
arglist_start(argp, fmt);
- vsnprintf(buf, sizeof(buf), fmt, argp);
+ vsnprintf(buf, SIZEOF(buf), fmt, argp);
arglist_end(argp);
handle->error = newstralloc(handle->error, buf);
+ dbprintf(("security_seterror(handle=%p, driver=%p (%s) error=%s)\n",
+ handle, handle->driver, handle->driver->name, handle->error));
}
void
-security_close(handle)
- security_handle_t *handle;
+security_close(
+ security_handle_t * handle)
{
-
+ dbprintf(("security_close(handle=%p, driver=%p (%s))\n",
+ handle, handle->driver, handle->driver->name));
amfree(handle->error);
(*handle->driver->close)(handle);
}
* For the drivers: initialize the common part of a security_stream_t
*/
void
-security_streaminit(stream, driver)
- security_stream_t *stream;
- const security_driver_t *driver;
+security_streaminit(
+ security_stream_t * stream,
+ const security_driver_t * driver)
{
-
+ dbprintf(("security_streaminit(stream=%p, driver=%p (%s))\n",
+ stream, driver, driver->name));
stream->driver = driver;
stream->error = stralloc("unknown stream error");
}
static char buf[256];
va_list argp;
- assert(stream->error != NULL);
arglist_start(argp, fmt);
- vsnprintf(buf, sizeof(buf), fmt, argp);
+ vsnprintf(buf, SIZEOF(buf), fmt, argp);
arglist_end(argp);
stream->error = newstralloc(stream->error, buf);
+ dbprintf(("security_stream_seterr(%p, %s)\n", stream, stream->error));
}
void
-security_stream_close(stream)
- security_stream_t *stream;
+security_stream_close(
+ security_stream_t * stream)
{
-
+ dbprintf(("security_stream_close(%p)\n", stream));
amfree(stream->error);
(*stream->driver->stream_close)(stream);
}
* file named AUTHORS, in the root directory of this distribution.
*/
/*
- * $Id: security.h,v 1.11 2003/04/26 02:02:19 kovert Exp $
+ * $Id: security.h,v 1.17 2006/05/26 14:00:58 martinea Exp $
*
* security api
*/
#ifndef SECURITY_H
#define SECURITY_H
+#include "packet.h"
+
struct security_handle;
/*
* Connects a security handle, for this driver to a remote
* host.
*/
- void (*connect) P((const char *,
+ void (*connect)(const char *,
char *(*)(char *, void *),
void (*)(void *, struct security_handle *, security_status_t),
- void *));
+ void *, void *);
/*
* This form sets up a callback that returns new handles as
* they are received. It takes an input and output file descriptor.
*/
- void (*accept) P((int, int, void (*)(struct security_handle *, pkt_t *)));
+ void (*accept)(const struct security_driver *, int, int,
+ void (*)(struct security_handle *, pkt_t *));
/*
* Frees up handles allocated by the previous
*/
- void (*close) P((void *));
+ void (*close)(void *);
/*
* This transmits a packet after adding the security information
* Returns 0 on success, negative on error.
*/
- int (*sendpkt) P((void *, pkt_t *));
+ ssize_t (*sendpkt)(void *, pkt_t *);
/*
* This creates an event in the event handler for receiving pkt_t's
*
* Only one recvpkt request can exist per handle.
*/
- void (*recvpkt) P((void *, void (*)(void *, pkt_t *,
- security_status_t), void *, int));
+ void (*recvpkt)(void *, void (*)(void *, pkt_t *,
+ security_status_t), void *, int);
/*
* Cancel an outstanding recvpkt request on a handle.
*/
- void (*recvpkt_cancel) P((void *));
+ void (*recvpkt_cancel)(void *);
/*
* Get a stream given a security handle
*/
- void *(*stream_server) P((void *));
+ void *(*stream_server)(void *);
/*
* Accept a stream created by stream_server
*/
- int (*stream_accept) P((void *));
+ int (*stream_accept)(void *);
/*
* Get a stream and connect it to a remote given a security handle
* and a stream id.
*/
- void *(*stream_client) P((void *, int));
+ void *(*stream_client)(void *, int);
/*
* Close a stream opened with stream_server or stream_client
*/
- void (*stream_close) P((void *));
+ void (*stream_close)(void *);
/*
* Authenticate a stream.
*/
- int (*stream_auth) P((void *));
+ int (*stream_auth)(void *);
/*
* Return a numeric id for a stream.
*/
- int (*stream_id) P((void *));
+ int (*stream_id)(void *);
/*
* Write to a stream.
*/
- int (*stream_write) P((void *, const void *, size_t));
+ int (*stream_write)(void *, const void *, size_t);
/*
* Read asyncronously from a stream. Only one request can exist
* per stream.
*/
- void (*stream_read) P((void *, void (*)(void *, void *, ssize_t), void *));
+ void (*stream_read)(void *, void (*)(void *, void *, ssize_t), void *);
+
+ /*
+ * Read syncronously from a stream.
+ */
+ ssize_t (*stream_read_sync)(void *, void **);
/*
* Cancel a stream read request
*/
- void (*stream_read_cancel) P((void *));
+ void (*stream_read_cancel)(void *);
+
+ void (*close_connection)(void *, char *);
} security_driver_t;
} security_stream_t;
-const security_driver_t *security_getdriver P((const char *));
-void security_handleinit P((security_handle_t *, const security_driver_t *));
-void security_streaminit P((security_stream_t *, const security_driver_t *));
+const security_driver_t *security_getdriver(const char *);
+void security_handleinit(security_handle_t *, const security_driver_t *);
+void security_streaminit(security_stream_t *, const security_driver_t *);
-/* const char *security_geterror P((security_handle_t *)); */
+/* const char *security_geterror(security_handle_t *); */
#define security_geterror(handle) ((handle)->error)
-void security_seterror P((security_handle_t *, const char *, ...))
+void security_seterror(security_handle_t *, const char *, ...)
__attribute__ ((format (printf, 2, 3)));
-/* void security_connect P((const security_driver_t *, const char *,
- void (*)(void *, security_handle_t *, security_status_t), void *)); */
-#define security_connect(driver, hostname, conf_fn, fn, arg) \
- (*(driver)->connect)(hostname, conf_fn, fn, arg)
-/* void security_accept P((const security_driver_t *, int, int,
- void (*)(security_handle_t *, pkt_t *))); */
+/* void security_connect(const security_driver_t *, const char *,
+ void (*)(void *, security_handle_t *, security_status_t), void *, void *); */
+#define security_connect(driver, hostname, conf_fn, fn, arg, datap) \
+ (*(driver)->connect)(hostname, conf_fn, fn, arg, datap)
+/* void security_accept(const security_driver_t *, int, int,
+ void (*)(security_handle_t *, pkt_t *)); */
#define security_accept(driver, in, out, fn) \
- (*(driver)->accept)(in, out, fn)
-void security_close P((security_handle_t *));
+ (*(driver)->accept)(driver, in, out, fn)
+void security_close(security_handle_t *);
-/* int security_sendpkt P((security_handle_t *, const pkt_t *)); */
+/* int security_sendpkt(security_handle_t *, const pkt_t *); */
#define security_sendpkt(handle, pkt) \
(*(handle)->driver->sendpkt)(handle, pkt)
-/* void security_recvpkt P((security_handle_t *,
+/* void security_recvpkt(security_handle_t *,
void (*)(void *, pkt_t *, security_status_t), void *, int); */
#define security_recvpkt(handle, fn, arg, timeout) \
(*(handle)->driver->recvpkt)(handle, fn, arg, timeout)
-/* void security_recvpkt_cancel P((security_handle_t *)); */
+/* void security_recvpkt_cancel(security_handle_t *); */
#define security_recvpkt_cancel(handle) \
(*(handle)->driver->recvpkt_cancel)(handle)
-/* const char *security_stream_geterror P((security_stream_t *)); */
+/* const char *security_stream_geterror(security_stream_t *); */
#define security_stream_geterror(stream) ((stream)->error)
-void security_stream_seterror P((security_stream_t *, const char *, ...))
+void security_stream_seterror(security_stream_t *, const char *, ...)
__attribute__ ((format (printf, 2, 3)));
-/* security_stream_t *security_stream_server P((security_handle_t *)); */
+/* security_stream_t *security_stream_server(security_handle_t *); */
#define security_stream_server(handle) \
(*(handle)->driver->stream_server)(handle)
-/* int security_stream_accept P((security_stream_t *)); */
+/* int security_stream_accept(security_stream_t *); */
#define security_stream_accept(stream) \
(*(stream)->driver->stream_accept)(stream)
-/* security_stream_t *security_stream_client P((security_handle_t *, int)); */
+/* security_stream_t *security_stream_client(security_handle_t *, int); */
#define security_stream_client(handle, id) \
(*(handle)->driver->stream_client)(handle, id)
-void security_stream_close P((security_stream_t *));
+void security_stream_close(security_stream_t *);
-/* int security_stream_auth P((security_stream_t *)); */
+/* int security_stream_auth(security_stream_t *); */
#define security_stream_auth(stream) \
(*(stream)->driver->stream_auth)(stream)
-/* int security_stream_id P((security_stream_t *)); */
+/* int security_stream_id(security_stream_t *); */
#define security_stream_id(stream) \
(*(stream)->driver->stream_id)(stream)
-/* int security_stream_write P((security_stream_t *, const void *, size_t)); */
+/* int security_stream_write(security_stream_t *, const void *, size_t); */
#define security_stream_write(stream, buf, size) \
(*(stream)->driver->stream_write)(stream, buf, size)
-/* void security_stream_read P((security_stream_t *,
- void (*)(void *, void *, size_t), void *)); */
+/* void security_stream_read(security_stream_t *,
+ void (*)(void *, void *, size_t), void *); */
#define security_stream_read(stream, fn, arg) \
(*(stream)->driver->stream_read)(stream, fn, arg)
-/* void security_stream_read_cancel P((security_stream_t *)); */
+/* void security_stream_read_sync(security_stream_t *, void *); */
+#define security_stream_read_sync(stream, buf) \
+ (*(stream)->driver->stream_read_sync)(stream, buf)
+
+/* void security_stream_read_cancel(security_stream_t *); */
#define security_stream_read_cancel(stream) \
(*(stream)->driver->stream_read_cancel)(stream)
+#define security_close_connection(handle, hostname) \
+ (*(handle)->driver->close_connection)(handle, hostname)
#endif /* SECURITY_H */
* University of Maryland at College Park
*/
/*
- * $Id: sl.c,v 1.5 2005/09/30 19:01:43 martinea Exp $
+ * $Id: sl.c,v 1.6 2006/05/25 01:47:12 johnfranks Exp $
*
* A doubly linked list of string (char *)
*/
#include "sl.h"
-void init_sl(sl)
-sl_t *sl;
+void init_sl(
+ sl_t *sl)
{
sl->first = NULL;
sl->last = NULL;
}
-sl_t *new_sl() {
+sl_t *
+new_sl(void)
+{
sl_t *sl;
- sl = alloc(sizeof(sl_t));
+ sl = alloc(SIZEOF(sl_t));
init_sl(sl);
return(sl);
}
-sl_t *insert_sl(sl, name)
-sl_t *sl;
-char *name;
+sl_t *
+insert_sl(
+ sl_t *sl,
+ char *name)
{
sle_t *a;
if(!sl) {
sl = new_sl();
}
- a = alloc(sizeof(sle_t));
+ a = alloc(SIZEOF(sle_t));
a->name = stralloc(name);
a->next = sl->first;
a->prev = NULL;
}
-sl_t *append_sl(sl, name)
-sl_t *sl;
-char *name;
+sl_t *
+append_sl(
+ sl_t * sl,
+ char * name)
{
sle_t *a;
if(!sl) {
sl = new_sl();
}
- a = alloc(sizeof(sle_t));
+ a = alloc(SIZEOF(sle_t));
a->name = stralloc(name);
a->prev = sl->last;
a->next = NULL;
}
-sl_t *insert_sort_sl(sl, name)
-sl_t *sl;
-char *name;
+sl_t *
+insert_sort_sl(
+ sl_t * sl,
+ char * name)
{
sle_t *a, *b;
if(b == sl->first) return insert_sl(sl, name);
if(b == NULL) return append_sl(sl, name);
- a = alloc(sizeof(sle_t));
+ a = alloc(SIZEOF(sle_t));
a->name = stralloc(name);
/* insert before b */
}
-void free_sl(sl)
-sl_t *sl;
+void
+free_sl(
+ sl_t * sl)
{
sle_t *a, *b;
}
-void remove_sl(sl, elem)
-sl_t *sl;
-sle_t *elem;
+void
+remove_sl(
+ sl_t * sl,
+ sle_t * elem)
{
if(elem->prev)
elem->prev->next = elem->next;
}
-sl_t *duplicate_sl(sl)
-sl_t *sl;
+sl_t *
+duplicate_sl(
+ sl_t * sl)
{
sl_t *new_sl = NULL;
sle_t *a;
/*
* Return "true" iff sl is empty (i.e. contains no elements).
*/
-int is_empty_sl(sl)
-sl_t *sl;
+int
+is_empty_sl(
+ sl_t * sl)
{
if (sl == NULL)
return 1;
* University of Maryland at College Park
*/
/*
- * $Id: sl.h,v 1.3 2004/04/23 11:44:46 martinea Exp $
+ * $Id: sl.h,v 1.4 2006/05/25 01:47:12 johnfranks Exp $
*
* A doubly linked list of string (char *)
*/
int nb_element;
} sl_t;
-void init_sl P((sl_t *sl));
-sl_t *new_sl P(());
-sl_t *insert_sl P((sl_t *sl, char *name));
-sl_t *append_sl P((sl_t *sl, char *name));
-sl_t *insert_sort_sl P((sl_t *sl, char *name));
-void free_sl P((sl_t *sl));
-void remove_sl P((sl_t *sl,sle_t *elem));
-sl_t *duplicate_sl P((sl_t *sl));
-int is_empty_sl P((sl_t *sl));
+void init_sl(sl_t *sl);
+sl_t *new_sl(void);
+sl_t *insert_sl(sl_t *sl, char *name);
+sl_t *append_sl(sl_t *sl, char *name);
+sl_t *insert_sort_sl(sl_t *sl, char *name);
+void free_sl(sl_t *sl);
+void remove_sl(sl_t *sl,sle_t *elem);
+sl_t *duplicate_sl(sl_t *sl);
+int is_empty_sl(sl_t *sl);
#endif
*/
/*
- * $Id: ssh-security.c,v 1.8.2.1 2006/04/11 11:11:16 martinea Exp $
+ * $Id: ssh-security.c,v 1.23 2006/08/21 20:17:10 martinea Exp $
*
* ssh-security.c - security and transport over ssh or a ssh-like command.
*
*/
#include "amanda.h"
+#include "util.h"
#include "event.h"
#include "packet.h"
#include "queue.h"
#include "security.h"
+#include "security-util.h"
#include "stream.h"
#include "version.h"
/*#define SSH_DEBUG*/
#ifdef SSH_DEBUG
-#define sshprintf(x) dbprintf(x)
+int ssh_debug = 1;
#else
-#define sshprintf(x)
+int ssh_debug = 0;
#endif
+#define sshprintf(x) \
+ do { \
+ if (ssh_debug) { \
+ dbprintf(x); \
+ } \
+ } while (0)
+
/*
* Path to the ssh binary. This should be configurable.
*/
/*
* Arguments to ssh. This should also be configurable
*/
-#define SSH_ARGS "-x", "-l", CLIENT_LOGIN
+#define SSH_ARGS "-x", "-o", "BatchMode=yes", "-o", "PreferredAuthentications=publickey"
/*
* Number of seconds ssh has to start up
#define H_TAKEN -1 /* ssh_conn->tok was already read */
#define H_EOF -2 /* this connection has been shut down */
-/*
- * This is a ssh connection to a host. We should only have
- * one connection per host.
- */
-struct ssh_conn {
- int read, write; /* pipes to ssh */
- pid_t pid; /* pid of ssh process */
- char pkt[NETWORK_BLOCK_BYTES]; /* last pkt read */
- unsigned long pktlen; /* len of above */
- struct { /* buffer read() calls */
- char buf[STREAM_BUFSIZE]; /* buffer */
- size_t left; /* unread data */
- ssize_t size; /* size of last read */
- } readbuf;
- event_handle_t *ev_read; /* read (EV_READFD) handle */
- int ev_read_refcnt; /* number of readers */
- char hostname[MAX_HOSTNAME_LENGTH+1]; /* host we're talking to */
- char *errmsg; /* error passed up */
- int refcnt; /* number of handles using */
- int handle; /* last proto handle read */
- TAILQ_ENTRY(ssh_conn) tq; /* queue handle */
-};
-
-
-struct ssh_stream;
-
-/*
- * This is the private handle data.
- */
-struct ssh_handle {
- security_handle_t sech; /* MUST be first */
- char *hostname; /* ptr to rc->hostname */
- struct ssh_stream *rs; /* virtual stream we xmit over */
-
- union {
- void (*recvpkt) P((void *, pkt_t *, security_status_t));
- /* func to call when packet recvd */
- void (*connect) P((void *, security_handle_t *, security_status_t));
- /* func to call when connected */
- } fn;
- void *arg; /* argument to pass function */
- event_handle_t *ev_timeout; /* timeout handle for recv */
-};
-
-/*
- * This is the internal security_stream data for ssh.
- */
-struct ssh_stream {
- security_stream_t secstr; /* MUST be first */
- struct ssh_conn *rc; /* physical connection */
- int handle; /* protocol handle */
- event_handle_t *ev_read; /* read (EV_WAIT) event handle */
- void (*fn) P((void *, void *, ssize_t)); /* read event fn */
- void *arg; /* arg for previous */
-};
-
/*
* Interface functions
*/
-static int ssh_sendpkt P((void *, pkt_t *));
-static int ssh_stream_accept P((void *));
-static int ssh_stream_auth P((void *));
-static int ssh_stream_id P((void *));
-static int ssh_stream_write P((void *, const void *, size_t));
-static void *ssh_stream_client P((void *, int));
-static void *ssh_stream_server P((void *));
-static void ssh_accept P((int, int,
- void (*)(security_handle_t *, pkt_t *)));
-static void ssh_close P((void *));
-static void ssh_connect P((const char *,
- char *(*)(char *, void *),
- void (*)(void *, security_handle_t *, security_status_t), void *));
-static void ssh_recvpkt P((void *,
- void (*)(void *, pkt_t *, security_status_t), void *, int));
-static void ssh_recvpkt_cancel P((void *));
-static void ssh_stream_close P((void *));
-static void ssh_stream_read P((void *, void (*)(void *, void *, ssize_t),
- void *));
-static void ssh_stream_read_cancel P((void *));
+static void ssh_connect(const char *, char *(*)(char *, void *),
+ void (*)(void *, security_handle_t *, security_status_t),
+ void *, void *);
/*
* This is our interface to the outside world.
const security_driver_t ssh_security_driver = {
"SSH",
ssh_connect,
- ssh_accept,
- ssh_close,
- ssh_sendpkt,
- ssh_recvpkt,
- ssh_recvpkt_cancel,
- ssh_stream_server,
- ssh_stream_accept,
- ssh_stream_client,
- ssh_stream_close,
- ssh_stream_auth,
- ssh_stream_id,
- ssh_stream_write,
- ssh_stream_read,
- ssh_stream_read_cancel,
-};
-
-/*
- * This is a queue of open connections
- */
-static struct {
- TAILQ_HEAD(, ssh_conn) tailq;
- int qlength;
-} connq = {
- TAILQ_HEAD_INITIALIZER(connq.tailq), 0
+ sec_accept,
+ sec_close,
+ stream_sendpkt,
+ stream_recvpkt,
+ stream_recvpkt_cancel,
+ tcpma_stream_server,
+ tcpma_stream_accept,
+ tcpma_stream_client,
+ tcpma_stream_close,
+ sec_stream_auth,
+ sec_stream_id,
+ tcpm_stream_write,
+ tcpm_stream_read,
+ tcpm_stream_read_sync,
+ tcpm_stream_read_cancel,
+ tcpm_close_connection,
};
-#define connq_first() TAILQ_FIRST(&connq.tailq)
-#define connq_next(rc) TAILQ_NEXT(rc, tq)
-#define connq_append(rc) do { \
- TAILQ_INSERT_TAIL(&connq.tailq, rc, tq); \
- connq.qlength++; \
-} while (0)
-#define connq_remove(rc) do { \
- assert(connq.qlength > 0); \
- TAILQ_REMOVE(&connq.tailq, rc, tq); \
- connq.qlength--; \
-} while (0)
static int newhandle = 1;
-/*
- * This is a function that should be called if a new security_handle_t is
- * created. If NULL, no new handles are created.
- * It is passed the new handle and the received pkt
- */
-static void (*accept_fn) P((security_handle_t *, pkt_t *));
-
/*
* Local functions
*/
-static void connect_callback P((void *));
-static void connect_timeout P((void *));
-static int send_token P((struct ssh_conn *, int, const void *, size_t));
-static int recv_token P((struct ssh_conn *, int));
-static void recvpkt_callback P((void *, void *, ssize_t));
-static void recvpkt_timeout P((void *));
-static void stream_read_callback P((void *));
-
-static int runssh P((struct ssh_conn *));
-static struct ssh_conn *conn_get P((const char *));
-static void conn_put P((struct ssh_conn *));
-static void conn_read P((struct ssh_conn *));
-static void conn_read_cancel P((struct ssh_conn *));
-static void conn_read_callback P((void *));
-static int net_writev P((int, struct iovec *, int));
-static ssize_t net_read P((struct ssh_conn *, void *, size_t, int));
-static int net_read_fillbuf P((struct ssh_conn *, int, int));
-static void parse_pkt P((pkt_t *, const void *, size_t));
-
+static int runssh(struct tcp_conn *, const char *, const char *, const char *);
/*
* ssh version of a security handle allocator. Logically sets
* up a network "connection".
*/
static void
-ssh_connect(hostname, conf_fn, fn, arg)
- const char *hostname;
- char *(*conf_fn) P((char *, void *));
- void (*fn) P((void *, security_handle_t *, security_status_t));
- void *arg;
-{
- struct ssh_handle *rh;
+ssh_connect(
+ const char * hostname,
+ char * (*conf_fn)(char *, void *),
+ void (*fn)(void *, security_handle_t *, security_status_t),
+ void * arg,
+ void * datap)
+{
+ struct sec_handle *rh;
struct hostent *he;
+ char *amandad_path=NULL, *client_username=NULL, *ssh_keys=NULL;
assert(fn != NULL);
assert(hostname != NULL);
- sshprintf(("%s: ssh: ssh_connect: %s\n", debug_prefix_time(NULL), hostname));
+ (void)conf_fn; /* Quiet unused parameter warning */
+
+ sshprintf(("%s: ssh: ssh_connect: %s\n", debug_prefix_time(NULL),
+ hostname));
- rh = alloc(sizeof(*rh));
+ rh = alloc(SIZEOF(*rh));
security_handleinit(&rh->sech, &ssh_security_driver);
rh->hostname = NULL;
rh->rs = NULL;
rh->ev_timeout = NULL;
+ rh->rc = NULL;
if ((he = gethostbyname(hostname)) == NULL) {
security_seterror(&rh->sech,
- "%s: could not resolve hostname", hostname);
+ "%s: ssh could not resolve hostname", hostname);
(*fn)(arg, &rh->sech, S_ERROR);
return;
}
- rh->hostname = he->h_name; /* will be replaced */
- rh->rs = ssh_stream_client(rh, newhandle++);
+ rh->hostname = stralloc(he->h_name); /* will be replaced */
+ rh->rs = tcpma_stream_client(rh, newhandle++);
if (rh->rs == NULL)
goto error;
- rh->hostname = rh->rs->rc->hostname;
+ amfree(rh->hostname);
+ rh->hostname = stralloc(rh->rs->rc->hostname);
- if (rh->rs->rc->pid < 0) {
- /*
- * We need to open a new connection.
- *
- * XXX need to eventually limit number of outgoing connections here.
- */
- if (runssh(rh->rs->rc) < 0) {
- security_seterror(&rh->sech,
- "can't connect to %s: %s", hostname, rh->rs->rc->errmsg);
+ /*
+ * We need to open a new connection.
+ *
+ * XXX need to eventually limit number of outgoing connections here.
+ */
+ if(conf_fn) {
+ amandad_path = conf_fn("amandad_path", datap);
+ client_username = conf_fn("client_username", datap);
+ ssh_keys = conf_fn("ssh_keys", datap);
+ }
+ if(rh->rc->read == -1) {
+ if (runssh(rh->rs->rc, amandad_path, client_username, ssh_keys) < 0) {
+ security_seterror(&rh->sech, "can't connect to %s: %s",
+ hostname, rh->rs->rc->errmsg);
goto error;
}
+ rh->rc->refcnt++;
}
+
/*
* The socket will be opened async so hosts that are down won't
* block everything. We need to register a write event
*/
rh->fn.connect = fn;
rh->arg = arg;
- rh->rs->ev_read = event_register(rh->rs->rc->write, EV_WRITEFD,
- connect_callback, rh);
- rh->ev_timeout = event_register(CONNECT_TIMEOUT, EV_TIME,
- connect_timeout, rh);
+ rh->rs->ev_read = event_register((event_id_t)rh->rs->rc->write, EV_WRITEFD,
+ sec_connect_callback, rh);
+ rh->ev_timeout = event_register((event_id_t)CONNECT_TIMEOUT, EV_TIME,
+ sec_connect_timeout, rh);
return;
(*fn)(arg, &rh->sech, S_ERROR);
}
-/*
- * Called when a ssh connection is finished connecting and is ready
- * to be authenticated.
- */
-static void
-connect_callback(cookie)
- void *cookie;
-{
- struct ssh_handle *rh = cookie;
-
- event_release(rh->rs->ev_read);
- rh->rs->ev_read = NULL;
- event_release(rh->ev_timeout);
- rh->ev_timeout = NULL;
-
- (*rh->fn.connect)(rh->arg, &rh->sech, S_OK);
-}
-
-/*
- * Called if a connection times out before completion.
- */
-static void
-connect_timeout(cookie)
- void *cookie;
-{
- struct ssh_handle *rh = cookie;
-
- event_release(rh->rs->ev_read);
- rh->rs->ev_read = NULL;
- event_release(rh->ev_timeout);
- rh->ev_timeout = NULL;
-
- (*rh->fn.connect)(rh->arg, &rh->sech, S_TIMEOUT);
-}
-
-/*
- * Setup to handle new incoming connections
- */
-static void
-ssh_accept(in, out, fn)
- int in, out;
- void (*fn) P((security_handle_t *, pkt_t *));
-{
- struct ssh_conn *rc;
-
- rc = conn_get("unknown");
- rc->read = in;
- rc->write = out;
- accept_fn = fn;
- conn_read(rc);
-}
-
-/*
- * Locate an existing connection to the given host, or create a new,
- * unconnected entry if none exists. The caller is expected to check
- * for the lack of a connection (rc->read == -1) and set one up.
- */
-static struct ssh_conn *
-conn_get(hostname)
- const char *hostname;
-{
- struct ssh_conn *rc;
-
- sshprintf(("%s: ssh: conn_get: %s\n", debug_prefix_time(NULL), hostname));
-
- for (rc = connq_first(); rc != NULL; rc = connq_next(rc)) {
- if (strcasecmp(hostname, rc->hostname) == 0)
- break;
- }
-
- if (rc != NULL) {
- rc->refcnt++;
- sshprintf(("%s: ssh: conn_get: exists, refcnt to %s is now %d\n", debug_prefix_time(NULL),
- rc->hostname, rc->refcnt));
- return (rc);
- }
-
- sshprintf(("%s: ssh: conn_get: creating new handle\n", debug_prefix_time(NULL)));
- /*
- * We can't be creating a new handle if we are the client
- */
- assert(accept_fn == NULL);
- rc = alloc(sizeof(*rc));
- rc->read = rc->write = -1;
- rc->pid = -1;
- rc->readbuf.left = 0;
- rc->readbuf.size = 0;
- rc->ev_read = NULL;
- strncpy(rc->hostname, hostname, sizeof(rc->hostname) - 1);
- rc->hostname[sizeof(rc->hostname) - 1] = '\0';
- rc->errmsg = NULL;
- rc->refcnt = 1;
- rc->handle = -1;
- connq_append(rc);
- return (rc);
-}
-
-/*
- * Delete a reference to a connection, and close it if it is the last
- * reference.
- */
-static void
-conn_put(rc)
- struct ssh_conn *rc;
-{
- amwait_t status;
-
- assert(rc->refcnt > 0);
- --rc->refcnt;
- sshprintf(("%s: ssh: conn_put: decrementing refcnt for %s to %d\n", debug_prefix_time(NULL),
- rc->hostname, rc->refcnt));
- if (rc->refcnt > 0) {
- return;
- }
- sshprintf(("%s: ssh: conn_put: closing connection to %s\n", debug_prefix_time(NULL), rc->hostname));
- if (rc->read != -1)
- aclose(rc->read);
- if (rc->write != -1)
- aclose(rc->write);
- if (rc->pid != -1) {
- waitpid(rc->pid, &status, WNOHANG);
- }
- if (rc->ev_read != NULL)
- event_release(rc->ev_read);
- if (rc->errmsg != NULL)
- amfree(rc->errmsg);
- connq_remove(rc);
- amfree(rc);
-}
-
-/*
- * Turn on read events for a conn. Or, increase a ev_read_refcnt if we are
- * already receiving read events.
- */
-static void
-conn_read(rc)
- struct ssh_conn *rc;
-{
-
- if (rc->ev_read != NULL) {
- rc->ev_read_refcnt++;
- sshprintf(("%s: ssh: conn_read: incremented ev_read_refcnt to %d for %s\n", debug_prefix_time(NULL),
- rc->ev_read_refcnt, rc->hostname));
- return;
- }
- sshprintf(("%s: ssh: conn_read registering event handler for %s\n", debug_prefix_time(NULL),
- rc->hostname));
- rc->ev_read = event_register(rc->read, EV_READFD, conn_read_callback, rc);
- rc->ev_read_refcnt = 1;
-}
-
-static void
-conn_read_cancel(rc)
- struct ssh_conn *rc;
-{
-
- --rc->ev_read_refcnt;
- sshprintf(("%s: ssh: conn_read_cancel: decremented ev_read_refcnt to %d for %s\n", debug_prefix_time(NULL),
- rc->ev_read_refcnt, rc->hostname));
- if(rc->ev_read_refcnt > 0) {
- return;
- }
- sshprintf(("%s: ssh: conn_read_cancel: releasing event handler for %s\n", debug_prefix_time(NULL),
- rc->hostname));
- event_release(rc->ev_read);
- rc->ev_read = NULL;
-}
-
-/*
- * frees a handle allocated by the above
- */
-static void
-ssh_close(inst)
- void *inst;
-{
- struct ssh_handle *rh = inst;
-
- assert(rh != NULL);
-
- sshprintf(("%s: ssh: closing handle to %s\n", debug_prefix_time(NULL), rh->hostname));
-
- if (rh->rs != NULL) {
- /* This may be null if we get here on an error */
- ssh_recvpkt_cancel(rh);
- security_stream_close(&rh->rs->secstr);
- }
- /* keep us from getting here again */
- rh->sech.driver = NULL;
- amfree(rh);
-}
-
/*
* Forks a ssh to the host listed in rc->hostname
* Returns negative on error, with an errmsg in rc->errmsg.
*/
static int
-runssh(rc)
- struct ssh_conn *rc;
+runssh(
+ struct tcp_conn * rc,
+ const char * amandad_path,
+ const char * client_username,
+ const char * ssh_keys)
{
int rpipe[2], wpipe[2];
- char *amandad_path;
+ char *xamandad_path = (char *)amandad_path;
+ char *xclient_username = (char *)client_username;
+ char *xssh_keys = (char *)ssh_keys;
+ memset(rpipe, -1, SIZEOF(rpipe));
+ memset(wpipe, -1, SIZEOF(wpipe));
if (pipe(rpipe) < 0 || pipe(wpipe) < 0) {
- rc->errmsg = newvstralloc("pipe: ", strerror(errno), NULL);
+ rc->errmsg = newvstralloc(rc->errmsg, "pipe: ", strerror(errno), NULL);
return (-1);
}
+
switch (rc->pid = fork()) {
case -1:
- rc->errmsg = newvstralloc("fork: ", strerror(errno), NULL);
+ rc->errmsg = newvstralloc(rc->errmsg, "fork: ", strerror(errno), NULL);
aclose(rpipe[0]);
aclose(rpipe[1]);
aclose(wpipe[0]);
case 0:
dup2(wpipe[0], 0);
dup2(rpipe[1], 1);
- dup2(rpipe[1], 2);
break;
default:
rc->read = rpipe[0];
safe_fd(-1, 0);
- amandad_path = vstralloc(libexecdir, "/", "amandad", versionsuffix(),
- NULL);
- execlp(SSH_PATH, SSH_PATH, SSH_ARGS, rc->hostname, amandad_path,
- "-auth=ssh", NULL);
- error("error: couldn't exec %s: %s", SSH_PATH, strerror(errno));
-
- /* should nerver go here, shut up compiler warning */
- return(-1);
-}
-
-/*
- * Transmit a packet.
- */
-static int
-ssh_sendpkt(cookie, pkt)
- void *cookie;
- pkt_t *pkt;
-{
- char buf[sizeof(pkt_t)];
- struct ssh_handle *rh = cookie;
- size_t len;
-
- assert(rh != NULL);
- assert(pkt != NULL);
-
- sshprintf(("%s: ssh: sendpkt: enter\n", debug_prefix_time(NULL)));
-
- len = strlen(pkt->body) + 2;
- buf[0] = (char)pkt->type;
- strcpy(&buf[1], pkt->body);
-
- sshprintf(("%s: ssh: sendpkt: %s (%d) pkt_t (len %d) contains:\n\n\"%s\"\n\n", debug_prefix_time(NULL),
- pkt_type2str(pkt->type), pkt->type, strlen(pkt->body), pkt->body));
-
- if (ssh_stream_write(rh->rs, buf, len) < 0) {
- security_seterror(&rh->sech, security_stream_geterror(&rh->rs->secstr));
- return (-1);
- }
- return (0);
-}
-
-/*
- * Set up to receive a packet asyncronously, and call back when
- * it has been read.
- */
-static void
-ssh_recvpkt(cookie, fn, arg, timeout)
- void *cookie, *arg;
- void (*fn) P((void *, pkt_t *, security_status_t));
- int timeout;
-{
- struct ssh_handle *rh = cookie;
-
- assert(rh != NULL);
-
- sshprintf(("%s: ssh: recvpkt registered for %s\n", debug_prefix_time(NULL), rh->hostname));
-
- /*
- * Reset any pending timeout on this handle
- */
- if (rh->ev_timeout != NULL)
- event_release(rh->ev_timeout);
-
- /*
- * Negative timeouts mean no timeout
- */
- if (timeout < 0)
- rh->ev_timeout = NULL;
- else
- rh->ev_timeout = event_register(timeout, EV_TIME, recvpkt_timeout, rh);
-
- rh->fn.recvpkt = fn;
- rh->arg = arg;
- ssh_stream_read(rh->rs, recvpkt_callback, rh);
-}
-
-/*
- * Remove a async receive request from the queue
- */
-static void
-ssh_recvpkt_cancel(cookie)
- void *cookie;
-{
- struct ssh_handle *rh = cookie;
-
- sshprintf(("%s: ssh: cancelling recvpkt for %s\n", debug_prefix_time(NULL), rh->hostname));
-
- assert(rh != NULL);
-
- ssh_stream_read_cancel(rh->rs);
- if (rh->ev_timeout != NULL) {
- event_release(rh->ev_timeout);
- rh->ev_timeout = NULL;
- }
-}
-
-/*
- * This is called when a handle is woken up because data read off of the
- * net is for it.
- */
-static void
-recvpkt_callback(cookie, buf, bufsize)
- void *cookie, *buf;
- ssize_t bufsize;
-{
- pkt_t pkt;
- struct ssh_handle *rh = cookie;
-
- assert(rh != NULL);
-
- /*
- * We need to cancel the recvpkt request before calling
- * the callback because the callback may reschedule us.
- */
- ssh_recvpkt_cancel(rh);
-
- switch (bufsize) {
- case 0:
- security_seterror(&rh->sech,
- "EOF on read from %s", rh->hostname);
- (*rh->fn.recvpkt)(rh->arg, NULL, S_ERROR);
- return;
- case -1:
- security_seterror(&rh->sech, security_stream_geterror(&rh->rs->secstr));
- (*rh->fn.recvpkt)(rh->arg, NULL, S_ERROR);
- return;
- default:
- break;
- }
-
- parse_pkt(&pkt, buf, bufsize);
- sshprintf(("%s: ssh: received %s packet (%d) from %s, contains:\n\n\"%s\"\n\n", debug_prefix_time(NULL),
- pkt_type2str(pkt.type), pkt.type, rh->hostname, pkt.body));
- (*rh->fn.recvpkt)(rh->arg, &pkt, S_OK);
-}
-
-/*
- * This is called when a handle times out before receiving a packet.
- */
-static void
-recvpkt_timeout(cookie)
- void *cookie;
-{
- struct ssh_handle *rh = cookie;
-
- assert(rh != NULL);
-
- sshprintf(("%s: ssh: recvpkt timeout for %s\n", debug_prefix_time(NULL), rh->hostname));
-
- ssh_recvpkt_cancel(rh);
- (*rh->fn.recvpkt)(rh->arg, NULL, S_TIMEOUT);
-}
-
-/*
- * Create the server end of a stream. For ssh, this means setup a stream
- * object and allocate a new handle for it.
- */
-static void *
-ssh_stream_server(h)
- void *h;
-{
- struct ssh_handle *rh = h;
- struct ssh_stream *rs;
-
- assert(rh != NULL);
-
- rs = alloc(sizeof(*rs));
- security_streaminit(&rs->secstr, &ssh_security_driver);
- rs->rc = conn_get(rh->hostname);
- /*
- * Stream should already be setup!
- */
- if (rs->rc->read < 0) {
- conn_put(rs->rc);
- amfree(rs);
- security_seterror(&rh->sech, "lost connection to %s", rh->hostname);
- return (NULL);
- }
- rh->hostname = rs->rc->hostname;
- /*
- * so as not to conflict with the amanda server's handle numbers,
- * we start at 5000 and work down
- */
- rs->handle = 5000 - newhandle++;
- rs->ev_read = NULL;
- sshprintf(("%s: ssh: stream_server: created stream %d\n", debug_prefix_time(NULL), rs->handle));
- return (rs);
-}
-
-/*
- * Accept an incoming connection on a stream_server socket
- * Nothing needed for ssh.
- */
-static int
-ssh_stream_accept(s)
- void *s;
-{
-
- return (0);
-}
-
-/*
- * Return a connected stream. For ssh, this means setup a stream
- * with the supplied handle.
- */
-static void *
-ssh_stream_client(h, id)
- void *h;
- int id;
-{
- struct ssh_handle *rh = h;
- struct ssh_stream *rs;
-
- assert(rh != NULL);
-
- if (id <= 0) {
- security_seterror(&rh->sech,
- "%d: invalid security stream id", id);
- return (NULL);
- }
-
- rs = alloc(sizeof(*rs));
- security_streaminit(&rs->secstr, &ssh_security_driver);
- rs->handle = id;
- rs->ev_read = NULL;
- rs->rc = conn_get(rh->hostname);
-
- sshprintf(("%s: ssh: stream_client: connected to stream %d\n", debug_prefix_time(NULL), id));
-
- return (rs);
-}
-
-/*
- * Close and unallocate resources for a stream.
- */
-static void
-ssh_stream_close(s)
- void *s;
-{
- struct ssh_stream *rs = s;
-
- assert(rs != NULL);
-
- sshprintf(("%s: ssh: stream_close: closing stream %d\n", debug_prefix_time(NULL), rs->handle));
-
- ssh_stream_read_cancel(rs);
- conn_put(rs->rc);
- amfree(rs);
-}
-
-/*
- * Authenticate a stream
- * Nothing needed for ssh. The connection is authenticated by sshd
- * on startup.
- */
-static int
-ssh_stream_auth(s)
- void *s;
-{
-
- return (0);
-}
-
-/*
- * Returns the stream id for this stream. This is just the local
- * port.
- */
-static int
-ssh_stream_id(s)
- void *s;
-{
- struct ssh_stream *rs = s;
-
- assert(rs != NULL);
-
- return (rs->handle);
-}
-
-/*
- * Write a chunk of data to a stream. Blocks until completion.
- */
-static int
-ssh_stream_write(s, buf, size)
- void *s;
- const void *buf;
- size_t size;
-{
- struct ssh_stream *rs = s;
-
- assert(rs != NULL);
-
- sshprintf(("%s: ssh: stream_write: writing %d bytes to %s:%d\n", debug_prefix_time(NULL), size,
- rs->rc->hostname, rs->handle));
-
- if (send_token(rs->rc, rs->handle, buf, size) < 0) {
- security_stream_seterror(&rs->secstr, rs->rc->errmsg);
- return (-1);
- }
- return (0);
-}
-
-/*
- * Submit a request to read some data. Calls back with the given
- * function and arg when completed.
- */
-static void
-ssh_stream_read(s, fn, arg)
- void *s, *arg;
- void (*fn) P((void *, void *, ssize_t));
-{
- struct ssh_stream *rs = s;
-
- assert(rs != NULL);
-
- /*
- * Only one read request can be active per stream.
- */
- if (rs->ev_read == NULL) {
- rs->ev_read = event_register((event_id_t)rs->rc, EV_WAIT,
- stream_read_callback, rs);
- conn_read(rs->rc);
- }
- rs->fn = fn;
- rs->arg = arg;
-}
-
-/*
- * Cancel a previous stream read request. It's ok if we didn't have a read
- * scheduled.
- */
-static void
-ssh_stream_read_cancel(s)
- void *s;
-{
- struct ssh_stream *rs = s;
-
- assert(rs != NULL);
-
- if (rs->ev_read != NULL) {
- event_release(rs->ev_read);
- rs->ev_read = NULL;
- conn_read_cancel(rs->rc);
- }
-}
-
-/*
- * Callback for ssh_stream_read
- */
-static void
-stream_read_callback(arg)
- void *arg;
-{
- struct ssh_stream *rs = arg;
- assert(rs != NULL);
-
- sshprintf(("%s: ssh: stream_read_callback: handle %d\n", debug_prefix_time(NULL), rs->handle));
-
- /*
- * Make sure this was for us. If it was, then blow away the handle
- * so it doesn't get claimed twice. Otherwise, leave it alone.
- *
- * If the handle is EOF, pass that up to our callback.
- */
- if (rs->rc->handle == rs->handle) {
- sshprintf(("%s: ssh: stream_read_callback: it was for us\n", debug_prefix_time(NULL)));
- rs->rc->handle = H_TAKEN;
- } else if (rs->rc->handle != H_EOF) {
- sshprintf(("%s: ssh: stream_read_callback: not for us\n", debug_prefix_time(NULL)));
- return;
- }
-
- /*
- * Remove the event first, and then call the callback.
- * We remove it first because we don't want to get in their
- * way if they reschedule it.
- */
- ssh_stream_read_cancel(rs);
-
- if (rs->rc->pktlen == 0) {
- sshprintf(("%s: ssh: stream_read_callback: EOF\n", debug_prefix_time(NULL)));
- (*rs->fn)(rs->arg, NULL, 0);
- return;
- }
- sshprintf(("%s: ssh: stream_read_callback: read %ld bytes from %s:%d\n", debug_prefix_time(NULL),
- rs->rc->pktlen, rs->rc->hostname, rs->handle));
- (*rs->fn)(rs->arg, rs->rc->pkt, rs->rc->pktlen);
-}
-
-/*
- * The callback for the netfd for the event handler
- * Determines if this packet is for this security handle,
- * and does the real callback if so.
- */
-static void
-conn_read_callback(cookie)
- void *cookie;
-{
- struct ssh_conn *rc = cookie;
- struct ssh_handle *rh;
- pkt_t pkt;
- int rval;
-
- assert(cookie != NULL);
-
- sshprintf(("%s: ssh: conn_read_callback\n",debug_prefix_time(NULL)));
-
- /* Read the data off the wire. If we get errors, shut down. */
- rval = recv_token(rc, 60);
- sshprintf(("%s: ssh: conn_read_callback: recv_token returned %d\n", debug_prefix_time(NULL), rval));
- if (rval <= 0) {
- rc->pktlen = 0;
- rc->handle = H_EOF;
- rval = event_wakeup((event_id_t)rc);
- sshprintf(("%s: ssh: conn_read_callback: event_wakeup return %d\n", debug_prefix_time(NULL), rval));
- /* delete our 'accept' reference */
- if (accept_fn != NULL)
- conn_put(rc);
- accept_fn = NULL;
- return;
- }
-
- /* If there are events waiting on this handle, we're done */
- rval = event_wakeup((event_id_t)rc);
- sshprintf(("%s: ssh: conn_read_callback: event_wakeup return %d\n", debug_prefix_time(NULL), rval));
- if (rval > 0)
- return;
-
- /* If there is no accept fn registered, then drop the packet */
- if (accept_fn == NULL)
- return;
-
- rh = alloc(sizeof(*rh));
- security_handleinit(&rh->sech, &ssh_security_driver);
- rh->hostname = rc->hostname;
- rh->rs = ssh_stream_client(rh, rc->handle);
- rh->ev_timeout = NULL;
-
- sshprintf(("%s: ssh: new connection\n", debug_prefix_time(NULL)));
- parse_pkt(&pkt, rc->pkt, rc->pktlen);
- sshprintf(("%s: ssh: calling accept_fn\n", debug_prefix_time(NULL)));
- (*accept_fn)(&rh->sech, &pkt);
-}
-
-static void
-parse_pkt(pkt, buf, bufsize)
- pkt_t *pkt;
- const void *buf;
- size_t bufsize;
-{
- const unsigned char *bufp = buf;
-
- sshprintf(("%s: ssh: parse_pkt: parsing buffer of %d bytes\n", debug_prefix_time(NULL), bufsize));
-
- pkt->type = (pktype_t)*bufp++;
- bufsize--;
-
- if (bufsize == 0) {
- pkt->body[0] = '\0';
- } else {
- if (bufsize > sizeof(pkt->body) - 1)
- bufsize = sizeof(pkt->body) - 1;
- memcpy(pkt->body, bufp, bufsize);
- pkt->body[sizeof(pkt->body) - 1] = '\0';
- }
-
- sshprintf(("%s: ssh: parse_pkt: %s (%d): \"%s\"\n", debug_prefix_time(NULL), pkt_type2str(pkt->type),
- pkt->type, pkt->body));
-}
-
-
-/*
- * Transmits a chunk of data over a ssh_handle, adding
- * the necessary headers to allow the remote end to decode it.
- */
-static int
-send_token(rc, handle, buf, len)
- struct ssh_conn *rc;
- int handle;
- const void *buf;
- size_t len;
-{
- unsigned int netlength, nethandle;
- struct iovec iov[3];
-
- sshprintf(("%s: ssh: send_token: handle %d writing %d bytes to %s\n", debug_prefix_time(NULL), handle, len,
- rc->hostname));
-
- assert(sizeof(netlength) == 4);
-
- /*
- * Format is:
- * 32 bit length (network byte order)
- * 32 bit handle (network byte order)
- * data
- */
- netlength = htonl(len);
- iov[0].iov_base = (void *)&netlength;
- iov[0].iov_len = sizeof(netlength);
-
- nethandle = htonl(handle);
- iov[1].iov_base = (void *)&nethandle;
- iov[1].iov_len = sizeof(nethandle);
-
- iov[2].iov_base = (void *)buf;
- iov[2].iov_len = len;
-
- if (net_writev(rc->write, iov, 3) < 0) {
- rc->errmsg = newvstralloc(rc->errmsg, "ssh write error to ",
- rc->hostname, ": ", strerror(errno), NULL);
- return (-1);
+ if(!xamandad_path || strlen(xamandad_path) <= 1)
+ xamandad_path = vstralloc(libexecdir, "/", "amandad",
+ versionsuffix(), NULL);
+ if(!xclient_username || strlen(xclient_username) <= 1)
+ xclient_username = CLIENT_LOGIN;
+ if(!ssh_keys || strlen(ssh_keys) <= 1) {
+ execlp(SSH_PATH, SSH_PATH, SSH_ARGS, "-l", xclient_username,
+ rc->hostname, xamandad_path, "-auth=ssh", "amdump", "amindexd",
+ "amidxtaped", (char *)NULL);
}
- return (0);
-}
-
-static int
-recv_token(rc, timeout)
- struct ssh_conn *rc;
- int timeout;
-{
- unsigned int netint;
-
- assert(sizeof(netint) == 4);
-
- assert(rc->read >= 0);
-
- sshprintf(("%s: ssh: recv_token: reading from %s\n", debug_prefix_time(NULL), rc->hostname));
-
- switch (net_read(rc, &netint, sizeof(netint), timeout)) {
- case -1:
- rc->errmsg = newvstralloc(rc->errmsg, "recv error: ", strerror(errno),
- NULL);
- sshprintf(("%s: ssh: recv_token: A return(-1)\n", debug_prefix_time(NULL)));
- return (-1);
- case 0:
- rc->pktlen = 0;
- sshprintf(("%s: ssh: recv_token: A return(0)\n", debug_prefix_time(NULL)));
- return (0);
- default:
- break;
+ else {
+ execlp(SSH_PATH, SSH_PATH, SSH_ARGS, "-l", xclient_username,
+ "-i", xssh_keys, rc->hostname, xamandad_path, "-auth=ssh",
+ "amdump", "amindexd", "amidxtaped", (char *)NULL);
}
- rc->pktlen = ntohl(netint);
- if (rc->pktlen > sizeof(rc->pkt)) {
- rc->errmsg = newstralloc(rc->errmsg, "recv error: huge packet");
- sshprintf(("%s: ssh: recv_token: B return(-1)\n", debug_prefix_time(NULL)));
- return (-1);
- }
-
- switch (net_read(rc, &netint, sizeof(netint), timeout)) {
- case -1:
- rc->errmsg = newvstralloc(rc->errmsg, "recv error: ", strerror(errno),
- NULL);
- sshprintf(("%s: ssh: recv_token: C return(-1)\n", debug_prefix_time(NULL)));
- return (-1);
- case 0:
- rc->pktlen = 0;
- sshprintf(("%s: ssh: recv_token: D return(0)\n", debug_prefix_time(NULL)));
- return (0);
- default:
- break;
- }
- rc->handle = ntohl(netint);
-
- switch (net_read(rc, rc->pkt, rc->pktlen, timeout)) {
- case -1:
- rc->errmsg = newvstralloc(rc->errmsg, "recv error: ", strerror(errno),
- NULL);
- sshprintf(("%s: ssh: recv_token: E return(-1)\n", debug_prefix_time(NULL)));
- return (-1);
- case 0:
- rc->pktlen = 0;
- break;
- default:
- break;
- }
-
- sshprintf(("%s: ssh: recv_token: read %ld bytes from %s\n", debug_prefix_time(NULL), rc->pktlen,
- rc->hostname));
- sshprintf(("%s: ssh: recv_token: end %d\n", debug_prefix_time(NULL),rc->pktlen));
- return (rc->pktlen);
-}
-
-/*
- * Writes out the entire iovec
- */
-static int
-net_writev(fd, iov, iovcnt)
- int fd, iovcnt;
- struct iovec *iov;
-{
- int delta, n, total;
-
- assert(iov != NULL);
-
- total = 0;
- while (iovcnt > 0) {
- /*
- * Write the iovec
- */
- total += n = writev(fd, iov, iovcnt);
- if (n < 0)
- return (-1);
- if (n == 0) {
- errno = EIO;
- return (-1);
- }
- /*
- * Iterate through each iov. Figure out what we still need
- * to write out.
- */
- for (; n > 0; iovcnt--, iov++) {
- /* 'delta' is the bytes written from this iovec */
- delta = n < iov->iov_len ? n : iov->iov_len;
- /* subtract from the total num bytes written */
- n -= delta;
- assert(n >= 0);
- /* subtract from this iovec */
- iov->iov_len -= delta;
- iov->iov_base = (char *)iov->iov_base + delta;
- /* if this iovec isn't empty, run the writev again */
- if (iov->iov_len > 0)
- break;
- }
- }
- return (total);
-}
-
-/*
- * Like read(), but waits until the entire buffer has been filled.
- */
-static ssize_t
-net_read(rc, vbuf, origsize, timeout)
- struct ssh_conn *rc;
- void *vbuf;
- size_t origsize;
- int timeout;
-{
- char *buf = vbuf, *off; /* ptr arith */
- int nread;
- size_t size = origsize;
-
- sshprintf(("%s: ssh: net_read: begin %d\n", debug_prefix_time(NULL), origsize));
- while (size > 0) {
- sshprintf(("%s: ssh: net_read: while %d\n", debug_prefix_time(NULL), size));
- if (rc->readbuf.left == 0) {
- if (net_read_fillbuf(rc, timeout, size) < 0) {
- sshprintf(("%s: ssh: net_read: end retrun(-1)\n", debug_prefix_time(NULL)));
- return (-1);
- }
- if (rc->readbuf.size == 0) {
- sshprintf(("%s: ssh: net_read: end retrun(0)\n", debug_prefix_time(NULL)));
- return (0);
- }
- }
- nread = min(rc->readbuf.left, size);
- off = rc->readbuf.buf + rc->readbuf.size - rc->readbuf.left;
- memcpy(buf, off, nread);
-
- buf += nread;
- size -= nread;
- rc->readbuf.left -= nread;
- }
- sshprintf(("%s: ssh: net_read: end %d\n", debug_prefix_time(NULL), origsize));
- return ((ssize_t)origsize);
-}
-
-/*
- * net_read likes to do a lot of little reads. Buffer it.
- */
-static int
-net_read_fillbuf(rc, timeout, size)
- struct ssh_conn *rc;
- int timeout;
- int size;
-{
- fd_set readfds;
- struct timeval tv;
- if(size > sizeof(rc->readbuf.buf)) size = sizeof(rc->readbuf.buf);
+ error("error: couldn't exec %s: %s", SSH_PATH, strerror(errno));
- sshprintf(("%s: ssh: net_read_fillbuf: begin\n", debug_prefix_time(NULL)));
- FD_ZERO(&readfds);
- FD_SET(rc->read, &readfds);
- tv.tv_sec = timeout;
- tv.tv_usec = 0;
- switch (select(rc->read + 1, &readfds, NULL, NULL, &tv)) {
- case 0:
- errno = ETIMEDOUT;
- /* FALLTHROUGH */
- case -1:
- sshprintf(("%s: ssh: net_read_fillbuf: case -1\n", debug_prefix_time(NULL)));
- return (-1);
- case 1:
- sshprintf(("%s: ssh: net_read_fillbuf: case 1\n", debug_prefix_time(NULL)));
- assert(FD_ISSET(rc->read, &readfds));
- break;
- default:
- sshprintf(("%s: ssh: net_read_fillbuf: case default\n", debug_prefix_time(NULL)));
- assert(0);
- break;
- }
- rc->readbuf.left = 0;
- rc->readbuf.size = read(rc->read, rc->readbuf.buf, size);
- if (rc->readbuf.size < 0)
- return (-1);
- rc->readbuf.left = rc->readbuf.size;
- sshprintf(("%s: ssh: net_read_fillbuf: end %d\n", debug_prefix_time(NULL),rc->readbuf.size));
- return (0);
+ /* should never go here, shut up compiler warning */
+ return(-1);
}
#endif /* SSH_SECURITY */
* file named AUTHORS, in the root directory of this distribution.
*/
/*
- * $Id: statfs.c,v 1.13 2005/09/30 19:13:27 martinea Exp $
+ * $Id: statfs.c,v 1.16 2006/08/24 17:05:35 martinea Exp $
*
* a generic statfs-like routine
*/
# define STATFS_FAVAIL(buf) (buf).f_ffree
# define STATFS_FFREE(buf) (buf).f_ffree
# define STATFS_SCALE(buf) (buf).f_bsize
-# define STATFS(path, buffer) statfs(path, &buffer, sizeof(STATFS_STRUCT), 0)
+# define STATFS(path, buffer) statfs(path, &buffer, SIZEOF(STATFS_STRUCT), 0)
# else
# if HAVE_SYS_MOUNT_H
/*
# define STATFS_SCALE(buf) (buf).f_bsize
# define STATFS(path, buffer) statfs(path, &buffer)
# ifdef STATFS_OSF1
-# define STATFS(path, buffer) statfs(path, &buffer, sizeof(STATFS_STRUCT))
+# define STATFS(path, buffer) statfs(path, &buffer, SIZEOF(STATFS_STRUCT))
# endif
# endif
# endif
# endif
#endif
-#define scale(r,s) ( (r) == -1? -1 : (int)((r)*(double)(s)/1024.0) )
-int get_fs_stats(dir, sp)
-char *dir;
-generic_fs_stats_t *sp;
+off_t scale(off_t r, off_t s);
+
+off_t
+scale(
+ off_t r,
+ off_t s)
+{
+ if (r == (off_t)-1)
+ return (off_t)-1;
+ return r*(s/(off_t)1024);
+}
+
+int
+get_fs_stats(
+ char * dir,
+ generic_fs_stats_t *sp)
{
STATFS_STRUCT statbuf;
/* total, avail, free: converted to kbytes, rounded down */
- sp->total = scale(STATFS_TOTAL(statbuf), STATFS_SCALE(statbuf));
- sp->avail = scale(STATFS_AVAIL(statbuf), STATFS_SCALE(statbuf));
- sp->free = scale(STATFS_FREE(statbuf), STATFS_SCALE(statbuf));
+ sp->total = scale((off_t)STATFS_TOTAL(statbuf),
+ (off_t)STATFS_SCALE(statbuf));
+ sp->avail = scale((off_t)STATFS_AVAIL(statbuf),
+ (off_t)STATFS_SCALE(statbuf));
+ sp->free = scale((off_t)STATFS_FREE(statbuf),
+ (off_t)STATFS_SCALE(statbuf));
/* inode stats */
- sp->files = STATFS_FILES(statbuf);
- sp->favail = STATFS_FAVAIL(statbuf);
- sp->ffree = STATFS_FFREE(statbuf);
+ sp->files = (off_t)STATFS_FILES(statbuf);
+ sp->favail = (off_t)STATFS_FAVAIL(statbuf);
+ sp->ffree = (off_t)STATFS_FFREE(statbuf);
return 0;
}
#ifdef TEST
/* ----- test scaffolding ----- */
-int main(argc, argv)
-int argc;
-char **argv;
+int
+main(
+ int argc,
+ char ** argv)
{
generic_fs_stats_t statbuf;
set_pname(argv[0]);
+ dbopen(NULL);
+
if(argc < 2) {
fprintf(stderr, "Usage: %s files ...\n", get_pname());
return 1;
* file named AUTHORS, in the root directory of this distribution.
*/
/*
- * $Id: statfs.h,v 1.3 1998/07/04 00:18:58 oliva Exp $
+ * $Id: statfs.h,v 1.4 2006/05/25 01:47:12 johnfranks Exp $
*
* interface to statfs module
*/
+#ifndef STATFS_H
+#define STATFS_H
+
#include "amanda.h"
typedef struct generic_fs_stats {
- long total; /* total KB in filesystem */
- long avail; /* KB available to non-superuser */
- long free; /* KB free for superuser */
+ off_t total; /* total KB in filesystem */
+ off_t avail; /* KB available to non-superuser */
+ off_t free; /* KB free for superuser */
- long files; /* total # of files in filesystem */
- long favail; /* # files avail for non-superuser */
- long ffree; /* # files free for superuser */
+ off_t files; /* total # of files in filesystem */
+ off_t favail; /* # files avail for non-superuser */
+ off_t ffree; /* # files free for superuser */
} generic_fs_stats_t;
-int get_fs_stats P((char *dir, generic_fs_stats_t *sp));
+int get_fs_stats(char *dir, generic_fs_stats_t *sp);
+
+#endif /* !STATFS_H */
/* Provided by Michael Schmitz <mschmitz@sema.de>; public domain? */
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#if defined(STDC_HEADERS) || defined(HAVE_STRING_H)
-#include <string.h>
-#else
-#include <strings.h>
-#endif
+#include "amanda.h"
/* Compare S1 and S2 ignoring case, returning less than,
equal to or greater than zero if S1 is lexicographically
less than, equal to or greater than S2. */
int
-strcasecmp(s1, s2)
- const char *s1;
- const char *s2;
+strcasecmp(
+ const char *s1,
+ const char *s2)
{
register const unsigned char *p1 = (const unsigned char *) s1;
register const unsigned char *p2 = (const unsigned char *) s2;
if (p1 == p2)
return 0;
- do
- {
+ do {
c1 = tolower (*p1++);
c2 = tolower (*p2++);
if (c1 == '\0' || c2 == '\0' || c1 != c2)
return c1 - c2;
- } while ( 1 == 1 );
+ } while ( 1 == 1 );
}
* University of Maryland at College Park
*/
/*
- * $Id: stream.c,v 1.31 2006/01/14 04:37:19 paddy_s Exp $
+ * $Id: stream.c,v 1.39 2006/08/24 01:57:15 paddy_s Exp $
*
* functions for managing stream sockets
*/
#include "util.h"
/* local functions */
-static void try_socksize P((int sock, int which, int size));
+static void try_socksize(int sock, int which, size_t size);
+static int stream_client_internal(const char *hostname, in_port_t port,
+ size_t sendsize, size_t recvsize, in_port_t *localport,
+ int nonblock, int priv);
-int stream_server(portp, sendsize, recvsize)
-int *portp;
-int sendsize, recvsize;
+int
+stream_server(
+ in_port_t *portp,
+ size_t sendsize,
+ size_t recvsize,
+ int priv)
{
- int server_socket;
+ int server_socket, retries;
socklen_t len;
-#ifdef SO_KEEPALIVE
- int on = 1;
+#if defined(SO_KEEPALIVE) || defined(USE_REUSEADDR)
+ const int on = 1;
int r;
#endif
struct sockaddr_in server;
int save_errno;
- *portp = -1; /* in case we error exit */
+ *portp = USHRT_MAX; /* in case we error exit */
if((server_socket = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
save_errno = errno;
dbprintf(("%s: stream_server: socket() failed: %s\n",
errno = save_errno;
return -1;
}
- if(server_socket < 0 || server_socket >= FD_SETSIZE) {
+ if(server_socket < 0 || server_socket >= (int)FD_SETSIZE) {
aclose(server_socket);
errno = EMFILE; /* out of range */
save_errno = errno;
errno = save_errno;
return -1;
}
- memset(&server, 0, sizeof(server));
- server.sin_family = AF_INET;
+ memset(&server, 0, SIZEOF(server));
+ server.sin_family = (sa_family_t)AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
- if(sendsize >= 0)
- try_socksize(server_socket, SO_SNDBUF, sendsize);
- if(recvsize >= 0)
- try_socksize(server_socket, SO_RCVBUF, recvsize);
+#ifdef USE_REUSEADDR
+ r = setsockopt(server_socket, SOL_SOCKET, SO_REUSEADDR,
+ (void *)&on, (socklen_t)sizeof(on));
+ if (r < 0) {
+ dbprintf(("%s: stream_server: setsockopt(SO_REUSEADDR) failed: %s\n",
+ debug_prefix(NULL),
+ strerror(errno)));
+ }
+#endif
+
+ try_socksize(server_socket, SO_SNDBUF, sendsize);
+ try_socksize(server_socket, SO_RCVBUF, recvsize);
/*
* If a port range was specified, we try to get a port in that
* to get the desired port, and to make sure we return a port that
* is within the range it requires.
*/
+ for (retries = 0; ; retries++) {
#ifdef TCPPORTRANGE
- if (bind_portrange(server_socket, &server, TCPPORTRANGE, "tcp") == 0)
- goto out;
+ if (bind_portrange(server_socket, &server, TCPPORTRANGE, "tcp") == 0)
+ goto out;
+ dbprintf(("%s: stream_server: Could not bind to port in range: %d - %d.\n",
+ debug_prefix(NULL), TCPPORTRANGE));
#endif
- if (bind_portrange(server_socket, &server, 512, IPPORT_RESERVED - 1, "tcp") == 0)
- goto out;
+ if(priv) {
+ if (bind_portrange(server_socket, &server,
+ (in_port_t)512, (in_port_t)(IPPORT_RESERVED - 1), "tcp") == 0)
+ goto out;
+ dbprintf(("%s: stream_server: Could not bind to port in range 512 - %d.\n",
+ debug_prefix(NULL), IPPORT_RESERVED - 1));
+ }
- server.sin_port = INADDR_ANY;
- if (bind(server_socket, (struct sockaddr *)&server, (socklen_t) sizeof(server)) == -1) {
- save_errno = errno;
- dbprintf(("%s: stream_server: bind(INADDR_ANY) failed: %s\n",
+ server.sin_port = INADDR_ANY;
+ if (bind(server_socket, (struct sockaddr *)&server, (socklen_t)sizeof(server)) == 0)
+ goto out;
+ dbprintf(("%s: stream_server: Could not bind to any port: %s\n",
+ debug_prefix(NULL), strerror(errno)));
+
+ if (retries >= BIND_CYCLE_RETRIES)
+ break;
+
+ dbprintf(("%s: stream_server: Retrying entire range after 10 second delay.\n",
+ debug_prefix(NULL)));
+
+ sleep(15);
+ }
+
+ save_errno = errno;
+ dbprintf(("%s: stream_server: bind(INADDR_ANY) failed: %s\n",
debug_prefix(NULL),
strerror(save_errno)));
- aclose(server_socket);
- errno = save_errno;
- return -1;
- }
+ aclose(server_socket);
+ errno = save_errno;
+ return -1;
out:
listen(server_socket, 1);
/* find out what port was actually used */
- len = sizeof(server);
+ len = SIZEOF(server);
if(getsockname(server_socket, (struct sockaddr *)&server, &len) == -1) {
save_errno = errno;
dbprintf(("%s: stream_server: getsockname() failed: %s\n",
}
#endif
- *portp = (int) ntohs(server.sin_port);
+ *portp = (in_port_t)ntohs(server.sin_port);
dbprintf(("%s: stream_server: waiting for connection: %s.%d\n",
debug_prefix_time(NULL),
inet_ntoa(server.sin_addr),
}
static int
-stream_client_internal(hostname,
- port,
- sendsize,
- recvsize,
- localport,
- nonblock,
- priv)
- const char *hostname;
- int port, sendsize, recvsize, *localport, nonblock, priv;
+stream_client_internal(
+ const char *hostname,
+ in_port_t port,
+ size_t sendsize,
+ size_t recvsize,
+ in_port_t *localport,
+ int nonblock,
+ int priv)
{
- int client_socket;
- socklen_t len;
-#ifdef SO_KEEPALIVE
- int on = 1;
- int r;
-#endif
struct sockaddr_in svaddr, claddr;
struct hostent *hostp;
int save_errno;
char *f;
+ int client_socket;
f = priv ? "stream_client_privileged" : "stream_client";
if((hostp = gethostbyname(hostname)) == NULL) {
- save_errno = errno;
+ save_errno = EHOSTUNREACH;
dbprintf(("%s: %s: gethostbyname(%s) failed\n",
debug_prefix(NULL),
f,
return -1;
}
- memset(&svaddr, 0, sizeof(svaddr));
- svaddr.sin_family = AF_INET;
- svaddr.sin_port = htons(port);
- memcpy(&svaddr.sin_addr, hostp->h_addr, hostp->h_length);
+ memset(&svaddr, 0, SIZEOF(svaddr));
+ svaddr.sin_family = (sa_family_t)AF_INET;
+ svaddr.sin_port = (in_port_t)htons(port);
+ memcpy(&svaddr.sin_addr, hostp->h_addr, (size_t)hostp->h_length);
- if((client_socket = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
- save_errno = errno;
- dbprintf(("%s: %s: socket() failed: %s\n",
- debug_prefix(NULL),
- f,
- strerror(save_errno)));
- errno = save_errno;
- return -1;
- }
- if(client_socket < 0 || client_socket >= FD_SETSIZE) {
- aclose(client_socket);
- errno = EMFILE; /* out of range */
- return -1;
- }
-#ifdef SO_KEEPALIVE
- r = setsockopt(client_socket, SOL_SOCKET, SO_KEEPALIVE,
- (void *)&on, sizeof(on));
- if(r == -1) {
- save_errno = errno;
- dbprintf(("%s: %s: setsockopt() failed: %s\n",
- debug_prefix(NULL),
- f,
- strerror(save_errno)));
- aclose(client_socket);
- errno = save_errno;
- return -1;
- }
-#endif
-
- memset(&claddr, 0, sizeof(claddr));
- claddr.sin_family = AF_INET;
+ memset(&claddr, 0, SIZEOF(claddr));
+ claddr.sin_family = (sa_family_t)AF_INET;
claddr.sin_addr.s_addr = INADDR_ANY;
/*
* is within the range it requires.
*/
if (priv) {
- int b;
-
- b = bind_portrange(client_socket, &claddr, 512, IPPORT_RESERVED - 1, "tcp");
- if (b == 0) {
- goto out; /* got what we wanted */
- }
- save_errno = errno;
- dbprintf(("%s: %s: bind(IPPORT_RESERVED) failed: %s\n",
- debug_prefix(NULL),
- f,
- strerror(save_errno)));
- aclose(client_socket);
- errno = save_errno;
- return -1;
+#ifdef LOW_TCPPORTRANGE
+ client_socket = connect_portrange(&claddr, LOW_TCPPORTRANGE,
+ "tcp", &svaddr, nonblock);
+#else
+ client_socket = connect_portrange(&claddr, (socklen_t)512,
+ (socklen_t)(IPPORT_RESERVED - 1),
+ "tcp", &svaddr, nonblock);
+#endif
+
+ if (client_socket > 0)
+ goto out;
+
+#ifdef LOW_TCPPORTRANGE
+ dbprintf((
+ "%s: stream_client: Could not bind to port in range %d-%d.\n",
+ debug_prefix(NULL), LOW_TCPPORTRANGE));
+#else
+ dbprintf((
+ "%s: stream_client: Could not bind to port in range 512-%d.\n",
+ debug_prefix(NULL), IPPORT_RESERVED - 1));
+#endif
}
#ifdef TCPPORTRANGE
- if (bind_portrange(client_socket, &claddr, TCPPORTRANGE, "tcp") == 0)
+ client_socket = connect_portrange(&claddr, TCPPORTRANGE,
+ "tcp", &svaddr, nonblock);
+ if(client_socket > 0)
goto out;
-#endif
-
- claddr.sin_port = INADDR_ANY;
- if (bind(client_socket, (struct sockaddr *)&claddr, sizeof(claddr)) == -1) {
- save_errno = errno;
- dbprintf(("%s: %s: bind(INADDR_ANY) failed: %s\n",
- debug_prefix(NULL),
- f,
- strerror(save_errno)));
- aclose(client_socket);
- errno = save_errno;
- return -1;
- }
-out:
-
- /* find out what port was actually used */
-
- len = sizeof(claddr);
- if(getsockname(client_socket, (struct sockaddr *)&claddr, &len) == -1) {
- save_errno = errno;
- dbprintf(("%s: %s: getsockname() failed: %s\n",
- debug_prefix(NULL),
- f,
- strerror(save_errno)));
- aclose(client_socket);
- errno = save_errno;
- return -1;
- }
+ dbprintf(("%s: stream_client: Could not bind to port in range %d - %d.\n",
+ debug_prefix(NULL), TCPPORTRANGE));
+#endif
- if (nonblock)
- fcntl(client_socket, F_SETFL,
- fcntl(client_socket, F_GETFL, 0)|O_NONBLOCK);
+ client_socket = connect_portrange(&claddr, (socklen_t)(IPPORT_RESERVED+1),
+ (socklen_t)(65535),
+ "tcp", &svaddr, nonblock);
- if(connect(client_socket, (struct sockaddr *)&svaddr, sizeof(svaddr))
- == -1 && !nonblock) {
- save_errno = errno;
- dbprintf(("%s: %s: connect to %s.%d failed: %s\n",
- debug_prefix_time(NULL),
- f,
- inet_ntoa(svaddr.sin_addr),
- ntohs(svaddr.sin_port),
- strerror(save_errno)));
- aclose(client_socket);
- errno = save_errno;
- return -1;
- }
+ if(client_socket > 0)
+ goto out;
- dbprintf(("%s: %s: connected to %s.%d\n",
- debug_prefix_time(NULL),
- f,
- inet_ntoa(svaddr.sin_addr),
- ntohs(svaddr.sin_port)));
- dbprintf(("%s: %s: our side is %s.%d\n",
- debug_prefix(NULL),
- f,
- inet_ntoa(claddr.sin_addr),
- ntohs(claddr.sin_port)));
-
- if(sendsize >= 0)
- try_socksize(client_socket, SO_SNDBUF, sendsize);
- if(recvsize >= 0)
- try_socksize(client_socket, SO_RCVBUF, recvsize);
+ save_errno = errno;
+ dbprintf(("%s: stream_client: Could not bind to any port: %s\n",
+ debug_prefix(NULL), strerror(save_errno)));
+ errno = save_errno;
+ return -1;
+out:
+ try_socksize(client_socket, SO_SNDBUF, sendsize);
+ try_socksize(client_socket, SO_RCVBUF, recvsize);
if (localport != NULL)
- *localport = ntohs(claddr.sin_port);
-
+ *localport = (in_port_t)ntohs(claddr.sin_port);
return client_socket;
}
int
-stream_client_privileged(hostname,
- port,
- sendsize,
- recvsize,
- localport,
- nonblock)
- const char *hostname;
- int port, sendsize, recvsize, *localport, nonblock;
+stream_client_privileged(
+ const char *hostname,
+ in_port_t port,
+ size_t sendsize,
+ size_t recvsize,
+ in_port_t *localport,
+ int nonblock)
{
return stream_client_internal(hostname,
port,
}
int
-stream_client(hostname, port, sendsize, recvsize, localport, nonblock)
- const char *hostname;
- int port, sendsize, recvsize, *localport, nonblock;
+stream_client(
+ const char *hostname,
+ in_port_t port,
+ size_t sendsize,
+ size_t recvsize,
+ in_port_t *localport,
+ int nonblock)
{
return stream_client_internal(hostname,
port,
static struct sockaddr_in addr;
static socklen_t addrlen;
-int stream_accept(server_socket, timeout, sendsize, recvsize)
-int server_socket, timeout, sendsize, recvsize;
+int
+stream_accept(
+ int server_socket,
+ int timeout,
+ size_t sendsize,
+ size_t recvsize)
{
- fd_set readset;
+ SELECT_ARG_TYPE readset;
struct timeval tv;
int nfound, connected_socket;
int save_errno;
+ int ntries = 0;
assert(server_socket >= 0);
- tv.tv_sec = timeout;
- tv.tv_usec = 0;
- FD_ZERO(&readset);
- FD_SET(server_socket, &readset);
- nfound = select(server_socket+1, (SELECT_ARG_TYPE *)&readset, NULL, NULL, &tv);
- if(nfound <= 0 || !FD_ISSET(server_socket, &readset)) {
- save_errno = errno;
- if(nfound < 0) {
- dbprintf(("%s: stream_accept: select() failed: %s\n",
+ do {
+ ntries++;
+ memset(&tv, 0, SIZEOF(tv));
+ tv.tv_sec = timeout;
+ memset(&readset, 0, SIZEOF(readset));
+ FD_ZERO(&readset);
+ FD_SET(server_socket, &readset);
+ nfound = select(server_socket+1, &readset, NULL, NULL, &tv);
+ if(nfound <= 0 || !FD_ISSET(server_socket, &readset)) {
+ save_errno = errno;
+ if(nfound < 0) {
+ dbprintf(("%s: stream_accept: select() failed: %s\n",
debug_prefix_time(NULL),
strerror(save_errno)));
- } else if(nfound == 0) {
- dbprintf(("%s: stream_accept: timeout after %d second%s\n",
+ } else if(nfound == 0) {
+ dbprintf(("%s: stream_accept: timeout after %d second%s\n",
debug_prefix_time(NULL),
timeout,
(timeout == 1) ? "" : "s"));
- save_errno = ENOENT; /* ??? */
- } else if (!FD_ISSET(server_socket, &readset)) {
- int i;
-
- for(i = 0; i < server_socket + 1; i++) {
- if(FD_ISSET(i, &readset)) {
- dbprintf(("%s: stream_accept: got fd %d instead of %d\n",
+ errno = ENOENT; /* ??? */
+ return -1;
+ } else if (!FD_ISSET(server_socket, &readset)) {
+ int i;
+
+ for(i = 0; i < server_socket + 1; i++) {
+ if(FD_ISSET(i, &readset)) {
+ dbprintf(("%s: stream_accept: got fd %d instead of %d\n",
debug_prefix_time(NULL),
i,
server_socket));
+ }
}
+ save_errno = EBADF;
}
- save_errno = EBADF;
- }
- errno = save_errno;
- return -1;
- }
+ if (ntries > 5) {
+ errno = save_errno;
+ return -1;
+ }
+ }
+ } while (nfound <= 0);
while(1) {
- addrlen = sizeof(struct sockaddr);
+ addrlen = (socklen_t)sizeof(struct sockaddr);
connected_socket = accept(server_socket,
(struct sockaddr *)&addr,
&addrlen);
if(connected_socket < 0) {
- save_errno = errno;
- dbprintf(("%s: stream_accept: accept() failed: %s\n",
- debug_prefix_time(NULL),
- strerror(save_errno)));
- errno = save_errno;
- return -1;
+ break;
}
dbprintf(("%s: stream_accept: connection from %s.%d\n",
debug_prefix_time(NULL),
* Make certain we got an inet connection and that it is not
* from port 20 (a favorite unauthorized entry tool).
*/
- if(addr.sin_family == AF_INET && ntohs(addr.sin_port) != 20) {
- break;
+ if((addr.sin_family == (sa_family_t)AF_INET)
+ && (ntohs(addr.sin_port) != (in_port_t)20)) {
+ try_socksize(connected_socket, SO_SNDBUF, sendsize);
+ try_socksize(connected_socket, SO_RCVBUF, recvsize);
+ return connected_socket;
}
- if(addr.sin_family != AF_INET) {
+ if(addr.sin_family != (sa_family_t)AF_INET) {
dbprintf(("%s: family is %d instead of %d(AF_INET): ignored\n",
debug_prefix_time(NULL),
addr.sin_family,
aclose(connected_socket);
}
- if(sendsize >= 0)
- try_socksize(connected_socket, SO_SNDBUF, sendsize);
- if(recvsize >= 0)
- try_socksize(connected_socket, SO_RCVBUF, recvsize);
-
- return connected_socket;
+ save_errno = errno;
+ dbprintf(("%s: stream_accept: accept() failed: %s\n",
+ debug_prefix_time(NULL),
+ strerror(save_errno)));
+ errno = save_errno;
+ return -1;
}
-static void try_socksize(sock, which, size)
-int sock, which, size;
+static void
+try_socksize(
+ int sock,
+ int which,
+ size_t size)
{
- int origsize;
+ size_t origsize;
+
+ if (size == 0)
+ return;
origsize = size;
/* keep trying, get as big a buffer as possible */
- while(size > 1024 &&
- setsockopt(sock, SOL_SOCKET, which, (void *) &size, sizeof(int)) < 0)
+ while((size > 1024) &&
+ (setsockopt(sock, SOL_SOCKET,
+ which, (void *) &size, (socklen_t)sizeof(int)) < 0)) {
size -= 1024;
+ }
if(size > 1024) {
dbprintf(("%s: try_socksize: %s buffer size is %d\n",
debug_prefix(NULL),
* University of Maryland at College Park
*/
/*
- * $Id: stream.h,v 1.10 2001/08/14 22:38:26 jrjackson Exp $
+ * $Id: stream.h,v 1.12 2006/06/01 14:44:05 martinea Exp $
*
* interface to stream module
*/
#define NETWORK_BLOCK_BYTES DISK_BLOCK_BYTES
#define STREAM_BUFSIZE (NETWORK_BLOCK_BYTES * 2)
-int stream_server P((int *port, int sendsize, int recvsize));
-int stream_accept P((int sock, int timeout, int sendsize, int recvsize));
-int stream_client_privileged P((const char *hostname,
- int port,
- int sendsize,
- int recvsize,
- int *localport,
- int nonblock));
-int stream_client P((const char *hostname,
- int port,
- int sendsize,
- int recvsize,
- int *localport,
- int nonblock));
+int stream_server(in_port_t *port, size_t sendsize, size_t recvsize, int priv);
+int stream_accept(int sock, int timeout, size_t sendsize, size_t recvsize);
+int stream_client_privileged(const char *hostname,
+ in_port_t port,
+ size_t sendsize,
+ size_t recvsize,
+ in_port_t *localport,
+ int nonblock);
+int stream_client(const char *hostname,
+ in_port_t port,
+ size_t sendsize,
+ size_t recvsize,
+ in_port_t *localport,
+ int nonblock);
#endif
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
-/* $Id: strerror.c,v 1.6 1999/05/18 20:38:53 kashmir Exp $ */
+/* $Id: strerror.c,v 1.7 2006/05/25 01:47:12 johnfranks Exp $ */
#include "amanda.h"
extern int sys_nerr;
extern char *sys_errlist[];
unsigned int errnum;
- static char buf[NUM_STR_SIZE + sizeof(UPREFIX) + 1];
+ static char buf[NUM_STR_SIZE + SIZEOF(UPREFIX) + 1];
errnum = e; /* convert to unsigned */
if (errnum < sys_nerr)
return (sys_errlist[errnum]);
- snprintf(buf, sizeof(buf), UPREFIX, errnum);
+ snprintf(buf, SIZEOF(buf), UPREFIX, errnum);
return (buf);
}
static char sccsid[] = "@(#)strftime.c 5.8 (Berkeley) 6/1/90";
#endif /* LIBC_SCCS and not lint */
-#include <sys/types.h>
-#include <sys/time.h>
+#include "amanda.h"
#include <tzfile.h>
-#include <string.h>
static char *afmt[] = {
"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat",
static char buf[10];
register char *p;
- for (p = buf + sizeof(buf) - 2; n > 0 && p > buf; n /= 10, --digits)
+ for (p = buf + SIZEOF(buf) - 2; n > 0 && p > buf; n /= 10, --digits)
*p-- = n % 10 + '0';
while (p > buf && digits-- > 0)
*p-- = pad;
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#if defined(STDC_HEADERS) || defined(HAVE_STRING_H)
-#include <string.h>
-#else
-#include <strings.h>
-#endif
+#include "amanda.h"
/*
* The following function compares the first 'n' characters in 's1'
* file named AUTHORS, in the root directory of this distribution.
*/
/*
- * $Id: tapelist.c,v 1.3 2006/01/15 21:00:59 martinea Exp $
+ * $Id: tapelist.c,v 1.8 2006/06/12 15:34:48 martinea Exp $
*
* Support code for amidxtaped and amindexd.
*/
/*
* Count the number of entries in this tapelist
*/
-int num_entries (tapelist)
-tapelist_t *tapelist;
+int
+num_entries(
+ tapelist_t * tapelist)
{
tapelist_t *cur_tape;
int count = 0;
- for(cur_tape = tapelist ; cur_tape ; cur_tape = cur_tape->next) count++;
+ for(cur_tape = tapelist ; cur_tape ; cur_tape = cur_tape->next)
+ count++;
+ dbprintf(("num_entries(tapelist=%p)=%d\n", tapelist, count));
return(count);
}
+void
+dump_tapelist(
+ tapelist_t *tapelist)
+{
+ tapelist_t *cur_tape;
+ int count = 0;
+ int file;
+
+ dbprintf(("dump_tapelist(%p):\n", tapelist));
+ for(cur_tape = tapelist ; cur_tape != NULL ; cur_tape = cur_tape->next) {
+ dbprintf((" %p->next = %p\n", cur_tape, cur_tape->next));
+ dbprintf((" %p->label = %s\n", cur_tape, cur_tape->label));
+ dbprintf((" %p->isafile = %d\n", cur_tape, cur_tape->isafile));
+ dbprintf((" %p->numfiles = %d\n", cur_tape, cur_tape->numfiles));
+ for (file=0; file < cur_tape->numfiles; file++) {
+ dbprintf((" %p->files[%d] = " OFF_T_FMT "\n",
+ cur_tape, file, (OFF_T_FMT_TYPE)cur_tape->files[file]));
+ }
+ count++;
+ }
+ dbprintf((" %p count = %d\n", tapelist, count));
+}
+
/*
* Add a tape entry with the given label to the given tapelist, creating a new
* tapelist if handed a NULL one. Squashes duplicates.
*/
-tapelist_t *append_to_tapelist (tapelist, label, file, isafile)
-tapelist_t *tapelist;
-char *label;
-int file, isafile;
+tapelist_t *
+append_to_tapelist(
+ tapelist_t *tapelist,
+ char * label,
+ off_t file,
+ int isafile)
{
tapelist_t *new_tape, *cur_tape;
int c;
+ dbprintf(("append_to_tapelist(tapelist=%p, label='%s', , file="
+ OFF_T_FMT ", isafile=%d)\n",
+ tapelist, label, (OFF_T_FMT_TYPE)file, isafile));
+
/* see if we have this tape already, and if so just add to its file list */
- for(cur_tape = tapelist; cur_tape; cur_tape = cur_tape->next){
- if(!strcmp(label, cur_tape->label)){
+ for(cur_tape = tapelist; cur_tape; cur_tape = cur_tape->next) {
+ if(strcmp(label, cur_tape->label) == 0) {
int d_idx = 0;
- int *newfiles;
- if(file >= 0){
- newfiles = alloc(sizeof(int) * (cur_tape->numfiles + 1));
- for(c = 0; c < cur_tape->numfiles ; c++){
- if(cur_tape->files[c] > file && c == d_idx){
+ off_t *newfiles;
+
+ if(file >= (off_t)0) {
+ newfiles = alloc(SIZEOF(*newfiles) *
+ (cur_tape->numfiles + 1));
+ for(c = 0; c < cur_tape->numfiles ; c++) {
+ if(cur_tape->files[c] > file && c == d_idx) {
newfiles[d_idx] = file;
d_idx++;
}
newfiles[d_idx] = cur_tape->files[c];
d_idx++;
}
- if(c == d_idx) newfiles[d_idx] = file;
+ if(c == d_idx)
+ newfiles[d_idx] = file;
cur_tape->numfiles++;
amfree(cur_tape->files);
cur_tape->files = newfiles;
}
+ dump_tapelist(tapelist);
return(tapelist);
}
}
- new_tape = alloc(sizeof(tapelist_t));
- memset(new_tape, 0, sizeof(tapelist_t));
+ new_tape = alloc(SIZEOF(tapelist_t));
+ memset(new_tape, 0, SIZEOF(tapelist_t));
new_tape->label = stralloc(label);
- if(file >= 0){
- new_tape->files = alloc(sizeof(int));
+ if(file >= (off_t)0){
+ new_tape->files = alloc(SIZEOF(*(new_tape->files)));
new_tape->files[0] = file;
new_tape->numfiles = 1;
new_tape->isafile = isafile;
/* first instance of anything, start our tapelist with it */
if(!tapelist){
tapelist = new_tape;
- return(tapelist);
+ } else {
+ /* new tape, tack it onto the end of the list */
+ cur_tape = tapelist;
+ while (cur_tape->next != NULL)
+ cur_tape = cur_tape->next;
+ cur_tape->next = new_tape;
}
- /* new tape, tack it onto the end of the list */
- for(cur_tape = tapelist; cur_tape->next; cur_tape = cur_tape->next);
- cur_tape->next = new_tape;
-
+ dump_tapelist(tapelist);
return(tapelist);
}
/*
* Backslash-escape all of the commas (and backslashes) in a label string.
*/
-char *escape_label (label)
-char *label;
+char *
+escape_label(
+ char * label)
{
char *cooked_str, *temp_str;
int s_idx = 0, d_idx = 0;
/*
* Strip out any escape characters (backslashes)
*/
-char *unescape_label(label)
-char *label;
+char *
+unescape_label(
+ char * label)
{
char *cooked_str, *temp_str;
int s_idx = 0, d_idx = 0, prev_esc = 0;
/*
* Convert a tapelist into a parseable string of tape labels and file numbers.
*/
-char *marshal_tapelist (tapelist, do_escape)
-tapelist_t *tapelist;
-int do_escape;
+char *
+marshal_tapelist(
+ tapelist_t *tapelist,
+ int do_escape)
{
tapelist_t *cur_tape;
char *str = NULL;
for(c = 0; c < cur_tape->numfiles ; c++){
char num_str[NUM_STR_SIZE];
- snprintf(num_str, sizeof(num_str), "%d", cur_tape->files[c]);
- if(!files_str) files_str = stralloc(num_str);
- else files_str = vstralloc(files_str, ",", num_str, NULL);
+ snprintf(num_str, SIZEOF(num_str), OFF_T_FMT,
+ (OFF_T_FMT_TYPE)cur_tape->files[c]);
+ if (!files_str)
+ files_str = stralloc(num_str);
+ else
+ vstrextend(&files_str, ",", num_str, NULL);
}
- if(!str) str = vstralloc(esc_label, ":", files_str, NULL);
- else str = vstralloc(str, ";", esc_label, ":", files_str, NULL);
+ if (!str)
+ str = vstralloc(esc_label, ":", files_str, NULL);
+ else
+ vstrextend(&str, ";", esc_label, ":", files_str, NULL);
amfree(esc_label);
amfree(files_str);
* Convert a previously str-ified and escaped list of tapes back into a
* tapelist structure.
*/
-tapelist_t *unmarshal_tapelist_str (tapelist_str)
-char *tapelist_str;
+tapelist_t *
+unmarshal_tapelist_str(
+ char * tapelist_str)
{
char *temp_label, *temp_filenum;
- int l_idx, n_idx, input_length;
+ int l_idx, n_idx;
+ size_t input_length;
tapelist_t *tapelist = NULL;
if(!tapelist_str) return(NULL);
memset(temp_label, '\0', input_length+1);
l_idx = 0;
while(*tapelist_str != ':' && *tapelist_str != '\0'){
- if(*tapelist_str == '\\') *tapelist_str++; /* skip escapes */
+ if(*tapelist_str == '\\')
+ tapelist_str++; /* skip escapes */
temp_label[l_idx] = *tapelist_str;
- if(*tapelist_str == '\0') break; /* bad format, should kvetch */
- *tapelist_str++;
+ if(*tapelist_str == '\0')
+ break; /* bad format, should kvetch */
+ tapelist_str++;
l_idx++;
}
- if(*tapelist_str != '\0') *tapelist_str++;
- tapelist = append_to_tapelist(tapelist, temp_label, -1, 0);
+ if(*tapelist_str != '\0')
+ tapelist_str++;
+ tapelist = append_to_tapelist(tapelist, temp_label, (off_t)-1, 0);
/* now read the list of file numbers */
while(*tapelist_str != ';' && *tapelist_str != '\0'){
- int filenum = -1;
+ off_t filenum;
+
memset(temp_filenum, '\0', input_length+1);
n_idx = 0;
while(*tapelist_str != ';' && *tapelist_str != ',' &&
*tapelist_str != '\0'){
temp_filenum[n_idx] = *tapelist_str;
- *tapelist_str++;
+ tapelist_str++;
n_idx++;
}
- filenum = atoi(temp_filenum);
+ filenum = OFF_T_ATOI(temp_filenum);
tapelist = append_to_tapelist(tapelist, temp_label, filenum, 0);
- if(*tapelist_str != '\0' && *tapelist_str != ';') *tapelist_str++;
+ if(*tapelist_str != '\0' && *tapelist_str != ';')
+ tapelist_str++;
}
- if(*tapelist_str != '\0') *tapelist_str++;
+ if(*tapelist_str != '\0')
+ tapelist_str++;
} while(*tapelist_str != '\0');
/*
* Free up a list of tapes
*/
-void free_tapelist (tapelist)
-tapelist_t *tapelist;
+void
+free_tapelist(
+ tapelist_t * tapelist)
{
tapelist_t *cur_tape;
tapelist_t *prev = NULL;
for(cur_tape = tapelist ; cur_tape ; cur_tape = cur_tape->next){
- if(cur_tape->label) amfree(cur_tape->label);
- if(cur_tape->files) amfree(cur_tape->files);
- if(prev) amfree(prev);
+ amfree(cur_tape->label);
+ amfree(cur_tape->files);
+ amfree(prev);
prev = cur_tape;
}
- if(prev) amfree(prev);
-
+ amfree(prev);
}
* file named AUTHORS, in the root directory of this distribution.
*/
/*
- * $Id: tapelist.h,v 1.1 2005/10/11 01:17:00 vectro Exp $
+ * $Id: tapelist.h,v 1.2 2006/05/25 01:47:12 johnfranks Exp $
*
*/
struct tapelist_s *next;
char *label;
int isafile; /* set to 1 and make *label the path to the file */
- int *files;
+ off_t *files;
int numfiles;
} tapelist_t;
-extern int num_entries P((tapelist_t *tapelist));
-extern tapelist_t *append_to_tapelist P((tapelist_t *tapelist, char *label,
- int file, int isafile));
-extern char *marshal_tapelist P((tapelist_t *tapelist, int escape));
-extern tapelist_t *unmarshal_tapelist_str P((char *tapelist_str));
-extern char *escape_label P((char *label));
-extern char *unescape_label P((char *label));
-extern void free_tapelist P((tapelist_t *tapelist));
-
+int num_entries(tapelist_t *tapelist);
+tapelist_t *append_to_tapelist(tapelist_t *tapelist, char *label,
+ off_t file, int isafile);
+char *marshal_tapelist(tapelist_t *tapelist, int escape);
+tapelist_t *unmarshal_tapelist_str(char *tapelist_str);
+char *escape_label(char *label);
+char *unescape_label(char *label);
+void free_tapelist(tapelist_t *tapelist);
+void dump_tapelist(tapelist_t *);
+
#endif /* !TAPELIST_H */
* file named AUTHORS, in the root directory of this distribution.
*/
/*
- * $Id: token.c,v 1.29 2006/01/14 04:37:19 paddy_s Exp $
+ * $Id: token.c,v 1.32 2006/07/19 17:41:15 martinea Exp $
*
* token bashing routines
*/
** Inspired by awk and a routine called splitter() that I snarfed from
** the net ages ago (original author long forgotten).
*/
-int split(str, token, toklen, sep)
-char *str; /* String to split */
-char **token; /* Array of token pointers */
-int toklen; /* Size of token[] */
-char *sep; /* Token separators - usually " " */
+int
+split(
+ char * str, /* String to split */
+ char ** token, /* Array of token pointers */
+ int toklen, /* Size of token[] */
+ char * sep) /* Token separators - usually " " */
{
register char *pi, *po;
register int fld;
if (*sep == '\0' || *str == '\0' || toklen == 1) return fld;
/* Calculate the length of the unquoted string. */
-
- len = 0;
- for (pi = str; *pi && *pi != '\n'; pi++) {
- switch(*pi) {
- case '\\': /* had better not be trailing... */
- pi++;
- if (*pi >= '0' && *pi <= '3') pi = pi + 2;
- len++;
- break;
- case '"': /* just ignore "'s */
- break;
- default:
- len++;
- }
- }
+ len = strlen(str);;
/* Allocate some space */
in_quotes = 0;
po = buf;
token[++fld] = po;
- for (pi = str; *pi && *pi != '\n'; pi++) {
- if (*pi == '\\') { /* escape */
- pi++;
- if (*pi >= '0' && *pi <= '3') {
- *po = ((*pi++ - '0') << 6);
- *po = *po + ((*pi++ - '0') << 3);
- *po = *po + ((*pi - '0') );
- }
- else *po = *pi;
- po++;
- }
- else if (*pi == '"') { /* quotes */
- in_quotes = !in_quotes;
- }
- else if (!in_quotes && strchr(sep, *pi)) { /* separator */
+ for (pi = str; *pi && *pi != '\0'; pi++) {
+ if (*pi == '\n' && !in_quotes)
+ break;
+
+ if (!in_quotes && strchr(sep, *pi)) {
+ /*
+ * separator
+ * Advance to next field.
+ */
*po = '\0'; /* end of token */
if (fld+1 >= toklen) return fld; /* too many tokens */
token[++fld] = po + 1;
po++;
+ continue;
}
- else {
- *po++ = *pi; /* normal */
+
+ if (*pi == '"') {
+ /*
+ * Start or end of quote
+ * Emit quote in either case
+ */
+ in_quotes = !in_quotes;
+ } else if (in_quotes && *pi == '\\' && (*(pi + 1) == '"')) {
+ /*
+ * Quoted quote.
+ * emit '/' - default will pick up '"'
+ */
+ *po++ = *pi++;
}
+ *po++ = *pi; /* Emit character */
}
*po = '\0';
/* Format the token */
arglist_start(argp, format);
- vsnprintf(linebuf, sizeof(linebuf), format, argp);
+ vsnprintf(linebuf, SIZEOF(linebuf), format, argp);
arglist_end(argp);
return quote(" ", linebuf);
/* Format the token */
arglist_start(argp, format);
- vsnprintf(linebuf, sizeof(linebuf), format, argp);
+ vsnprintf(linebuf, SIZEOF(linebuf), format, argp);
arglist_end(argp);
return quote(sep, linebuf);
}
-char *squote(str)
-char *str; /* the string to quote */
+char *squote(
+ char * str) /* the string to quote */
{
return quote(" ", str);
}
-char *quote(sepchr, str)
-char *sepchr; /* separators that also need quoting */
-char *str; /* the string to quote */
+char *
+quote(
+ char * sepchr, /* separators that also need quoting */
+ char * str) /* the string to quote */
{
register char *pi, *po;
register size_t len;
/* Calculate the length of the quoted token. */
- len = sep = 0;
+ sep = 0;
+ len = 0;
for (pi = str; *pi; pi++) {
if (*pi < ' ' || *pi > '~')
len = len + 4;
for (pi = str; *pi; pi++) {
if (*pi < ' ' || *pi > '~') {
*po++ = '\\';
- *po++ = ((*pi >> 6) & 07) + '0';
- *po++ = ((*pi >> 3) & 07) + '0';
- *po++ = ((*pi ) & 07) + '0';
+ *po++ = (char)(((*pi >> 6) & 07) + '0');
+ *po++ = (char)(((*pi >> 3) & 07) + '0');
+ *po++ = (char)(((*pi ) & 07) + '0');
}
else if (*pi == '\\' || *pi == '"') {
*po++ = '\\';
*po = '\0';
- assert(po - buf == len); /* Just checking! */
+ assert(po == (buf + len)); /* Just checking! */
return buf;
}
/* Quote a string so that it can be used as a regular expression */
-char *rxquote(str)
-char *str; /* the string to quote */
+char *
+rxquote(
+ char * str) /* the string to quote */
{
char *pi, *po;
size_t len;
*po = '\0';
- assert(po - buf == len); /* Just checking! */
+ assert(po == (buf + len)); /* Just checking! */
return buf;
}
#ifndef HAVE_SHQUOTE
/* Quote a string so that it can be safely passed to a shell */
-char *shquote(str)
-char *str; /* the string to quote */
+char *
+shquote(
+ char * str) /* the string to quote */
{
char *pi, *po;
size_t len;
*po = '\0';
- assert(po - buf == len); /* Just checking! */
+ assert(po == (buf + len)); /* Just checking! */
return buf;
}
/* Table lookup.
*/
-int table_lookup(table, str)
-table_t *table;
-char *str;
+int
+table_lookup(
+ table_t * table,
+ char * str)
{
while(table->word != (char *)0) {
- if (*table->word == *str &&
- strcmp(table->word, str) == 0) return table->value;
+ if (*table->word == *str && strcmp(table->word, str) == 0) {
+ return table->value;
+ }
table++;
}
/* Reverse table lookup.
*/
-char *table_lookup_r(table, val)
-table_t *table;
-int val;
+char *
+table_lookup_r(
+ /*@keep@*/ table_t * table,
+ int val)
{
while(table->word != (char *)0) {
- if (table->value == val) return table->word;
+ if (table->value == val) {
+ return table->word;
+ }
table++;
}
#ifdef TEST
-int main()
+int
+main(
+ int argc,
+ char ** argv)
{
char *str = NULL;
char *t[20];
safe_fd(-1, 0);
+ /* shut up compiler */
+ argc = argc;
+ argv = argv;
+
set_pname("token test");
+ dbopen(NULL);
+
/* Don't die when child closes pipe */
signal(SIGPIPE, SIG_IGN);
}
sr = squote(str);
printf("Quoted = \"%s\"\n", sr);
- strncpy(str,sr,sizeof(str)-1);
- str[sizeof(str)-1] = '\0';
+ strncpy(str,sr,SIZEOF(str)-1);
+ str[SIZEOF(str)-1] = '\0';
r = split(str, t, 20, " ");
if (r != 1) printf("split()=%d!\n", r);
printf("Unquoted = \"%s\"\n", t[1]);
* file named AUTHORS, in the root directory of this distribution.
*/
/*
- * $Id: token.h,v 1.12 2003/03/26 20:17:13 kovert Exp $
+ * $Id: token.h,v 1.13 2006/05/25 01:47:12 johnfranks Exp $
*
* interface to token module
*/
typedef struct {char *word; int value;} table_t;
-extern int split P((char *str, char **token, int toklen, char *sep));
-extern char *squotef P((char *format, ...))
+extern int split(char *str, char **token, int toklen, char *sep);
+extern char *squotef(char *format, ...)
__attribute__ ((format (printf, 1, 2)));
-extern char *squote P((char *str));
-extern char *quotef P((char *sep, char *format, ...))
+extern char *squote(char *str);
+extern char *quotef(char *sep, char *format, ...)
__attribute__ ((format (printf, 2, 3)));
-extern char *quote P((char *sep, char *str));
-extern char *rxquote P((char *str));
+extern char *quote(char *sep, char *str);
+extern char *rxquote(char *str);
#ifndef HAVE_SHQUOTE
-extern char *shquote P((char *str));
+extern char *shquote(char *str);
#endif
-extern int table_lookup P((table_t *table, char *str));
-extern char *table_lookup_r P((table_t *table, int val));
+extern int table_lookup(table_t *table, char *str);
+extern char *table_lookup_r(table_t *table, int val);
#endif
* file named AUTHORS, in the root directory of this distribution.
*/
/*
- * $Id: util.c,v 1.17 2006/01/14 04:37:19 paddy_s Exp $
+ * $Id: util.c,v 1.42 2006/08/24 01:57:15 paddy_s Exp $
*/
#include "amanda.h"
#include "util.h"
+#include "arglist.h"
+#include "clock.h"
+
+int allow_overwrites;
+int token_pushed;
+
+tok_t tok, pushed_tok;
+val_t tokenval;
+
+int conf_line_num, got_parserror;
+FILE *conf_conf = (FILE *)NULL;
+char *conf_confname = NULL;
+char *conf_line = NULL;
+char *conf_char = NULL;
+
+/*#define NET_READ_DEBUG*/
+
+#ifdef NET_READ_DEBUG
+#define netprintf(x) dbprintf(x)
+#else
+#define netprintf(x)
+#endif
+
+static int make_socket(void);
+static int connect_port(struct sockaddr_in *addrp, in_port_t port, char *proto,
+ struct sockaddr_in *svaddr, int nonblock);
+
+char conftoken_getc(void);
+int conftoken_ungetc(int c);
/*
* Keep calling read() until we've read buflen's worth of data, or EOF,
* Returns the number of bytes read, 0 on EOF, or negative on error.
*/
ssize_t
-fullread(fd, vbuf, buflen)
- int fd;
- void *vbuf;
- size_t buflen;
+fullread(
+ int fd,
+ void * vbuf,
+ size_t buflen)
{
ssize_t nread, tot = 0;
char *buf = vbuf; /* cast to char so we can ++ it */
* Returns the number of bytes written, or negative on error.
*/
ssize_t
-fullwrite(fd, vbuf, buflen)
- int fd;
- const void *vbuf;
- size_t buflen;
+fullwrite(
+ int fd,
+ const void *vbuf,
+ size_t buflen)
{
ssize_t nwritten, tot = 0;
const char *buf = vbuf; /* cast to char so we can ++ it */
return (tot);
}
+static int
+make_socket(void)
+{
+ int s;
+ int save_errno;
+#if defined(SO_KEEPALIVE) || defined(USE_REUSEADDR)
+ int on=1;
+ int r;
+#endif
+
+ if ((s = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
+ save_errno = errno;
+ dbprintf(("%s: make_socket: socket() failed: %s\n",
+ debug_prefix(NULL),
+ strerror(save_errno)));
+ errno = save_errno;
+ return -1;
+ }
+ if (s < 0 || s >= (int)FD_SETSIZE) {
+ aclose(s);
+ errno = EMFILE; /* out of range */
+ return -1;
+ }
+
+#ifdef USE_REUSEADDR
+ r = setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
+ if (r < 0) {
+ save_errno = errno;
+ dbprintf(("%s: stream_server: setsockopt(SO_REUSEADDR) failed: %s\n",
+ debug_prefix(NULL),
+ strerror(errno)));
+ errno = save_errno;
+ }
+#endif
+
+#ifdef SO_KEEPALIVE
+ r = setsockopt(s, SOL_SOCKET, SO_KEEPALIVE,
+ (void *)&on, SIZEOF(on));
+ if (r == -1) {
+ save_errno = errno;
+ dbprintf(("%s: make_socket: setsockopt() failed: %s\n",
+ debug_prefix(NULL),
+ strerror(save_errno)));
+ aclose(s);
+ errno = save_errno;
+ return -1;
+ }
+#endif
+
+ return s;
+}
+
+/* addrp is my address */
+/* svaddr is the address of the remote machine */
+/* return socket on success */
+/* return -1 on failure */
+int
+connect_portrange(
+ struct sockaddr_in *addrp,
+ in_port_t first_port,
+ in_port_t last_port,
+ char * proto,
+ struct sockaddr_in *svaddr,
+ int nonblock)
+{
+ int s;
+ in_port_t port;
+ static in_port_t port_in_use[1024];
+ static int nb_port_in_use = 0;
+ int i;
+
+ assert(first_port <= last_port);
+
+ /* Try a port already used */
+ for(i=0; i < nb_port_in_use; i++) {
+ port = port_in_use[i];
+ if(port >= first_port && port <= last_port) {
+ s = connect_port(addrp, port, proto, svaddr, nonblock);
+ if(s == -2) return -1;
+ if(s > 0) {
+ return s;
+ }
+ }
+ }
+
+ /* Try a port in the range */
+ for (port = first_port; port <= last_port; port++) {
+ s = connect_port(addrp, port, proto, svaddr, nonblock);
+ if(s == -2) return -1;
+ if(s > 0) {
+ port_in_use[nb_port_in_use++] = port;
+ return s;
+ }
+ }
+
+ dbprintf(("%s: connect_portrange: all ports between %d and %d busy\n",
+ debug_prefix_time(NULL),
+ first_port,
+ last_port));
+ errno = EAGAIN;
+ return -1;
+}
+
+/* addrp is my address */
+/* svaddr is the address of the remote machine */
+/* return -2: Don't try again */
+/* return -1: Try with another port */
+/* return >0: this is the connected socket */
+int
+connect_port(
+ struct sockaddr_in *addrp,
+ in_port_t port,
+ char * proto,
+ struct sockaddr_in *svaddr,
+ int nonblock)
+{
+ int save_errno;
+ struct servent * servPort;
+ socklen_t len;
+ int s;
+
+ servPort = getservbyport((int)htons(port), proto);
+ if (servPort != NULL && !strstr(servPort->s_name, "amanda")) {
+ dbprintf(("%s: connect_port: Skip port %d: Owned by %s.\n",
+ debug_prefix_time(NULL), port, servPort->s_name));
+ return -1;
+ }
+
+ if(servPort == NULL)
+ dbprintf(("%s: connect_port: Try port %d: Available - ",
+ debug_prefix_time(NULL), port));
+ else {
+ dbprintf(("%s: connect_port: Try port %d: Owned by %s - ",
+ debug_prefix_time(NULL), port, servPort->s_name));
+ }
+
+ if ((s = make_socket()) == -1) return -2;
+
+ addrp->sin_port = (in_port_t)htons(port);
+
+ if (bind(s, (struct sockaddr *)addrp, sizeof(*addrp)) != 0) {
+ save_errno = errno;
+ aclose(s);
+ if (save_errno != EADDRINUSE) {
+ dbprintf(("errno %d strerror %s\n",
+ errno, strerror(errno)));
+ errno = save_errno;
+ return -2;
+ }
+ errno = save_errno;
+ return -1;
+ }
+
+ /* find out what port was actually used */
+
+ len = sizeof(*addrp);
+ if (getsockname(s, (struct sockaddr *)addrp, &len) == -1) {
+ save_errno = errno;
+ dbprintf(("%s: connect_port: getsockname() failed: %s\n",
+ debug_prefix(NULL),
+ strerror(save_errno)));
+ aclose(s);
+ errno = save_errno;
+ return -1;
+ }
+
+ if (nonblock)
+ fcntl(s, F_SETFL, fcntl(s, F_GETFL, 0)|O_NONBLOCK);
+ if (connect(s, (struct sockaddr *)svaddr,
+ (socklen_t)sizeof(*svaddr)) == -1 && !nonblock) {
+ save_errno = errno;
+ dbprintf(("%s: connect_portrange: connect from %s.%d failed\n",
+ debug_prefix_time(NULL),
+ inet_ntoa(addrp->sin_addr),
+ ntohs(addrp->sin_port),
+ strerror(save_errno)));
+ dbprintf(("%s: connect_portrange: connect to %s.%d failed: %s\n",
+ debug_prefix_time(NULL),
+ inet_ntoa(svaddr->sin_addr),
+ ntohs(svaddr->sin_port),
+ strerror(save_errno)));
+ aclose(s);
+ errno = save_errno;
+ if (save_errno == ECONNREFUSED ||
+ save_errno == ETIMEDOUT) {
+ return -2 ;
+ }
+ return -1;
+ }
+
+ dbprintf(("%s: connected to %s.%d\n",
+ debug_prefix_time(NULL),
+ inet_ntoa(svaddr->sin_addr),
+ ntohs(svaddr->sin_port)));
+ dbprintf(("%s: our side is %s.%d\n",
+ debug_prefix(NULL),
+ inet_ntoa(addrp->sin_addr),
+ ntohs(addrp->sin_port)));
+ return s;
+}
+
+
/*
* Bind to a port in the given range. Takes a begin,end pair of port numbers.
*
* on success.
*/
int
-bind_portrange(s, addrp, first_port, last_port, proto)
- int s;
- struct sockaddr_in *addrp;
- int first_port, last_port;
- char *proto;
+bind_portrange(
+ int s,
+ struct sockaddr_in *addrp,
+ in_port_t first_port,
+ in_port_t last_port,
+ char * proto)
{
- int port, cnt;
- const int num_ports = last_port - first_port + 1;
- int save_errno;
+ in_port_t port;
+ in_port_t cnt;
struct servent *servPort;
+ const in_port_t num_ports = (in_port_t)(last_port - first_port + 1);
- assert(first_port > 0 && first_port <= last_port && last_port < 65536);
+ assert(first_port <= last_port);
/*
* We pick a different starting port based on our pid and the current
* time to avoid always picking the same reserved port twice.
*/
- port = ((getpid() + time(0)) % num_ports) + first_port;
+ port = (in_port_t)(((getpid() + time(0)) % num_ports) + first_port);
+
/*
* Scan through the range, trying all available ports that are either
* not taken in /etc/services or registered for *amanda*. Wrap around
* if we don't happen to start at the beginning.
*/
for (cnt = 0; cnt < num_ports; cnt++) {
- servPort = getservbyport(htons(port), proto);
- if((servPort == NULL) || strstr(servPort->s_name, "amanda")){
- dbprintf(("%s: bind_portrange2: trying port=%d\n",
+ servPort = getservbyport((int)htons(port), proto);
+ if ((servPort == NULL) || strstr(servPort->s_name, "amanda")) {
+ if (servPort == NULL) {
+ dbprintf(("%s: bind_portrange2: Try port %d: Available - ",
debug_prefix_time(NULL), port));
- addrp->sin_port = htons(port);
- if (bind(s, (struct sockaddr *)addrp, sizeof(*addrp)) >= 0)
+ } else {
+ dbprintf(("%s: bind_portrange2: Try port %d: Owned by %s - ",
+ debug_prefix_time(NULL), port, servPort->s_name));
+ }
+ addrp->sin_port = (in_port_t)htons(port);
+ if (bind(s, (struct sockaddr *)addrp, (socklen_t)sizeof(*addrp)) >= 0) {
+ dbprintf(("Success\n"));
return 0;
- /*
- * If the error was something other then port in use, stop.
- */
- if (errno != EADDRINUSE)
- break;
+ }
+ dbprintf(("%s\n", strerror(errno)));
+ } else {
+ dbprintf(("%s: bind_portrange2: Skip port %d: Owned by %s.\n",
+ debug_prefix_time(NULL), port, servPort->s_name));
}
if (++port > last_port)
port = first_port;
}
- if (cnt == num_ports) {
- dbprintf(("%s: bind_portrange: all ports between %d and %d busy\n",
+ dbprintf(("%s: bind_portrange: all ports between %d and %d busy\n",
debug_prefix_time(NULL),
first_port,
last_port));
- errno = EAGAIN;
- } else if (last_port < IPPORT_RESERVED
- && getuid() != 0
- && errno == EACCES) {
- /*
- * Do not bother with an error message in this case because it
- * is expected.
- */
- } else {
- save_errno = errno;
- dbprintf(("%s: bind_portrange: port %d: %s\n",
- debug_prefix_time(NULL),
- port,
- strerror(errno)));
- errno = save_errno;
- }
+ errno = EAGAIN;
return -1;
}
* Construct a datestamp (YYYYMMDD) from a time_t.
*/
char *
-construct_datestamp(t)
- time_t *t;
+construct_datestamp(
+ time_t *t)
{
struct tm *tm;
- char datestamp[3*NUM_STR_SIZE];
+ char datestamp[3 * NUM_STR_SIZE];
time_t when;
- if(t == NULL) {
+ if (t == NULL) {
when = time((time_t *)NULL);
} else {
when = *t;
}
tm = localtime(&when);
- snprintf(datestamp, sizeof(datestamp),
+ if (!tm)
+ return stralloc("19000101");
+
+ snprintf(datestamp, SIZEOF(datestamp),
"%04d%02d%02d", tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday);
return stralloc(datestamp);
}
* Construct a timestamp (YYYYMMDDHHMMSS) from a time_t.
*/
char *
-construct_timestamp(t)
- time_t *t;
+construct_timestamp(
+ time_t *t)
{
struct tm *tm;
- char timestamp[6*NUM_STR_SIZE];
+ char timestamp[6 * NUM_STR_SIZE];
time_t when;
- if(t == NULL) {
+ if (t == NULL) {
when = time((time_t *)NULL);
} else {
when = *t;
}
tm = localtime(&when);
- snprintf(timestamp, sizeof(timestamp),
+ if (!tm)
+ return stralloc("19000101000000");
+
+ snprintf(timestamp, SIZEOF(timestamp),
"%04d%02d%02d%02d%02d%02d",
tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday,
tm->tm_hour, tm->tm_min, tm->tm_sec);
return stralloc(timestamp);
}
+
+
+int
+needs_quotes(
+ const char * str)
+{
+ return (match("[ \t\f\r\n\"]", str) != 0);
+}
+
+
+/*
+ * For backward compatibility we are trying for minimal quoting.
+ * We only quote a string if it contains whitespace or is misquoted...
+ */
+
+char *
+quote_string(
+ const char *str)
+{
+ char * s;
+ char * ret;
+
+ if ((str == NULL) || (*str == '\0')) {
+ ret = stralloc("\"\"");
+ } else if ((match("[\\\"[:space:][:cntrl:]]", str)) == 0) {
+ /*
+ * String does not need to be quoted since it contains
+ * neither whitespace, control or quote characters.
+ */
+ ret = stralloc(str);
+ } else {
+ /*
+ * Allocate maximum possible string length.
+ * (a string of all quotes plus room for leading ", trailing " and NULL)
+ */
+ ret = s = alloc((strlen(str) * 2) + 2 + 1);
+ *(s++) = '"';
+ while (*str != '\0') {
+ if (*str == '\t') {
+ *(s++) = '\\';
+ *(s++) = 't';
+ str++;
+ continue;
+ } else if (*str == '\n') {
+ *(s++) = '\\';
+ *(s++) = 'n';
+ str++;
+ continue;
+ } else if (*str == '\r') {
+ *(s++) = '\\';
+ *(s++) = 'r';
+ str++;
+ continue;
+ } else if (*str == '\f') {
+ *(s++) = '\\';
+ *(s++) = 'f';
+ str++;
+ continue;
+ }
+ if (*str == '"')
+ *(s++) = '\\';
+ *(s++) = *(str++);
+ }
+ *(s++) = '"';
+ *s = '\0';
+ }
+ return (ret);
+}
+
+
+char *
+unquote_string(
+ const char *str)
+{
+ char * ret;
+
+ if ((str == NULL) || (*str == '\0')) {
+ ret = stralloc("");
+ } else {
+ char * in;
+ char * out;
+
+ ret = in = out = stralloc(str);
+ while (*in != '\0') {
+ if (*in == '"') {
+ in++;
+ continue;
+ }
+
+ if (*in == '\\') {
+ in++;
+ if (*in == 'n') {
+ in++;
+ *(out++) = '\n';
+ continue;
+ } else if (*in == 't') {
+ in++;
+ *(out++) = '\t';
+ continue;
+ } else if (*in == 'r') {
+ in++;
+ *(out++) = '\r';
+ continue;
+ } else if (*in == 'f') {
+ in++;
+ *(out++) = '\f';
+ continue;
+ }
+ }
+ *(out++) = *(in++);
+ }
+ *out = '\0';
+ }
+ return (ret);
+}
+
+char *
+sanitize_string(
+ const char *str)
+{
+ char * s;
+ char * ret;
+
+ if ((str == NULL) || (*str == '\0')) {
+ ret = stralloc("");
+ } else {
+ ret = stralloc(str);
+ for (s = ret; *s != '\0'; s++) {
+ if (iscntrl(*s))
+ *s = '?';
+ }
+ }
+ return (ret);
+}
+
+char *
+strquotedstr(void)
+{
+ char * tok = strtok(NULL, " ");
+
+ if ((tok != NULL) && (tok[0] == '"')) {
+ char * t;
+ size_t len;
+
+ len = strlen(tok);
+ do {
+ t = strtok(NULL, " ");
+ tok[len] = ' ';
+ len = strlen(tok);
+ } while ((t != NULL) &&
+ (tok[len - 1] != '"') && (tok[len - 2] != '\\'));
+ }
+ return tok;
+}
+
+ssize_t
+hexdump(
+ const char *buffer,
+ size_t len)
+{
+ ssize_t rc = -1;
+
+ FILE *stream = popen("od -w10 -c -x -", "w");
+
+ if (stream != NULL) {
+ fflush(stdout);
+ rc = (ssize_t)fwrite(buffer, len, 1, stream);
+ if (ferror(stream))
+ rc = -1;
+ fclose(stream);
+ }
+ return rc;
+}
+
+/*
+ Return 0 if the following characters are present
+ * ( ) < > [ ] , ; : ! $ \ / "
+ else returns 1
+*/
+
+int
+validate_mailto(
+ const char *mailto)
+{
+ return !match("\\*|<|>|\\(|\\)|\\[|\\]|,|;|:|\\\\|/|\"|\\!|\\$|\\|", mailto);
+}
+
+
+t_conf_var *
+get_np(
+ t_conf_var *get_var,
+ int parm)
+{
+ t_conf_var *np;
+
+ for(np = get_var; np->token != CONF_UNKNOWN; np++) {
+ if(np->parm == parm)
+ break;
+ }
+
+ if(np->token == CONF_UNKNOWN) {
+ error("error [unknown getconf_np parm: %d]", parm);
+ /* NOTREACHED */
+ }
+ return np;
+}
+
+void
+get_simple(
+ val_t *var,
+ tok_t type)
+{
+ ckseen(&var->seen);
+
+ switch(type) {
+ case CONF_STRING:
+ case CONF_IDENT:
+ get_conftoken(type);
+ var->v.s = newstralloc(var->v.s, tokenval.v.s);
+ malloc_mark(var->v.s);
+ break;
+
+ case CONF_INT:
+ var->v.i = get_int();
+ break;
+
+ case CONF_LONG:
+ var->v.l = get_long();
+ break;
+
+ case CONF_SIZE:
+ var->v.size = get_size();
+ break;
+
+ case CONF_AM64:
+ var->v.am64 = get_am64_t();
+ break;
+
+ case CONF_BOOL:
+ var->v.i = get_bool();
+ break;
+
+ case CONF_REAL:
+ get_conftoken(CONF_REAL);
+ var->v.r = tokenval.v.r;
+ break;
+
+ case CONF_TIME:
+ var->v.t = get_time();
+ break;
+
+ default:
+ error("error [unknown get_simple type: %d]", type);
+ /* NOTREACHED */
+ }
+ return;
+}
+
+time_t
+get_time(void)
+{
+ time_t hhmm;
+
+ get_conftoken(CONF_ANY);
+ switch(tok) {
+ case CONF_INT:
+#if SIZEOF_TIME_T < SIZEOF_INT
+ if ((off_t)tokenval.v.i >= (off_t)TIME_MAX)
+ conf_parserror("value too large");
+#endif
+ hhmm = (time_t)tokenval.v.i;
+ break;
+
+ case CONF_LONG:
+#if SIZEOF_TIME_T < SIZEOF_LONG
+ if ((off_t)tokenval.v.l >= (off_t)TIME_MAX)
+ conf_parserror("value too large");
+#endif
+ hhmm = (time_t)tokenval.v.l;
+ break;
+
+ case CONF_SIZE:
+#if SIZEOF_TIME_T < SIZEOF_SSIZE_T
+ if ((off_t)tokenval.v.size >= (off_t)TIME_MAX)
+ conf_parserror("value too large");
+#endif
+ hhmm = (time_t)tokenval.v.size;
+ break;
+
+ case CONF_AM64:
+#if SIZEOF_TIME_T < SIZEOF_LONG_LONG
+ if ((off_t)tokenval.v.am64 >= (off_t)TIME_MAX)
+ conf_parserror("value too large");
+#endif
+ hhmm = (time_t)tokenval.v.am64;
+ break;
+
+ case CONF_AMINFINITY:
+ hhmm = TIME_MAX;
+ break;
+
+ default:
+ conf_parserror("a time is expected");
+ hhmm = 0;
+ break;
+ }
+ return hhmm;
+}
+
+keytab_t numb_keytable[] = {
+ { "B", CONF_MULT1 },
+ { "BPS", CONF_MULT1 },
+ { "BYTE", CONF_MULT1 },
+ { "BYTES", CONF_MULT1 },
+ { "DAY", CONF_MULT1 },
+ { "DAYS", CONF_MULT1 },
+ { "INF", CONF_AMINFINITY },
+ { "K", CONF_MULT1K },
+ { "KB", CONF_MULT1K },
+ { "KBPS", CONF_MULT1K },
+ { "KBYTE", CONF_MULT1K },
+ { "KBYTES", CONF_MULT1K },
+ { "KILOBYTE", CONF_MULT1K },
+ { "KILOBYTES", CONF_MULT1K },
+ { "KPS", CONF_MULT1K },
+ { "M", CONF_MULT1M },
+ { "MB", CONF_MULT1M },
+ { "MBPS", CONF_MULT1M },
+ { "MBYTE", CONF_MULT1M },
+ { "MBYTES", CONF_MULT1M },
+ { "MEG", CONF_MULT1M },
+ { "MEGABYTE", CONF_MULT1M },
+ { "MEGABYTES", CONF_MULT1M },
+ { "G", CONF_MULT1G },
+ { "GB", CONF_MULT1G },
+ { "GBPS", CONF_MULT1G },
+ { "GBYTE", CONF_MULT1G },
+ { "GBYTES", CONF_MULT1G },
+ { "GIG", CONF_MULT1G },
+ { "GIGABYTE", CONF_MULT1G },
+ { "GIGABYTES", CONF_MULT1G },
+ { "MPS", CONF_MULT1M },
+ { "TAPE", CONF_MULT1 },
+ { "TAPES", CONF_MULT1 },
+ { "WEEK", CONF_MULT7 },
+ { "WEEKS", CONF_MULT7 },
+ { NULL, CONF_IDENT }
+};
+
+int
+get_int(void)
+{
+ int val;
+ keytab_t *save_kt;
+
+ save_kt = keytable;
+ keytable = numb_keytable;
+
+ get_conftoken(CONF_ANY);
+ switch(tok) {
+ case CONF_INT:
+ val = tokenval.v.i;
+ break;
+
+ case CONF_LONG:
+#if SIZEOF_INT < SIZEOF_LONG
+ if ((off_t)tokenval.v.l > (off_t)INT_MAX)
+ conf_parserror("value too large");
+ if ((off_t)tokenval.v.l < (off_t)INT_MIN)
+ conf_parserror("value too small");
+#endif
+ val = (int)tokenval.v.l;
+ break;
+
+ case CONF_SIZE:
+#if SIZEOF_INT < SIZEOF_SSIZE_T
+ if ((off_t)tokenval.v.size > (off_t)INT_MAX)
+ conf_parserror("value too large");
+ if ((off_t)tokenval.v.size < (off_t)INT_MIN)
+ conf_parserror("value too small");
+#endif
+ val = (int)tokenval.v.size;
+ break;
+
+ case CONF_AM64:
+#if SIZEOF_INT < SIZEOF_LONG_LONG
+ if (tokenval.v.am64 > (off_t)INT_MAX)
+ conf_parserror("value too large");
+ if (tokenval.v.am64 < (off_t)INT_MIN)
+ conf_parserror("value too small");
+#endif
+ val = (int)tokenval.v.am64;
+ break;
+
+ case CONF_AMINFINITY:
+ val = INT_MAX;
+ break;
+
+ default:
+ conf_parserror("an int is expected");
+ val = 0;
+ break;
+ }
+
+ /* get multiplier, if any */
+ get_conftoken(CONF_ANY);
+ switch(tok) {
+ case CONF_NL: /* multiply by one */
+ case CONF_END:
+ case CONF_MULT1:
+ case CONF_MULT1K:
+ break;
+
+ case CONF_MULT7:
+ if (val > (INT_MAX / 7))
+ conf_parserror("value too large");
+ if (val < (INT_MIN / 7))
+ conf_parserror("value too small");
+ val *= 7;
+ break;
+
+ case CONF_MULT1M:
+ if (val > (INT_MAX / 1024))
+ conf_parserror("value too large");
+ if (val < (INT_MIN / 1024))
+ conf_parserror("value too small");
+ val *= 1024;
+ break;
+
+ case CONF_MULT1G:
+ if (val > (INT_MAX / (1024 * 1024)))
+ conf_parserror("value too large");
+ if (val < (INT_MIN / (1024 * 1024)))
+ conf_parserror("value too small");
+ val *= 1024 * 1024;
+ break;
+
+ default: /* it was not a multiplier */
+ unget_conftoken();
+ break;
+ }
+
+ keytable = save_kt;
+ return val;
+}
+
+long
+get_long(void)
+{
+ long val;
+ keytab_t *save_kt;
+
+ save_kt = keytable;
+ keytable = numb_keytable;
+
+ get_conftoken(CONF_ANY);
+
+ switch(tok) {
+ case CONF_LONG:
+ val = tokenval.v.l;
+ break;
+
+ case CONF_INT:
+#if SIZEOF_LONG < SIZEOF_INT
+ if ((off_t)tokenval.v.i > (off_t)LONG_MAX)
+ conf_parserror("value too large");
+ if ((off_t)tokenval.v.i < (off_t)LONG_MIN)
+ conf_parserror("value too small");
+#endif
+ val = (long)tokenval.v.i;
+ break;
+
+ case CONF_SIZE:
+#if SIZEOF_LONG < SIZEOF_SSIZE_T
+ if ((off_t)tokenval.v.size > (off_t)LONG_MAX)
+ conf_parserror("value too large");
+ if ((off_t)tokenval.v.size < (off_t)LONG_MIN)
+ conf_parserror("value too small");
+#endif
+ val = (long)tokenval.v.size;
+ break;
+
+ case CONF_AM64:
+#if SIZEOF_LONG < SIZEOF_LONG_LONG
+ if (tokenval.v.am64 > (off_t)LONG_MAX)
+ conf_parserror("value too large");
+ if (tokenval.v.am64 < (off_t)LONG_MIN)
+ conf_parserror("value too small");
+#endif
+ val = (long)tokenval.v.am64;
+ break;
+
+ case CONF_AMINFINITY:
+ val = (long)LONG_MAX;
+ break;
+
+ default:
+ conf_parserror("a long is expected");
+ val = 0;
+ break;
+ }
+
+ /* get multiplier, if any */
+ get_conftoken(CONF_ANY);
+
+ switch(tok) {
+ case CONF_NL: /* multiply by one */
+ case CONF_MULT1:
+ case CONF_MULT1K:
+ break;
+
+ case CONF_MULT7:
+ if (val > (LONG_MAX / 7L))
+ conf_parserror("value too large");
+ if (val < (LONG_MIN / 7L))
+ conf_parserror("value too small");
+ val *= 7L;
+ break;
+
+ case CONF_MULT1M:
+ if (val > (LONG_MAX / 1024L))
+ conf_parserror("value too large");
+ if (val < (LONG_MIN / 1024L))
+ conf_parserror("value too small");
+ val *= 1024L;
+ break;
+
+ case CONF_MULT1G:
+ if (val > (LONG_MAX / (1024L * 1024L)))
+ conf_parserror("value too large");
+ if (val < (LONG_MIN / (1024L * 1024L)))
+ conf_parserror("value too small");
+ val *= 1024L * 1024L;
+ break;
+
+ default: /* it was not a multiplier */
+ unget_conftoken();
+ break;
+ }
+
+ keytable = save_kt;
+ return val;
+}
+
+ssize_t
+get_size(void)
+{
+ ssize_t val;
+ keytab_t *save_kt;
+
+ save_kt = keytable;
+ keytable = numb_keytable;
+
+ get_conftoken(CONF_ANY);
+
+ switch(tok) {
+ case CONF_SIZE:
+ val = tokenval.v.size;
+ break;
+
+ case CONF_INT:
+#if SIZEOF_SIZE_T < SIZEOF_INT
+ if ((off_t)tokenval.v.i > (off_t)SSIZE_MAX)
+ conf_parserror("value too large");
+ if ((off_t)tokenval.v.i < (off_t)SSIZE_MIN)
+ conf_parserror("value too small");
+#endif
+ val = (ssize_t)tokenval.v.i;
+ break;
+
+ case CONF_LONG:
+#if SIZEOF_SIZE_T < SIZEOF_LONG
+ if ((off_t)tokenval.v.l > (off_t)SSIZE_MAX)
+ conf_parserror("value too large");
+ if ((off_t)tokenval.v.l < (off_t)SSIZE_MIN)
+ conf_parserror("value too small");
+#endif
+ val = (ssize_t)tokenval.v.l;
+ break;
+
+ case CONF_AM64:
+#if SIZEOF_SIZE_T < SIZEOF_LONG_LONG
+ if (tokenval.v.am64 > (off_t)SSIZE_MAX)
+ conf_parserror("value too large");
+ if (tokenval.v.am64 < (off_t)SSIZE_MIN)
+ conf_parserror("value too small");
+#endif
+ val = (ssize_t)tokenval.v.am64;
+ break;
+
+ case CONF_AMINFINITY:
+ val = (ssize_t)SSIZE_MAX;
+ break;
+
+ default:
+ conf_parserror("an integer is expected");
+ val = 0;
+ break;
+ }
+
+ /* get multiplier, if any */
+ get_conftoken(CONF_ANY);
+
+ switch(tok) {
+ case CONF_NL: /* multiply by one */
+ case CONF_MULT1:
+ case CONF_MULT1K:
+ break;
+
+ case CONF_MULT7:
+ if (val > (ssize_t)(SSIZE_MAX / 7))
+ conf_parserror("value too large");
+ if (val < (ssize_t)(SSIZE_MIN / 7))
+ conf_parserror("value too small");
+ val *= (ssize_t)7;
+ break;
+
+ case CONF_MULT1M:
+ if (val > (ssize_t)(SSIZE_MAX / (ssize_t)1024))
+ conf_parserror("value too large");
+ if (val < (ssize_t)(SSIZE_MIN / (ssize_t)1024))
+ conf_parserror("value too small");
+ val *= (ssize_t)1024;
+ break;
+
+ case CONF_MULT1G:
+ if (val > (ssize_t)(SSIZE_MAX / (1024 * 1024)))
+ conf_parserror("value too large");
+ if (val < (ssize_t)(SSIZE_MIN / (1024 * 1024)))
+ conf_parserror("value too small");
+ val *= (ssize_t)(1024 * 1024);
+ break;
+
+ default: /* it was not a multiplier */
+ unget_conftoken();
+ break;
+ }
+
+ keytable = save_kt;
+ return val;
+}
+
+off_t
+get_am64_t(void)
+{
+ off_t val;
+ keytab_t *save_kt;
+
+ save_kt = keytable;
+ keytable = numb_keytable;
+
+ get_conftoken(CONF_ANY);
+
+ switch(tok) {
+ case CONF_INT:
+ val = (off_t)tokenval.v.i;
+ break;
+
+ case CONF_LONG:
+ val = (off_t)tokenval.v.l;
+ break;
+
+ case CONF_SIZE:
+ val = (off_t)tokenval.v.size;
+ break;
+
+ case CONF_AM64:
+ val = tokenval.v.am64;
+ break;
+
+ case CONF_AMINFINITY:
+ val = AM64_MAX;
+ break;
+
+ default:
+ conf_parserror("an am64 is expected %d", tok);
+ val = 0;
+ break;
+ }
+
+ /* get multiplier, if any */
+ get_conftoken(CONF_ANY);
+
+ switch(tok) {
+ case CONF_NL: /* multiply by one */
+ case CONF_MULT1:
+ case CONF_MULT1K:
+ break;
+
+ case CONF_MULT7:
+ if (val > AM64_MAX/7 || val < AM64_MIN/7)
+ conf_parserror("value too large");
+ val *= 7;
+ break;
+
+ case CONF_MULT1M:
+ if (val > AM64_MAX/1024 || val < AM64_MIN/1024)
+ conf_parserror("value too large");
+ val *= 1024;
+ break;
+
+ case CONF_MULT1G:
+ if (val > AM64_MAX/(1024*1024) || val < AM64_MIN/(1024*1024))
+ conf_parserror("value too large");
+ val *= 1024*1024;
+ break;
+
+ default: /* it was not a multiplier */
+ unget_conftoken();
+ break;
+ }
+
+ keytable = save_kt;
+
+ return val;
+}
+
+keytab_t bool_keytable[] = {
+ { "Y", CONF_ATRUE },
+ { "YES", CONF_ATRUE },
+ { "T", CONF_ATRUE },
+ { "TRUE", CONF_ATRUE },
+ { "ON", CONF_ATRUE },
+ { "N", CONF_AFALSE },
+ { "NO", CONF_AFALSE },
+ { "F", CONF_AFALSE },
+ { "FALSE", CONF_AFALSE },
+ { "OFF", CONF_AFALSE },
+ { NULL, CONF_IDENT }
+};
+
+int
+get_bool(void)
+{
+ int val;
+ keytab_t *save_kt;
+
+ save_kt = keytable;
+ keytable = bool_keytable;
+
+ get_conftoken(CONF_ANY);
+
+ switch(tok) {
+ case CONF_INT:
+ if (tokenval.v.i != 0)
+ val = 1;
+ else
+ val = 0;
+ break;
+
+ case CONF_LONG:
+ if (tokenval.v.l != 0L)
+ val = 1;
+ else
+ val = 0;
+ break;
+
+ case CONF_SIZE:
+ if (tokenval.v.size != (size_t)0)
+ val = 1;
+ else
+ val = 0;
+ break;
+
+ case CONF_AM64:
+ if (tokenval.v.am64 != (off_t)0)
+ val = 1;
+ else
+ val = 0;
+ break;
+
+ case CONF_ATRUE:
+ val = 1;
+ break;
+
+ case CONF_AFALSE:
+ val = 0;
+ break;
+
+ case CONF_NL:
+ unget_conftoken();
+ val = 2; /* no argument - most likely TRUE */
+ break;
+ default:
+ unget_conftoken();
+ val = 3; /* a bad argument - most likely TRUE */
+ conf_parserror("YES, NO, TRUE, FALSE, ON, OFF expected");
+ break;
+ }
+
+ keytable = save_kt;
+ return val;
+}
+
+void
+ckseen(
+ int *seen)
+{
+ if (*seen && !allow_overwrites && conf_line_num != -2) {
+ conf_parserror("duplicate parameter, prev def on line %d", *seen);
+ }
+ *seen = conf_line_num;
+}
+
+printf_arglist_function(void conf_parserror, const char *, format)
+{
+ va_list argp;
+
+ /* print error message */
+
+ if(conf_line)
+ fprintf(stderr, "argument \"%s\": ", conf_line);
+ else
+ fprintf(stderr, "\"%s\", line %d: ", conf_confname, conf_line_num);
+ arglist_start(argp, format);
+ vfprintf(stderr, format, argp);
+ arglist_end(argp);
+ fputc('\n', stderr);
+
+ got_parserror = 1;
+}
+
+tok_t
+lookup_keyword(
+ char * str)
+{
+ keytab_t *kwp;
+
+ /* switch to binary search if performance warrants */
+
+ for(kwp = keytable; kwp->keyword != NULL; kwp++) {
+ if (strcmp(kwp->keyword, str) == 0) break;
+ }
+ return kwp->token;
+}
+
+char tkbuf[4096];
+
+/* push the last token back (can only unget ANY tokens) */
+void
+unget_conftoken(void)
+{
+ token_pushed = 1;
+ pushed_tok = tok;
+ tok = CONF_UNKNOWN;
+ return;
+}
+
+char
+conftoken_getc(void)
+{
+ if(conf_line == NULL)
+ return getc(conf_conf);
+ if(*conf_char == '\0')
+ return -1;
+ return(*conf_char++);
+}
+
+int
+conftoken_ungetc(
+ int c)
+{
+ if(conf_line == NULL)
+ return ungetc(c, conf_conf);
+ else if(conf_char > conf_line) {
+ if(c == -1)
+ return c;
+ conf_char--;
+ if(*conf_char != c) {
+ error("*conf_char != c : %c %c", *conf_char, c);
+ /* NOTREACHED */
+ }
+ } else {
+ error("conf_char == conf_line");
+ /* NOTREACHED */
+ }
+ return c;
+}
+
+void
+get_conftoken(
+ tok_t exp)
+{
+ int ch, d;
+ off_t am64;
+ char *buf;
+ char *tmps;
+ int token_overflow;
+ int inquote = 0;
+ int escape = 0;
+ int sign;
+
+ if (token_pushed) {
+ token_pushed = 0;
+ tok = pushed_tok;
+
+ /*
+ ** If it looked like a key word before then look it
+ ** up again in the current keyword table.
+ */
+ switch(tok) {
+ case CONF_LONG: case CONF_AM64: case CONF_SIZE:
+ case CONF_INT: case CONF_REAL: case CONF_STRING:
+ case CONF_LBRACE: case CONF_RBRACE: case CONF_COMMA:
+ case CONF_NL: case CONF_END: case CONF_UNKNOWN:
+ case CONF_TIME:
+ break;
+
+ default:
+ if (exp == CONF_IDENT)
+ tok = CONF_IDENT;
+ else
+ tok = lookup_keyword(tokenval.v.s);
+ break;
+ }
+ }
+ else {
+ ch = conftoken_getc();
+
+ while(ch != EOF && ch != '\n' && isspace(ch))
+ ch = conftoken_getc();
+ if (ch == '#') { /* comment - eat everything but eol/eof */
+ while((ch = conftoken_getc()) != EOF && ch != '\n') {
+ (void)ch; /* Quiet empty loop complaints */
+ }
+ }
+
+ if (isalpha(ch)) { /* identifier */
+ buf = tkbuf;
+ token_overflow = 0;
+ do {
+ if (islower(ch)) ch = toupper(ch);
+ if (buf < tkbuf+sizeof(tkbuf)-1) {
+ *buf++ = (char)ch;
+ } else {
+ *buf = '\0';
+ if (!token_overflow) {
+ conf_parserror("token too long: %.20s...", tkbuf);
+ }
+ token_overflow = 1;
+ }
+ ch = conftoken_getc();
+ } while(isalnum(ch) || ch == '_' || ch == '-');
+
+ if (ch != EOF && conftoken_ungetc(ch) == EOF) {
+ if (ferror(conf_conf)) {
+ conf_parserror("Pushback of '%c' failed: %s",
+ ch, strerror(ferror(conf_conf)));
+ } else {
+ conf_parserror("Pushback of '%c' failed: EOF", ch);
+ }
+ }
+ *buf = '\0';
+
+ tokenval.v.s = tkbuf;
+
+ if (token_overflow) tok = CONF_UNKNOWN;
+ else if (exp == CONF_IDENT) tok = CONF_IDENT;
+ else tok = lookup_keyword(tokenval.v.s);
+ }
+ else if (isdigit(ch)) { /* integer */
+ sign = 1;
+
+negative_number: /* look for goto negative_number below sign is set there */
+ am64 = 0;
+ do {
+ am64 = am64 * 10 + (ch - '0');
+ ch = conftoken_getc();
+ } while (isdigit(ch));
+
+ if (ch != '.') {
+ if (exp == CONF_INT) {
+ tok = CONF_INT;
+ tokenval.v.i = sign * (int)am64;
+ } else if (exp == CONF_LONG) {
+ tok = CONF_LONG;
+ tokenval.v.l = (long)sign * (long)am64;
+ } else if (exp != CONF_REAL) {
+ tok = CONF_AM64;
+ tokenval.v.am64 = (off_t)sign * am64;
+ } else {
+ /* automatically convert to real when expected */
+ tokenval.v.r = (double)sign * (double)am64;
+ tok = CONF_REAL;
+ }
+ } else {
+ /* got a real number, not an int */
+ tokenval.v.r = sign * (double) am64;
+ am64 = 0;
+ d = 1;
+ ch = conftoken_getc();
+ while (isdigit(ch)) {
+ am64 = am64 * 10 + (ch - '0');
+ d = d * 10;
+ ch = conftoken_getc();
+ }
+ tokenval.v.r += sign * ((double)am64) / d;
+ tok = CONF_REAL;
+ }
+
+ if (ch != EOF && conftoken_ungetc(ch) == EOF) {
+ if (ferror(conf_conf)) {
+ conf_parserror("Pushback of '%c' failed: %s",
+ ch, strerror(ferror(conf_conf)));
+ } else {
+ conf_parserror("Pushback of '%c' failed: EOF", ch);
+ }
+ }
+ } else switch(ch) {
+ case '"': /* string */
+ buf = tkbuf;
+ token_overflow = 0;
+ inquote = 1;
+ *buf++ = (char)ch;
+ while (inquote && ((ch = conftoken_getc()) != EOF)) {
+ if (ch == '\n') {
+ if (!escape)
+ break;
+ escape = 0;
+ buf--; /* Consume escape in buffer */
+ } else if (ch == '\\') {
+ escape = 1;
+ } else {
+ if (ch == '"') {
+ if (!escape)
+ inquote = 0;
+ }
+ escape = 0;
+ }
+
+ if(buf >= &tkbuf[sizeof(tkbuf) - 1]) {
+ if (!token_overflow) {
+ conf_parserror("string too long: %.20s...", tkbuf);
+ }
+ token_overflow = 1;
+ break;
+ }
+ *buf++ = (char)ch;
+ }
+ *buf = '\0';
+
+ /*
+ * A little manuver to leave a fully unquoted, unallocated string
+ * in tokenval.v.s
+ */
+ tmps = unquote_string(tkbuf);
+ strncpy(tkbuf, tmps, sizeof(tkbuf));
+ amfree(tmps);
+ tokenval.v.s = tkbuf;
+
+ tok = (token_overflow) ? CONF_UNKNOWN :
+ (exp == CONF_IDENT) ? CONF_IDENT : CONF_STRING;
+ break;
+
+ case '-':
+ ch = conftoken_getc();
+ if (isdigit(ch)) {
+ sign = -1;
+ goto negative_number;
+ }
+ else {
+ if (ch != EOF && conftoken_ungetc(ch) == EOF) {
+ if (ferror(conf_conf)) {
+ conf_parserror("Pushback of '%c' failed: %s",
+ ch, strerror(ferror(conf_conf)));
+ } else {
+ conf_parserror("Pushback of '%c' failed: EOF", ch);
+ }
+ }
+ tok = CONF_UNKNOWN;
+ }
+ break;
+
+ case ',':
+ tok = CONF_COMMA;
+ break;
+
+ case '{':
+ tok = CONF_LBRACE;
+ break;
+
+ case '}':
+ tok = CONF_RBRACE;
+ break;
+
+ case '\n':
+ tok = CONF_NL;
+ break;
+
+ case EOF:
+ tok = CONF_END;
+ break;
+
+ default:
+ tok = CONF_UNKNOWN;
+ break;
+ }
+ }
+
+ if (exp != CONF_ANY && tok != exp) {
+ char *str;
+ keytab_t *kwp;
+
+ switch(exp) {
+ case CONF_LBRACE:
+ str = "\"{\"";
+ break;
+
+ case CONF_RBRACE:
+ str = "\"}\"";
+ break;
+
+ case CONF_COMMA:
+ str = "\",\"";
+ break;
+
+ case CONF_NL:
+ str = "end of line";
+ break;
+
+ case CONF_END:
+ str = "end of file";
+ break;
+
+ case CONF_INT:
+ str = "an integer";
+ break;
+
+ case CONF_REAL:
+ str = "a real number";
+ break;
+
+ case CONF_STRING:
+ str = "a quoted string";
+ break;
+
+ case CONF_IDENT:
+ str = "an identifier";
+ break;
+
+ default:
+ for(kwp = keytable; kwp->keyword != NULL; kwp++) {
+ if (exp == kwp->token)
+ break;
+ }
+ if (kwp->keyword == NULL)
+ str = "token not";
+ else
+ str = kwp->keyword;
+ break;
+ }
+ conf_parserror("%s is expected", str);
+ tok = exp;
+ if (tok == CONF_INT)
+ tokenval.v.i = 0;
+ else
+ tokenval.v.s = "";
+ }
+}
+
+
+void
+read_string(
+ t_conf_var *np,
+ val_t *val)
+{
+ np = np;
+ ckseen(&val->seen);
+ get_conftoken(CONF_STRING);
+ val->v.s = newstralloc(val->v.s, tokenval.v.s);
+}
+
+void
+read_ident(
+ t_conf_var *np,
+ val_t *val)
+{
+ np = np;
+ ckseen(&val->seen);
+ get_conftoken(CONF_IDENT);
+ val->v.s = newstralloc(val->v.s, tokenval.v.s);
+}
+
+void
+read_int(
+ t_conf_var *np,
+ val_t *val)
+{
+ np = np;
+ ckseen(&val->seen);
+ val->v.i = get_int();
+}
+
+void
+read_long(
+ t_conf_var *np,
+ val_t *val)
+{
+ np = np;
+ ckseen(&val->seen);
+ val->v.l = get_long();
+}
+
+void
+read_size(
+ t_conf_var *np,
+ val_t *val)
+{
+ np = np;
+ ckseen(&val->seen);
+ val->v.size = get_size();
+}
+
+void
+read_am64(
+ t_conf_var *np,
+ val_t *val)
+{
+ np = np;
+ ckseen(&val->seen);
+ val->v.am64 = get_am64_t();
+}
+
+void
+read_bool(
+ t_conf_var *np,
+ val_t *val)
+{
+ np = np;
+ ckseen(&val->seen);
+ val->v.i = get_bool();
+}
+
+void
+read_real(
+ t_conf_var *np,
+ val_t *val)
+{
+ np = np;
+ ckseen(&val->seen);
+ get_conftoken(CONF_REAL);
+ val->v.r = tokenval.v.r;
+}
+
+void
+read_time(
+ t_conf_var *np,
+ val_t *val)
+{
+ np = np;
+ ckseen(&val->seen);
+ val->v.t = get_time();
+}
+
+void
+copy_val_t(
+ val_t *valdst,
+ val_t *valsrc)
+{
+ if(valsrc->seen) {
+ valdst->type = valsrc->type;
+ valdst->seen = valsrc->seen;
+ switch(valsrc->type) {
+ case CONFTYPE_INT:
+ case CONFTYPE_BOOL:
+ case CONFTYPE_COMPRESS:
+ case CONFTYPE_ENCRYPT:
+ case CONFTYPE_HOLDING:
+ case CONFTYPE_ESTIMATE:
+ case CONFTYPE_STRATEGY:
+ case CONFTYPE_TAPERALGO:
+ case CONFTYPE_PRIORITY:
+ valdst->v.i = valsrc->v.i;
+ break;
+
+ case CONFTYPE_LONG:
+ valdst->v.l = valsrc->v.l;
+ break;
+
+ case CONFTYPE_SIZE:
+ valdst->v.size = valsrc->v.size;
+ break;
+
+ case CONFTYPE_AM64:
+ valdst->v.am64 = valsrc->v.am64;
+ break;
+
+ case CONFTYPE_REAL:
+ valdst->v.r = valsrc->v.r;
+ break;
+
+ case CONFTYPE_RATE:
+ valdst->v.rate[0] = valsrc->v.rate[0];
+ valdst->v.rate[1] = valsrc->v.rate[1];
+ break;
+
+ case CONFTYPE_IDENT:
+ case CONFTYPE_STRING:
+ valdst->v.s = stralloc(valsrc->v.s);
+ break;
+
+ case CONFTYPE_TIME:
+ valdst->v.t = valsrc->v.t;
+ break;
+
+ case CONFTYPE_SL:
+ valdst->v.sl = duplicate_sl(valsrc->v.sl);
+ break;
+
+ case CONFTYPE_EXINCLUDE:
+ valdst->v.exinclude.type = valsrc->v.exinclude.type;
+ valdst->v.exinclude.optional = valsrc->v.exinclude.optional;
+ valdst->v.exinclude.sl = duplicate_sl(valsrc->v.exinclude.sl);
+ break;
+ }
+ }
+}
+
+void
+free_val_t(
+ val_t *val)
+{
+ switch(val->type) {
+ case CONFTYPE_INT:
+ case CONFTYPE_BOOL:
+ case CONFTYPE_COMPRESS:
+ case CONFTYPE_ENCRYPT:
+ case CONFTYPE_HOLDING:
+ case CONFTYPE_ESTIMATE:
+ case CONFTYPE_STRATEGY:
+ case CONFTYPE_SIZE:
+ case CONFTYPE_TAPERALGO:
+ case CONFTYPE_PRIORITY:
+ case CONFTYPE_LONG:
+ case CONFTYPE_AM64:
+ case CONFTYPE_REAL:
+ case CONFTYPE_RATE:
+ break;
+
+ case CONFTYPE_IDENT:
+ case CONFTYPE_STRING:
+ amfree(val->v.s);
+ break;
+
+ case CONFTYPE_TIME:
+ break;
+
+ case CONFTYPE_SL:
+ free_sl(val->v.sl);
+ break;
+
+ case CONFTYPE_EXINCLUDE:
+ free_sl(val->v.exinclude.sl);
+ break;
+ }
+ val->seen = 0;
+}
+
+char *
+taperalgo2str(
+ int taperalgo)
+{
+ if(taperalgo == ALGO_FIRST) return "FIRST";
+ if(taperalgo == ALGO_FIRSTFIT) return "FIRSTFIT";
+ if(taperalgo == ALGO_LARGEST) return "LARGEST";
+ if(taperalgo == ALGO_LARGESTFIT) return "LARGESTFIT";
+ if(taperalgo == ALGO_SMALLEST) return "SMALLEST";
+ if(taperalgo == ALGO_LAST) return "LAST";
+ return "UNKNOWN";
+}
+
+static char buffer_conf_print[1025];
+
+char *
+conf_print(
+ val_t *val)
+{
+ struct tm *stm;
+ int pos;
+
+ buffer_conf_print[0] = '\0';
+ switch(val->type) {
+ case CONFTYPE_INT:
+ snprintf(buffer_conf_print, SIZEOF(buffer_conf_print), "%d", val->v.i);
+ break;
+
+ case CONFTYPE_LONG:
+ snprintf(buffer_conf_print, SIZEOF(buffer_conf_print), "%ld", val->v.l);
+ break;
+
+ case CONFTYPE_SIZE:
+ snprintf(buffer_conf_print, SIZEOF(buffer_conf_print), SSIZE_T_FMT,
+ (SSIZE_T_FMT_TYPE)val->v.size);
+ break;
+
+ case CONFTYPE_AM64:
+ snprintf(buffer_conf_print, SIZEOF(buffer_conf_print), OFF_T_FMT ,
+ (OFF_T_FMT_TYPE)val->v.am64);
+ break;
+
+ case CONFTYPE_REAL:
+ snprintf(buffer_conf_print, SIZEOF(buffer_conf_print), "%0.5f" , val->v.r);
+ break;
+
+ case CONFTYPE_RATE:
+ snprintf(buffer_conf_print, SIZEOF(buffer_conf_print), "%0.5f %0.5f" , val->v.rate[0], val->v.rate[1]);
+ break;
+
+ case CONFTYPE_IDENT:
+ if(val->v.s) {
+ strncpy(buffer_conf_print, val->v.s, SIZEOF(buffer_conf_print));
+ buffer_conf_print[SIZEOF(buffer_conf_print) - 1] = '\0';
+ } else
+ buffer_conf_print[0] = '\0';
+ break;
+
+ case CONFTYPE_STRING:
+ buffer_conf_print[0] = '"';
+ if(val->v.s) {
+ strncpy(&buffer_conf_print[1], val->v.s,
+ SIZEOF(buffer_conf_print) - 1);
+ buffer_conf_print[SIZEOF(buffer_conf_print) - 2] = '\0';
+ buffer_conf_print[strlen(buffer_conf_print)] = '"';
+ } else {
+ buffer_conf_print[1] = '"';
+ buffer_conf_print[2] = '\0';
+ }
+ break;
+
+ case CONFTYPE_TIME:
+ stm = localtime(&val->v.t);
+ if (stm) {
+ snprintf(buffer_conf_print, SIZEOF(buffer_conf_print),
+ "%d%02d%02d", stm->tm_hour, stm->tm_min, stm->tm_sec);
+ } else {
+ strcpy(buffer_conf_print, "00000");
+ }
+ break;
+
+ case CONFTYPE_SL:
+ buffer_conf_print[0] = '\0';
+ break;
+
+ case CONFTYPE_EXINCLUDE:
+ buffer_conf_print[0] = '\0';
+ if(val->v.exinclude.type == 0)
+ strncpy(buffer_conf_print, "LIST ", SIZEOF(buffer_conf_print));
+ else
+ strncpy(buffer_conf_print, "FILE ", SIZEOF(buffer_conf_print));
+ pos = 5;
+ if(val->v.exinclude.optional == 1)
+ strncpy(&buffer_conf_print[pos], "OPTIONAL ", SIZEOF(buffer_conf_print));
+ pos += 9;
+ break;
+
+ case CONFTYPE_BOOL:
+ if(val->v.i)
+ strncpy(buffer_conf_print, "yes", SIZEOF(buffer_conf_print));
+ else
+ strncpy(buffer_conf_print, "no", SIZEOF(buffer_conf_print));
+ break;
+
+ case CONFTYPE_STRATEGY:
+ switch(val->v.i) {
+ case DS_SKIP:
+ strncpy(buffer_conf_print, "SKIP", SIZEOF(buffer_conf_print));
+ break;
+
+ case DS_STANDARD:
+ strncpy(buffer_conf_print, "STANDARD", SIZEOF(buffer_conf_print));
+ break;
+
+ case DS_NOFULL:
+ strncpy(buffer_conf_print, "NOFULL", SIZEOF(buffer_conf_print));
+ break;
+
+ case DS_NOINC:
+ strncpy(buffer_conf_print, "NOINC", SIZEOF(buffer_conf_print));
+ break;
+
+ case DS_HANOI:
+ strncpy(buffer_conf_print, "HANOI", SIZEOF(buffer_conf_print));
+ break;
+
+ case DS_INCRONLY:
+ strncpy(buffer_conf_print, "INCRONLY", SIZEOF(buffer_conf_print));
+ break;
+ }
+ break;
+
+ case CONFTYPE_COMPRESS:
+ switch(val->v.i) {
+ case COMP_NONE:
+ strncpy(buffer_conf_print, "NONE", SIZEOF(buffer_conf_print));
+ break;
+
+ case COMP_FAST:
+ strncpy(buffer_conf_print, "CLIENT FAST", SIZEOF(buffer_conf_print));
+ break;
+
+ case COMP_BEST:
+ strncpy(buffer_conf_print, "CLIENT BEST", SIZEOF(buffer_conf_print));
+ break;
+
+ case COMP_CUST:
+ strncpy(buffer_conf_print, "CLIENT CUSTOM", SIZEOF(buffer_conf_print));
+ break;
+
+ case COMP_SERV_FAST:
+ strncpy(buffer_conf_print, "SERVER FAST", SIZEOF(buffer_conf_print));
+ break;
+
+ case COMP_SERV_BEST:
+ strncpy(buffer_conf_print, "SERVER FAST", SIZEOF(buffer_conf_print));
+ break;
+
+ case COMP_SERV_CUST:
+ strncpy(buffer_conf_print, "SERVER CUSTOM", SIZEOF(buffer_conf_print));
+ break;
+ }
+ break;
+
+ case CONFTYPE_ESTIMATE:
+ switch(val->v.i) {
+ case ES_CLIENT:
+ strncpy(buffer_conf_print, "CLIENT", SIZEOF(buffer_conf_print));
+ break;
+
+ case ES_SERVER:
+ strncpy(buffer_conf_print, "SERVER", SIZEOF(buffer_conf_print));
+ break;
+
+ case ES_CALCSIZE:
+ strncpy(buffer_conf_print, "CALCSIZE", SIZEOF(buffer_conf_print));
+ break;
+ }
+ break;
+
+ case CONFTYPE_ENCRYPT:
+ switch(val->v.i) {
+ case ENCRYPT_NONE:
+ strncpy(buffer_conf_print, "NONE", SIZEOF(buffer_conf_print));
+ break;
+
+ case ENCRYPT_CUST:
+ strncpy(buffer_conf_print, "CLIENT", SIZEOF(buffer_conf_print));
+ break;
+
+ case ENCRYPT_SERV_CUST:
+ strncpy(buffer_conf_print, "SERVER", SIZEOF(buffer_conf_print));
+ break;
+ }
+ break;
+
+ case CONFTYPE_HOLDING:
+ switch(val->v.i) {
+ case HOLD_NEVER:
+ strncpy(buffer_conf_print, "NEVER", SIZEOF(buffer_conf_print));
+ break;
+
+ case HOLD_AUTO:
+ strncpy(buffer_conf_print, "AUTO", SIZEOF(buffer_conf_print));
+ break;
+
+ case HOLD_REQUIRED:
+ strncpy(buffer_conf_print, "REQUIRED", SIZEOF(buffer_conf_print));
+ break;
+ }
+ break;
+
+ case CONFTYPE_TAPERALGO:
+ strncpy(buffer_conf_print, taperalgo2str(val->v.i), SIZEOF(buffer_conf_print));
+ break;
+
+ case CONFTYPE_PRIORITY:
+ switch(val->v.i) {
+ case 0:
+ strncpy(buffer_conf_print, "LOW", SIZEOF(buffer_conf_print));
+ break;
+
+ case 1:
+ strncpy(buffer_conf_print, "MEDIUM", SIZEOF(buffer_conf_print));
+ break;
+
+ case 2:
+ strncpy(buffer_conf_print, "HIGH", SIZEOF(buffer_conf_print));
+ break;
+ }
+ break;
+ }
+ buffer_conf_print[SIZEOF(buffer_conf_print) - 1] = '\0';
+ return buffer_conf_print;
+}
+
+void
+conf_init_string(
+ val_t *val,
+ char *s)
+{
+ val->seen = 0;
+ val->type = CONFTYPE_STRING;
+ if(s)
+ val->v.s = stralloc(s);
+ else
+ val->v.s = NULL;
+}
+
+void
+conf_init_ident(
+ val_t *val,
+ char *s)
+{
+ val->seen = 0;
+ val->type = CONFTYPE_IDENT;
+ if(s)
+ val->v.s = stralloc(s);
+ else
+ val->v.s = NULL;
+}
+
+void
+conf_init_int(
+ val_t *val,
+ int i)
+{
+ val->seen = 0;
+ val->type = CONFTYPE_INT;
+ val->v.i = i;
+}
+
+void
+conf_init_bool(
+ val_t *val,
+ int i)
+{
+ val->seen = 0;
+ val->type = CONFTYPE_BOOL;
+ val->v.i = i;
+}
+
+void
+conf_init_strategy(
+ val_t *val,
+ int i)
+{
+ val->seen = 0;
+ val->type = CONFTYPE_STRATEGY;
+ val->v.i = i;
+}
+
+void
+conf_init_estimate(
+ val_t *val,
+ int i)
+{
+ val->seen = 0;
+ val->type = CONFTYPE_ESTIMATE;
+ val->v.i = i;
+}
+
+void
+conf_init_taperalgo(
+ val_t *val,
+ int i)
+{
+ val->seen = 0;
+ val->type = CONFTYPE_TAPERALGO;
+ val->v.i = i;
+}
+
+void
+conf_init_priority(
+ val_t *val,
+ int i)
+{
+ val->seen = 0;
+ val->type = CONFTYPE_PRIORITY;
+ val->v.i = i;
+}
+
+void
+conf_init_compress(
+ val_t *val,
+ comp_t i)
+{
+ val->seen = 0;
+ val->type = CONFTYPE_COMPRESS;
+ val->v.i = (int)i;
+}
+
+void
+conf_init_encrypt(
+ val_t *val,
+ encrypt_t i)
+{
+ val->seen = 0;
+ val->type = CONFTYPE_ENCRYPT;
+ val->v.i = (int)i;
+}
+
+void
+conf_init_holding(
+ val_t *val,
+ dump_holdingdisk_t i)
+{
+ val->seen = 0;
+ val->type = CONFTYPE_HOLDING;
+ val->v.i = (int)i;
+}
+
+void
+conf_init_long(
+ val_t *val,
+ long l)
+{
+ val->seen = 0;
+ val->type = CONFTYPE_LONG;
+ val->v.l = l;
+}
+
+void
+conf_init_size(
+ val_t *val,
+ ssize_t sz)
+{
+ val->seen = 0;
+ val->type = CONFTYPE_SIZE;
+ val->v.size = sz;
+}
+
+void
+conf_init_am64(
+ val_t *val,
+ off_t l)
+{
+ val->seen = 0;
+ val->type = CONFTYPE_AM64;
+ val->v.am64 = l;
+}
+
+void
+conf_init_real(
+ val_t *val,
+ double r)
+{
+ val->seen = 0;
+ val->type = CONFTYPE_REAL;
+ val->v.r = r;
+}
+
+void
+conf_init_rate(
+ val_t *val,
+ double r1,
+ double r2)
+{
+ val->seen = 0;
+ val->type = CONFTYPE_RATE;
+ val->v.rate[0] = r1;
+ val->v.rate[1] = r2;
+}
+
+void
+conf_init_time(
+ val_t *val,
+ time_t t)
+{
+ val->seen = 0;
+ val->type = CONFTYPE_TIME;
+ val->v.t = t;
+}
+
+void
+conf_init_sl(
+ val_t *val,
+ sl_t *sl)
+{
+ val->seen = 0;
+ val->type = CONFTYPE_AM64;
+ val->v.sl = sl;
+}
+
+void
+conf_init_exinclude(
+ val_t *val)
+{
+ val->seen = 0;
+ val->type = CONFTYPE_EXINCLUDE;
+ val->v.exinclude.type = 0;
+ val->v.exinclude.optional = 0;
+ val->v.exinclude.sl = NULL;
+}
+
+void
+conf_set_string(
+ val_t *val,
+ char *s)
+{
+ val->seen = -1;
+ val->type = CONFTYPE_STRING;
+ amfree(val->v.s);
+ val->v.s = stralloc(s);
+}
+
+void
+conf_set_int(
+ val_t *val,
+ int i)
+{
+ val->seen = -1;
+ val->type = CONFTYPE_INT;
+ val->v.i = i;
+}
+
+void
+conf_set_bool(
+ val_t *val,
+ int i)
+{
+ val->seen = -1;
+ val->type = CONFTYPE_BOOL;
+ val->v.i = i;
+}
+
+void
+conf_set_compress(
+ val_t *val,
+ comp_t i)
+{
+ val->seen = -1;
+ val->type = CONFTYPE_COMPRESS;
+ val->v.i = (int)i;
+}
+
+void
+conf_set_encrypt(
+ val_t *val,
+ encrypt_t i)
+{
+ val->seen = -1;
+ val->type = CONFTYPE_COMPRESS;
+ val->v.i = (int)i;
+}
+
+void
+conf_set_holding(
+ val_t *val,
+ dump_holdingdisk_t i)
+{
+ val->seen = -1;
+ val->type = CONFTYPE_HOLDING;
+ val->v.i = (int)i;
+}
+
+void
+conf_set_strategy(
+ val_t *val,
+ int i)
+{
+ val->seen = -1;
+ val->type = CONFTYPE_STRATEGY;
+ val->v.i = i;
+}
+
+
+int
+get_conftype_int(
+ val_t *val)
+{
+ if (val->type != CONFTYPE_INT) {
+ error("get_conftype_int: val.type is not CONFTYPE_INT");
+ /*NOTREACHED*/
+ }
+ return val->v.i;
+}
+
+long
+get_conftype_long(
+ val_t *val)
+{
+ if (val->type != CONFTYPE_LONG) {
+ error("get_conftype_long: val.type is not CONFTYPE_LONG");
+ /*NOTREACHED*/
+ }
+ return val->v.l;
+}
+
+off_t
+get_conftype_am64(
+ val_t *val)
+{
+ if (val->type != CONFTYPE_AM64) {
+ error("get_conftype_am64: val.type is not CONFTYPE_AM64");
+ /*NOTREACHED*/
+ }
+ return val->v.am64;
+}
+
+double
+get_conftype_real(
+ val_t *val)
+{
+ if (val->type != CONFTYPE_REAL) {
+ error("get_conftype_real: val.type is not CONFTYPE_REAL");
+ /*NOTREACHED*/
+ }
+ return val->v.r;
+}
+
+char *
+get_conftype_string(
+ val_t *val)
+{
+ if (val->type != CONFTYPE_STRING) {
+ error("get_conftype_string: val.type is not CONFTYPE_STRING");
+ /*NOTREACHED*/
+ }
+ return val->v.s;
+}
+
+char *
+get_conftype_ident(
+ val_t *val)
+{
+ if (val->type != CONFTYPE_IDENT) {
+ error("get_conftype_ident: val.type is not CONFTYPE_IDENT");
+ /*NOTREACHED*/
+ }
+ return val->v.s;
+}
+
+time_t
+get_conftype_time(
+ val_t *val)
+{
+ if (val->type != CONFTYPE_TIME) {
+ error("get_conftype_time: val.type is not CONFTYPE_TIME");
+ /*NOTREACHED*/
+ }
+ return val->v.t;
+}
+
+ssize_t
+get_conftype_size(
+ val_t *val)
+{
+ if (val->type != CONFTYPE_SIZE) {
+ error("get_conftype_size: val.type is not CONFTYPE_SIZE");
+ /*NOTREACHED*/
+ }
+ return val->v.size;
+}
+
+sl_t *
+get_conftype_sl(
+ val_t *val)
+{
+ if (val->type != CONFTYPE_SL) {
+ error("get_conftype_size: val.type is not CONFTYPE_SL");
+ /*NOTREACHED*/
+ }
+ return val->v.sl;
+}
+
+int
+get_conftype_bool(
+ val_t *val)
+{
+ if (val->type != CONFTYPE_BOOL) {
+ error("get_conftype_bool: val.type is not CONFTYPE_BOOL");
+ /*NOTREACHED*/
+ }
+ return val->v.i;
+}
+
+int
+get_conftype_hold(
+ val_t *val)
+{
+ if (val->type != CONFTYPE_HOLDING) {
+ error("get_conftype_hold: val.type is not CONFTYPE_HOLDING");
+ /*NOTREACHED*/
+ }
+ return val->v.i;
+}
+
+int
+get_conftype_compress(
+ val_t *val)
+{
+ if (val->type != CONFTYPE_COMPRESS) {
+ error("get_conftype_compress: val.type is not CONFTYPE_COMPRESS");
+ /*NOTREACHED*/
+ }
+ return val->v.i;
+}
+
+int
+get_conftype_encrypt(
+ val_t *val)
+{
+ if (val->type != CONFTYPE_ENCRYPT) {
+ error("get_conftype_encrypt: val.type is not CONFTYPE_ENCRYPT");
+ /*NOTREACHED*/
+ }
+ return val->v.i;
+}
+
+int
+get_conftype_estimate(
+ val_t *val)
+{
+ if (val->type != CONFTYPE_ESTIMATE) {
+ error("get_conftype_extimate: val.type is not CONFTYPE_ESTIMATE");
+ /*NOTREACHED*/
+ }
+ return val->v.i;
+}
+
+int
+get_conftype_strategy(
+ val_t *val)
+{
+ if (val->type != CONFTYPE_STRATEGY) {
+ error("get_conftype_strategy: val.type is not CONFTYPE_STRATEGY");
+ /*NOTREACHED*/
+ }
+ return val->v.i;
+}
+
+int
+get_conftype_taperalgo(
+ val_t *val)
+{
+ if (val->type != CONFTYPE_TAPERALGO) {
+ error("get_conftype_taperalgo: val.type is not CONFTYPE_TAPERALGO");
+ /*NOTREACHED*/
+ }
+ return val->v.i;
+}
+
+int
+get_conftype_priority(
+ val_t *val)
+{
+ if (val->type != CONFTYPE_PRIORITY) {
+ error("get_conftype_priority: val.type is not CONFTYPE_PRIORITY");
+ /*NOTREACHED*/
+ }
+ return val->v.i;
+}
+
+exinclude_t
+get_conftype_exinclude(
+ val_t *val)
+{
+ if (val->type != CONFTYPE_EXINCLUDE) {
+ error("get_conftype_exinclude: val.type is not CONFTYPE_EXINCLUDE");
+ /*NOTREACHED*/
+ }
+ return val->v.exinclude;
+}
+
+
+void
+dump_sockaddr(
+ struct sockaddr_in * sa)
+{
+ dbprintf(("%s: (sockaddr_in *)%p = { %d, %hd, %s }\n",
+ debug_prefix(NULL), sa, sa->sin_family, sa->sin_port,
+ inet_ntoa(sa->sin_addr)));
+}
+
+void
+read_block(
+ command_option_t *command_options,
+ t_conf_var *read_var,
+ keytab_t *keytab,
+ val_t *valarray,
+ char *prefix,
+ char *errormsg,
+ int read_brace,
+ void (*copy_function)(void))
+{
+ t_conf_var *np;
+ int saved_conf_line_num;
+ int done;
+
+ if(read_brace) {
+ get_conftoken(CONF_LBRACE);
+ get_conftoken(CONF_NL);
+ }
+
+ done = 0;
+ do {
+ conf_line_num += 1;
+ get_conftoken(CONF_ANY);
+ switch(tok) {
+ case CONF_RBRACE:
+ done = 1;
+ break;
+ case CONF_NL: /* empty line */
+ break;
+ case CONF_END: /* end of file */
+ done = 1;
+ break;
+ case CONF_IDENT:
+ case CONF_STRING:
+ if(copy_function)
+ copy_function();
+ else
+ conf_parserror("ident not expected");
+ break;
+ default:
+ {
+ for(np = read_var; np->token != CONF_UNKNOWN; np++)
+ if(np->token == tok) break;
+
+ if(np->token == CONF_UNKNOWN)
+ conf_parserror(errormsg);
+ else {
+ np->read_function(np, &valarray[np->parm]);
+ if(np->validate)
+ np->validate(np, &valarray[np->parm]);
+ }
+ }
+ }
+ if(tok != CONF_NL && tok != CONF_END && tok != CONF_RBRACE)
+ get_conftoken(CONF_NL);
+ } while(!done);
+
+ /* overwrite with command line option */
+ saved_conf_line_num = conf_line_num;
+ command_overwrite(command_options, read_var, keytab, valarray, prefix);
+ conf_line_num = saved_conf_line_num;
+}
+
+void
+command_overwrite(
+ command_option_t *command_options,
+ t_conf_var *overwrite_var,
+ keytab_t *keytab,
+ val_t *valarray,
+ char *prefix)
+{
+ t_conf_var *np;
+ keytab_t *kt;
+ char *myprefix;
+ command_option_t *command_option;
+
+ if(!command_options) return;
+
+ for(np = overwrite_var; np->token != CONF_UNKNOWN; np++) {
+ for(kt = keytab; kt->token != CONF_UNKNOWN; kt++)
+ if(kt->token == np->token) break;
+
+ if(kt->token == CONF_UNKNOWN) {
+ error("read_conf: invalid token");
+ /* NOTREACHED */
+ }
+
+ for(command_option = command_options; command_option->name != NULL;
+ command_option++) {
+ myprefix = stralloc2(prefix, kt->keyword);
+ if(strcasecmp(myprefix, command_option->name) == 0) {
+ command_option->used = 1;
+ valarray[np->parm].seen = -2;
+ if(np->type == CONFTYPE_STRING &&
+ command_option->value[0] != '"') {
+ conf_line = vstralloc("\"", command_option->value, "\"",
+ NULL);
+ }
+ else {
+ conf_line = stralloc(command_option->value);
+ }
+ conf_char = conf_line;
+ token_pushed = 0;
+ conf_line_num = -2;
+ np->read_function(np, &valarray[np->parm]);
+ amfree(conf_line);
+ conf_line = conf_char = NULL;
+
+ if(np->validate)
+ np->validate(np, &valarray[np->parm]);
+ }
+ amfree(myprefix);
+ }
+ }
+}
+
+void
+free_new_argv(
+ int new_argc,
+ char **new_argv)
+{
+ int i;
+ for(i=0; i<new_argc; i++)
+ amfree(new_argv[i]);
+ amfree(new_argv);
+}
+
+
+#ifndef HAVE_LIBREADLINE
+/*
+ * simple readline() replacements
+ */
+
+char *
+readline(
+ const char *prompt)
+{
+ printf("%s", prompt);
+ fflush(stdout);
+ fflush(stderr);
+ return agets(stdin);
+}
+
+void
+add_history(
+ const char *line)
+{
+ (void)line; /* Quite unused parameter warning */
+}
+#endif
* file named AUTHORS, in the root directory of this distribution.
*/
/*
- * $Id: util.h,v 1.5 2005/12/09 03:22:52 paddy_s Exp $
+ * $Id: util.h,v 1.17 2006/07/26 15:17:36 martinea Exp $
*/
#ifndef UTIL_H
#define UTIL_H
+#include "amanda.h"
+#include "sl.h"
+
+/* */
+typedef enum {
+ CONFTYPE_INT,
+ CONFTYPE_LONG,
+ CONFTYPE_AM64,
+ CONFTYPE_REAL,
+ CONFTYPE_STRING,
+ CONFTYPE_IDENT,
+ CONFTYPE_TIME,
+ CONFTYPE_SIZE,
+ CONFTYPE_SL,
+ CONFTYPE_BOOL,
+ CONFTYPE_COMPRESS,
+ CONFTYPE_ENCRYPT,
+ CONFTYPE_HOLDING,
+ CONFTYPE_ESTIMATE,
+ CONFTYPE_STRATEGY,
+ CONFTYPE_TAPERALGO,
+ CONFTYPE_PRIORITY,
+ CONFTYPE_RATE,
+ CONFTYPE_EXINCLUDE,
+} conftype_t;
+
+/* Compression types */
+typedef enum {
+ COMP_NONE, /* No compression */
+ COMP_FAST, /* Fast compression on client */
+ COMP_BEST, /* Best compression on client */
+ COMP_CUST, /* Custom compression on client */
+ COMP_SERV_FAST, /* Fast compression on server */
+ COMP_SERV_BEST, /* Best compression on server */
+ COMP_SERV_CUST /* Custom compression on server */
+} comp_t;
+
+/* Encryption types */
+typedef enum {
+ ENCRYPT_NONE, /* No encryption */
+ ENCRYPT_CUST, /* Custom encryption on client */
+ ENCRYPT_SERV_CUST, /* Custom encryption on server */
+} encrypt_t;
+
+/* holdingdisk types */
+typedef enum {
+ HOLD_NEVER, /* Always direct to tape */
+ HOLD_AUTO, /* If possible */
+ HOLD_REQUIRED /* Always to holding disk */
+} dump_holdingdisk_t;
+
+/* Dump strategies */
+#define DS_SKIP 0 /* Don't do any dumps at all */
+#define DS_STANDARD 1 /* Standard (0 1 1 1 1 2 2 2 ...) */
+#define DS_NOFULL 2 /* No full's (1 1 1 ...) */
+#define DS_NOINC 3 /* No inc's (0 0 0 ...) */
+#define DS_4 4 /* ? (0 1 2 3 4 5 6 7 8 9 10 11 ...) */
+#define DS_5 5 /* ? (0 1 1 1 1 1 1 1 1 1 1 1 ...) */
+#define DS_HANOI 6 /* Tower of Hanoi (? ? ? ? ? ...) */
+#define DS_INCRONLY 7 /* Forced fulls (0 1 1 2 2 FORCE0 1 1 ...) */
+
+/* Estimate strategies */
+#define ES_CLIENT 0 /* client estimate */
+#define ES_SERVER 1 /* server estimate */
+#define ES_CALCSIZE 2 /* calcsize estimate */
+
+#define ALGO_FIRST 0
+#define ALGO_FIRSTFIT 1
+#define ALGO_LARGEST 2
+#define ALGO_LARGESTFIT 3
+#define ALGO_SMALLEST 4
+#define ALGO_LAST 5
#define BSTRNCMP(a,b) strncmp(a, b, strlen(b))
-
-ssize_t fullread P((int, void *, size_t));
-ssize_t fullwrite P((int, const void *, size_t));
+typedef enum {
+ CONF_UNKNOWN, CONF_ANY, CONF_COMMA,
+ CONF_LBRACE, CONF_RBRACE, CONF_NL,
+ CONF_END, CONF_IDENT, CONF_INT,
+ CONF_LONG, CONF_AM64, CONF_BOOL,
+ CONF_REAL, CONF_STRING, CONF_TIME,
+ CONF_SIZE,
+
+ /* config parameters */
+ CONF_INCLUDEFILE, CONF_ORG, CONF_MAILTO,
+ CONF_DUMPUSER, CONF_TAPECYCLE, CONF_TAPEDEV,
+ CONF_CHNGRDEV, CONF_CHNGRFILE, CONF_LABELSTR,
+ CONF_BUMPPERCENT, CONF_BUMPSIZE, CONF_BUMPDAYS,
+ CONF_BUMPMULT, CONF_ETIMEOUT, CONF_DTIMEOUT,
+ CONF_CTIMEOUT, CONF_TAPEBUFS, CONF_TAPELIST,
+ CONF_DISKFILE, CONF_INFOFILE, CONF_LOGDIR,
+ CONF_LOGFILE, CONF_DISKDIR, CONF_DISKSIZE,
+ CONF_INDEXDIR, CONF_NETUSAGE, CONF_INPARALLEL,
+ CONF_DUMPORDER, CONF_TIMEOUT, CONF_TPCHANGER,
+ CONF_RUNTAPES, CONF_DEFINE, CONF_DUMPTYPE,
+ CONF_TAPETYPE, CONF_INTERFACE, CONF_PRINTER,
+ CONF_AUTOFLUSH, CONF_RESERVE, CONF_MAXDUMPSIZE,
+ CONF_COLUMNSPEC, CONF_AMRECOVER_DO_FSF, CONF_AMRECOVER_CHECK_LABEL,
+ CONF_AMRECOVER_CHANGER, CONF_LABEL_NEW_TAPES, CONF_USETIMESTAMPS,
+
+ CONF_TAPERALGO, CONF_FIRST, CONF_FIRSTFIT,
+ CONF_LARGEST, CONF_LARGESTFIT, CONF_SMALLEST,
+ CONF_LAST, CONF_DISPLAYUNIT,
+
+ /* kerberos 5 */
+ CONF_KRB5KEYTAB, CONF_KRB5PRINCIPAL,
+
+ /* holding disk */
+ CONF_COMMENT, CONF_DIRECTORY, CONF_USE,
+ CONF_CHUNKSIZE,
+
+ /* dump type */
+ /*COMMENT,*/ CONF_PROGRAM, CONF_DUMPCYCLE,
+ CONF_RUNSPERCYCLE, CONF_MAXCYCLE, CONF_MAXDUMPS,
+ CONF_OPTIONS, CONF_PRIORITY, CONF_FREQUENCY,
+ CONF_INDEX, CONF_MAXPROMOTEDAY, CONF_STARTTIME,
+ CONF_COMPRESS, CONF_ENCRYPT, CONF_AUTH,
+ CONF_STRATEGY, CONF_ESTIMATE, CONF_SKIP_INCR,
+ CONF_SKIP_FULL, CONF_RECORD, CONF_HOLDING,
+ CONF_EXCLUDE, CONF_INCLUDE, CONF_KENCRYPT,
+ CONF_IGNORE, CONF_COMPRATE, CONF_TAPE_SPLITSIZE,
+ CONF_SPLIT_DISKBUFFER, CONF_FALLBACK_SPLITSIZE,CONF_SRVCOMPPROG,
+ CONF_CLNTCOMPPROG, CONF_SRV_ENCRYPT, CONF_CLNT_ENCRYPT,
+ CONF_SRV_DECRYPT_OPT, CONF_CLNT_DECRYPT_OPT, CONF_AMANDAD_PATH,
+ CONF_CLIENT_USERNAME,
+
+ /* tape type */
+ /*COMMENT,*/ CONF_BLOCKSIZE, CONF_FILE_PAD,
+ CONF_LBL_TEMPL, CONF_FILEMARK, CONF_LENGTH,
+ CONF_SPEED,
+
+ /* client conf */
+ CONF_CONF, CONF_INDEX_SERVER, CONF_TAPE_SERVER,
+ CONF_SSH_KEYS, CONF_GNUTAR_LIST_DIR, CONF_AMANDATES,
+
+ /* network interface */
+ /* COMMENT, */ /* USE, */
+
+ /* dump options (obsolete) */
+ CONF_EXCLUDE_FILE, CONF_EXCLUDE_LIST,
+
+ /* compress, estimate, encryption */
+ CONF_NONE, CONF_FAST, CONF_BEST,
+ CONF_SERVER, CONF_CLIENT, CONF_CALCSIZE,
+ CONF_CUSTOM,
+
+ /* holdingdisk */
+ CONF_NEVER, CONF_AUTO, CONF_REQUIRED,
+
+ /* priority */
+ CONF_LOW, CONF_MEDIUM, CONF_HIGH,
+
+ /* dump strategy */
+ CONF_SKIP, CONF_STANDARD, CONF_NOFULL,
+ CONF_NOINC, CONF_HANOI, CONF_INCRONLY,
+
+ /* exclude list */
+ CONF_LIST, CONF_EFILE, CONF_APPEND,
+ CONF_OPTIONAL,
+
+ /* numbers */
+ CONF_AMINFINITY, CONF_MULT1, CONF_MULT7,
+ CONF_MULT1K, CONF_MULT1M, CONF_MULT1G,
+
+ /* boolean */
+ CONF_ATRUE, CONF_AFALSE,
+
+ CONF_RAWTAPEDEV
+} tok_t;
-int bind_portrange P((int, struct sockaddr_in *, int, int, char *));
+#define BIGINT INT_MAX
+
+/* internal types and variables */
+
+typedef struct { /* token table entry */
+ char *keyword;
+ tok_t token;
+} keytab_t;
+
+keytab_t *keytable;
+
+typedef struct {
+ char *name;
+ char *value;
+ int used;
+} command_option_t;
+
+typedef struct exinclude_s {
+ int type; /* 0=list 1=file */
+ sl_t *sl;
+ int optional;
+} exinclude_t;
+
+typedef struct val_s {
+ union {
+ int i;
+ long l;
+ off_t am64;
+ double r;
+ char *s;
+ sl_t *sl;
+ ssize_t size;
+ time_t t;
+ float rate[2];
+ exinclude_t exinclude;
+ } v;
+ int seen;
+ conftype_t type;
+} val_t;
+
+typedef struct s_conf_var {
+ tok_t token;
+ conftype_t type;
+ void (*read_function) (struct s_conf_var *, val_t*);
+ int parm;
+ void (*validate) (struct s_conf_var *, val_t *);
+} t_conf_var;
+
+extern int allow_overwrites;
+extern int token_pushed;
+
+extern tok_t tok, pushed_tok;
+extern val_t tokenval;
+
+extern int conf_line_num, got_parserror;
+extern FILE *conf_conf;
+extern char *conf_confname;
+extern char *conf_line;
+extern char *conf_char;
+
+/* predeclare local functions */
+
+t_conf_var *get_np(t_conf_var *get_var, int parm);
+void get_simple(val_t *var, tok_t type);
+int get_int(void);
+long get_long(void);
+time_t get_time(void);
+ssize_t get_size(void);
+off_t get_am64_t(void);
+int get_bool(void);
+void ckseen(int *seen);
+void conf_parserror(const char *format, ...)
+ __attribute__ ((format (printf, 1, 2)));
+tok_t lookup_keyword(char *str);
+void unget_conftoken(void);
+void get_conftoken(tok_t exp);
+
+void read_string(t_conf_var *, val_t *);
+void read_ident(t_conf_var *, val_t *);
+void read_int(t_conf_var *, val_t *);
+void read_long(t_conf_var *, val_t *);
+void read_size(t_conf_var *, val_t *);
+void read_am64(t_conf_var *, val_t *);
+void read_bool(t_conf_var *, val_t *);
+void read_real(t_conf_var *, val_t *);
+void read_time(t_conf_var *, val_t *);
+void copy_val_t(val_t *, val_t *);
+void free_val_t(val_t *);
+char *conf_print(val_t *);
+void conf_init_string(val_t *, char *);
+void conf_init_ident(val_t *, char *);
+void conf_init_int(val_t *, int);
+void conf_init_bool(val_t *, int);
+void conf_init_strategy(val_t *, int);
+void conf_init_estimate(val_t *, int);
+void conf_init_taperalgo(val_t *, int);
+void conf_init_priority(val_t *, int);
+void conf_init_strategy(val_t *, int);
+void conf_init_compress(val_t *, comp_t);
+void conf_init_encrypt(val_t *, encrypt_t);
+void conf_init_holding(val_t *, dump_holdingdisk_t);
+void conf_init_long(val_t *, long);
+void conf_init_size(val_t *, ssize_t);
+void conf_init_am64(val_t *, off_t);
+void conf_init_real(val_t *, double);
+void conf_init_rate(val_t *, double, double);
+void conf_init_time(val_t *, time_t);
+void conf_init_sl(val_t *, sl_t *);
+void conf_init_exinclude(val_t *);
+void conf_set_string(val_t *, char *);
+void conf_set_int(val_t *, int);
+void conf_set_bool(val_t *, int);
+void conf_set_compress(val_t *, comp_t);
+void conf_set_encrypt(val_t *, encrypt_t);
+void conf_set_holding(val_t *, dump_holdingdisk_t);
+void conf_set_strategy(val_t *, int);
+int get_conftype_int (val_t *);
+long get_conftype_long (val_t *);
+off_t get_conftype_am64 (val_t *);
+double get_conftype_real (val_t *);
+char *get_conftype_string (val_t *);
+char *get_conftype_ident (val_t *);
+time_t get_conftype_time (val_t *);
+ssize_t get_conftype_size (val_t *);
+sl_t *get_conftype_sl (val_t *);
+int get_conftype_bool (val_t *);
+int get_conftype_hold (val_t *);
+int get_conftype_compress (val_t *);
+int get_conftype_encrypt (val_t *);
+int get_conftype_estimate (val_t *);
+int get_conftype_strategy (val_t *);
+int get_conftype_taperalgo(val_t *);
+int get_conftype_priority (val_t *);
+float *get_conftype_rate (val_t *);
+exinclude_t get_conftype_exinclude(val_t *);
+
+void read_block(command_option_t *command_options, t_conf_var *read_var,
+ keytab_t *keytab, val_t *valarray, char *prefix, char *errormsg,
+ int read_brace, void (*copy_function)(void));
+void command_overwrite(command_option_t *command_options, t_conf_var *overwrite_var,
+ keytab_t *keytab, val_t *valarray, char *prefix);
+
+
+
+ssize_t fullread(int, void *, size_t);
+ssize_t fullwrite(int, const void *, size_t);
+
+int connect_portrange(struct sockaddr_in *, in_port_t, in_port_t, char *,
+ struct sockaddr_in *, int);
+int bind_portrange(int, struct sockaddr_in *, in_port_t, in_port_t,
+ char *);
+
+char * construct_datestamp(time_t *t);
+char * construct_timestamp(time_t *t);
+
+/*@only@*//*@null@*/char *quote_string(const char *str);
+/*@only@*//*@null@*/char *unquote_string(const char *str);
+int needs_quotes(const char * str);
+
+char * sanitize_string(const char *str);
+char * strquotedstr(void);
+ssize_t hexdump(const char *buffer, size_t bytes);
+void dump_sockaddr(struct sockaddr_in * sa);
+
+/*
+ * validate_email return 0 if the following characters are present
+ * * ( ) < > [ ] , ; : ! $ \ / "
+ * else returns 1
+ */
+int validate_mailto(const char *mailto);
-char *construct_datestamp P((time_t *t));
-char *construct_timestamp P((time_t *t));
+char *taperalgo2str(int taperalgo);
+void free_new_argv(int new_argc, char **new_argv);
#endif /* UTIL_H */
/* version.c - generated by genversion.c - DO NOT EDIT! */
const char * const version_info[] = {
- "build: VERSION=\"Amanda-2.5.0p2\"\n",
- " BUILT_DATE=\"Mon May 8 07:54:11 EDT 2006\"\n",
- " BUILT_MACH=\"Linux modemcable099.122-200-24.mc.videotron.ca 2.6.16-1.2111_FC5 #1 SMP Thu May 4 21:16:04 EDT 2006 x86_64 x86_64 x86_64 GNU/Linux\"\n",
+ "build: VERSION=\"Amanda-2.5.1\"\n",
+ " BUILT_DATE=\"Tue Sep 5 10:09:05 EDT 2006\"\n",
+ " BUILT_MACH=\"Linux modemcable197.174-201-24.mc.videotron.ca 2.6.17-1.2174_FC5 #1 SMP Tue Aug 8 15:30:44 EDT 2006 x86_64 x86_64 x86_64 GNU/Linux\"\n",
" CC=\"gcc\"\n",
" CONFIGURE_COMMAND=\"'./configure' '--prefix=/home/martinea/linux' '--with-configdir=/home/martinea/etc/amanda' '--with-gnutar-listdir=/var/gnutar-lists' '--with-bsd-security' '--with-ssh-security' '--with-rsh-security' '--with-krb4-security' '--without-krb5-security' '--with-user=martinea' '--with-group=martinea' '--mandir=/home/martinea/man'\"\n",
"paths: bindir=\"/home/martinea/linux/bin\"\n",
" COMPRESS_PATH=\"/usr/bin/gzip\"\n",
" UNCOMPRESS_PATH=\"/usr/bin/gzip\" LPRCMD=\"/usr/bin/lpr\"\n",
" MAILER=\"/usr/bin/Mail\" listed_incr_dir=\"/var/gnutar-lists\"\n",
- "defs: DEFAULT_SERVER=\"modemcable099.122-200-24.mc.videotron.ca\"\n",
+ "defs: DEFAULT_SERVER=\"modemcable197.174-201-24.mc.videotron.ca\"\n",
" DEFAULT_CONFIG=\"DailySet1\"\n",
- " DEFAULT_TAPE_SERVER=\"modemcable099.122-200-24.mc.videotron.ca\"\n",
- " DEFAULT_TAPE_DEVICE=\"null:\" HAVE_MMAP HAVE_SYSVSHM\n",
- " LOCKING=POSIX_FCNTL SETPGRP_VOID DEBUG_CODE\n",
- " AMANDA_DEBUG_DAYS=4 BSD_SECURITY RSH_SECURITY USE_AMANDAHOSTS\n",
- " CLIENT_LOGIN=\"martinea\" FORCE_USERID HAVE_GZIP\n",
- " COMPRESS_SUFFIX=\".gz\" COMPRESS_FAST_OPT=\"--fast\"\n",
+ " DEFAULT_TAPE_SERVER=\"modemcable197.174-201-24.mc.videotron.ca\"\n",
+ " HAVE_MMAP HAVE_SYSVSHM LOCKING=POSIX_FCNTL SETPGRP_VOID\n",
+ " DEBUG_CODE AMANDA_DEBUG_DAYS=4 BSD_SECURITY RSH_SECURITY\n",
+ " USE_AMANDAHOSTS CLIENT_LOGIN=\"martinea\" FORCE_USERID\n",
+ " HAVE_GZIP COMPRESS_SUFFIX=\".gz\" COMPRESS_FAST_OPT=\"--fast\"\n",
" COMPRESS_BEST_OPT=\"--best\" UNCOMPRESS_OPT=\"-dc\"\n",
0
};
* file named AUTHORS, in the root directory of this distribution.
*/
/*
- * $Id: version.h,v 1.5 1999/04/16 04:58:58 kashmir Exp $
+ * $Id: version.h,v 1.6 2006/05/25 01:47:12 johnfranks Exp $
*
* interface to obtain the current amanda version
*/
extern const char * const version_info[];
/* versionsuffix returns an empty string or a string like -2.3.0.4b1. */
-extern const char *versionsuffix P((void));
+extern const char *versionsuffix(void);
/* version returns a string representing the version of Amanda. */
-extern const char *version P((void));
+extern const char *version(void);
#endif
* file named AUTHORS, in the root directory of this distribution.
*/
/*
- * $Id: versuff.c.in,v 1.11 2003/05/20 17:33:53 martinea Exp $
+ * $Id: versuff.c.in,v 1.12 2006/05/25 01:47:12 johnfranks Exp $
*
* provide amanda version number and suffix appended to program names
*/
const int VERSION_MAJOR = 2;
const int VERSION_MINOR = 5;
-const int VERSION_PATCH = 0;
-const char *const VERSION_COMMENT = "p2";
+const int VERSION_PATCH = 1;
+const char *const VERSION_COMMENT = "";
const char *
-versionsuffix()
+versionsuffix(void)
{
#ifdef USE_VERSION_SUFFIXES
- return "-2.5.0p2";
+ return "-2.5.1";
#else
return "";
#endif
}
const char *
-version()
+version(void)
{
- return "2.5.0p2";
+ return "2.5.1";
}
* file named AUTHORS, in the root directory of this distribution.
*/
/*
- * $Id: versuff.c.in,v 1.11 2003/05/20 17:33:53 martinea Exp $
+ * $Id: versuff.c.in,v 1.12 2006/05/25 01:47:12 johnfranks Exp $
*
* provide amanda version number and suffix appended to program names
*/
const char *const VERSION_COMMENT = @VERSION_COMMENT@;
const char *
-versionsuffix()
+versionsuffix(void)
{
#ifdef USE_VERSION_SUFFIXES
return "-@VERSION_SUFFIX@";
}
const char *
-version()
+version(void)
{
return "@VERSION_SUFFIX@";
}
AMANDA_TMPDIR = @AMANDA_TMPDIR@
AMDEP_FALSE = @AMDEP_FALSE@
AMDEP_TRUE = @AMDEP_TRUE@
+AMLINT = @AMLINT@
+AMLINTFLAGS = @AMLINTFLAGS@
AMPLOT_CAT_COMPRESS = @AMPLOT_CAT_COMPRESS@
AMPLOT_CAT_GZIP = @AMPLOT_CAT_GZIP@
AMPLOT_CAT_PACK = @AMPLOT_CAT_PACK@
AMPLOT_COMPRESS = @AMPLOT_COMPRESS@
AMTAR = @AMTAR@
+AM_CFLAGS = @AM_CFLAGS@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AWK = @AWK@
AWK_VAR_ASSIGNMENT_OPT = @AWK_VAR_ASSIGNMENT_OPT@
BINARY_OWNER = @BINARY_OWNER@
+BUILD_MAN_PAGES_FALSE = @BUILD_MAN_PAGES_FALSE@
+BUILD_MAN_PAGES_TRUE = @BUILD_MAN_PAGES_TRUE@
CAT = @CAT@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
/* Define as the user who owns installed binaries. */
#undef BINARY_OWNER
+/* Define if BSDTCP transport should be enabled. */
+#undef BSDTCP_SECURITY
+
+/* Define if BSDUDP transport should be enabled. */
+#undef BSDUDP_SECURITY
+
/* Define to use BSD .rhosts/.amandahosts security. */
#undef BSD_SECURITY
/* Define if atof is declared. */
#undef HAVE_ATOF_DECL
+/* Define to 1 if you have the `atoi' function. */
+#undef HAVE_ATOI
+
+/* Define if atoi is declared. */
+#undef HAVE_ATOI_DECL
+
+/* Define to 1 if you have the `atol' function. */
+#undef HAVE_ATOL
+
+/* Define to 1 if you have the `atoll' function. */
+#undef HAVE_ATOLL
+
+/* Define if atoll is declared. */
+#undef HAVE_ATOLL_DECL
+
+/* Define if atol is declared. */
+#undef HAVE_ATOL_DECL
+
/* Define to 1 if you have the `basename' function. */
#undef HAVE_BASENAME
/* Define to 1 if you have the `isascii' function. */
#undef HAVE_ISASCII
+/* Define to 1 if you have the `isnormal' function. */
+#undef HAVE_ISNORMAL
+
+/* Define if isnormal is declared. */
+#undef HAVE_ISNORMAL_DECL
+
/* Define to 1 if you have the `c' library (-lc). */
#undef HAVE_LIBC
/* Define to 1 if you have the `dbm' library (-ldbm). */
#undef HAVE_LIBDBM
+/* Define to 1 if you have the `dbmalloc' library (-ldbmalloc). */
+#undef HAVE_LIBDBMALLOC
+
/* Define to 1 if you have the `gdbm' library (-lgdbm). */
#undef HAVE_LIBGDBM
+/* Define to 1 if you have the <libgen.h> header file. */
+#undef HAVE_LIBGEN_H
+
/* Define to 1 if you have the `intl' library (-lintl). */
#undef HAVE_LIBINTL
+/* Define to 1 if you have the `krb5support' library (-lkrb5support). */
+#undef HAVE_LIBKRB5SUPPORT
+
/* Define to 1 if you have the `m' library (-lm). */
#undef HAVE_LIBM
/* Define to 1 if you have the `nsl' library (-lnsl). */
#undef HAVE_LIBNSL
+/* Define to 1 if you have the `readline' library (-lreadline). */
+#undef HAVE_LIBREADLINE
+
/* Define to 1 if you have the `resolv' library (-lresolv). */
#undef HAVE_LIBRESOLV
/* Define if malloc is declared. */
#undef HAVE_MALLOC_DECL
+/* Define to 1 if you have the <math.h> header file. */
+#undef HAVE_MATH_H
+
/* Define to 1 if you have the `memmove' function. */
#undef HAVE_MEMMOVE
/* Define to 1 if you have the `statvfs' function. */
#undef HAVE_STATVFS
+/* Define to 1 if you have the <stdarg.h> header file. */
+#undef HAVE_STDARG_H
+
/* Define to 1 if you have the <stdint.h> header file. */
#undef HAVE_STDINT_H
/* Define if writev is declared. */
#undef HAVE_WRITEV_DECL
+/* xslt is available to generate man pages */
+#undef HAVE_XSLTPROC
+
/* Define if limits.h defines _POSIX2_RE_DUP_MAX. */
#undef HAVE__POSIX2_RE_DUP_MAX
/* Format for a long long printf. */
#undef LL_FMT
+/* A comma-separated list of two integers, determining the minimum and maximum
+ reserved TCP port numbers sockets should be bound to. (mainly for
+ amrecover) */
+#undef LOW_TCPPORTRANGE
+
/* Command for starting printing jobs. */
#undef LPRCMD
/* The size of a `short', as computed by sizeof. */
#undef SIZEOF_SHORT
+/* The size of a `size_t', as computed by sizeof. */
+#undef SIZEOF_SIZE_T
+
+/* The size of a `ssize_t', as computed by sizeof. */
+#undef SIZEOF_SSIZE_T
+
+/* The size of a `time_t', as computed by sizeof. */
+#undef SIZEOF_TIME_T
+
/* The size of a `void*', as computed by sizeof. */
#undef SIZEOF_VOIDP
/* Define to use Posix fcntl for file locking. */
#undef USE_POSIX_FCNTL
+/* Define to set SO_REUSEADDR on network connections. */
+#undef USE_REUSEADDR
+
/* Define to invoke rundump (setuid-root) instead of DUMP program directly. */
#undef USE_RUNDUMP
/* Define to `int' if <sys/types.h> does not define. */
#undef pid_t
+/* Define if sa_family_t is not a standard system type */
+#undef sa_family_t
+
/* Directory in which administrator binaries should be installed. */
#undef sbindir
# include <unistd.h>
#endif"
-ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os CONFIGURE_COMMAND INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar SNAPSHOT_STAMP VERSION_MAJOR VERSION_MINOR VERSION_PATCH VERSION_COMMENT VERSION_SUFFIX DUMPER_DIR CONFIG_DIR USE_VERSION_SUFFIXES CLIENT_SCRIPTS_OPT DEFAULT_SERVER CLIENT_LOGIN SETUID_GROUP BINARY_OWNER DEFAULT_CONFIG DEFAULT_TAPE_SERVER DEFAULT_TAPE_DEVICE DEFAULT_RAW_TAPE_DEVICE DEFAULT_CHANGER_DEVICE GNUTAR_LISTED_INCREMENTAL_DIRX GNUTAR_LISTED_INCREMENTAL_DIR MAXTAPEBLOCKSIZE AMANDA_TMPDIR AMANDA_DBGDIR AMANDA_DEBUG_DAYS SERVICE_SUFFIX CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE MT_FILE_FLAG CPP EGREP AR AWK_VAR_ASSIGNMENT_OPT YACC CAT COMPRESS DD GETCONF GNUPLOT GREP GNUTAR SAMBA_CLIENT GZIP MAILER MT CHIO CHS MTX MCUTIL PRINT PCAT PERL DUMP RESTORE XFSDUMP XFSRESTORE VXDUMP VXRESTORE VDUMP VRESTORE AMPLOT_COMPRESS AMPLOT_CAT_GZIP AMPLOT_CAT_COMPRESS AMPLOT_CAT_PACK LL_FMT LN_S ECHO ac_ct_AR RANLIB ac_ct_RANLIB CXX CXXFLAGS ac_ct_CXX CXXDEPMODE am__fastdepCXX_TRUE am__fastdepCXX_FALSE CXXCPP F77 FFLAGS ac_ct_F77 LIBTOOL LIBTOOL_DEPS LEX LEXLIB LEX_OUTPUT_ROOT READLINE_LIBS DB_EXT ALLOCA LIBOBJS ac_n ac_c WANT_CLIENT_TRUE WANT_CLIENT_FALSE WANT_SAMBA_TRUE WANT_SAMBA_FALSE WANT_RESTORE_TRUE WANT_RESTORE_FALSE WANT_SERVER_TRUE WANT_SERVER_FALSE WANT_RECOVER_TRUE WANT_RECOVER_FALSE WANT_TAPE_TRUE WANT_TAPE_FALSE WANT_AMPLOT_TRUE WANT_AMPLOT_FALSE WANT_CHG_SCSI_TRUE WANT_CHG_SCSI_FALSE WANT_CHIO_SCSI_TRUE WANT_CHIO_SCSI_FALSE WANT_RUNTIME_PSEUDO_RELOC_TRUE WANT_RUNTIME_PSEUDO_RELOC_FALSE WANT_SETUID_CLIENT_TRUE WANT_SETUID_CLIENT_FALSE WANT_SSH_SECURITY_TRUE WANT_SSH_SECURITY_FALSE LTLIBOBJS LTALLOCA DOC_BUILD_DATE XSLTPROC HAVE_XSLTPROC_TRUE HAVE_XSLTPROC_FALSE'
+ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os CONFIGURE_COMMAND INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar SNAPSHOT_STAMP VERSION_MAJOR VERSION_MINOR VERSION_PATCH VERSION_COMMENT VERSION_SUFFIX CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE GREP EGREP AMLINT AMLINTFLAGS DUMPER_DIR CONFIG_DIR USE_VERSION_SUFFIXES CLIENT_SCRIPTS_OPT DEFAULT_SERVER CLIENT_LOGIN SETUID_GROUP BINARY_OWNER DEFAULT_CONFIG DEFAULT_TAPE_SERVER DEFAULT_TAPE_DEVICE DEFAULT_RAW_TAPE_DEVICE DEFAULT_CHANGER_DEVICE GNUTAR_LISTED_INCREMENTAL_DIRX GNUTAR_LISTED_INCREMENTAL_DIR MAXTAPEBLOCKSIZE AMANDA_TMPDIR AMANDA_DBGDIR AMANDA_DEBUG_DAYS SERVICE_SUFFIX MT_FILE_FLAG CPP AR AWK_VAR_ASSIGNMENT_OPT YACC CAT COMPRESS DD GETCONF GNUPLOT GNUTAR SAMBA_CLIENT GZIP MAILER MT CHIO CHS MTX MCUTIL PRINT PCAT PERL DUMP RESTORE XFSDUMP XFSRESTORE VXDUMP VXRESTORE VDUMP VRESTORE AMPLOT_COMPRESS AMPLOT_CAT_GZIP AMPLOT_CAT_COMPRESS AMPLOT_CAT_PACK LL_FMT LN_S ECHO ac_ct_AR RANLIB ac_ct_RANLIB CXX CXXFLAGS ac_ct_CXX CXXDEPMODE am__fastdepCXX_TRUE am__fastdepCXX_FALSE CXXCPP F77 FFLAGS ac_ct_F77 LIBTOOL LIBTOOL_DEPS LEX LEXLIB LEX_OUTPUT_ROOT READLINE_LIBS DB_EXT ALLOCA LIBOBJS ac_n ac_c WANT_CLIENT_TRUE WANT_CLIENT_FALSE WANT_SAMBA_TRUE WANT_SAMBA_FALSE WANT_RESTORE_TRUE WANT_RESTORE_FALSE WANT_SERVER_TRUE WANT_SERVER_FALSE WANT_RECOVER_TRUE WANT_RECOVER_FALSE WANT_TAPE_TRUE WANT_TAPE_FALSE WANT_AMPLOT_TRUE WANT_AMPLOT_FALSE WANT_CHG_SCSI_TRUE WANT_CHG_SCSI_FALSE WANT_CHIO_SCSI_TRUE WANT_CHIO_SCSI_FALSE WANT_RUNTIME_PSEUDO_RELOC_TRUE WANT_RUNTIME_PSEUDO_RELOC_FALSE WANT_SETUID_CLIENT_TRUE WANT_SETUID_CLIENT_FALSE WANT_SSH_SECURITY_TRUE WANT_SSH_SECURITY_FALSE LTLIBOBJS LTALLOCA DOC_BUILD_DATE BUILD_MAN_PAGES_TRUE BUILD_MAN_PAGES_FALSE XSLTPROC HAVE_XSLTPROC_TRUE HAVE_XSLTPROC_FALSE AM_CFLAGS'
ac_subst_files=''
# Initialize some variables set by options.
--enable-FEATURE[=ARG] include FEATURE [ARG=yes]
--disable-dependency-tracking speeds up one-time build
--enable-dependency-tracking do not reject slow dependency extractors
+ --disable-largefile omit support for large files
--enable-shared[=PKGS]
build shared libraries [default=yes]
--enable-static[=PKGS]
--enable-fast-install[=PKGS]
optimize for fast installation [default=yes]
--disable-libtool-lock avoid locking (might break parallel builds)
- --disable-largefile omit support for large files
Optional Packages:
--with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
--with-changer-device=ARG default tape changer device [/dev/ch0 if it exists]
--with-fqdn use FQDN's to backup multiple networks
--with-broken-fsf only enable if tape fsf calls fail mid-file
+ --without-reuseaddr Don't closed network connections to be reused until full timeout period.
--with-gnutar[=PROG] use PROG as GNU tar executable [default: looks for one]
--with-smbclient[=PROG] use PROG as Samba's smbclient executable [default: looks for one]
--with-samba-user was deprecated
--with-krb4-security=DIR Location of Kerberos software [/usr/kerberos /usr/cygnus /usr /opt/kerberos]
--with-rsh-security use rsh as a transport
--with-ssh-security use ssh as a transport
+ --with-bsdtcp-security use tcp as a transport
+ --with-bsdudp-security use tcp as a transport
--with-server-principal=ARG server host principal ["amanda"]
--with-server-instance=ARG server host instance ["amanda"]
--with-server-keyfile=ARG server host key file ["/.amanda"]
--with-client-keyfile=ARG client host key file [KEYFILE]
--with-ticket-lifetime=ARG ticket lifetime [128]
--with-krb5-security=DIR Location of Kerberos V software [/usr/kerberos /usr/cygnus /usr /opt/kerberos]
- --with-portrange=low,high bind unreserved TCP server sockets to ports within this range [unlimited]
+ --with-low-tcpportrange=low,high bind reserved TCP server sockets to ports within this range unlimited (mainly for amrecover)
--with-tcpportrange=low,high bind unreserved TCP server sockets to ports within this range [unlimited]
--with-udpportrange=low,high bind reserved UDP server sockets to ports within this range [unlimited]
--with-maxtapeblocksize=kb Maximum size of a tape block
# Define the identity of the package.
PACKAGE=amanda
- VERSION=2.5.0p2
+ VERSION=2.5.1
cat >>confdefs.h <<_ACEOF
-SYSPATH="/bin:/usr/bin:/sbin:/usr/sbin:/usr/ucb:/usr/bsd:/etc:/usr/etc"
+SYSPATH="/bin:/usr/bin:/sbin:/usr/sbin:/opt/SUNWspro/bin:/usr/ucb:/usr/bsd:/etc:/usr/etc"
LOCPATH=`(
test "x$prefix" = xNONE && prefix=$ac_default_prefix
test "x$exec_prefix" = xNONE && exec_prefix=${prefix}
LOCSYSPATH="$LOCPATH:$SYSPATH"
+
# Check whether --with-cflags or --without-cflags was given.
if test "${with_cflags+set}" = set; then
withval="$with_cflags"
case "$withval" in
"" | y | ye | yes | n | no)
- { { echo "$as_me:$LINENO: error: *** You must supply an argument to the --with-includes option." >&5
-echo "$as_me: error: *** You must supply an argument to the --with-includes option." >&2;}
+ { { echo "$as_me:$LINENO: error: *** You must supply an argument to the --with-cflags option." >&5
+echo "$as_me: error: *** You must supply an argument to the --with-cflags option." >&2;}
{ (exit 1); exit 1; }; }
;;
esac
fi;
+CFLAGS="-D_GNU_SOURCE $CFLAGS"
-# Check whether --with-includes or --without-includes was given.
-if test "${with_includes+set}" = set; then
- withval="$with_includes"
-
- case "$withval" in
- "" | y | ye | yes | n | no)
- { { echo "$as_me:$LINENO: error: *** You must supply an argument to the --with-includes option." >&5
-echo "$as_me: error: *** You must supply an argument to the --with-includes option." >&2;}
- { (exit 1); exit 1; }; }
- ;;
- esac
- INCLUDE_DIRS="$withval"
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="${ac_tool_prefix}gcc"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
-fi;
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
-if test "$INCLUDE_DIRS"; then
- for dir in $INCLUDE_DIRS; do
- if test -d "$dir"; then
- AMANDA_CPPFLAGS="$AMANDA_CPPFLAGS -I$dir"
- else
- { echo "$as_me:$LINENO: WARNING: *** Include directory $dir does not exist." >&5
-echo "$as_me: WARNING: *** Include directory $dir does not exist." >&2;}
- fi
- done
fi
+if test -z "$ac_cv_prog_CC"; then
+ ac_ct_CC=$CC
+ # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_CC="gcc"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
-# Check whether --with-libraries or --without-libraries was given.
-if test "${with_libraries+set}" = set; then
- withval="$with_libraries"
+ CC=$ac_ct_CC
+else
+ CC="$ac_cv_prog_CC"
+fi
- case "$withval" in
- "" | y | ye | yes | n | no)
- { { echo "$as_me:$LINENO: error: *** You must supply an argument to the --with-libraries option." >&5
-echo "$as_me: error: *** You must supply an argument to the --with-libraries option." >&2;}
- { (exit 1); exit 1; }; }
- ;;
- esac
- LIBRARY_DIRS="$withval"
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="${ac_tool_prefix}cc"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
-fi;
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
-if test "$LIBRARY_DIRS"; then
- for dir in $LIBRARY_DIRS; do
- if test -d "$dir"; then
- case "$target" in
- *-solaris2*,*-netbsd*)
- AMANDA_LDFLAGS="$AMANDA_LDFLAGS -R$dir"
- ;;
- esac
- AMANDA_LDFLAGS="$AMANDA_LDFLAGS -L$dir"
- else
- { echo "$as_me:$LINENO: WARNING: *** Library directory $dir does not exist." >&5
-echo "$as_me: WARNING: *** Library directory $dir does not exist." >&2;}
- fi
- done
fi
+if test -z "$ac_cv_prog_CC"; then
+ ac_ct_CC=$CC
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_CC="cc"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
-# Check whether --with-dumperdir or --without-dumperdir was given.
-if test "${with_dumperdir+set}" = set; then
- withval="$with_dumperdir"
+ CC=$ac_ct_CC
+else
+ CC="$ac_cv_prog_CC"
+fi
- case "$withval" in
- "" | y | ye | yes | n | no)
- { { echo "$as_me:$LINENO: error: *** You must supply an argument to the --with-dumperdir option." >&5
-echo "$as_me: error: *** You must supply an argument to the --with-dumperdir option." >&2;}
- { (exit 1); exit 1; }; }
- ;;
- esac
- DUMPER_DIR="$withval"
+fi
+if test -z "$CC"; then
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+if test $ac_prog_rejected = yes; then
+ # We found a bogon in the path, so make sure we never use it.
+ set dummy $ac_cv_prog_CC
+ shift
+ if test $# != 0; then
+ # We chose a different compiler from the bogus one.
+ # However, it has the same basename, so the bogon will be chosen
+ # first if we set CC to just the basename; use the full file name.
+ shift
+ ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+ fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
- test "x$prefix" = xNONE && prefix=$ac_default_prefix
- test "x$exec_prefix" = xNONE && exec_prefix=${prefix}
- DUMPER_DIR=$exec_prefix/dumper
+fi
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ for ac_prog in cl
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
-fi;
-DUMPER_DIR=`(
- test "x$prefix" = xNONE && prefix=$ac_default_prefix
- test "x$exec_prefix" = xNONE && exec_prefix=${prefix}
- eval echo "$DUMPER_DIR"
-)`
+ test -n "$CC" && break
+ done
+fi
+if test -z "$CC"; then
+ ac_ct_CC=$CC
+ for ac_prog in cl
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_CC="$ac_prog"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
-cat >>confdefs.h <<_ACEOF
-#define DUMPER_DIR "$DUMPER_DIR"
-_ACEOF
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+ test -n "$ac_ct_CC" && break
+done
+ CC=$ac_ct_CC
+fi
+fi
-# Check whether --with-configdir or --without-configdir was given.
-if test "${with_configdir+set}" = set; then
- withval="$with_configdir"
- case "$withval" in
- "" | y | ye | yes | n | no)
- { { echo "$as_me:$LINENO: error: *** You must supply an argument to the --with-configdir option." >&5
-echo "$as_me: error: *** You must supply an argument to the --with-configdir option." >&2;}
+test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&5
+echo "$as_me: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&2;}
{ (exit 1); exit 1; }; }
- ;;
- *) CONFIG_DIR="$withval"
- ;;
- esac
-
-else
- : ${CONFIG_DIR="$sysconfdir/amanda"}
-fi;
-CONFIG_DIR=`(
- test "x$prefix" = xNONE && prefix=$ac_default_prefix
- test "x$exec_prefix" = xNONE && exec_prefix=${prefix}
- eval echo "$CONFIG_DIR"
-)`
+# Provide some information about the compiler.
+echo "$as_me:$LINENO:" \
+ "checking for C compiler version" >&5
+ac_compiler=`set X $ac_compile; echo $2`
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version </dev/null >&5\"") >&5
+ (eval $ac_compiler --version </dev/null >&5) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v </dev/null >&5\"") >&5
+ (eval $ac_compiler -v </dev/null >&5) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V </dev/null >&5\"") >&5
+ (eval $ac_compiler -V </dev/null >&5) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
-cat >>confdefs.h <<_ACEOF
-#define CONFIG_DIR "$CONFIG_DIR"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+int
+main ()
+{
+ ;
+ return 0;
+}
+_ACEOF
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files a.out a.exe b.out"
+# Try to create an executable without -o first, disregard a.out.
+# It will help us diagnose broken compilers, and finding out an intuition
+# of exeext.
+echo "$as_me:$LINENO: checking for C compiler default output file name" >&5
+echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6
+ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5
+ (eval $ac_link_default) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; then
+ # Find the output, starting from the most likely. This scheme is
+# not robust to junk in `.', hence go to wildcards (a.*) only as a last
+# resort.
+# Be careful to initialize this variable, since it used to be cached.
+# Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile.
+ac_cv_exeext=
+# b.out is created by i960 compilers.
+for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out
+do
+ test -f "$ac_file" || continue
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj )
+ ;;
+ conftest.$ac_ext )
+ # This is the source file.
+ ;;
+ [ab].out )
+ # We found the default executable, but exeext='' is most
+ # certainly right.
+ break;;
+ *.* )
+ ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+ # FIXME: I believe we export ac_cv_exeext for Libtool,
+ # but it would be cool to find out if it's true. Does anybody
+ # maintain Libtool? --akim.
+ export ac_cv_exeext
+ break;;
+ * )
+ break;;
+ esac
+done
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
-# Check whether --with-indexdir or --without-indexdir was given.
-if test "${with_indexdir+set}" = set; then
- withval="$with_indexdir"
- { { echo "$as_me:$LINENO: error: *** --with-indexdir is deprecated, use indexdir in amanda.conf instead." >&5
-echo "$as_me: error: *** --with-indexdir is deprecated, use indexdir in amanda.conf instead." >&2;}
- { (exit 1); exit 1; }; }
-
-fi;
+{ { echo "$as_me:$LINENO: error: C compiler cannot create executables
+See \`config.log' for more details." >&5
+echo "$as_me: error: C compiler cannot create executables
+See \`config.log' for more details." >&2;}
+ { (exit 77); exit 77; }; }
+fi
+ac_exeext=$ac_cv_exeext
+echo "$as_me:$LINENO: result: $ac_file" >&5
+echo "${ECHO_T}$ac_file" >&6
-# Check whether --with-dbdir or --without-dbdir was given.
-if test "${with_dbdir+set}" = set; then
- withval="$with_dbdir"
- { { echo "$as_me:$LINENO: error: *** --with-dbdir is deprecated, use infofile in amanda.conf instead." >&5
-echo "$as_me: error: *** --with-dbdir is deprecated, use infofile in amanda.conf instead." >&2;}
+# Check the compiler produces executables we can run. If not, either
+# the compiler is broken, or we cross compile.
+echo "$as_me:$LINENO: checking whether the C compiler works" >&5
+echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6
+# FIXME: These cross compiler hacks should be removed for Autoconf 3.0
+# If not cross compiling, check that we can run a simple program.
+if test "$cross_compiling" != yes; then
+ if { ac_try='./$ac_file'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ cross_compiling=no
+ else
+ if test "$cross_compiling" = maybe; then
+ cross_compiling=yes
+ else
+ { { echo "$as_me:$LINENO: error: cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." >&2;}
{ (exit 1); exit 1; }; }
+ fi
+ fi
+fi
+echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
-fi;
-
+rm -f a.out a.exe conftest$ac_cv_exeext b.out
+ac_clean_files=$ac_clean_files_save
+# Check the compiler produces executables we can run. If not, either
+# the compiler is broken, or we cross compile.
+echo "$as_me:$LINENO: checking whether we are cross compiling" >&5
+echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6
+echo "$as_me:$LINENO: result: $cross_compiling" >&5
+echo "${ECHO_T}$cross_compiling" >&6
-# Check whether --with-logdir or --without-logdir was given.
-if test "${with_logdir+set}" = set; then
- withval="$with_logdir"
- { { echo "$as_me:$LINENO: error: *** --with-logdir is deprecated, use logdir in amanda.conf instead." >&5
-echo "$as_me: error: *** --with-logdir is deprecated, use logdir in amanda.conf instead." >&2;}
+echo "$as_me:$LINENO: checking for suffix of executables" >&5
+echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; then
+ # If both `conftest.exe' and `conftest' are `present' (well, observable)
+# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will
+# work properly (i.e., refer to `conftest.exe'), while it won't with
+# `rm'.
+for ac_file in conftest.exe conftest conftest.*; do
+ test -f "$ac_file" || continue
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;;
+ *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+ export ac_cv_exeext
+ break;;
+ * ) break;;
+ esac
+done
+else
+ { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." >&2;}
{ (exit 1); exit 1; }; }
+fi
-fi;
-
+rm -f conftest$ac_cv_exeext
+echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5
+echo "${ECHO_T}$ac_cv_exeext" >&6
-# Check whether --with-suffixes or --without-suffixes was given.
-if test "${with_suffixes+set}" = set; then
- withval="$with_suffixes"
- USE_VERSION_SUFFIXES=$withval
+rm -f conftest.$ac_ext
+EXEEXT=$ac_cv_exeext
+ac_exeext=$EXEEXT
+echo "$as_me:$LINENO: checking for suffix of object files" >&5
+echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6
+if test "${ac_cv_objext+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
else
- : ${USE_VERSION_SUFFIXES=no}
-
-fi;
-case "$USE_VERSION_SUFFIXES" in
-y | ye | yes)
-
-cat >>confdefs.h <<\_ACEOF
-#define USE_VERSION_SUFFIXES 1
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+int
+main ()
+{
- program_suffix="-$VERSION"
- # This is from the output of configure.in.
- if test "x$program_transform_name" = xs,x,x,; then
- program_transform_name=
- else
- # Double any \ or $. echo might interpret backslashes.
- cat <<\EOF_SED > conftestsed
-s,\\,\\\\,g; s,\$,$$,g
-EOF_SED
- program_transform_name="`echo $program_transform_name|sed -f conftestsed`"
- rm -f conftestsed
- fi
- test "x$program_prefix" != xNONE &&
- program_transform_name="s,^,${program_prefix},; $program_transform_name"
- # Use a double $ so make ignores it.
- test "x$program_suffix" != xNONE &&
- program_transform_name="s,\$\$,${program_suffix},; $program_transform_name"
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.o conftest.obj
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; then
+ for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;;
+ *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
+ break;;
+ esac
+done
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
- # sed with no file args requires a program.
- test "x$program_transform_name" = "" && program_transform_name="xs,x,x,"
- # Remove empty command
- cat <<\EOF_SED > conftestsed
-s,\;\;,\;,g; s,\; \$,,g; s,\;$,,g
-EOF_SED
- program_transform_name="`echo $program_transform_name|sed -f conftestsed`"
- rm -f conftestsed
- ;;
-n | no) USE_VERSION_SUFFIXES=no
- ;;
-*) { { echo "$as_me:$LINENO: error: *** You must not supply an argument to --with-suffixes option." >&5
-echo "$as_me: error: *** You must not supply an argument to --with-suffixes option." >&2;}
+{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." >&2;}
{ (exit 1); exit 1; }; }
- ;;
-esac
-
-
-case "$target" in
- *-hp-*)
- CLIENT_SCRIPTS_OPT=amhpfixdevs
- ;;
- *-sni-sysv4)
- CLIENT_SCRIPTS_OPT=amsinixfixdevs
- ;;
- *)
- CLIENT_SCRIPTS_OPT=
- ;;
-esac
-
+fi
+rm -f conftest.$ac_cv_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_objext" >&5
+echo "${ECHO_T}$ac_cv_objext" >&6
+OBJEXT=$ac_cv_objext
+ac_objext=$OBJEXT
+echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5
+echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6
+if test "${ac_cv_c_compiler_gnu+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+int
+main ()
+{
+#ifndef __GNUC__
+ choke me
+#endif
-# Check whether --with-client-only or --without-client-only was given.
-if test "${with_client_only+set}" = set; then
- withval="$with_client_only"
- { { echo "$as_me:$LINENO: error: *** --with-client-only is deprecated, use --without-server instead." >&5
-echo "$as_me: error: *** --with-client-only is deprecated, use --without-server instead." >&2;}
- { (exit 1); exit 1; }; }
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_compiler_gnu=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
-fi;
+ac_compiler_gnu=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
-# Check whether --with-server-only or --without-server-only was given.
-if test "${with_server_only+set}" = set; then
- withval="$with_server_only"
- { { echo "$as_me:$LINENO: error: *** --with-server-only is deprecated, use --without-client instead." >&5
-echo "$as_me: error: *** --with-server-only is deprecated, use --without-client instead." >&2;}
- { (exit 1); exit 1; }; }
+fi
+echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5
+echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6
+GCC=`test $ac_compiler_gnu = yes && echo yes`
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+CFLAGS="-g"
+echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5
+echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6
+if test "${ac_cv_prog_cc_g+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
-fi;
+int
+main ()
+{
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_prog_cc_g=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
-# Check whether --with-client or --without-client was given.
-if test "${with_client+set}" = set; then
- withval="$with_client"
+ac_cv_prog_cc_g=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_g" >&6
+if test "$ac_test_CFLAGS" = set; then
+ CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+ if test "$GCC" = yes; then
+ CFLAGS="-g -O2"
+ else
+ CFLAGS="-g"
+ fi
+else
+ if test "$GCC" = yes; then
+ CFLAGS="-O2"
+ else
+ CFLAGS=
+ fi
+fi
+echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5
+echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6
+if test "${ac_cv_prog_cc_stdc+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_cv_prog_cc_stdc=no
+ac_save_CC=$CC
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <stdarg.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+ char **p;
+ int i;
+{
+ return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+ char *s;
+ va_list v;
+ va_start (v,p);
+ s = g (p, va_arg (v,int));
+ va_end (v);
+ return s;
+}
- case "$withval" in
- y | ye | yes) NO_CLIENT_MODE=false;;
- n | no) NO_CLIENT_MODE=true;;
- *)
- { { echo "$as_me:$LINENO: error: *** You must not supply an argument to --with-client option." >&5
-echo "$as_me: error: *** You must not supply an argument to --with-client option." >&2;}
- { (exit 1); exit 1; }; }
- ;;
- esac
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has
+ function prototypes and stuff, but not '\xHH' hex character constants.
+ These don't provoke an error unfortunately, instead are silently treated
+ as 'x'. The following induces an error, until -std1 is added to get
+ proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an
+ array size at least. It's necessary to write '\x00'==0 to get something
+ that's true only with -std1. */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1];
+ ;
+ return 0;
+}
+_ACEOF
+# Don't try gcc -ansi; that turns off useful extensions and
+# breaks some systems' header files.
+# AIX -qlanglvl=ansi
+# Ultrix and OSF/1 -std1
+# HP-UX 10.20 and later -Ae
+# HP-UX older versions -Aa -D_HPUX_SOURCE
+# SVR4 -Xc -D__EXTENSIONS__
+for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+ CC="$ac_save_CC $ac_arg"
+ rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_prog_cc_stdc=$ac_arg
+break
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
-fi;
+fi
+rm -f conftest.err conftest.$ac_objext
+done
+rm -f conftest.$ac_ext conftest.$ac_objext
+CC=$ac_save_CC
+fi
-# Check whether --with-server or --without-server was given.
-if test "${with_server+set}" = set; then
- withval="$with_server"
+case "x$ac_cv_prog_cc_stdc" in
+ x|xno)
+ echo "$as_me:$LINENO: result: none needed" >&5
+echo "${ECHO_T}none needed" >&6 ;;
+ *)
+ echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6
+ CC="$CC $ac_cv_prog_cc_stdc" ;;
+esac
- case "$withval" in
- y | ye | yes) NO_SERVER_MODE=false ;;
- n | no) NO_SERVER_MODE=true;NO_RESTORE_MODE=true;;
- *)
- { { echo "$as_me:$LINENO: error: *** You must not supply an argument to --with-server option. Maybe you meant --with-index-server=$withval" >&5
-echo "$as_me: error: *** You must not supply an argument to --with-server option. Maybe you meant --with-index-server=$withval" >&2;}
- { (exit 1); exit 1; }; }
- ;;
- esac
+# Some people use a C++ compiler to compile C. Since we use `exit',
+# in C++ we need to declare it. In case someone uses the same compiler
+# for both compiling C and C++ we need to have the C++ compiler decide
+# the declaration of exit, since it's the most demanding environment.
+cat >conftest.$ac_ext <<_ACEOF
+#ifndef __cplusplus
+ choke me
+#endif
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ for ac_declaration in \
+ '' \
+ 'extern "C" void std::exit (int) throw (); using std::exit;' \
+ 'extern "C" void std::exit (int); using std::exit;' \
+ 'extern "C" void exit (int) throw ();' \
+ 'extern "C" void exit (int);' \
+ 'void exit (int);'
+do
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_declaration
+#include <stdlib.h>
+int
+main ()
+{
+exit (42);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ :
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+continue
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_declaration
+int
+main ()
+{
+exit (42);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ break
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
-fi;
-if test "x${NO_SERVER_MODE+set}" != xset ; then
- NO_SERVER_MODE=false
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+rm -f conftest*
+if test -n "$ac_declaration"; then
+ echo '#ifdef __cplusplus' >>confdefs.h
+ echo $ac_declaration >>confdefs.h
+ echo '#endif' >>confdefs.h
fi
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
-# Check whether --with-restore or --without-restore was given.
-if test "${with_restore+set}" = set; then
- withval="$with_restore"
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+DEPDIR="${am__leading_dot}deps"
- case "$withval" in
- y | ye | yes) NO_RESTORE_MODE=false;;
- n | no) NO_RESTORE_MODE=true;;
- *)
- { { echo "$as_me:$LINENO: error: *** You must not supply an argument to --with-restore option." >&5
-echo "$as_me: error: *** You must not supply an argument to --with-restore option." >&2;}
- { (exit 1); exit 1; }; }
- ;;
- esac
+ ac_config_commands="$ac_config_commands depfiles"
-fi;
-if test "x${NO_RESTORE_MODE+set}" != xset ; then
- NO_RESTORE_MODE=${NO_SERVER_MODE-false}
+am_make=${MAKE-make}
+cat > confinc << 'END'
+am__doit:
+ @echo done
+.PHONY: am__doit
+END
+# If we don't find an include directive, just comment out the code.
+echo "$as_me:$LINENO: checking for style of include used by $am_make" >&5
+echo $ECHO_N "checking for style of include used by $am_make... $ECHO_C" >&6
+am__include="#"
+am__quote=
+_am_result=none
+# First try GNU make style include.
+echo "include confinc" > confmf
+# We grep out `Entering directory' and `Leaving directory'
+# messages which can occur if `w' ends up in MAKEFLAGS.
+# In particular we don't look at `^make:' because GNU make might
+# be invoked under some other name (usually "gmake"), in which
+# case it prints its new name instead of `make'.
+if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then
+ am__include=include
+ am__quote=
+ _am_result=GNU
fi
-
-if ${NO_SERVER_MODE-false}; then
- if ${NO_RESTORE_MODE-false}; then
- true
- else
- { { echo "$as_me:$LINENO: error: *** --without-server requires --without-restore" >&5
-echo "$as_me: error: *** --without-server requires --without-restore" >&2;}
- { (exit 1); exit 1; }; }
+# Now try BSD make style include.
+if test "$am__include" = "#"; then
+ echo '.include "confinc"' > confmf
+ if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then
+ am__include=.include
+ am__quote="\""
+ _am_result=BSD
fi
fi
-# Check whether --with-amrecover or --without-amrecover was given.
-if test "${with_amrecover+set}" = set; then
- withval="$with_amrecover"
-
- case "$withval" in
- y | ye | yes)
- if ${NO_CLIENT_MODE-false}; then
- { { echo "$as_me:$LINENO: error: *** --without-client and --with-amrecover are incompatible" >&5
-echo "$as_me: error: *** --without-client and --with-amrecover are incompatible" >&2;}
- { (exit 1); exit 1; }; }
- fi
- NO_RECOVER_MODE=false;;
- n | no) NO_RECOVER_MODE=true;;
- *)
- { { echo "$as_me:$LINENO: error: *** You must not supply an argument to --with-amrecover option." >&5
-echo "$as_me: error: *** You must not supply an argument to --with-amrecover option." >&2;}
- { (exit 1); exit 1; }; }
- ;;
- esac
+echo "$as_me:$LINENO: result: $_am_result" >&5
+echo "${ECHO_T}$_am_result" >&6
+rm -f confinc confmf
+# Check whether --enable-dependency-tracking or --disable-dependency-tracking was given.
+if test "${enable_dependency_tracking+set}" = set; then
+ enableval="$enable_dependency_tracking"
fi;
+if test "x$enable_dependency_tracking" != xno; then
+ am_depcomp="$ac_aux_dir/depcomp"
+ AMDEPBACKSLASH='\'
+fi
-# Check whether --with-index-server or --without-index-server was given.
-if test "${with_index_server+set}" = set; then
- withval="$with_index_server"
-
- case "$withval" in
- "" | y | ye | yes | n | no)
- { { echo "$as_me:$LINENO: error: *** You must supply an argument to the --with-index-server option." >&5
-echo "$as_me: error: *** You must supply an argument to the --with-index-server option." >&2;}
- { (exit 1); exit 1; }; }
- ;;
- *) DEFAULT_SERVER="$withval"
- ;;
- esac
-
+if test "x$enable_dependency_tracking" != xno; then
+ AMDEP_TRUE=
+ AMDEP_FALSE='#'
else
- : ${DEFAULT_SERVER=`uname -n`}
+ AMDEP_TRUE='#'
+ AMDEP_FALSE=
+fi
-fi;
-
-cat >>confdefs.h <<_ACEOF
-#define DEFAULT_SERVER "$DEFAULT_SERVER"
-_ACEOF
+depcc="$CC" am_compiler_list=
-# Check whether --with-force-uid or --without-force-uid was given.
-if test "${with_force_uid+set}" = set; then
- withval="$with_force_uid"
- FORCE_USERID="$withval"
+echo "$as_me:$LINENO: checking dependency style of $depcc" >&5
+echo $ECHO_N "checking dependency style of $depcc... $ECHO_C" >&6
+if test "${am_cv_CC_dependencies_compiler_type+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
else
- : ${FORCE_USERID=yes}
-
-fi;
-case "$FORCE_USERID" in
-y | ye | yes)
-cat >>confdefs.h <<\_ACEOF
-#define FORCE_USERID 1
-_ACEOF
-
- ;;
-n | no) :
- ;;
-*) { { echo "$as_me:$LINENO: error: *** You must not supply an argument to --with-force-uid option." >&5
-echo "$as_me: error: *** You must not supply an argument to --with-force-uid option." >&2;}
- { (exit 1); exit 1; }; }
-esac
-
-
-# Check whether --with-user or --without-user was given.
-if test "${with_user+set}" = set; then
- withval="$with_user"
+ if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+ # We make a subdir and do the tests there. Otherwise we can end up
+ # making bogus files that we don't know about and never remove. For
+ # instance it was reported that on HP-UX the gcc test will end up
+ # making a dummy file named `D' -- because `-MD' means `put the output
+ # in D'.
+ mkdir conftest.dir
+ # Copy depcomp to subdir because otherwise we won't find it if we're
+ # using a relative directory.
+ cp "$am_depcomp" conftest.dir
+ cd conftest.dir
+ # We will build objects and dependencies in a subdirectory because
+ # it helps to detect inapplicable dependency modes. For instance
+ # both Tru64's cc and ICC support -MD to output dependencies as a
+ # side effect of compilation, but ICC will put the dependencies in
+ # the current directory while Tru64 will put them in the object
+ # directory.
+ mkdir sub
- case "$withval" in
- "" | y | ye | yes | n | no)
- { { echo "$as_me:$LINENO: error: *** You must supply an argument to the --with-user option." >&5
-echo "$as_me: error: *** You must supply an argument to the --with-user option." >&2;}
- { (exit 1); exit 1; }; }
- ;;
- *) CLIENT_LOGIN="$withval"
- ;;
- esac
+ am_cv_CC_dependencies_compiler_type=none
+ if test "$am_compiler_list" = ""; then
+ am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp`
+ fi
+ for depmode in $am_compiler_list; do
+ # Setup a source with many dependencies, because some compilers
+ # like to wrap large dependency lists on column 80 (with \), and
+ # we should not choose a depcomp mode which is confused by this.
+ #
+ # We need to recreate these files for each test, as the compiler may
+ # overwrite some of them when testing with obscure command lines.
+ # This happens at least with the AIX C compiler.
+ : > sub/conftest.c
+ for i in 1 2 3 4 5 6; do
+ echo '#include "conftst'$i'.h"' >> sub/conftest.c
+ # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with
+ # Solaris 8's {/usr,}/bin/sh.
+ touch sub/conftst$i.h
+ done
+ echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+ case $depmode in
+ nosideeffect)
+ # after this tag, mechanisms are not by side-effect, so they'll
+ # only be used when explicitly requested
+ if test "x$enable_dependency_tracking" = xyes; then
+ continue
+ else
+ break
+ fi
+ ;;
+ none) break ;;
+ esac
+ # We check with `-c' and `-o' for the sake of the "dashmstdout"
+ # mode. It turns out that the SunPro C++ compiler does not properly
+ # handle `-M -o', and we need to detect this.
+ if depmode=$depmode \
+ source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \
+ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+ $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \
+ >/dev/null 2>conftest.err &&
+ grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 &&
+ ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+ # icc doesn't choke on unknown options, it will just issue warnings
+ # or remarks (even with -Werror). So we grep stderr for any message
+ # that says an option was ignored or not supported.
+ # When given -MP, icc 7.0 and 7.1 complain thusly:
+ # icc: Command line warning: ignoring option '-M'; no argument required
+ # The diagnosis changed in icc 8.0:
+ # icc: Command line remark: option '-MP' not supported
+ if (grep 'ignoring option' conftest.err ||
+ grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+ am_cv_CC_dependencies_compiler_type=$depmode
+ break
+ fi
+ fi
+ done
-fi;
-if test "x${CLIENT_LOGIN+set}" != xset; then
- { { echo "$as_me:$LINENO: error: *** --with-user=USER is missing" >&5
-echo "$as_me: error: *** --with-user=USER is missing" >&2;}
- { (exit 1); exit 1; }; }
+ cd ..
+ rm -rf conftest.dir
+else
+ am_cv_CC_dependencies_compiler_type=none
fi
-cat >>confdefs.h <<_ACEOF
-#define CLIENT_LOGIN "$CLIENT_LOGIN"
-_ACEOF
-
-
-
-
-# Check whether --with-group or --without-group was given.
-if test "${with_group+set}" = set; then
- withval="$with_group"
+fi
+echo "$as_me:$LINENO: result: $am_cv_CC_dependencies_compiler_type" >&5
+echo "${ECHO_T}$am_cv_CC_dependencies_compiler_type" >&6
+CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type
- case "$withval" in
- "" | y | ye | yes | n | no)
- { { echo "$as_me:$LINENO: error: *** You must supply an argument to the --with-group option." >&5
-echo "$as_me: error: *** You must supply an argument to the --with-group option." >&2;}
- { (exit 1); exit 1; }; }
- ;;
- *) SETUID_GROUP="$withval"
- ;;
- esac
-fi;
-if test "x${SETUID_GROUP+set}" != xset; then
- { { echo "$as_me:$LINENO: error: *** --with-group=GROUP is missing" >&5
-echo "$as_me: error: *** --with-group=GROUP is missing" >&2;}
- { (exit 1); exit 1; }; }
+if
+ test "x$enable_dependency_tracking" != xno \
+ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then
+ am__fastdepCC_TRUE=
+ am__fastdepCC_FALSE='#'
+else
+ am__fastdepCC_TRUE='#'
+ am__fastdepCC_FALSE=
fi
-# Check whether --with-owner or --without-owner was given.
-if test "${with_owner+set}" = set; then
- withval="$with_owner"
- case "$withval" in
- "" | y | ye | yes | n | no)
- { { echo "$as_me:$LINENO: error: *** You must supply an argument to the --with-owner option." >&5
-echo "$as_me: error: *** You must supply an argument to the --with-owner option." >&2;}
- { (exit 1); exit 1; }; }
- ;;
- *) BINARY_OWNER="$withval"
- ;;
- esac
+# Check whether --enable-largefile or --disable-largefile was given.
+if test "${enable_largefile+set}" = set; then
+ enableval="$enable_largefile"
fi;
-if test "x${BINARY_OWNER+set}" != xset ; then
- BINARY_OWNER=$CLIENT_LOGIN
-fi
+if test "$enable_largefile" != no; then
-cat >>confdefs.h <<_ACEOF
-#define BINARY_OWNER "$BINARY_OWNER"
+ echo "$as_me:$LINENO: checking for special C compiler options needed for large files" >&5
+echo $ECHO_N "checking for special C compiler options needed for large files... $ECHO_C" >&6
+if test "${ac_cv_sys_largefile_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_cv_sys_largefile_CC=no
+ if test "$GCC" != yes; then
+ ac_save_CC=$CC
+ while :; do
+ # IRIX 6.2 and later do not support large files by default,
+ # so use the C compiler's -n32 option if that helps.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <sys/types.h>
+ /* Check that off_t can represent 2**63 - 1 correctly.
+ We can't simply define LARGE_OFF_T to be 9223372036854775807,
+ since some C++ compilers masquerading as C compilers
+ incorrectly reject 9223372036854775807. */
+#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+ int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
+ && LARGE_OFF_T % 2147483647 == 1)
+ ? 1 : -1];
+int
+main ()
+{
+ ;
+ return 0;
+}
+_ACEOF
+ rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ break
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+fi
+rm -f conftest.err conftest.$ac_objext
+ CC="$CC -n32"
+ rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_sys_largefile_CC=' -n32'; break
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+fi
+rm -f conftest.err conftest.$ac_objext
+ break
+ done
+ CC=$ac_save_CC
+ rm -f conftest.$ac_ext
+ fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_sys_largefile_CC" >&5
+echo "${ECHO_T}$ac_cv_sys_largefile_CC" >&6
+ if test "$ac_cv_sys_largefile_CC" != no; then
+ CC=$CC$ac_cv_sys_largefile_CC
+ fi
-# Check whether --with-rundump or --without-rundump was given.
-if test "${with_rundump+set}" = set; then
- withval="$with_rundump"
-
- case "$withval" in
- n | no | y | ye | yes) FORCE_USE_RUNDUMP="$withval";;
- *) { { echo "$as_me:$LINENO: error: *** You must not supply an argument to --with-rundump option." >&5
-echo "$as_me: error: *** You must not supply an argument to --with-rundump option." >&2;}
- { (exit 1); exit 1; }; };;
- esac
-
-
-fi;
-
-
-# Check whether --with-config or --without-config was given.
-if test "${with_config+set}" = set; then
- withval="$with_config"
-
- case "$withval" in
- "" | y | ye | yes | n | no)
- { { echo "$as_me:$LINENO: error: *** You must supply an argument to the --with-config option." >&5
-echo "$as_me: error: *** You must supply an argument to the --with-config option." >&2;}
- { (exit 1); exit 1; }; }
- ;;
- *) DEFAULT_CONFIG="$withval"
- ;;
- esac
-
+ echo "$as_me:$LINENO: checking for _FILE_OFFSET_BITS value needed for large files" >&5
+echo $ECHO_N "checking for _FILE_OFFSET_BITS value needed for large files... $ECHO_C" >&6
+if test "${ac_cv_sys_file_offset_bits+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
else
- : ${DEFAULT_CONFIG=DailySet1}
-
-fi;
-
-cat >>confdefs.h <<_ACEOF
-#define DEFAULT_CONFIG "$DEFAULT_CONFIG"
+ while :; do
+ ac_cv_sys_file_offset_bits=no
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <sys/types.h>
+ /* Check that off_t can represent 2**63 - 1 correctly.
+ We can't simply define LARGE_OFF_T to be 9223372036854775807,
+ since some C++ compilers masquerading as C compilers
+ incorrectly reject 9223372036854775807. */
+#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+ int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
+ && LARGE_OFF_T % 2147483647 == 1)
+ ? 1 : -1];
+int
+main ()
+{
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ break
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#define _FILE_OFFSET_BITS 64
+#include <sys/types.h>
+ /* Check that off_t can represent 2**63 - 1 correctly.
+ We can't simply define LARGE_OFF_T to be 9223372036854775807,
+ since some C++ compilers masquerading as C compilers
+ incorrectly reject 9223372036854775807. */
+#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+ int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
+ && LARGE_OFF_T % 2147483647 == 1)
+ ? 1 : -1];
+int
+main ()
+{
-
-# Check whether --with-tape-server or --without-tape-server was given.
-if test "${with_tape_server+set}" = set; then
- withval="$with_tape_server"
-
- case "$withval" in
- "" | y | ye | yes | n | no)
- { { echo "$as_me:$LINENO: error: *** You must supply an argument to the --with-tape-server option." >&5
-echo "$as_me: error: *** You must supply an argument to the --with-tape-server option." >&2;}
- { (exit 1); exit 1; }; }
- ;;
- *) DEFAULT_TAPE_SERVER="$withval"
- ;;
- esac
-
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_sys_file_offset_bits=64; break
else
- : ${DEFAULT_TAPE_SERVER=$DEFAULT_SERVER}
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
-fi;
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ break
+done
+fi
+echo "$as_me:$LINENO: result: $ac_cv_sys_file_offset_bits" >&5
+echo "${ECHO_T}$ac_cv_sys_file_offset_bits" >&6
+if test "$ac_cv_sys_file_offset_bits" != no; then
cat >>confdefs.h <<_ACEOF
-#define DEFAULT_TAPE_SERVER "$DEFAULT_TAPE_SERVER"
+#define _FILE_OFFSET_BITS $ac_cv_sys_file_offset_bits
_ACEOF
-
-
-
-# Check whether --with-tape-device or --without-tape-device was given.
-if test "${with_tape_device+set}" = set; then
- withval="$with_tape_device"
-
- case "$withval" in
- "" | y | ye | yes | n | no)
- { { echo "$as_me:$LINENO: error: *** You must supply an argument to the --with-tape-device option." >&5
-echo "$as_me: error: *** You must supply an argument to the --with-tape-device option." >&2;}
- { (exit 1); exit 1; }; }
- ;;
- *) DEFAULT_TAPE_DEVICE="$withval"
- ;;
- esac
-
+fi
+rm -f conftest*
+ echo "$as_me:$LINENO: checking for _LARGE_FILES value needed for large files" >&5
+echo $ECHO_N "checking for _LARGE_FILES value needed for large files... $ECHO_C" >&6
+if test "${ac_cv_sys_large_files+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
else
+ while :; do
+ ac_cv_sys_large_files=no
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <sys/types.h>
+ /* Check that off_t can represent 2**63 - 1 correctly.
+ We can't simply define LARGE_OFF_T to be 9223372036854775807,
+ since some C++ compilers masquerading as C compilers
+ incorrectly reject 9223372036854775807. */
+#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+ int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
+ && LARGE_OFF_T % 2147483647 == 1)
+ ? 1 : -1];
+int
+main ()
+{
- if test -z "$DEFAULT_TAPE_DEVICE"; then
- echo "$as_me:$LINENO: checking for non-rewinding tape device" >&5
-echo $ECHO_N "checking for non-rewinding tape device... $ECHO_C" >&6
- tape_dev=null:
- nr_tape_dev=null:
- if test -d /dev/rmt; then
-
-
- for num in 9 8 7 6 5 4 3 2 1 0; do
- td=/dev/rmt/${num}b
- ntd=/dev/rmt/${num}bn
- if test -r $td -a -r $ntd; then
- tape_dev=$td
- nr_tape_dev=$ntd
- fi
- done
- else
- for num in 9 8 7 6 5 4 3 2 1 0; do
- td=/dev/rst${num}
- ntd=/dev/nrst${num}
- if test -r $td -a -r $ntd; then
- tape_dev=$td
- nr_tape_dev=$ntd
- fi
- done
- fi
- DEFAULT_TAPE_DEVICE=$nr_tape_dev
- echo "$as_me:$LINENO: result: $DEFAULT_TAPE_DEVICE" >&5
-echo "${ECHO_T}$DEFAULT_TAPE_DEVICE" >&6
- fi
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ break
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#define _LARGE_FILES 1
+#include <sys/types.h>
+ /* Check that off_t can represent 2**63 - 1 correctly.
+ We can't simply define LARGE_OFF_T to be 9223372036854775807,
+ since some C++ compilers masquerading as C compilers
+ incorrectly reject 9223372036854775807. */
+#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+ int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
+ && LARGE_OFF_T % 2147483647 == 1)
+ ? 1 : -1];
+int
+main ()
+{
-fi;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_sys_large_files=1; break
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
-if test -z "$DEFAULT_TAPE_DEVICE"; then
- DEFAULT_TAPE_DEVICE=/dev/null
fi
-
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ break
+done
+fi
+echo "$as_me:$LINENO: result: $ac_cv_sys_large_files" >&5
+echo "${ECHO_T}$ac_cv_sys_large_files" >&6
+if test "$ac_cv_sys_large_files" != no; then
cat >>confdefs.h <<_ACEOF
-#define DEFAULT_TAPE_DEVICE "$DEFAULT_TAPE_DEVICE"
+#define _LARGE_FILES $ac_cv_sys_large_files
_ACEOF
+fi
+rm -f conftest*
+fi
-
-# Check whether --with-ftape-raw-device or --without-ftape-raw-device was given.
-if test "${with_ftape_raw_device+set}" = set; then
- withval="$with_ftape_raw_device"
-
- case "$withval" in
- "" | y | ye | yes | n | no)
- { { echo "$as_me:$LINENO: error: *** You must supply an argument to the --with-ftape-rawdevice option." >&5
-echo "$as_me: error: *** You must supply an argument to the --with-ftape-rawdevice option." >&2;}
- { (exit 1); exit 1; }; }
- ;;
- *) DEFAULT_RAW_TAPE_DEVICE="$withval"
- ;;
- esac
-
+for ac_prog in grep
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_path_GREP+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
else
+ case $GREP in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_GREP="$GREP" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $LOCSYSPATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_GREP="$as_dir/$ac_word$ac_exec_ext"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
- if test -z "$DEFAULT_RAW_TAPE_DEVICE"; then
- echo "$as_me:$LINENO: checking for raw ftape device" >&5
-echo $ECHO_N "checking for raw ftape device... $ECHO_C" >&6
- raw_tape_dev=/dev/null
- for num in 3 2 1 0 ; do
- td=/dev/rawft${num}
- if test -r $td; then
- raw_tape_dev=$td
- fi
- done
- DEFAULT_RAW_TAPE_DEVICE=$raw_tape_dev
- echo "$as_me:$LINENO: result: $DEFAULT_RAW_TAPE_DEVICE" >&5
-echo "${ECHO_T}$DEFAULT_RAW_TAPE_DEVICE" >&6
- fi
+ ;;
+esac
+fi
+GREP=$ac_cv_path_GREP
+if test -n "$GREP"; then
+ echo "$as_me:$LINENO: result: $GREP" >&5
+echo "${ECHO_T}$GREP" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
-fi;
+ test -n "$GREP" && break
+done
-if test -z "$DEFAULT_RAW_TAPE_DEVICE"; then
- DEFAULT_RAW_TAPE_DEVICE=/dev/null
+if test -z "$GREP"; then
+ GREP=grep
fi
-
cat >>confdefs.h <<_ACEOF
-#define DEFAULT_RAW_TAPE_DEVICE "$DEFAULT_RAW_TAPE_DEVICE"
+#define GREP "$GREP"
_ACEOF
-
-
-
-# Check whether --with-rew-tape or --without-rew-tape was given.
-if test "${with_rew_tape+set}" = set; then
- withval="$with_rew_tape"
- { { echo "$as_me:$LINENO: error: *** --with-rew-tape is deprecated, use --with-tape-device instead." >&5
-echo "$as_me: error: *** --with-rew-tape is deprecated, use --with-tape-device instead." >&2;}
- { (exit 1); exit 1; }; }
-
-fi;
-
-
-# Check whether --with-norew-tape or --without-norew-tape was given.
-if test "${with_norew_tape+set}" = set; then
- withval="$with_norew_tape"
- { { echo "$as_me:$LINENO: error: *** --with-norew-tape is deprecated, use --with-tape-device instead." >&5
-echo "$as_me: error: *** --with-norew-tape is deprecated, use --with-tape-device instead." >&2;}
- { (exit 1); exit 1; }; }
-
-fi;
-
-
-# Check whether --with-changer-device or --without-changer-device was given.
-if test "${with_changer_device+set}" = set; then
- withval="$with_changer_device"
-
- case "$withval" in
- "" | y | ye | yes | n | no)
- { { echo "$as_me:$LINENO: error: *** You must supply an argument to the --with-changer-device option." >&5
-echo "$as_me: error: *** You must supply an argument to the --with-changer-device option." >&2;}
- { (exit 1); exit 1; }; }
- ;;
- *) DEFAULT_CHANGER_DEVICE="$withval"
- ;;
- esac
-
+for ac_prog in egrep
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_path_EGREP+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
else
+ case $EGREP in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_EGREP="$EGREP" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $LOCSYSPATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_EGREP="$as_dir/$ac_word$ac_exec_ext"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
- if test -z "$DEFAULT_CHANGER_DEVICE" &&
- test -f /dev/ch0; then
- DEFAULT_CHANGER_DEVICE=/dev/ch0
- fi
-
-
-fi;
-
-if test -z "$DEFAULT_CHANGER_DEVICE"; then
- DEFAULT_CHANGER_DEVICE=/dev/null
+ ;;
+esac
fi
+EGREP=$ac_cv_path_EGREP
+if test -n "$EGREP"; then
+ echo "$as_me:$LINENO: result: $EGREP" >&5
+echo "${ECHO_T}$EGREP" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
-cat >>confdefs.h <<_ACEOF
-#define DEFAULT_CHANGER_DEVICE "$DEFAULT_CHANGER_DEVICE"
-_ACEOF
+ test -n "$EGREP" && break
+done
+for ac_prog in lint
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_path_AMLINT+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ case $AMLINT in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_AMLINT="$AMLINT" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+as_dummy="/opt/SUNWspro/bin:$SYSLOCPATH"
+for as_dir in $as_dummy
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_AMLINT="$as_dir/$ac_word$ac_exec_ext"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+ ;;
+esac
+fi
+AMLINT=$ac_cv_path_AMLINT
-# Check whether --with-fqdn or --without-fqdn was given.
-if test "${with_fqdn+set}" = set; then
- withval="$with_fqdn"
- USE_FQDN=$withval
+if test -n "$AMLINT"; then
+ echo "$as_me:$LINENO: result: $AMLINT" >&5
+echo "${ECHO_T}$AMLINT" >&6
else
- : ${USE_FQDN=no}
-
-fi;
-case "$USE_FQDN" in
-n | no) : ;;
-y | ye | yes)
-cat >>confdefs.h <<\_ACEOF
-#define USE_FQDN 1
-_ACEOF
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+ test -n "$AMLINT" && break
+done
+
+if test ! -z "$AMLINT"; then
+ $AMLINT -flags | $GREP -- '-errfmt=' 2>&1 > /dev/null
+ if test $? -eq 0; then
+ AMLINTFLAGS="-n -s -u -m -x"
+ AMLINTFLAGS="$AMLINTFLAGS -errchk=%all"
+ AMLINTFLAGS="$AMLINTFLAGS -errfmt=macro"
+ AMLINTFLAGS="$AMLINTFLAGS -errhdr=no%/usr/include"
+ AMLINTFLAGS="$AMLINTFLAGS -errhdr=%user"
+ AMLINTFLAGS="$AMLINTFLAGS -errsecurity=extended"
+ AMLINTFLAGS="$AMLINTFLAGS -errtags=yes"
+ AMLINTFLAGS="$AMLINTFLAGS -Ncheck=%all"
+ AMLINTFLAGS="$AMLINTFLAGS -Nlevel=2"
+ AMLINTFLAGS="$AMLINTFLAGS -erroff=E_ASGN_NEVER_USED"
+ AMLINTFLAGS="$AMLINTFLAGS,E_ASGN_RESET"
+ AMLINTFLAGS="$AMLINTFLAGS,E_CAST_INT_CONST_TO_SMALL_INT"
+ AMLINTFLAGS="$AMLINTFLAGS,E_CAST_INT_TO_SMALL_INT"
+ AMLINTFLAGS="$AMLINTFLAGS,E_CAST_UINT_TO_SIGNED_INT"
+ AMLINTFLAGS="$AMLINTFLAGS,E_CONSTANT_CONDITION"
+ AMLINTFLAGS="$AMLINTFLAGS,E_ENUM_UNUSE"
+ AMLINTFLAGS="$AMLINTFLAGS,E_EXPR_NULL_EFFECT"
+ AMLINTFLAGS="$AMLINTFLAGS,E_FUNC_RET_ALWAYS_IGNOR"
+ AMLINTFLAGS="$AMLINTFLAGS,E_FUNC_RET_MAYBE_IGNORED"
+ AMLINTFLAGS="$AMLINTFLAGS,E_H_C_CHECK0"
+ AMLINTFLAGS="$AMLINTFLAGS,E_H_C_CHECK1"
+ AMLINTFLAGS="$AMLINTFLAGS,E_H_C_CHECK2"
+ AMLINTFLAGS="$AMLINTFLAGS,E_INCL_MNUSD"
+ AMLINTFLAGS="$AMLINTFLAGS,E_INCL_NUSD"
+ AMLINTFLAGS="$AMLINTFLAGS,E_MCR_NODIFF"
+ AMLINTFLAGS="$AMLINTFLAGS,E_NAME_MULTIPLY_DEF"
+ AMLINTFLAGS="$AMLINTFLAGS,E_P_REF_NULL_PSBL"
+ AMLINTFLAGS="$AMLINTFLAGS,E_P_REF_SUSP"
+ AMLINTFLAGS="$AMLINTFLAGS,E_PTRDIFF_OVERFLOW"
+ AMLINTFLAGS="$AMLINTFLAGS,E_P_USE_NULL_PSBL"
+ AMLINTFLAGS="$AMLINTFLAGS,E_P_USE_SUSP"
+ AMLINTFLAGS="$AMLINTFLAGS,E_SEC_ACCESS_WARN"
+ AMLINTFLAGS="$AMLINTFLAGS,E_SEC_CHDIR_WARN"
+ AMLINTFLAGS="$AMLINTFLAGS,E_SEC_CHMOD_WARN"
+ AMLINTFLAGS="$AMLINTFLAGS,E_SEC_CREAT_WITHOUT_EXCL"
+ AMLINTFLAGS="$AMLINTFLAGS,E_SEC_EXEC_PATH"
+ AMLINTFLAGS="$AMLINTFLAGS,E_SEC_EXEC_WARN"
+ AMLINTFLAGS="$AMLINTFLAGS,E_SEC_FOPEN_MODE"
+ AMLINTFLAGS="$AMLINTFLAGS,E_SEC_GETENV_WARN"
+ AMLINTFLAGS="$AMLINTFLAGS,E_SEC_MKDIR_WARN"
+ AMLINTFLAGS="$AMLINTFLAGS,E_SEC_PRINTF_VAR_FMT"
+ AMLINTFLAGS="$AMLINTFLAGS,E_SEC_RAND_WARN"
+ AMLINTFLAGS="$AMLINTFLAGS,E_SEC_SCANF_VAR_FMT"
+ AMLINTFLAGS="$AMLINTFLAGS,E_SEC_SELECT_WARN"
+ AMLINTFLAGS="$AMLINTFLAGS,E_SEC_SHELL_WARN"
+ AMLINTFLAGS="$AMLINTFLAGS,E_SEC_STRNCPY_WARN"
+ AMLINTFLAGS="$AMLINTFLAGS,E_SEC_UMASK_WARN"
+ AMLINTFLAGS="$AMLINTFLAGS,E_SEC_USE_AFTER_STAT"
+ AMLINTFLAGS="$AMLINTFLAGS,E_SIGN_EXTENSION_PSBL"
+ AMLINTFLAGS="$AMLINTFLAGS,E_TYPEDEF_UNUSE"
+ AMLINTFLAGS="$AMLINTFLAGS,E_UNCAL_F"
+ else
+ AMLINTFLAGS=""
+ fi
+else
+ for ac_prog in splint
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_path_AMLINT+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ case $AMLINT in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_AMLINT="$AMLINT" # Let the user override the test with a path.
;;
-*) { { echo "$as_me:$LINENO: error: *** You must not supply an argument to --with-fqdn option." >&5
-echo "$as_me: error: *** You must not supply an argument to --with-fqdn option." >&2;}
- { (exit 1); exit 1; }; }
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $SYSLOCPATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_AMLINT="$as_dir/$ac_word$ac_exec_ext"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
;;
esac
+fi
+AMLINT=$ac_cv_path_AMLINT
-
-# Check whether --with-broken-fsf or --without-broken-fsf was given.
-if test "${with_broken_fsf+set}" = set; then
- withval="$with_broken_fsf"
- HAVE_BROKEN_FSF=$withval
+if test -n "$AMLINT"; then
+ echo "$as_me:$LINENO: result: $AMLINT" >&5
+echo "${ECHO_T}$AMLINT" >&6
else
- : ${HAVE_BROKEN_FSF=no}
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
-fi;
-case "$HAVE_BROKEN_FSF" in
-n | no) : ;;
-y | ye | yes)
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_BROKEN_FSF 1
-_ACEOF
+ test -n "$AMLINT" && break
+done
- ;;
-*) { { echo "$as_me:$LINENO: error: *** You must not supply an argument to --with-broken-fsf option." >&5
-echo "$as_me: error: *** You must not supply an argument to --with-broken-fsf option." >&2;}
- { (exit 1); exit 1; }; }
- ;;
-esac
+ if test ! -z "$AMLINT"; then
+ AMLINT="splint"
+ fi
+ AMLINTFLAGS='+show-scan +unixlib -weak -globs +usedef +usereleased +impouts -paramimptemp -varuse -warnposix -redef -preproc -fixedformalarray -retval -unrecog -usevarargs -formatcode'
+fi
-# Check whether --with-gnutar or --without-gnutar was given.
-if test "${with_gnutar+set}" = set; then
- withval="$with_gnutar"
+
+# Check whether --with-includes or --without-includes was given.
+if test "${with_includes+set}" = set; then
+ withval="$with_includes"
case "$withval" in
- /*) GNUTAR="$withval";;
- y|ye|yes) :;;
- n|no) GNUTAR=;;
- *) { { echo "$as_me:$LINENO: error: *** You must supply a full pathname to --with-gnutar" >&5
-echo "$as_me: error: *** You must supply a full pathname to --with-gnutar" >&2;}
- { (exit 1); exit 1; }; };;
+ "" | y | ye | yes | n | no)
+ { { echo "$as_me:$LINENO: error: *** You must supply an argument to the --with-includes option." >&5
+echo "$as_me: error: *** You must supply an argument to the --with-includes option." >&2;}
+ { (exit 1); exit 1; }; }
+ ;;
esac
-
+ INCLUDE_DIRS="$withval"
fi;
+if test "$INCLUDE_DIRS"; then
+ for dir in $INCLUDE_DIRS; do
+ if test -d "$dir"; then
+ AMANDA_CPPFLAGS="$AMANDA_CPPFLAGS -I$dir"
+ else
+ { echo "$as_me:$LINENO: WARNING: *** Include directory $dir does not exist." >&5
+echo "$as_me: WARNING: *** Include directory $dir does not exist." >&2;}
+ fi
+ done
+fi
+
-# Check whether --with-smbclient or --without-smbclient was given.
-if test "${with_smbclient+set}" = set; then
- withval="$with_smbclient"
+# Check whether --with-libraries or --without-libraries was given.
+if test "${with_libraries+set}" = set; then
+ withval="$with_libraries"
case "$withval" in
- /*) SAMBA_CLIENT="$withval";;
- y|ye|yes) :;;
- n|no) SAMBA_CLIENT=;;
- *) { { echo "$as_me:$LINENO: error: *** You must supply a full pathname to --with-smbclient" >&5
-echo "$as_me: error: *** You must supply a full pathname to --with-smbclient" >&2;}
- { (exit 1); exit 1; }; };;
+ "" | y | ye | yes | n | no)
+ { { echo "$as_me:$LINENO: error: *** You must supply an argument to the --with-libraries option." >&5
+echo "$as_me: error: *** You must supply an argument to the --with-libraries option." >&2;}
+ { (exit 1); exit 1; }; }
+ ;;
esac
-
+ LIBRARY_DIRS="$withval"
fi;
+if test "$LIBRARY_DIRS"; then
+ for dir in $LIBRARY_DIRS; do
+ if test -d "$dir"; then
+ case "$target" in
+ *-solaris2*,*-netbsd*)
+ AMANDA_LDFLAGS="$AMANDA_LDFLAGS -R$dir"
+ ;;
+ esac
+ AMANDA_LDFLAGS="$AMANDA_LDFLAGS -L$dir"
+ else
+ { echo "$as_me:$LINENO: WARNING: *** Library directory $dir does not exist." >&5
+echo "$as_me: WARNING: *** Library directory $dir does not exist." >&2;}
+ fi
+ done
+fi
-# Check whether --with-samba-user or --without-samba-user was given.
-if test "${with_samba_user+set}" = set; then
- withval="$with_samba_user"
- { { echo "$as_me:$LINENO: error: *** The samba-user option was deprecated, the username go in the amandapass" >&5
-echo "$as_me: error: *** The samba-user option was deprecated, the username go in the amandapass" >&2;}
- { (exit 1); exit 1; }; }
-
-
-fi;
-# Check whether --with-gnutar-listdir or --without-gnutar-listdir was given.
-if test "${with_gnutar_listdir+set}" = set; then
- withval="$with_gnutar_listdir"
+# Check whether --with-dumperdir or --without-dumperdir was given.
+if test "${with_dumperdir+set}" = set; then
+ withval="$with_dumperdir"
case "$withval" in
- n | no) unset GNUTAR_LISTDIR ;;
- y | ye | yes) : ${GNUTAR_LISTDIR=$localstatedir/amanda/gnutar-lists} ;;
- /*) GNUTAR_LISTDIR="$withval" ;;
- *) { { echo "$as_me:$LINENO: error: *** You must supply a full pathname to --with-gnutar-listdir" >&5
-echo "$as_me: error: *** You must supply a full pathname to --with-gnutar-listdir" >&2;}
+ "" | y | ye | yes | n | no)
+ { { echo "$as_me:$LINENO: error: *** You must supply an argument to the --with-dumperdir option." >&5
+echo "$as_me: error: *** You must supply an argument to the --with-dumperdir option." >&2;}
{ (exit 1); exit 1; }; }
+ ;;
esac
+ DUMPER_DIR="$withval"
else
- : ${GNUTAR_LISTDIR="$localstatedir/amanda/gnutar-lists"}
-fi;
-if test "$GNUTAR_LISTDIR"; then
- GNUTAR_LISTDIR=`(
test "x$prefix" = xNONE && prefix=$ac_default_prefix
- eval echo "$GNUTAR_LISTDIR"
- )`
-
-cat >>confdefs.h <<_ACEOF
-#define GNUTAR_LISTED_INCREMENTAL_DIR "$GNUTAR_LISTDIR"
-_ACEOF
+ test "x$exec_prefix" = xNONE && exec_prefix=${prefix}
+ DUMPER_DIR=$exec_prefix/dumper
- GNUTAR_LISTED_INCREMENTAL_DIRX=$GNUTAR_LISTDIR
-else
- GNUTAR_LISTED_INCREMENTAL_DIRX=
-fi
+fi;
+DUMPER_DIR=`(
+ test "x$prefix" = xNONE && prefix=$ac_default_prefix
+ test "x$exec_prefix" = xNONE && exec_prefix=${prefix}
+ eval echo "$DUMPER_DIR"
+)`
+cat >>confdefs.h <<_ACEOF
+#define DUMPER_DIR "$DUMPER_DIR"
+_ACEOF
-# Check whether --with-gnutar-listed-incremental or --without-gnutar-listed-incremental was given.
-if test "${with_gnutar_listed_incremental+set}" = set; then
- withval="$with_gnutar_listed_incremental"
- { { echo "$as_me:$LINENO: error: *** The gnutar-listed-incremental option was deprecated, use gnutar-listdir instead" >&5
-echo "$as_me: error: *** The gnutar-listed-incremental option was deprecated, use gnutar-listdir instead" >&2;}
- { (exit 1); exit 1; }; }
-fi;
-GNUTAR_LISTED_INCREMENTAL_DIR=$GNUTAR_LISTDIR
+# Check whether --with-configdir or --without-configdir was given.
+if test "${with_configdir+set}" = set; then
+ withval="$with_configdir"
+ case "$withval" in
+ "" | y | ye | yes | n | no)
+ { { echo "$as_me:$LINENO: error: *** You must supply an argument to the --with-configdir option." >&5
+echo "$as_me: error: *** You must supply an argument to the --with-configdir option." >&2;}
+ { (exit 1); exit 1; }; }
+ ;;
+ *) CONFIG_DIR="$withval"
+ ;;
+ esac
-# Check whether --with-bsd-security or --without-bsd-security was given.
-if test "${with_bsd_security+set}" = set; then
- withval="$with_bsd_security"
- BSD_SECURITY=$withval
else
- : ${BSD_SECURITY=yes}
+ : ${CONFIG_DIR="$sysconfdir/amanda"}
fi;
-case "$BSD_SECURITY" in
-n | no) : ;;
-y | ye | yes)
-cat >>confdefs.h <<\_ACEOF
-#define BSD_SECURITY 1
-_ACEOF
+CONFIG_DIR=`(
+ test "x$prefix" = xNONE && prefix=$ac_default_prefix
+ test "x$exec_prefix" = xNONE && exec_prefix=${prefix}
+ eval echo "$CONFIG_DIR"
+)`
- ;;
-*) { { echo "$as_me:$LINENO: error: *** You must not supply an argument to --with-bsd-security option." >&5
-echo "$as_me: error: *** You must not supply an argument to --with-bsd-security option." >&2;}
- { (exit 1); exit 1; }; }
- ;;
-esac
+cat >>confdefs.h <<_ACEOF
+#define CONFIG_DIR "$CONFIG_DIR"
+_ACEOF
-# Check whether --with-amandahosts or --without-amandahosts was given.
-if test "${with_amandahosts+set}" = set; then
- withval="$with_amandahosts"
- USE_AMANDAHOSTS=$withval
-else
- : ${USE_AMANDAHOSTS=yes}
-fi;
-case "$USE_AMANDAHOSTS" in
-n | no) : ;;
-y | ye | yes) :
- case "$BSD_SECURITY" in
- y | ye | yes)
-cat >>confdefs.h <<\_ACEOF
-#define USE_AMANDAHOSTS 1
-_ACEOF
- ;;
- esac
- ;;
-*) { { echo "$as_me:$LINENO: error: *** You must not supply an argument to --with-amandahosts option." >&5
-echo "$as_me: error: *** You must not supply an argument to --with-amandahosts option." >&2;}
+# Check whether --with-indexdir or --without-indexdir was given.
+if test "${with_indexdir+set}" = set; then
+ withval="$with_indexdir"
+ { { echo "$as_me:$LINENO: error: *** --with-indexdir is deprecated, use indexdir in amanda.conf instead." >&5
+echo "$as_me: error: *** --with-indexdir is deprecated, use indexdir in amanda.conf instead." >&2;}
{ (exit 1); exit 1; }; }
- ;;
-esac
+fi;
-# Check whether --with-dbmalloc or --without-dbmalloc was given.
-if test "${with_dbmalloc+set}" = set; then
- withval="$with_dbmalloc"
- DBMALLOC="$withval"
-else
- : ${DBMALLOC=no}
+# Check whether --with-dbdir or --without-dbdir was given.
+if test "${with_dbdir+set}" = set; then
+ withval="$with_dbdir"
+ { { echo "$as_me:$LINENO: error: *** --with-dbdir is deprecated, use infofile in amanda.conf instead." >&5
+echo "$as_me: error: *** --with-dbdir is deprecated, use infofile in amanda.conf instead." >&2;}
+ { (exit 1); exit 1; }; }
fi;
-case "$DBMALLOC" in
-n | no)
- DBMALLOCCFLAGS=""
- DBMALLOCLIBS=""
- ;;
-*)
- DBMALLOCCFLAGS="-I$DBMALLOC -DUSE_DBMALLOC"
- DBMALLOCLIBS="-L$DBMALLOC -ldbmalloc"
- ;;
-esac
+# Check whether --with-logdir or --without-logdir was given.
+if test "${with_logdir+set}" = set; then
+ withval="$with_logdir"
+ { { echo "$as_me:$LINENO: error: *** --with-logdir is deprecated, use logdir in amanda.conf instead." >&5
+echo "$as_me: error: *** --with-logdir is deprecated, use logdir in amanda.conf instead." >&2;}
+ { (exit 1); exit 1; }; }
-: ${KRB4_SPOTS="/usr/kerberos /usr/cygnus /usr /opt/kerberos"}
+fi;
-# Check whether --with-krb4-security or --without-krb4-security was given.
-if test "${with_krb4_security+set}" = set; then
- withval="$with_krb4_security"
- KRB4_SECURITY="$withval"
+# Check whether --with-suffixes or --without-suffixes was given.
+if test "${with_suffixes+set}" = set; then
+ withval="$with_suffixes"
+ USE_VERSION_SUFFIXES=$withval
else
- : ${KRB4_SECURITY=no}
+ : ${USE_VERSION_SUFFIXES=no}
fi;
-
-case "$KRB4_SECURITY" in
-n | no) KRB4_SECURITY=no ;;
-y | ye | yes) : ;;
-*) KRB4_SPOTS="$KRB4_SECURITY"
- KRB4_SECURITY=yes
- ;;
-esac
-
-echo "$as_me:$LINENO: checking for Kerberos and Amanda kerberos4 bits" >&5
-echo $ECHO_N "checking for Kerberos and Amanda kerberos4 bits... $ECHO_C" >&6
-if test "x${KRB4_SECURITY}" = xyes -a -f ${srcdir-.}/common-src/krb4-security.c ; then
- for dir in $KRB4_SPOTS; do
- if test -f ${dir}/lib/libkrb.a -a -f ${dir}/lib/libdes.a ; then
- #
- # This is the original Kerberos 4.
- #
- echo "$as_me:$LINENO: result: found in $dir" >&5
-echo "${ECHO_T}found in $dir" >&6
- KRB4_SECURITY=yes
-
-cat >>confdefs.h <<\_ACEOF
-#define KRB4_SECURITY 1
-_ACEOF
-
- if test -d $dir/include/kerberosIV ; then
- #
- # This handles BSD/OS.
- #
- KRB4INCLUDES=-I$dir/include/kerberosIV
- else
- KRB4INCLUDES=-I$dir/include
- fi
- KRB4LDFLAGS=-L$dir/lib
- KRB4LIBS="-lkrb -ldes"
- if test -f ${dir}/lib/libcom_err.a; then
- KRB4LIBS="$KRB4LIBS -lcom_err"
- fi
- break
- elif test -f ${dir}/lib/libkrb4.a &&
- test -f ${dir}/lib/libcrypto.a &&
- test -f ${dir}/lib/libdes425.a ; then
- #
- # This is Kerberos 5 with Kerberos 4 back-support.
- #
- echo "$as_me:$LINENO: result: found in $dir" >&5
-echo "${ECHO_T}found in $dir" >&6
- KRB4_SECURITY=yes
+case "$USE_VERSION_SUFFIXES" in
+y | ye | yes)
cat >>confdefs.h <<\_ACEOF
-#define KRB4_SECURITY 1
+#define USE_VERSION_SUFFIXES 1
_ACEOF
- KRB4INCLUDES="-I$dir/include -I$dir/include/kerberosIV"
- KRB4LDFLAGS=-L$dir/lib
- if test -f ${dir}/lib/libkrb5.a &&
- test -f ${dir}/lib/libcom_err.a; then
- KRB4LIBS="-lkrb4 -lkrb5 -lcrypto -ldes425 -lcom_err"
- else
- KRB4LIBS="-lkrb4 -lcrypto -ldes425"
- fi
- break
- fi
- done
- if test "x$KRB4LDFLAGS" = "x" ; then
- echo "$as_me:$LINENO: result: no libraries found" >&5
-echo "${ECHO_T}no libraries found" >&6
+ program_suffix="-$VERSION"
+ # This is from the output of configure.in.
+ if test "x$program_transform_name" = xs,x,x,; then
+ program_transform_name=
+ else
+ # Double any \ or $. echo might interpret backslashes.
+ cat <<\EOF_SED > conftestsed
+s,\\,\\\\,g; s,\$,$$,g
+EOF_SED
+ program_transform_name="`echo $program_transform_name|sed -f conftestsed`"
+ rm -f conftestsed
fi
-else
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
-fi
-
-
-# Check whether --with-rsh-security or --without-rsh-security was given.
-if test "${with_rsh_security+set}" = set; then
- withval="$with_rsh_security"
- RSH_SECURITY=$withval
-else
- : ${RSH_SECURITY=yes}
-
-fi;
-case "$RSH_SECURITY" in
-n | no) : ;;
-y | ye | yes)
-cat >>confdefs.h <<\_ACEOF
-#define RSH_SECURITY 1
-_ACEOF
+ test "x$program_prefix" != xNONE &&
+ program_transform_name="s,^,${program_prefix},; $program_transform_name"
+ # Use a double $ so make ignores it.
+ test "x$program_suffix" != xNONE &&
+ program_transform_name="s,\$\$,${program_suffix},; $program_transform_name"
+ # sed with no file args requires a program.
+ test "x$program_transform_name" = "" && program_transform_name="xs,x,x,"
+ # Remove empty command
+ cat <<\EOF_SED > conftestsed
+s,\;\;,\;,g; s,\; \$,,g; s,\;$,,g
+EOF_SED
+ program_transform_name="`echo $program_transform_name|sed -f conftestsed`"
+ rm -f conftestsed
;;
-*) { { echo "$as_me:$LINENO: error: *** You must not supply an argument the to --with-rsh-security option." >&5
-echo "$as_me: error: *** You must not supply an argument the to --with-rsh-security option." >&2;}
- { (exit 1); exit 1; }; }
- ;;
-esac
-
-
-# Check whether --with-ssh-security or --without-ssh-security was given.
-if test "${with_ssh_security+set}" = set; then
- withval="$with_ssh_security"
- SSH_SECURITY=$withval
-else
- : ${SSH_SECURITY=no}
-
-fi;
-case "$SSH_SECURITY" in
-n | no) : ;;
-y | ye | yes)
-cat >>confdefs.h <<\_ACEOF
-#define SSH_SECURITY 1
-_ACEOF
-
- SSH_SECURITY_SET=true
+n | no) USE_VERSION_SUFFIXES=no
;;
-*) { { echo "$as_me:$LINENO: error: *** You must not supply an argument the to --with-ssh-security option." >&5
-echo "$as_me: error: *** You must not supply an argument the to --with-ssh-security option." >&2;}
+*) { { echo "$as_me:$LINENO: error: *** You must not supply an argument to --with-suffixes option." >&5
+echo "$as_me: error: *** You must not supply an argument to --with-suffixes option." >&2;}
{ (exit 1); exit 1; }; }
;;
esac
-# Check whether --with-server-principal or --without-server-principal was given.
-if test "${with_server_principal+set}" = set; then
- withval="$with_server_principal"
-
- case "$withval" in
- "" | y | ye | yes | n | no)
- { { echo "$as_me:$LINENO: error: *** You must supply an argument to the --with-server-principal option." >&5
-echo "$as_me: error: *** You must supply an argument to the --with-server-principal option." >&2;}
- { (exit 1); exit 1; }; }
- ;;
- *)
- SERVER_HOST_PRINCIPLE="$withval"
- ;;
- esac
-
-else
- : ${SERVER_HOST_PRINCIPLE="amanda"}
-
-fi;
-
-cat >>confdefs.h <<_ACEOF
-#define SERVER_HOST_PRINCIPLE "$SERVER_HOST_PRINCIPLE"
-_ACEOF
+case "$target" in
+ *-hp-*)
+ CLIENT_SCRIPTS_OPT=amhpfixdevs
+ ;;
+ *-sni-sysv4)
+ CLIENT_SCRIPTS_OPT=amsinixfixdevs
+ ;;
+ *)
+ CLIENT_SCRIPTS_OPT=
+ ;;
+esac
-# Check whether --with-server-instance or --without-server-instance was given.
-if test "${with_server_instance+set}" = set; then
- withval="$with_server_instance"
- case "$withval" in
- "" | y | ye | yes | n | no)
- { { echo "$as_me:$LINENO: error: *** You must supply an argument to the --with-server-instance option." >&5
-echo "$as_me: error: *** You must supply an argument to the --with-server-instance option." >&2;}
+# Check whether --with-client-only or --without-client-only was given.
+if test "${with_client_only+set}" = set; then
+ withval="$with_client_only"
+ { { echo "$as_me:$LINENO: error: *** --with-client-only is deprecated, use --without-server instead." >&5
+echo "$as_me: error: *** --with-client-only is deprecated, use --without-server instead." >&2;}
{ (exit 1); exit 1; }; }
- ;;
- *) SERVER_HOST_INSTANCE="$withval"
- ;;
- esac
-
-else
- : ${SERVER_HOST_INSTANCE="amanda"}
fi;
-cat >>confdefs.h <<_ACEOF
-#define SERVER_HOST_INSTANCE "$SERVER_HOST_INSTANCE"
-_ACEOF
-
-
-
-# Check whether --with-server-keyfile or --without-server-keyfile was given.
-if test "${with_server_keyfile+set}" = set; then
- withval="$with_server_keyfile"
-
- case "$withval" in
- "" | y | ye | yes | n | no)
- { { echo "$as_me:$LINENO: error: *** You must supply an argument to the --with-server-keyfile option." >&5
-echo "$as_me: error: *** You must supply an argument to the --with-server-keyfile option." >&2;}
+# Check whether --with-server-only or --without-server-only was given.
+if test "${with_server_only+set}" = set; then
+ withval="$with_server_only"
+ { { echo "$as_me:$LINENO: error: *** --with-server-only is deprecated, use --without-client instead." >&5
+echo "$as_me: error: *** --with-server-only is deprecated, use --without-client instead." >&2;}
{ (exit 1); exit 1; }; }
- ;;
- *) SERVER_HOST_KEY_FILE="$withval"
- ;;
- esac
-
-else
- : ${SERVER_HOST_KEY_FILE="/.amanda"}
fi;
-cat >>confdefs.h <<_ACEOF
-#define SERVER_HOST_KEY_FILE "$SERVER_HOST_KEY_FILE"
-_ACEOF
-
-
-# Check whether --with-client-principal or --without-client-principal was given.
-if test "${with_client_principal+set}" = set; then
- withval="$with_client_principal"
+# Check whether --with-client or --without-client was given.
+if test "${with_client+set}" = set; then
+ withval="$with_client"
case "$withval" in
- "" | y | ye | yes | n | no)
- { { echo "$as_me:$LINENO: error: *** You must supply an argument to the --with-client-principal option." >&5
-echo "$as_me: error: *** You must supply an argument to the --with-client-principal option." >&2;}
+ y | ye | yes) NO_CLIENT_MODE=false;;
+ n | no) NO_CLIENT_MODE=true;;
+ *)
+ { { echo "$as_me:$LINENO: error: *** You must not supply an argument to --with-client option." >&5
+echo "$as_me: error: *** You must not supply an argument to --with-client option." >&2;}
{ (exit 1); exit 1; }; }
;;
- *) CLIENT_HOST_PRINCIPLE="$withval"
- ;;
esac
-else
- : ${CLIENT_HOST_PRINCIPLE="rcmd"}
fi;
-cat >>confdefs.h <<_ACEOF
-#define CLIENT_HOST_PRINCIPLE "$CLIENT_HOST_PRINCIPLE"
-_ACEOF
-
-
-# Check whether --with-client-instance or --without-client-instance was given.
-if test "${with_client_instance+set}" = set; then
- withval="$with_client_instance"
+# Check whether --with-server or --without-server was given.
+if test "${with_server+set}" = set; then
+ withval="$with_server"
case "$withval" in
- "" | y | ye | yes | n | no)
- { { echo "$as_me:$LINENO: error: *** You must supply an argument to the --with-client-instance option." >&5
-echo "$as_me: error: *** You must supply an argument to the --with-client-instance option." >&2;}
+ y | ye | yes) NO_SERVER_MODE=false ;;
+ n | no) NO_SERVER_MODE=true;NO_RESTORE_MODE=true;;
+ *)
+ { { echo "$as_me:$LINENO: error: *** You must not supply an argument to --with-server option. Maybe you meant --with-index-server=$withval" >&5
+echo "$as_me: error: *** You must not supply an argument to --with-server option. Maybe you meant --with-index-server=$withval" >&2;}
{ (exit 1); exit 1; }; }
;;
- *) CLIENT_HOST_INSTANCE="$withval"
- ;;
esac
-else
- : ${CLIENT_HOST_INSTANCE=HOSTNAME_INSTANCE}
fi;
-
-cat >>confdefs.h <<_ACEOF
-#define CLIENT_HOST_INSTANCE $CLIENT_HOST_INSTANCE
-_ACEOF
-
+if test "x${NO_SERVER_MODE+set}" != xset ; then
+ NO_SERVER_MODE=false
+fi
-# Check whether --with-client-keyfile or --without-client-keyfile was given.
-if test "${with_client_keyfile+set}" = set; then
- withval="$with_client_keyfile"
+# Check whether --with-restore or --without-restore was given.
+if test "${with_restore+set}" = set; then
+ withval="$with_restore"
case "$withval" in
- "" | y | ye | yes | n | no)
- { { echo "$as_me:$LINENO: error: *** You must supply an argument to the --with-client-keyfile option." >&5
-echo "$as_me: error: *** You must supply an argument to the --with-client-keyfile option." >&2;}
+ y | ye | yes) NO_RESTORE_MODE=false;;
+ n | no) NO_RESTORE_MODE=true;;
+ *)
+ { { echo "$as_me:$LINENO: error: *** You must not supply an argument to --with-restore option." >&5
+echo "$as_me: error: *** You must not supply an argument to --with-restore option." >&2;}
{ (exit 1); exit 1; }; }
;;
- *) CLIENT_HOST_KEY_FILE="$withval"
- ;;
esac
-else
- : ${CLIENT_HOST_KEY_FILE=KEYFILE}
fi;
+if test "x${NO_RESTORE_MODE+set}" != xset ; then
+ NO_RESTORE_MODE=${NO_SERVER_MODE-false}
+fi
-# Assume it's either KEYFILE (defined in krb.h), or a string filename...
-if test "x$CLIENT_HOST_KEY_FILE" != "xKEYFILE"; then
- CLIENT_HOST_KEY_FILE="\"$CLIENT_HOST_KEY_FILE\""
+if ${NO_SERVER_MODE-false}; then
+ if ${NO_RESTORE_MODE-false}; then
+ true
+ else
+ { { echo "$as_me:$LINENO: error: *** --without-server requires --without-restore" >&5
+echo "$as_me: error: *** --without-server requires --without-restore" >&2;}
+ { (exit 1); exit 1; }; }
+ fi
fi
-cat >>confdefs.h <<_ACEOF
-#define CLIENT_HOST_KEY_FILE $CLIENT_HOST_KEY_FILE
-_ACEOF
+# Check whether --with-amrecover or --without-amrecover was given.
+if test "${with_amrecover+set}" = set; then
+ withval="$with_amrecover"
+ case "$withval" in
+ y | ye | yes)
+ if ${NO_CLIENT_MODE-false}; then
+ { { echo "$as_me:$LINENO: error: *** --without-client and --with-amrecover are incompatible" >&5
+echo "$as_me: error: *** --without-client and --with-amrecover are incompatible" >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+ NO_RECOVER_MODE=false;;
+ n | no) NO_RECOVER_MODE=true;;
+ *)
+ { { echo "$as_me:$LINENO: error: *** You must not supply an argument to --with-amrecover option." >&5
+echo "$as_me: error: *** You must not supply an argument to --with-amrecover option." >&2;}
+ { (exit 1); exit 1; }; }
+ ;;
+ esac
-# Check whether --with-ticket-lifetime or --without-ticket-lifetime was given.
-if test "${with_ticket_lifetime+set}" = set; then
- withval="$with_ticket_lifetime"
+fi;
+
+
+# Check whether --with-index-server or --without-index-server was given.
+if test "${with_index_server+set}" = set; then
+ withval="$with_index_server"
case "$withval" in
"" | y | ye | yes | n | no)
- { { echo "$as_me:$LINENO: error: *** You must supply an argument to the --with-ticket-lifetime option." >&5
-echo "$as_me: error: *** You must supply an argument to the --with-ticket-lifetime option." >&2;}
+ { { echo "$as_me:$LINENO: error: *** You must supply an argument to the --with-index-server option." >&5
+echo "$as_me: error: *** You must supply an argument to the --with-index-server option." >&2;}
{ (exit 1); exit 1; }; }
;;
- *) TICKET_LIFETIME="$withval"
+ *) DEFAULT_SERVER="$withval"
;;
esac
else
- : ${TICKET_LIFETIME=128}
+ : ${DEFAULT_SERVER=`uname -n`}
fi;
cat >>confdefs.h <<_ACEOF
-#define TICKET_LIFETIME $TICKET_LIFETIME
+#define DEFAULT_SERVER "$DEFAULT_SERVER"
_ACEOF
-: ${KRB5_SPOTS="/usr/kerberos /usr/cygnus /usr /opt/kerberos"}
-
-# Check whether --with-krb5-security or --without-krb5-security was given.
-if test "${with_krb5_security+set}" = set; then
- withval="$with_krb5_security"
- KRB5_SECURITY="$withval"
+# Check whether --with-force-uid or --without-force-uid was given.
+if test "${with_force_uid+set}" = set; then
+ withval="$with_force_uid"
+ FORCE_USERID="$withval"
else
- : ${KRB5_SECURITY=no}
+ : ${FORCE_USERID=yes}
fi;
+case "$FORCE_USERID" in
+y | ye | yes)
+cat >>confdefs.h <<\_ACEOF
+#define FORCE_USERID 1
+_ACEOF
-case "$KRB5_SECURITY" in
-n | no) KRB5_SECURITY=no
- KRB5_SPOTS=""
- ;;
-y | ye | yes) : ;;
-*) KRB5_SPOTS="$KRB5_SECURITY"
- KRB5_SECURITY=yes
- ;;
+ ;;
+n | no) :
+ ;;
+*) { { echo "$as_me:$LINENO: error: *** You must not supply an argument to --with-force-uid option." >&5
+echo "$as_me: error: *** You must not supply an argument to --with-force-uid option." >&2;}
+ { (exit 1); exit 1; }; }
esac
-# if found, force the static versions of these libs (.a) by linking directly
-# with the .a files. I don't know how to get -R dependancies checked
-# in autoconf at this time. -kashmir
-echo "$as_me:$LINENO: checking for Kerberos V" >&5
-echo $ECHO_N "checking for Kerberos V... $ECHO_C" >&6
-KRB5_DIR_FOUND=""
-KRB5_CFLAGS=""
-for dir in $KRB5_SPOTS; do
- k5libdir=${dir}/lib
- if test -f ${k5libdir}/libkrb5.a -a -f ${k5libdir}/libgssapi_krb5.a -a -f ${k5libdir}/libcom_err.a; then
- if test -f ${k5libdir}/libcrypto.a; then
- K5CRYPTO=${k5libdir}/libcrypto.a
- elif test -f ${k5libdir}/libk5crypto.a; then
- K5CRYPTO=${k5libdir}/libk5crypto.a
- else
- K5CRYPTO=""
- fi
- KRB5_DIR_FOUND=$dir
- KRB5LIBS="${k5libdir}/libgssapi_krb5.a ${k5libdir}/libkrb5.a $K5CRYPTO ${k5libdir}/libcom_err.a"
- KRB5CFLAGS=""
- break
- elif test -f ${k5libdir}/libkrb5.a -a -f ${k5libdir}/libasn1.a -a -f ${k5libdir}/libgssapi.a; then
- KRB5_DIR_FOUND=$dir
- KRB5LIBS="${k5libdir}/libgssapi.a ${k5libdir}/libkrb5.a ${k5libdir}/libasn1.a"
- KRB5_CFLAGS="-DKRB5_HEIMDAL_INCLUDES"
- break
- fi
-done
-if test "$KRB5_DIR_FOUND"; then
- echo "$as_me:$LINENO: result: found in $KRB5_DIR_FOUND" >&5
-echo "${ECHO_T}found in $KRB5_DIR_FOUND" >&6
- KRB5_SECURITY=yes
+# Check whether --with-user or --without-user was given.
+if test "${with_user+set}" = set; then
+ withval="$with_user"
-cat >>confdefs.h <<\_ACEOF
-#define KRB5_SECURITY 1
-_ACEOF
+ case "$withval" in
+ "" | y | ye | yes | n | no)
+ { { echo "$as_me:$LINENO: error: *** You must supply an argument to the --with-user option." >&5
+echo "$as_me: error: *** You must supply an argument to the --with-user option." >&2;}
+ { (exit 1); exit 1; }; }
+ ;;
+ *) CLIENT_LOGIN="$withval"
+ ;;
+ esac
- #
- # some OS's, such as NetBSD, stick krb5 includes out of the way...
- # should probably just use autoconf to look for various include
- # options and set them, but don't quite want to do that until I've
- # dug into it a bit more.
- #
- if test -d "$KRB5_DIR_FOUND/krb5" ; then
- KRB5INCLUDES="-I$KRB5_DIR_FOUND/include/krb5"
- else
- KRB5INCLUDES="-I$KRB5_DIR_FOUND/include"
- fi
- if test "$KRB5_CFLAGS" ; then
- KRB5INCLUDES="$KRB5INCLUDES $KRB5_CFLAGS"
- fi
- KRB5LDFLAGS=-L$k5libdir
- break
-fi
-if test "x$KRB5LDFLAGS" = "x" ; then
- echo "$as_me:$LINENO: result: no krb5 system libraries found" >&5
-echo "${ECHO_T}no krb5 system libraries found" >&6
+fi;
+if test "x${CLIENT_LOGIN+set}" != xset; then
+ { { echo "$as_me:$LINENO: error: *** --with-user=USER is missing" >&5
+echo "$as_me: error: *** --with-user=USER is missing" >&2;}
+ { (exit 1); exit 1; }; }
fi
+cat >>confdefs.h <<_ACEOF
+#define CLIENT_LOGIN "$CLIENT_LOGIN"
+_ACEOF
-# Check whether --with-portrange or --without-portrange was given.
-if test "${with_portrange+set}" = set; then
- withval="$with_portrange"
-
- TCPPORTRANGE="$withval"
-
-fi;
-# Check whether --with-tcpportrange or --without-tcpportrange was given.
-if test "${with_tcpportrange+set}" = set; then
- withval="$with_tcpportrange"
+# Check whether --with-group or --without-group was given.
+if test "${with_group+set}" = set; then
+ withval="$with_group"
- TCPPORTRANGE="$withval"
+ case "$withval" in
+ "" | y | ye | yes | n | no)
+ { { echo "$as_me:$LINENO: error: *** You must supply an argument to the --with-group option." >&5
+echo "$as_me: error: *** You must supply an argument to the --with-group option." >&2;}
+ { (exit 1); exit 1; }; }
+ ;;
+ *) SETUID_GROUP="$withval"
+ ;;
+ esac
fi;
-if test x"${TCPPORTRANGE+set}" = x"set"; then
- if test x`echo "$TCPPORTRANGE" | sed 's/[0-9][0-9]*,[0-9][0-9]*//'` != x""; then
- { { echo "$as_me:$LINENO: error: *** --with-tcpportrange requires two comma-separated positive numbers" >&5
-echo "$as_me: error: *** --with-tcpportrange requires two comma-separated positive numbers" >&2;}
- { (exit 1); exit 1; }; }
- fi
- min_tcp_port=`echo "$TCPPORTRANGE" | sed 's/,.*//'`
- max_tcp_port=`echo "$TCPPORTRANGE" | sed 's/.*,//'`
- if test $min_tcp_port -gt $max_tcp_port; then
- { { echo "$as_me:$LINENO: error: *** the second TCP port number must be greater than the first in --with-tcpportrange" >&5
-echo "$as_me: error: *** the second TCP port number must be greater than the first in --with-tcpportrange" >&2;}
+if test "x${SETUID_GROUP+set}" != xset; then
+ { { echo "$as_me:$LINENO: error: *** --with-group=GROUP is missing" >&5
+echo "$as_me: error: *** --with-group=GROUP is missing" >&2;}
{ (exit 1); exit 1; }; }
- fi
- if test $min_tcp_port -lt 1024; then
- { echo "$as_me:$LINENO: WARNING: *** the TCP port range should be 1024 or greater in --with-tcpportrange" >&5
-echo "$as_me: WARNING: *** the TCP port range should be 1024 or greater in --with-tcpportrange" >&2;}
- fi
- if test $max_tcp_port -ge 65536; then
- { echo "$as_me:$LINENO: WARNING: *** the TCP port range should be less than 65536 in --with-tcpportrange" >&5
-echo "$as_me: WARNING: *** the TCP port range should be less than 65536 in --with-tcpportrange" >&2;}
- fi
-
-cat >>confdefs.h <<_ACEOF
-#define TCPPORTRANGE $TCPPORTRANGE
-_ACEOF
-
fi
-# Check whether --with-udpportrange or --without-udpportrange was given.
-if test "${with_udpportrange+set}" = set; then
- withval="$with_udpportrange"
-
- UDPPORTRANGE="$withval"
+# Check whether --with-owner or --without-owner was given.
+if test "${with_owner+set}" = set; then
+ withval="$with_owner"
-fi;
-if test x"${UDPPORTRANGE+set}" = x"set"; then
- if test x`echo "$UDPPORTRANGE" | sed 's/[0-9][0-9]*,[0-9][0-9]*//'` != x""; then
- { { echo "$as_me:$LINENO: error: *** --with-udpportrange requires two comma-separated positive numbers" >&5
-echo "$as_me: error: *** --with-udpportrange requires two comma-separated positive numbers" >&2;}
- { (exit 1); exit 1; }; }
- fi
- min_udp_port=`echo "$UDPPORTRANGE" | sed 's/,.*//'`
- max_udp_port=`echo "$UDPPORTRANGE" | sed 's/.*,//'`
- if test $min_udp_port -gt $max_udp_port; then
- { { echo "$as_me:$LINENO: error: *** the second UDP port number must be greater than the first in --with-udpportrange" >&5
-echo "$as_me: error: *** the second UDP port number must be greater than the first in --with-udpportrange" >&2;}
+ case "$withval" in
+ "" | y | ye | yes | n | no)
+ { { echo "$as_me:$LINENO: error: *** You must supply an argument to the --with-owner option." >&5
+echo "$as_me: error: *** You must supply an argument to the --with-owner option." >&2;}
{ (exit 1); exit 1; }; }
- fi
- if test $max_udp_port -ge 1024; then
- { echo "$as_me:$LINENO: WARNING: *** the UDP port range should be less than 1024 in --with-udpportrange" >&5
-echo "$as_me: WARNING: *** the UDP port range should be less than 1024 in --with-udpportrange" >&2;}
- fi
- if test $min_udp_port -le 0; then
- { echo "$as_me:$LINENO: WARNING: *** the UDP port range should be greater than 0 in --with-udpportrange" >&5
-echo "$as_me: WARNING: *** the UDP port range should be greater than 0 in --with-udpportrange" >&2;}
- fi
+ ;;
+ *) BINARY_OWNER="$withval"
+ ;;
+ esac
-cat >>confdefs.h <<_ACEOF
-#define UDPPORTRANGE $UDPPORTRANGE
-_ACEOF
+fi;
+if test "x${BINARY_OWNER+set}" != xset ; then
+ BINARY_OWNER=$CLIENT_LOGIN
fi
+cat >>confdefs.h <<_ACEOF
+#define BINARY_OWNER "$BINARY_OWNER"
+_ACEOF
-# Check whether --with-maxtapeblocksize or --without-maxtapeblocksize was given.
-if test "${with_maxtapeblocksize+set}" = set; then
- withval="$with_maxtapeblocksize"
-
- MAXTAPEBLOCKSIZE="$withval"
-else
- : ${MAXTAPEBLOCKSIZE=32}
-fi;
+# Check whether --with-rundump or --without-rundump was given.
+if test "${with_rundump+set}" = set; then
+ withval="$with_rundump"
-cat >>confdefs.h <<_ACEOF
-#define MAX_TAPE_BLOCK_KB ($MAXTAPEBLOCKSIZE)
-_ACEOF
+ case "$withval" in
+ n | no | y | ye | yes) FORCE_USE_RUNDUMP="$withval";;
+ *) { { echo "$as_me:$LINENO: error: *** You must not supply an argument to --with-rundump option." >&5
+echo "$as_me: error: *** You must not supply an argument to --with-rundump option." >&2;}
+ { (exit 1); exit 1; }; };;
+ esac
+fi;
-# Check whether --with-db or --without-db was given.
-if test "${with_db+set}" = set; then
- withval="$with_db"
+# Check whether --with-config or --without-config was given.
+if test "${with_config+set}" = set; then
+ withval="$with_config"
case "$withval" in
"" | y | ye | yes | n | no)
- { { echo "$as_me:$LINENO: error: *** You must supply an argument to the --with-db option." >&5
-echo "$as_me: error: *** You must supply an argument to the --with-db option." >&2;}
+ { { echo "$as_me:$LINENO: error: *** You must supply an argument to the --with-config option." >&5
+echo "$as_me: error: *** You must supply an argument to the --with-config option." >&2;}
{ (exit 1); exit 1; }; }
;;
- *) DB_STYLE="$withval"
+ *) DEFAULT_CONFIG="$withval"
;;
esac
-
-fi;
-if test "$DB_STYLE"; then
- case "$DB_STYLE" in
- db | dbm | gdbm | ndbm | text) ;;
- *)
- { { echo "$as_me:$LINENO: error: *** Unknown argument $DB_STYLE given to --with-db. Choose from db, dbm, gdbm, ndbm, text." >&5
-echo "$as_me: error: *** Unknown argument $DB_STYLE given to --with-db. Choose from db, dbm, gdbm, ndbm, text." >&2;}
- { (exit 1); exit 1; }; }
- DB_STYLE=
- ;;
- esac
-fi
-
-
-# Check whether --with-mmap or --without-mmap was given.
-if test "${with_mmap+set}" = set; then
- withval="$with_mmap"
- FORCE_MMAP=$withval
else
- : ${FORCE_MMAP=no}
+ : ${DEFAULT_CONFIG=DailySet1}
fi;
-case "$FORCE_MMAP" in
-y | ye | yes | n | no) : ;;
-*) { { echo "$as_me:$LINENO: error: *** You must not supply an argument to --with-mmap." >&5
-echo "$as_me: error: *** You must not supply an argument to --with-mmap." >&2;}
- { (exit 1); exit 1; }; }
- ;;
-esac
-
-# Check whether --with-buffered-dump or --without-buffered-dump was given.
-if test "${with_buffered_dump+set}" = set; then
- withval="$with_buffered_dump"
- DUMPER_SOCKET_BUFFERING=$withval
-else
- : ${DUMPER_SOCKET_BUFFERING=no}
-
-fi;
-case "$DUMPER_SOCKET_BUFFERING" in
-n | no) :
- ;;
-y | ye | yes)
-cat >>confdefs.h <<\_ACEOF
-#define DUMPER_SOCKET_BUFFERING 1
+cat >>confdefs.h <<_ACEOF
+#define DEFAULT_CONFIG "$DEFAULT_CONFIG"
_ACEOF
- ;;
-*) { { echo "$as_me:$LINENO: error: *** You must not supply an argument to --with-buffered-dump." >&5
-echo "$as_me: error: *** You must not supply an argument to --with-buffered-dump." >&2;}
- { (exit 1); exit 1; }; }
- ;;
-esac
-# Check whether --with-assertions or --without-assertions was given.
-if test "${with_assertions+set}" = set; then
- withval="$with_assertions"
- ASSERTIONS="$withval"
-else
- : ${ASSERTIONS=no}
-fi;
-case "$ASSERTIONS" in
-n | no) : ;;
-y | ye | yes)
-cat >>confdefs.h <<\_ACEOF
-#define ASSERTIONS 1
-_ACEOF
+# Check whether --with-tape-server or --without-tape-server was given.
+if test "${with_tape_server+set}" = set; then
+ withval="$with_tape_server"
- ;;
-*) { { echo "$as_me:$LINENO: error: *** You must not supply an argument to --with-assertions option." >&5
-echo "$as_me: error: *** You must not supply an argument to --with-assertions option." >&2;}
+ case "$withval" in
+ "" | y | ye | yes | n | no)
+ { { echo "$as_me:$LINENO: error: *** You must supply an argument to the --with-tape-server option." >&5
+echo "$as_me: error: *** You must supply an argument to the --with-tape-server option." >&2;}
{ (exit 1); exit 1; }; }
- ;;
-esac
-
+ ;;
+ *) DEFAULT_TAPE_SERVER="$withval"
+ ;;
+ esac
-# Check whether --with-tmpdir or --without-tmpdir was given.
-if test "${with_tmpdir+set}" = set; then
- withval="$with_tmpdir"
- tmpdir="$withval"
else
- : ${tmpdir=yes}
+ : ${DEFAULT_TAPE_SERVER=$DEFAULT_SERVER}
fi;
-tmpdir=`(
- test "x$prefix" = xNONE && prefix=$ac_default_prefix
- test "x$exec_prefix" = xNONE && exec_prefix=${prefix}
- eval echo "$tmpdir"
-)`
-case "$tmpdir" in
-n | no) { { echo "$as_me:$LINENO: error: *** --without-tmpdir is not allowed." >&5
-echo "$as_me: error: *** --without-tmpdir is not allowed." >&2;}
- { (exit 1); exit 1; }; };;
-y | ye | yes)
- AMANDA_TMPDIR="/tmp/amanda";;
-/*)
- AMANDA_TMPDIR="$tmpdir";;
-*) { { echo "$as_me:$LINENO: error: *** You must supply a full pathname to --with-tmpdir option." >&5
-echo "$as_me: error: *** You must supply a full pathname to --with-tmpdir option." >&2;}
- { (exit 1); exit 1; }; };;
-esac
cat >>confdefs.h <<_ACEOF
-#define AMANDA_TMPDIR "$AMANDA_TMPDIR"
+#define DEFAULT_TAPE_SERVER "$DEFAULT_TAPE_SERVER"
_ACEOF
-# Check whether --with-debugging or --without-debugging was given.
-if test "${with_debugging+set}" = set; then
- withval="$with_debugging"
- debugging="$withval"
-else
- : ${debugging=yes}
+# Check whether --with-tape-device or --without-tape-device was given.
+if test "${with_tape_device+set}" = set; then
+ withval="$with_tape_device"
-fi;
-debugging=`(
- test "x$prefix" = xNONE && prefix=$ac_default_prefix
- test "x$exec_prefix" = xNONE && exec_prefix=${prefix}
- eval echo "$debugging"
-)`
-case "$debugging" in
-n | no) AMANDA_DBGDIR="";;
-y | ye | yes) AMANDA_DBGDIR="$AMANDA_TMPDIR";;
-/*) AMANDA_DBGDIR="$debugging";;
-*) { { echo "$as_me:$LINENO: error: *** You must supply a full pathname to --with-debugging option." >&5
-echo "$as_me: error: *** You must supply a full pathname to --with-debugging option." >&2;}
+ case "$withval" in
+ "" | y | ye | yes | n | no)
+ { { echo "$as_me:$LINENO: error: *** You must supply an argument to the --with-tape-device option." >&5
+echo "$as_me: error: *** You must supply an argument to the --with-tape-device option." >&2;}
{ (exit 1); exit 1; }; }
- ;;
-esac
-case "$AMANDA_DBGDIR" in
-"") :;;
-*)
-cat >>confdefs.h <<\_ACEOF
-#define DEBUG_CODE 1
-_ACEOF
+ ;;
+ *) DEFAULT_TAPE_DEVICE="$withval"
+ ;;
+ esac
+else
-cat >>confdefs.h <<_ACEOF
-#define AMANDA_DBGDIR "$AMANDA_DBGDIR"
-_ACEOF
+ if test -z "$DEFAULT_TAPE_DEVICE"; then
+ echo "$as_me:$LINENO: checking for non-rewinding tape device" >&5
+echo $ECHO_N "checking for non-rewinding tape device... $ECHO_C" >&6
+ tape_dev=
+ nr_tape_dev=
+ if test -d /dev/rmt; then
- ;;
-esac
+ for num in 9 8 7 6 5 4 3 2 1 0; do
+ td=/dev/rmt/${num}b
+ ntd=/dev/rmt/${num}bn
+ if test -r $td -a -r $ntd; then
+ tape_dev=$td
+ nr_tape_dev=$ntd
+ fi
+ done
+ else
+ for num in 9 8 7 6 5 4 3 2 1 0; do
+ td=/dev/rst${num}
+ ntd=/dev/nrst${num}
+ if test -r $td -a -r $ntd; then
+ tape_dev=$td
+ nr_tape_dev=$ntd
+ fi
+ done
+ fi
+ DEFAULT_TAPE_DEVICE=$nr_tape_dev
+ echo "$as_me:$LINENO: result: $DEFAULT_TAPE_DEVICE" >&5
+echo "${ECHO_T}$DEFAULT_TAPE_DEVICE" >&6
+ fi
-# Check whether --with-debug_days or --without-debug_days was given.
-if test "${with_debug_days+set}" = set; then
- withval="$with_debug_days"
- debug_days="$withval"
-else
- : ${debug_days=4}
fi;
-case "$debug_days" in
-n | no) AMANDA_DEBUG_DAYS=0 ;;
-y | ye | yes) AMANDA_DEBUG_DAYS=4 ;;
-[0-9] | [0-9][0-9] | [0-9][0-9][0-9]) AMANDA_DEBUG_DAYS="$debug_days" ;;
-*) { { echo "$as_me:$LINENO: error: *** --with-debug-days value not numeric or out of range." >&5
-echo "$as_me: error: *** --with-debug-days value not numeric or out of range." >&2;}
- { (exit 1); exit 1; }; }
- ;;
-esac
+
+if test ! -z "$DEFAULT_TAPE_DEVICE"; then
cat >>confdefs.h <<_ACEOF
-#define AMANDA_DEBUG_DAYS $AMANDA_DEBUG_DAYS
+#define DEFAULT_TAPE_DEVICE "$DEFAULT_TAPE_DEVICE"
_ACEOF
+fi
-# Check whether --with-testing or --without-testing was given.
-if test "${with_testing+set}" = set; then
- withval="$with_testing"
- TESTING="$withval"
-else
- : ${TESTING=no}
+# Check whether --with-ftape-raw-device or --without-ftape-raw-device was given.
+if test "${with_ftape_raw_device+set}" = set; then
+ withval="$with_ftape_raw_device"
-fi;
-case "$TESTING" in
-n | no) SERVICE_SUFFIX="";;
-y | ye | yes) SERVICE_SUFFIX="-test";;
-*) SERVICE_SUFFIX="-$TESTING";;
-esac
-AMANDA_SERVICE_NAME="amanda$SERVICE_SUFFIX"
-KAMANDA_SERVICE_NAME="kamanda$SERVICE_SUFFIX"
+ case "$withval" in
+ "" | y | ye | yes | n | no)
+ { { echo "$as_me:$LINENO: error: *** You must supply an argument to the --with-ftape-rawdevice option." >&5
+echo "$as_me: error: *** You must supply an argument to the --with-ftape-rawdevice option." >&2;}
+ { (exit 1); exit 1; }; }
+ ;;
+ *) DEFAULT_RAW_TAPE_DEVICE="$withval"
+ ;;
+ esac
+else
-cat >>confdefs.h <<_ACEOF
-#define SERVICE_SUFFIX "$SERVICE_SUFFIX"
-_ACEOF
+ if test -z "$DEFAULT_RAW_TAPE_DEVICE"; then
+ echo "$as_me:$LINENO: checking for raw ftape device" >&5
+echo $ECHO_N "checking for raw ftape device... $ECHO_C" >&6
+ raw_tape_dev=/dev/null
+ for num in 3 2 1 0 ; do
+ td=/dev/rawft${num}
+ if test -r $td; then
+ raw_tape_dev=$td
+ fi
+ done
+ DEFAULT_RAW_TAPE_DEVICE=$raw_tape_dev
+ echo "$as_me:$LINENO: result: $DEFAULT_RAW_TAPE_DEVICE" >&5
+echo "${ECHO_T}$DEFAULT_RAW_TAPE_DEVICE" >&6
+ fi
-cat >>confdefs.h <<_ACEOF
-#define AMANDA_SERVICE_NAME "$AMANDA_SERVICE_NAME"
-_ACEOF
+fi;
+
+if test -z "$DEFAULT_RAW_TAPE_DEVICE"; then
+ DEFAULT_RAW_TAPE_DEVICE=/dev/null
+fi
cat >>confdefs.h <<_ACEOF
-#define KAMANDA_SERVICE_NAME "$KAMANDA_SERVICE_NAME"
+#define DEFAULT_RAW_TAPE_DEVICE "$DEFAULT_RAW_TAPE_DEVICE"
_ACEOF
-(
- test "x$prefix" = xNONE && prefix=$ac_default_prefix
- test "x$exec_prefix" = xNONE && exec_prefix=${prefix}
- tmp=`eval echo "$bindir"`
-cat >>confdefs.h <<_ACEOF
-#define bindir "$tmp"
-_ACEOF
+# Check whether --with-rew-tape or --without-rew-tape was given.
+if test "${with_rew_tape+set}" = set; then
+ withval="$with_rew_tape"
+ { { echo "$as_me:$LINENO: error: *** --with-rew-tape is deprecated, use --with-tape-device instead." >&5
+echo "$as_me: error: *** --with-rew-tape is deprecated, use --with-tape-device instead." >&2;}
+ { (exit 1); exit 1; }; }
+fi;
- tmp=`eval echo "$sbindir"`
-cat >>confdefs.h <<_ACEOF
-#define sbindir "$tmp"
-_ACEOF
+# Check whether --with-norew-tape or --without-norew-tape was given.
+if test "${with_norew_tape+set}" = set; then
+ withval="$with_norew_tape"
+ { { echo "$as_me:$LINENO: error: *** --with-norew-tape is deprecated, use --with-tape-device instead." >&5
+echo "$as_me: error: *** --with-norew-tape is deprecated, use --with-tape-device instead." >&2;}
+ { (exit 1); exit 1; }; }
+fi;
- tmp=`eval echo "$libexecdir"`
-cat >>confdefs.h <<_ACEOF
-#define libexecdir "$tmp"
-_ACEOF
+# Check whether --with-changer-device or --without-changer-device was given.
+if test "${with_changer_device+set}" = set; then
+ withval="$with_changer_device"
+ case "$withval" in
+ "" | y | ye | yes | n | no)
+ { { echo "$as_me:$LINENO: error: *** You must supply an argument to the --with-changer-device option." >&5
+echo "$as_me: error: *** You must supply an argument to the --with-changer-device option." >&2;}
+ { (exit 1); exit 1; }; }
+ ;;
+ *) DEFAULT_CHANGER_DEVICE="$withval"
+ ;;
+ esac
- tmp=`eval echo $mandir`
+else
-cat >>confdefs.h <<_ACEOF
-#define mandir "$tmp"
-_ACEOF
+ if test -z "$DEFAULT_CHANGER_DEVICE" &&
+ test -f /dev/ch0; then
+ DEFAULT_CHANGER_DEVICE=/dev/ch0
+ fi
-)
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-if test -n "$ac_tool_prefix"; then
- # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
-set dummy ${ac_tool_prefix}gcc; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_prog_CC+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$CC"; then
- ac_cv_prog_CC="$CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- ac_cv_prog_CC="${ac_tool_prefix}gcc"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
+fi;
-fi
-fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
- echo "$as_me:$LINENO: result: $CC" >&5
-echo "${ECHO_T}$CC" >&6
-else
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
+if test -z "$DEFAULT_CHANGER_DEVICE"; then
+ DEFAULT_CHANGER_DEVICE=/dev/null
fi
-fi
-if test -z "$ac_cv_prog_CC"; then
- ac_ct_CC=$CC
- # Extract the first word of "gcc", so it can be a program name with args.
-set dummy gcc; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$ac_ct_CC"; then
- ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- ac_cv_prog_ac_ct_CC="gcc"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-fi
-fi
-ac_ct_CC=$ac_cv_prog_ac_ct_CC
-if test -n "$ac_ct_CC"; then
- echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
-echo "${ECHO_T}$ac_ct_CC" >&6
-else
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
-fi
+cat >>confdefs.h <<_ACEOF
+#define DEFAULT_CHANGER_DEVICE "$DEFAULT_CHANGER_DEVICE"
+_ACEOF
- CC=$ac_ct_CC
-else
- CC="$ac_cv_prog_CC"
-fi
-if test -z "$CC"; then
- if test -n "$ac_tool_prefix"; then
- # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
-set dummy ${ac_tool_prefix}cc; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_prog_CC+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$CC"; then
- ac_cv_prog_CC="$CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- ac_cv_prog_CC="${ac_tool_prefix}cc"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-fi
-fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
- echo "$as_me:$LINENO: result: $CC" >&5
-echo "${ECHO_T}$CC" >&6
-else
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
-fi
-fi
-if test -z "$ac_cv_prog_CC"; then
- ac_ct_CC=$CC
- # Extract the first word of "cc", so it can be a program name with args.
-set dummy cc; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$ac_ct_CC"; then
- ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+# Check whether --with-fqdn or --without-fqdn was given.
+if test "${with_fqdn+set}" = set; then
+ withval="$with_fqdn"
+ USE_FQDN=$withval
else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- ac_cv_prog_ac_ct_CC="cc"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
+ : ${USE_FQDN=no}
-fi
-fi
-ac_ct_CC=$ac_cv_prog_ac_ct_CC
-if test -n "$ac_ct_CC"; then
- echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
-echo "${ECHO_T}$ac_ct_CC" >&6
-else
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
-fi
+fi;
+case "$USE_FQDN" in
+n | no) : ;;
+y | ye | yes)
+cat >>confdefs.h <<\_ACEOF
+#define USE_FQDN 1
+_ACEOF
- CC=$ac_ct_CC
-else
- CC="$ac_cv_prog_CC"
-fi
+ ;;
+*) { { echo "$as_me:$LINENO: error: *** You must not supply an argument to --with-fqdn option." >&5
+echo "$as_me: error: *** You must not supply an argument to --with-fqdn option." >&2;}
+ { (exit 1); exit 1; }; }
+ ;;
+esac
-fi
-if test -z "$CC"; then
- # Extract the first word of "cc", so it can be a program name with args.
-set dummy cc; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_prog_CC+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$CC"; then
- ac_cv_prog_CC="$CC" # Let the user override the test.
-else
- ac_prog_rejected=no
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
- ac_prog_rejected=yes
- continue
- fi
- ac_cv_prog_CC="cc"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-if test $ac_prog_rejected = yes; then
- # We found a bogon in the path, so make sure we never use it.
- set dummy $ac_cv_prog_CC
- shift
- if test $# != 0; then
- # We chose a different compiler from the bogus one.
- # However, it has the same basename, so the bogon will be chosen
- # first if we set CC to just the basename; use the full file name.
- shift
- ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
- fi
-fi
-fi
-fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
- echo "$as_me:$LINENO: result: $CC" >&5
-echo "${ECHO_T}$CC" >&6
+# Check whether --with-broken-fsf or --without-broken-fsf was given.
+if test "${with_broken_fsf+set}" = set; then
+ withval="$with_broken_fsf"
+ HAVE_BROKEN_FSF=$withval
else
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
-fi
+ : ${HAVE_BROKEN_FSF=no}
-fi
-if test -z "$CC"; then
- if test -n "$ac_tool_prefix"; then
- for ac_prog in cl
- do
- # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
-set dummy $ac_tool_prefix$ac_prog; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_prog_CC+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$CC"; then
- ac_cv_prog_CC="$CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
+fi;
+case "$HAVE_BROKEN_FSF" in
+n | no) : ;;
+y | ye | yes)
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_BROKEN_FSF 1
+_ACEOF
-fi
-fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
- echo "$as_me:$LINENO: result: $CC" >&5
-echo "${ECHO_T}$CC" >&6
-else
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
-fi
+ ;;
+*) { { echo "$as_me:$LINENO: error: *** You must not supply an argument to --with-broken-fsf option." >&5
+echo "$as_me: error: *** You must not supply an argument to --with-broken-fsf option." >&2;}
+ { (exit 1); exit 1; }; }
+ ;;
+esac
- test -n "$CC" && break
- done
-fi
-if test -z "$CC"; then
- ac_ct_CC=$CC
- for ac_prog in cl
-do
- # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$ac_ct_CC"; then
- ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- ac_cv_prog_ac_ct_CC="$ac_prog"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-fi
-fi
-ac_ct_CC=$ac_cv_prog_ac_ct_CC
-if test -n "$ac_ct_CC"; then
- echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
-echo "${ECHO_T}$ac_ct_CC" >&6
+# Check whether --with-reuseports or --without-reuseports was given.
+if test "${with_reuseports+set}" = set; then
+ withval="$with_reuseports"
+ case "$withval" in
+ y | ye | yes)
+ REUSEADDR=no;;
+ n | no)
+ REUSEADDR=yes;;
+ *)
+ REUSEADDR=no;;
+ esac
+
else
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
-fi
+ REUSEADDR=yes;
+fi;
+case "$REUSEADDR" in
+n | no) :
+ ;;
+y | ye | yes)
- test -n "$ac_ct_CC" && break
-done
+cat >>confdefs.h <<\_ACEOF
+#define USE_REUSEADDR 1
+_ACEOF
- CC=$ac_ct_CC
-fi
+ ;;
+*)
+ { { echo "$as_me:$LINENO: error: *** You must not supply an argument to --with-reuseports option." >&5
+echo "$as_me: error: *** You must not supply an argument to --with-reuseports option." >&2;}
+ { (exit 1); exit 1; }; }
+ ;;
+esac
-fi
+# Check whether --with-gnutar or --without-gnutar was given.
+if test "${with_gnutar+set}" = set; then
+ withval="$with_gnutar"
-test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH
-See \`config.log' for more details." >&5
-echo "$as_me: error: no acceptable C compiler found in \$PATH
-See \`config.log' for more details." >&2;}
- { (exit 1); exit 1; }; }
+ case "$withval" in
+ /*) GNUTAR="$withval";;
+ y|ye|yes) :;;
+ n|no) GNUTAR=;;
+ *) { { echo "$as_me:$LINENO: error: *** You must supply a full pathname to --with-gnutar" >&5
+echo "$as_me: error: *** You must supply a full pathname to --with-gnutar" >&2;}
+ { (exit 1); exit 1; }; };;
+ esac
-# Provide some information about the compiler.
-echo "$as_me:$LINENO:" \
- "checking for C compiler version" >&5
-ac_compiler=`set X $ac_compile; echo $2`
-{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version </dev/null >&5\"") >&5
- (eval $ac_compiler --version </dev/null >&5) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }
-{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v </dev/null >&5\"") >&5
- (eval $ac_compiler -v </dev/null >&5) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }
-{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V </dev/null >&5\"") >&5
- (eval $ac_compiler -V </dev/null >&5) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
+fi;
-int
-main ()
-{
- ;
- return 0;
-}
-_ACEOF
-ac_clean_files_save=$ac_clean_files
-ac_clean_files="$ac_clean_files a.out a.exe b.out"
-# Try to create an executable without -o first, disregard a.out.
-# It will help us diagnose broken compilers, and finding out an intuition
-# of exeext.
-echo "$as_me:$LINENO: checking for C compiler default output file name" >&5
-echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6
-ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
-if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5
- (eval $ac_link_default) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; then
- # Find the output, starting from the most likely. This scheme is
-# not robust to junk in `.', hence go to wildcards (a.*) only as a last
-# resort.
+# Check whether --with-smbclient or --without-smbclient was given.
+if test "${with_smbclient+set}" = set; then
+ withval="$with_smbclient"
-# Be careful to initialize this variable, since it used to be cached.
-# Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile.
-ac_cv_exeext=
-# b.out is created by i960 compilers.
-for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out
-do
- test -f "$ac_file" || continue
- case $ac_file in
- *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj )
- ;;
- conftest.$ac_ext )
- # This is the source file.
- ;;
- [ab].out )
- # We found the default executable, but exeext='' is most
- # certainly right.
- break;;
- *.* )
- ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
- # FIXME: I believe we export ac_cv_exeext for Libtool,
- # but it would be cool to find out if it's true. Does anybody
- # maintain Libtool? --akim.
- export ac_cv_exeext
- break;;
- * )
- break;;
- esac
-done
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
+ case "$withval" in
+ /*) SAMBA_CLIENT="$withval";;
+ y|ye|yes) :;;
+ n|no) SAMBA_CLIENT=;;
+ *) { { echo "$as_me:$LINENO: error: *** You must supply a full pathname to --with-smbclient" >&5
+echo "$as_me: error: *** You must supply a full pathname to --with-smbclient" >&2;}
+ { (exit 1); exit 1; }; };;
+ esac
-{ { echo "$as_me:$LINENO: error: C compiler cannot create executables
-See \`config.log' for more details." >&5
-echo "$as_me: error: C compiler cannot create executables
-See \`config.log' for more details." >&2;}
- { (exit 77); exit 77; }; }
-fi
-ac_exeext=$ac_cv_exeext
-echo "$as_me:$LINENO: result: $ac_file" >&5
-echo "${ECHO_T}$ac_file" >&6
+fi;
-# Check the compiler produces executables we can run. If not, either
-# the compiler is broken, or we cross compile.
-echo "$as_me:$LINENO: checking whether the C compiler works" >&5
-echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6
-# FIXME: These cross compiler hacks should be removed for Autoconf 3.0
-# If not cross compiling, check that we can run a simple program.
-if test "$cross_compiling" != yes; then
- if { ac_try='./$ac_file'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- cross_compiling=no
- else
- if test "$cross_compiling" = maybe; then
- cross_compiling=yes
- else
- { { echo "$as_me:$LINENO: error: cannot run C compiled programs.
-If you meant to cross compile, use \`--host'.
-See \`config.log' for more details." >&5
-echo "$as_me: error: cannot run C compiled programs.
-If you meant to cross compile, use \`--host'.
-See \`config.log' for more details." >&2;}
+
+# Check whether --with-samba-user or --without-samba-user was given.
+if test "${with_samba_user+set}" = set; then
+ withval="$with_samba_user"
+ { { echo "$as_me:$LINENO: error: *** The samba-user option was deprecated, the username go in the amandapass" >&5
+echo "$as_me: error: *** The samba-user option was deprecated, the username go in the amandapass" >&2;}
{ (exit 1); exit 1; }; }
- fi
- fi
-fi
-echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6
-rm -f a.out a.exe conftest$ac_cv_exeext b.out
-ac_clean_files=$ac_clean_files_save
-# Check the compiler produces executables we can run. If not, either
-# the compiler is broken, or we cross compile.
-echo "$as_me:$LINENO: checking whether we are cross compiling" >&5
-echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6
-echo "$as_me:$LINENO: result: $cross_compiling" >&5
-echo "${ECHO_T}$cross_compiling" >&6
-echo "$as_me:$LINENO: checking for suffix of executables" >&5
-echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; then
- # If both `conftest.exe' and `conftest' are `present' (well, observable)
-# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will
-# work properly (i.e., refer to `conftest.exe'), while it won't with
-# `rm'.
-for ac_file in conftest.exe conftest conftest.*; do
- test -f "$ac_file" || continue
- case $ac_file in
- *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;;
- *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
- export ac_cv_exeext
- break;;
- * ) break;;
- esac
-done
-else
- { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link
-See \`config.log' for more details." >&5
-echo "$as_me: error: cannot compute suffix of executables: cannot compile and link
-See \`config.log' for more details." >&2;}
- { (exit 1); exit 1; }; }
-fi
+fi;
-rm -f conftest$ac_cv_exeext
-echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5
-echo "${ECHO_T}$ac_cv_exeext" >&6
-rm -f conftest.$ac_ext
-EXEEXT=$ac_cv_exeext
-ac_exeext=$EXEEXT
-echo "$as_me:$LINENO: checking for suffix of object files" >&5
-echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6
-if test "${ac_cv_objext+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+# Check whether --with-gnutar-listdir or --without-gnutar-listdir was given.
+if test "${with_gnutar_listdir+set}" = set; then
+ withval="$with_gnutar_listdir"
+
+ case "$withval" in
+ n | no) unset GNUTAR_LISTDIR ;;
+ y | ye | yes) : ${GNUTAR_LISTDIR=$localstatedir/amanda/gnutar-lists} ;;
+ /*) GNUTAR_LISTDIR="$withval" ;;
+ *) { { echo "$as_me:$LINENO: error: *** You must supply a full pathname to --with-gnutar-listdir" >&5
+echo "$as_me: error: *** You must supply a full pathname to --with-gnutar-listdir" >&2;}
+ { (exit 1); exit 1; }; }
+ esac
+
else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
+ : ${GNUTAR_LISTDIR="$localstatedir/amanda/gnutar-lists"}
-int
-main ()
-{
+fi;
+if test "$GNUTAR_LISTDIR"; then
+ GNUTAR_LISTDIR=`(
+ test "x$prefix" = xNONE && prefix=$ac_default_prefix
+ eval echo "$GNUTAR_LISTDIR"
+ )`
- ;
- return 0;
-}
+cat >>confdefs.h <<_ACEOF
+#define GNUTAR_LISTED_INCREMENTAL_DIR "$GNUTAR_LISTDIR"
_ACEOF
-rm -f conftest.o conftest.obj
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; then
- for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do
- case $ac_file in
- *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;;
- *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
- break;;
- esac
-done
+
+ GNUTAR_LISTED_INCREMENTAL_DIRX=$GNUTAR_LISTDIR
else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
+ GNUTAR_LISTED_INCREMENTAL_DIRX=
+fi
-{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile
-See \`config.log' for more details." >&5
-echo "$as_me: error: cannot compute suffix of object files: cannot compile
-See \`config.log' for more details." >&2;}
+
+
+# Check whether --with-gnutar-listed-incremental or --without-gnutar-listed-incremental was given.
+if test "${with_gnutar_listed_incremental+set}" = set; then
+ withval="$with_gnutar_listed_incremental"
+ { { echo "$as_me:$LINENO: error: *** The gnutar-listed-incremental option was deprecated, use gnutar-listdir instead" >&5
+echo "$as_me: error: *** The gnutar-listed-incremental option was deprecated, use gnutar-listdir instead" >&2;}
{ (exit 1); exit 1; }; }
-fi
-rm -f conftest.$ac_cv_objext conftest.$ac_ext
-fi
-echo "$as_me:$LINENO: result: $ac_cv_objext" >&5
-echo "${ECHO_T}$ac_cv_objext" >&6
-OBJEXT=$ac_cv_objext
-ac_objext=$OBJEXT
-echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5
-echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6
-if test "${ac_cv_c_compiler_gnu+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-int
-main ()
-{
-#ifndef __GNUC__
- choke me
-#endif
+fi;
+GNUTAR_LISTED_INCREMENTAL_DIR=$GNUTAR_LISTDIR
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_compiler_gnu=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-ac_compiler_gnu=no
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-ac_cv_c_compiler_gnu=$ac_compiler_gnu
-fi
-echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5
-echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6
-GCC=`test $ac_compiler_gnu = yes && echo yes`
-ac_test_CFLAGS=${CFLAGS+set}
-ac_save_CFLAGS=$CFLAGS
-CFLAGS="-g"
-echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5
-echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6
-if test "${ac_cv_prog_cc_g+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+# Check whether --with-bsd-security or --without-bsd-security was given.
+if test "${with_bsd_security+set}" = set; then
+ withval="$with_bsd_security"
+ BSD_SECURITY=$withval
else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
+ : ${BSD_SECURITY=yes}
+
+fi;
+case "$BSD_SECURITY" in
+n | no) : ;;
+y | ye | yes)
+cat >>confdefs.h <<\_ACEOF
+#define BSD_SECURITY 1
_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-int
-main ()
-{
+ ;;
+*) { { echo "$as_me:$LINENO: error: *** You must not supply an argument to --with-bsd-security option." >&5
+echo "$as_me: error: *** You must not supply an argument to --with-bsd-security option." >&2;}
+ { (exit 1); exit 1; }; }
+ ;;
+esac
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_prog_cc_g=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-ac_cv_prog_cc_g=no
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5
-echo "${ECHO_T}$ac_cv_prog_cc_g" >&6
-if test "$ac_test_CFLAGS" = set; then
- CFLAGS=$ac_save_CFLAGS
-elif test $ac_cv_prog_cc_g = yes; then
- if test "$GCC" = yes; then
- CFLAGS="-g -O2"
- else
- CFLAGS="-g"
- fi
-else
- if test "$GCC" = yes; then
- CFLAGS="-O2"
- else
- CFLAGS=
- fi
-fi
-echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5
-echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6
-if test "${ac_cv_prog_cc_stdc+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+# Check whether --with-amandahosts or --without-amandahosts was given.
+if test "${with_amandahosts+set}" = set; then
+ withval="$with_amandahosts"
+ USE_AMANDAHOSTS=$withval
else
- ac_cv_prog_cc_stdc=no
-ac_save_CC=$CC
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
+ : ${USE_AMANDAHOSTS=yes}
+
+fi;
+case "$USE_AMANDAHOSTS" in
+n | no) : ;;
+y | ye | yes) :
+ case "$BSD_SECURITY" in
+ y | ye | yes)
+cat >>confdefs.h <<\_ACEOF
+#define USE_AMANDAHOSTS 1
_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <stdarg.h>
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
-struct buf { int x; };
-FILE * (*rcsopen) (struct buf *, struct stat *, int);
-static char *e (p, i)
- char **p;
- int i;
-{
- return p[i];
-}
-static char *f (char * (*g) (char **, int), char **p, ...)
-{
- char *s;
- va_list v;
- va_start (v,p);
- s = g (p, va_arg (v,int));
- va_end (v);
- return s;
-}
-/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has
- function prototypes and stuff, but not '\xHH' hex character constants.
- These don't provoke an error unfortunately, instead are silently treated
- as 'x'. The following induces an error, until -std1 is added to get
- proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an
- array size at least. It's necessary to write '\x00'==0 to get something
- that's true only with -std1. */
-int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+ ;;
+ esac
+ ;;
+*) { { echo "$as_me:$LINENO: error: *** You must not supply an argument to --with-amandahosts option." >&5
+echo "$as_me: error: *** You must not supply an argument to --with-amandahosts option." >&2;}
+ { (exit 1); exit 1; }; }
+ ;;
+esac
-int test (int i, double x);
-struct s1 {int (*f) (int a);};
-struct s2 {int (*f) (double a);};
-int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
-int argc;
-char **argv;
-int
-main ()
-{
-return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1];
- ;
- return 0;
-}
-_ACEOF
-# Don't try gcc -ansi; that turns off useful extensions and
-# breaks some systems' header files.
-# AIX -qlanglvl=ansi
-# Ultrix and OSF/1 -std1
-# HP-UX 10.20 and later -Ae
-# HP-UX older versions -Aa -D_HPUX_SOURCE
-# SVR4 -Xc -D__EXTENSIONS__
-for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
-do
- CC="$ac_save_CC $ac_arg"
- rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_prog_cc_stdc=$ac_arg
-break
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-fi
-rm -f conftest.err conftest.$ac_objext
-done
-rm -f conftest.$ac_ext conftest.$ac_objext
-CC=$ac_save_CC
-fi
+# Check whether --with-dbmalloc or --without-dbmalloc was given.
+if test "${with_dbmalloc+set}" = set; then
+ withval="$with_dbmalloc"
+ DBMALLOC="$withval"
+else
+ : ${DBMALLOC=no}
-case "x$ac_cv_prog_cc_stdc" in
- x|xno)
- echo "$as_me:$LINENO: result: none needed" >&5
-echo "${ECHO_T}none needed" >&6 ;;
- *)
- echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5
-echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6
- CC="$CC $ac_cv_prog_cc_stdc" ;;
-esac
+fi;
+
+case "$DBMALLOC" in
+n | no)
+ DBMALLOCCFLAGS=""
+ DBMALLOCLIBS=""
+ ;;
+*)
-# Some people use a C++ compiler to compile C. Since we use `exit',
-# in C++ we need to declare it. In case someone uses the same compiler
-# for both compiling C and C++ we need to have the C++ compiler decide
-# the declaration of exit, since it's the most demanding environment.
+echo "$as_me:$LINENO: checking for malloc in -ldbmalloc" >&5
+echo $ECHO_N "checking for malloc in -ldbmalloc... $ECHO_C" >&6
+if test "${ac_cv_lib_dbmalloc_malloc+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldbmalloc $LIBS"
cat >conftest.$ac_ext <<_ACEOF
-#ifndef __cplusplus
- choke me
-#endif
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- for ac_declaration in \
- '' \
- 'extern "C" void std::exit (int) throw (); using std::exit;' \
- 'extern "C" void std::exit (int); using std::exit;' \
- 'extern "C" void exit (int) throw ();' \
- 'extern "C" void exit (int);' \
- 'void exit (int);'
-do
- cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
-$ac_declaration
-#include <stdlib.h>
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char malloc ();
int
main ()
{
-exit (42);
+malloc ();
;
return 0;
}
_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
+ { ac_try='test -s conftest$ac_exeext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
- :
+ ac_cv_lib_dbmalloc_malloc=yes
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
-continue
+ac_cv_lib_dbmalloc_malloc=no
fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
- cat >conftest.$ac_ext <<_ACEOF
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_dbmalloc_malloc" >&5
+echo "${ECHO_T}$ac_cv_lib_dbmalloc_malloc" >&6
+if test $ac_cv_lib_dbmalloc_malloc = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBDBMALLOC 1
+_ACEOF
+
+ LIBS="-ldbmalloc $LIBS"
+
+fi
+
+ if test "x$ac_cv_lib_dbmalloc_malloc" != "xyes"; then
+ { echo "$as_me:$LINENO: WARNING: *** dbmalloc library not found - no malloc debugging support!" >&5
+echo "$as_me: WARNING: *** dbmalloc library not found - no malloc debugging support!" >&2;}
+ DBMALLOCCFLAGS=""
+ DBMALLOCLIBS=""
+ else
+ DBMALLOCCFLAGS="-I$DBMALLOC -DUSE_DBMALLOC"
+ DBMALLOCLIBS="-L$DBMALLOC -ldbmalloc"
+ fi
+ ;;
+esac
+
+
+: ${KRB4_SPOTS="/usr/kerberos /usr/cygnus /usr /opt/kerberos"}
+
+
+# Check whether --with-krb4-security or --without-krb4-security was given.
+if test "${with_krb4_security+set}" = set; then
+ withval="$with_krb4_security"
+ KRB4_SECURITY="$withval"
+else
+ : ${KRB4_SECURITY=no}
+
+fi;
+
+case "$KRB4_SECURITY" in
+n | no) KRB4_SECURITY=no ;;
+y | ye | yes) : ;;
+*) KRB4_SPOTS="$KRB4_SECURITY"
+ KRB4_SECURITY=yes
+ ;;
+esac
+
+echo "$as_me:$LINENO: checking for Kerberos and Amanda kerberos4 bits" >&5
+echo $ECHO_N "checking for Kerberos and Amanda kerberos4 bits... $ECHO_C" >&6
+if test "x${KRB4_SECURITY}" = xyes -a -f ${srcdir-.}/common-src/krb4-security.c ; then
+ for dir in $KRB4_SPOTS; do
+ if test -f ${dir}/lib/libkrb.a -a -f ${dir}/lib/libdes.a ; then
+ #
+ # This is the original Kerberos 4.
+ #
+ echo "$as_me:$LINENO: result: found in $dir" >&5
+echo "${ECHO_T}found in $dir" >&6
+ KRB4_SECURITY=yes
+
+cat >>confdefs.h <<\_ACEOF
+#define KRB4_SECURITY 1
+_ACEOF
+
+ if test -d $dir/include/kerberosIV ; then
+ #
+ # This handles BSD/OS.
+ #
+ KRB4INCLUDES=-I$dir/include/kerberosIV
+ else
+ KRB4INCLUDES=-I$dir/include
+ fi
+ KRB4LDFLAGS=-L$dir/lib
+ KRB4LIBS="-lkrb -ldes"
+ if test -f ${dir}/lib/libcom_err.a; then
+ KRB4LIBS="$KRB4LIBS -lcom_err"
+ fi
+ break
+ elif test -f ${dir}/lib/libkrb4.a &&
+ test -f ${dir}/lib/libcrypto.a &&
+ test -f ${dir}/lib/libdes425.a ; then
+ #
+ # This is Kerberos 5 with Kerberos 4 back-support.
+ #
+ echo "$as_me:$LINENO: result: found in $dir" >&5
+echo "${ECHO_T}found in $dir" >&6
+ KRB4_SECURITY=yes
+
+cat >>confdefs.h <<\_ACEOF
+#define KRB4_SECURITY 1
+_ACEOF
+
+ KRB4INCLUDES="-I$dir/include -I$dir/include/kerberosIV"
+ KRB4LDFLAGS=-L$dir/lib
+ if test -f ${dir}/lib/libkrb5.a &&
+ test -f ${dir}/lib/libcom_err.a; then
+ KRB4LIBS="-lkrb4 -lkrb5 -lcrypto -ldes425 -lcom_err"
+ else
+ KRB4LIBS="-lkrb4 -lcrypto -ldes425"
+ fi
+ break
+ fi
+ done
+
+ if test "x$KRB4LDFLAGS" = "x" ; then
+ echo "$as_me:$LINENO: result: no libraries found" >&5
+echo "${ECHO_T}no libraries found" >&6
+ fi
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+
+# Check whether --with-rsh-security or --without-rsh-security was given.
+if test "${with_rsh_security+set}" = set; then
+ withval="$with_rsh_security"
+ RSH_SECURITY=$withval
+else
+ : ${RSH_SECURITY=yes}
+
+fi;
+case "$RSH_SECURITY" in
+n | no) : ;;
+y | ye | yes)
+cat >>confdefs.h <<\_ACEOF
+#define RSH_SECURITY 1
+_ACEOF
+
+ ;;
+*) { { echo "$as_me:$LINENO: error: *** You must not supply an argument the to --with-rsh-security option." >&5
+echo "$as_me: error: *** You must not supply an argument the to --with-rsh-security option." >&2;}
+ { (exit 1); exit 1; }; }
+ ;;
+esac
+
+
+# Check whether --with-ssh-security or --without-ssh-security was given.
+if test "${with_ssh_security+set}" = set; then
+ withval="$with_ssh_security"
+ SSH_SECURITY=$withval
+else
+ : ${SSH_SECURITY=no}
+
+fi;
+case "$SSH_SECURITY" in
+n | no) : ;;
+y | ye | yes)
+cat >>confdefs.h <<\_ACEOF
+#define SSH_SECURITY 1
+_ACEOF
+
+ SSH_SECURITY_SET=true
+ ;;
+*) { { echo "$as_me:$LINENO: error: *** You must not supply an argument the to --with-ssh-security option." >&5
+echo "$as_me: error: *** You must not supply an argument the to --with-ssh-security option." >&2;}
+ { (exit 1); exit 1; }; }
+ ;;
+esac
+
+
+# Check whether --with-bsdtcp-security or --without-bsdtcp-security was given.
+if test "${with_bsdtcp_security+set}" = set; then
+ withval="$with_bsdtcp_security"
+ BSDTCP_SECURITY=$withval
+else
+ : ${BSDTCP_SECURITY=yes}
+
+fi;
+case "$BSDTCP_SECURITY" in
+n | no) : ;;
+y | ye | yes)
+cat >>confdefs.h <<\_ACEOF
+#define BSDTCP_SECURITY 1
+_ACEOF
+
+ BSDTCP_SECURITY_SET=true
+ ;;
+*) { { echo "$as_me:$LINENO: error: *** You must not supply an argument the to --with-bsdtcp-security option." >&5
+echo "$as_me: error: *** You must not supply an argument the to --with-bsdtcp-security option." >&2;}
+ { (exit 1); exit 1; }; }
+ ;;
+esac
+
+
+# Check whether --with-bsdudp-security or --without-bsdudp-security was given.
+if test "${with_bsdudp_security+set}" = set; then
+ withval="$with_bsdudp_security"
+ BSDUDP_SECURITY=$withval
+else
+ : ${BSDUDP_SECURITY=yes}
+
+fi;
+case "$BSDUDP_SECURITY" in
+n | no) : ;;
+y | ye | yes)
+cat >>confdefs.h <<\_ACEOF
+#define BSDUDP_SECURITY 1
+_ACEOF
+
+ BSDUDP_SECURITY_SET=true
+ ;;
+*) { { echo "$as_me:$LINENO: error: *** You must not supply an argument the to --with-bsdudp-security option." >&5
+echo "$as_me: error: *** You must not supply an argument the to --with-bsdudp-security option." >&2;}
+ { (exit 1); exit 1; }; }
+ ;;
+esac
+
+
+# Check whether --with-server-principal or --without-server-principal was given.
+if test "${with_server_principal+set}" = set; then
+ withval="$with_server_principal"
+
+ case "$withval" in
+ "" | y | ye | yes | n | no)
+ { { echo "$as_me:$LINENO: error: *** You must supply an argument to the --with-server-principal option." >&5
+echo "$as_me: error: *** You must supply an argument to the --with-server-principal option." >&2;}
+ { (exit 1); exit 1; }; }
+ ;;
+ *)
+ SERVER_HOST_PRINCIPLE="$withval"
+ ;;
+ esac
+
+else
+ : ${SERVER_HOST_PRINCIPLE="amanda"}
+
+fi;
+
+cat >>confdefs.h <<_ACEOF
+#define SERVER_HOST_PRINCIPLE "$SERVER_HOST_PRINCIPLE"
+_ACEOF
+
+
+
+# Check whether --with-server-instance or --without-server-instance was given.
+if test "${with_server_instance+set}" = set; then
+ withval="$with_server_instance"
+
+ case "$withval" in
+ "" | y | ye | yes | n | no)
+ { { echo "$as_me:$LINENO: error: *** You must supply an argument to the --with-server-instance option." >&5
+echo "$as_me: error: *** You must supply an argument to the --with-server-instance option." >&2;}
+ { (exit 1); exit 1; }; }
+ ;;
+ *) SERVER_HOST_INSTANCE="$withval"
+ ;;
+ esac
+
+else
+ : ${SERVER_HOST_INSTANCE="amanda"}
+
+fi;
+
+cat >>confdefs.h <<_ACEOF
+#define SERVER_HOST_INSTANCE "$SERVER_HOST_INSTANCE"
+_ACEOF
+
+
+
+# Check whether --with-server-keyfile or --without-server-keyfile was given.
+if test "${with_server_keyfile+set}" = set; then
+ withval="$with_server_keyfile"
+
+ case "$withval" in
+ "" | y | ye | yes | n | no)
+ { { echo "$as_me:$LINENO: error: *** You must supply an argument to the --with-server-keyfile option." >&5
+echo "$as_me: error: *** You must supply an argument to the --with-server-keyfile option." >&2;}
+ { (exit 1); exit 1; }; }
+ ;;
+ *) SERVER_HOST_KEY_FILE="$withval"
+ ;;
+ esac
+
+else
+ : ${SERVER_HOST_KEY_FILE="/.amanda"}
+
+fi;
+
+cat >>confdefs.h <<_ACEOF
+#define SERVER_HOST_KEY_FILE "$SERVER_HOST_KEY_FILE"
+_ACEOF
+
+
+
+# Check whether --with-client-principal or --without-client-principal was given.
+if test "${with_client_principal+set}" = set; then
+ withval="$with_client_principal"
+
+ case "$withval" in
+ "" | y | ye | yes | n | no)
+ { { echo "$as_me:$LINENO: error: *** You must supply an argument to the --with-client-principal option." >&5
+echo "$as_me: error: *** You must supply an argument to the --with-client-principal option." >&2;}
+ { (exit 1); exit 1; }; }
+ ;;
+ *) CLIENT_HOST_PRINCIPLE="$withval"
+ ;;
+ esac
+
+else
+ : ${CLIENT_HOST_PRINCIPLE="rcmd"}
+
+fi;
+
+cat >>confdefs.h <<_ACEOF
+#define CLIENT_HOST_PRINCIPLE "$CLIENT_HOST_PRINCIPLE"
+_ACEOF
+
+
+
+# Check whether --with-client-instance or --without-client-instance was given.
+if test "${with_client_instance+set}" = set; then
+ withval="$with_client_instance"
+
+ case "$withval" in
+ "" | y | ye | yes | n | no)
+ { { echo "$as_me:$LINENO: error: *** You must supply an argument to the --with-client-instance option." >&5
+echo "$as_me: error: *** You must supply an argument to the --with-client-instance option." >&2;}
+ { (exit 1); exit 1; }; }
+ ;;
+ *) CLIENT_HOST_INSTANCE="$withval"
+ ;;
+ esac
+
+else
+ : ${CLIENT_HOST_INSTANCE=HOSTNAME_INSTANCE}
+
+fi;
+
+cat >>confdefs.h <<_ACEOF
+#define CLIENT_HOST_INSTANCE $CLIENT_HOST_INSTANCE
+_ACEOF
+
+
+
+# Check whether --with-client-keyfile or --without-client-keyfile was given.
+if test "${with_client_keyfile+set}" = set; then
+ withval="$with_client_keyfile"
+
+ case "$withval" in
+ "" | y | ye | yes | n | no)
+ { { echo "$as_me:$LINENO: error: *** You must supply an argument to the --with-client-keyfile option." >&5
+echo "$as_me: error: *** You must supply an argument to the --with-client-keyfile option." >&2;}
+ { (exit 1); exit 1; }; }
+ ;;
+ *) CLIENT_HOST_KEY_FILE="$withval"
+ ;;
+ esac
+
+else
+ : ${CLIENT_HOST_KEY_FILE=KEYFILE}
+
+fi;
+
+# Assume it's either KEYFILE (defined in krb.h), or a string filename...
+if test "x$CLIENT_HOST_KEY_FILE" != "xKEYFILE"; then
+ CLIENT_HOST_KEY_FILE="\"$CLIENT_HOST_KEY_FILE\""
+fi
+
+
+cat >>confdefs.h <<_ACEOF
+#define CLIENT_HOST_KEY_FILE $CLIENT_HOST_KEY_FILE
+_ACEOF
+
+
+
+# Check whether --with-ticket-lifetime or --without-ticket-lifetime was given.
+if test "${with_ticket_lifetime+set}" = set; then
+ withval="$with_ticket_lifetime"
+
+ case "$withval" in
+ "" | y | ye | yes | n | no)
+ { { echo "$as_me:$LINENO: error: *** You must supply an argument to the --with-ticket-lifetime option." >&5
+echo "$as_me: error: *** You must supply an argument to the --with-ticket-lifetime option." >&2;}
+ { (exit 1); exit 1; }; }
+ ;;
+ *) TICKET_LIFETIME="$withval"
+ ;;
+ esac
+
+else
+ : ${TICKET_LIFETIME=128}
+
+fi;
+
+cat >>confdefs.h <<_ACEOF
+#define TICKET_LIFETIME $TICKET_LIFETIME
+_ACEOF
+
+
+
+: ${KRB5_SPOTS="/usr/kerberos /usr/cygnus /usr /opt/kerberos"}
+
+
+# Check whether --with-krb5-security or --without-krb5-security was given.
+if test "${with_krb5_security+set}" = set; then
+ withval="$with_krb5_security"
+ KRB5_SECURITY="$withval"
+else
+ : ${KRB5_SECURITY=no}
+
+fi;
+
+case "$KRB5_SECURITY" in
+n | no) KRB5_SECURITY=no
+ KRB5_SPOTS=""
+ ;;
+y | ye | yes) : ;;
+*) KRB5_SPOTS="$KRB5_SECURITY"
+ KRB5_SECURITY=yes
+ ;;
+esac
+
+# if found, force the static versions of these libs (.a) by linking directly
+# with the .a files. I don't know how to get -R dependancies checked
+# in autoconf at this time. -kashmir
+echo "$as_me:$LINENO: checking for Kerberos V" >&5
+echo $ECHO_N "checking for Kerberos V... $ECHO_C" >&6
+KRB5_DIR_FOUND=""
+KRB5_CFLAGS=""
+for dir in $KRB5_SPOTS; do
+ for lib in lib lib64; do
+ k5libdir=${dir}/${lib}
+ if test -f ${k5libdir}/libkrb5.a -a -f ${k5libdir}/libgssapi_krb5.a -a -f ${k5libdir}/libcom_err.a; then
+ if test -f ${k5libdir}/libk5crypto.a; then
+ K5CRYPTO=${k5libdir}/libk5crypto.a
+ elif test -f ${k5libdir}/libcrypto.a; then
+ K5CRYPTO=${k5libdir}/libcrypto.a
+ else
+ K5CRYPTO=""
+ fi
+ if test -f ${k5libdir}/libkrb5support.a; then
+ K5SUPPORT=${k5libdir}/libkrb5support.a
+ else
+ K5SUPPORT=""
+ fi
+ KRB5_DIR_FOUND=$dir
+ KRB5LIBS="${k5libdir}/libgssapi_krb5.a ${k5libdir}/libkrb5.a $K5CRYPTO $K5SUPPORT ${k5libdir}/libcom_err.a"
+ KRB5CFLAGS=""
+ break
+ elif test -f ${k5libdir}/libkrb5.a -a -f ${k5libdir}/libasn1.a -a -f ${k5libdir}/libgssapi.a; then
+ KRB5_DIR_FOUND=$dir
+ KRB5LIBS="${k5libdir}/libgssapi.a ${k5libdir}/libkrb5.a ${k5libdir}/libasn1.a"
+ KRB5_CFLAGS="-DKRB5_HEIMDAL_INCLUDES"
+ break
+ fi
+ done
+done
+
+if test "$KRB5_DIR_FOUND"; then
+ echo "$as_me:$LINENO: result: found in $KRB5_DIR_FOUND" >&5
+echo "${ECHO_T}found in $KRB5_DIR_FOUND" >&6
+ KRB5_SECURITY=yes
+
+cat >>confdefs.h <<\_ACEOF
+#define KRB5_SECURITY 1
+_ACEOF
+
+ #
+ # some OS's, such as NetBSD, stick krb5 includes out of the way...
+ # should probably just use autoconf to look for various include
+ # options and set them, but don't quite want to do that until I've
+ # dug into it a bit more.
+ #
+ if test -d "$KRB5_DIR_FOUND/krb5" ; then
+ KRB5INCLUDES="-I$KRB5_DIR_FOUND/include/krb5"
+ else
+ KRB5INCLUDES="-I$KRB5_DIR_FOUND/include"
+ fi
+ if test "$KRB5_CFLAGS" ; then
+ KRB5INCLUDES="$KRB5INCLUDES $KRB5_CFLAGS"
+ fi
+
+echo "$as_me:$LINENO: checking for main in -lkrb5support" >&5
+echo $ECHO_N "checking for main in -lkrb5support... $ECHO_C" >&6
+if test "${ac_cv_lib_krb5support_main+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lkrb5support $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
-$ac_declaration
+
+
int
main ()
{
-exit (42);
+main ();
;
return 0;
}
_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
+ { ac_try='test -s conftest$ac_exeext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
- break
+ ac_cv_lib_krb5support_main=yes
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
+ac_cv_lib_krb5support_main=no
fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-done
-rm -f conftest*
-if test -n "$ac_declaration"; then
- echo '#ifdef __cplusplus' >>confdefs.h
- echo $ac_declaration >>confdefs.h
- echo '#endif' >>confdefs.h
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_krb5support_main" >&5
+echo "${ECHO_T}$ac_cv_lib_krb5support_main" >&6
+if test $ac_cv_lib_krb5support_main = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBKRB5SUPPORT 1
+_ACEOF
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
+ LIBS="-lkrb5support $LIBS"
fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-DEPDIR="${am__leading_dot}deps"
- ac_config_commands="$ac_config_commands depfiles"
+ KRB5LDFLAGS=-L$k5libdir
+ break
+fi
+
+if test "x$KRB5LDFLAGS" = "x" ; then
+ echo "$as_me:$LINENO: result: no krb5 system libraries found" >&5
+echo "${ECHO_T}no krb5 system libraries found" >&6
+fi
-am_make=${MAKE-make}
-cat > confinc << 'END'
-am__doit:
- @echo done
-.PHONY: am__doit
-END
-# If we don't find an include directive, just comment out the code.
-echo "$as_me:$LINENO: checking for style of include used by $am_make" >&5
-echo $ECHO_N "checking for style of include used by $am_make... $ECHO_C" >&6
-am__include="#"
-am__quote=
-_am_result=none
-# First try GNU make style include.
-echo "include confinc" > confmf
-# We grep out `Entering directory' and `Leaving directory'
-# messages which can occur if `w' ends up in MAKEFLAGS.
-# In particular we don't look at `^make:' because GNU make might
-# be invoked under some other name (usually "gmake"), in which
-# case it prints its new name instead of `make'.
-if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then
- am__include=include
- am__quote=
- _am_result=GNU
+
+# Check whether --with-low-tcpportrange or --without-low-tcpportrange was given.
+if test "${with_low_tcpportrange+set}" = set; then
+ withval="$with_low_tcpportrange"
+
+ LOW_TCPPORTRANGE="$withval"
+
+
+fi;
+
+if test x"${LOW_TCPPORTRANGE+set}" = x"set"; then
+ if test x`echo "$LOW_TCPPORTRANGE" | sed 's/[0-9][0-9]*,[0-9][0-9]*//'` != x""; then
+ { { echo "$as_me:$LINENO: error: *** --with-low-tcpportrange requires two comma-separated positive numbers" >&5
+echo "$as_me: error: *** --with-low-tcpportrange requires two comma-separated positive numbers" >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+ min_low_tcp_port=`echo "$LOW_TCPPORTRANGE" | sed 's/,.*//'`
+ max_low_tcp_port=`echo "$LOW_TCPPORTRANGE" | sed 's/.*,//'`
+ if test $min_low_tcp_port -gt $max_low_tcp_port; then
+ { { echo "$as_me:$LINENO: error: *** the second TCP port number must be greater than the first in --with-low-tcpportrange" >&5
+echo "$as_me: error: *** the second TCP port number must be greater than the first in --with-low-tcpportrange" >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+ if test $min_low_tcp_port -lt 512; then
+ { echo "$as_me:$LINENO: WARNING: *** the low TCP port range should be 512 or greater in --with-low-tcpportrange" >&5
+echo "$as_me: WARNING: *** the low TCP port range should be 512 or greater in --with-low-tcpportrange" >&2;}
+ fi
+ if test $max_low_tcp_port -ge 1024; then
+ { echo "$as_me:$LINENO: WARNING: *** the low TCP port range should be less than 1024 in --with-low-tcpportrange" >&5
+echo "$as_me: WARNING: *** the low TCP port range should be less than 1024 in --with-low-tcpportrange" >&2;}
+ fi
+
+cat >>confdefs.h <<_ACEOF
+#define LOW_TCPPORTRANGE $LOW_TCPPORTRANGE
+_ACEOF
+
fi
-# Now try BSD make style include.
-if test "$am__include" = "#"; then
- echo '.include "confinc"' > confmf
- if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then
- am__include=.include
- am__quote="\""
- _am_result=BSD
- fi
+
+
+# Check whether --with-tcpportrange or --without-tcpportrange was given.
+if test "${with_tcpportrange+set}" = set; then
+ withval="$with_tcpportrange"
+
+ TCPPORTRANGE="$withval"
+
+
+fi;
+if test x"${TCPPORTRANGE+set}" = x"set"; then
+ if test x`echo "$TCPPORTRANGE" | sed 's/[0-9][0-9]*,[0-9][0-9]*//'` != x""; then
+ { { echo "$as_me:$LINENO: error: *** --with-tcpportrange requires two comma-separated positive numbers" >&5
+echo "$as_me: error: *** --with-tcpportrange requires two comma-separated positive numbers" >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+ min_tcp_port=`echo "$TCPPORTRANGE" | sed 's/,.*//'`
+ max_tcp_port=`echo "$TCPPORTRANGE" | sed 's/.*,//'`
+ if test $min_tcp_port -gt $max_tcp_port; then
+ { { echo "$as_me:$LINENO: error: *** the second TCP port number must be greater than the first in --with-tcpportrange" >&5
+echo "$as_me: error: *** the second TCP port number must be greater than the first in --with-tcpportrange" >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+ if test $min_tcp_port -lt 1024; then
+ { echo "$as_me:$LINENO: WARNING: *** the TCP port range should be 1024 or greater in --with-tcpportrange" >&5
+echo "$as_me: WARNING: *** the TCP port range should be 1024 or greater in --with-tcpportrange" >&2;}
+ fi
+ if test $max_tcp_port -ge 65536; then
+ { echo "$as_me:$LINENO: WARNING: *** the TCP port range should be less than 65536 in --with-tcpportrange" >&5
+echo "$as_me: WARNING: *** the TCP port range should be less than 65536 in --with-tcpportrange" >&2;}
+ fi
+
+cat >>confdefs.h <<_ACEOF
+#define TCPPORTRANGE $TCPPORTRANGE
+_ACEOF
+
fi
-echo "$as_me:$LINENO: result: $_am_result" >&5
-echo "${ECHO_T}$_am_result" >&6
-rm -f confinc confmf
+# Check whether --with-udpportrange or --without-udpportrange was given.
+if test "${with_udpportrange+set}" = set; then
+ withval="$with_udpportrange"
+
+ UDPPORTRANGE="$withval"
-# Check whether --enable-dependency-tracking or --disable-dependency-tracking was given.
-if test "${enable_dependency_tracking+set}" = set; then
- enableval="$enable_dependency_tracking"
fi;
-if test "x$enable_dependency_tracking" != xno; then
- am_depcomp="$ac_aux_dir/depcomp"
- AMDEPBACKSLASH='\'
+if test x"${UDPPORTRANGE+set}" = x"set"; then
+ if test x`echo "$UDPPORTRANGE" | sed 's/[0-9][0-9]*,[0-9][0-9]*//'` != x""; then
+ { { echo "$as_me:$LINENO: error: *** --with-udpportrange requires two comma-separated positive numbers" >&5
+echo "$as_me: error: *** --with-udpportrange requires two comma-separated positive numbers" >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+ min_udp_port=`echo "$UDPPORTRANGE" | sed 's/,.*//'`
+ max_udp_port=`echo "$UDPPORTRANGE" | sed 's/.*,//'`
+ if test $min_udp_port -gt $max_udp_port; then
+ { { echo "$as_me:$LINENO: error: *** the second UDP port number must be greater than the first in --with-udpportrange" >&5
+echo "$as_me: error: *** the second UDP port number must be greater than the first in --with-udpportrange" >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+ if test $max_udp_port -ge 1024; then
+ { echo "$as_me:$LINENO: WARNING: *** the UDP port range should be less than 1024 in --with-udpportrange" >&5
+echo "$as_me: WARNING: *** the UDP port range should be less than 1024 in --with-udpportrange" >&2;}
+ fi
+ if test $min_udp_port -le 0; then
+ { echo "$as_me:$LINENO: WARNING: *** the UDP port range should be greater than 0 in --with-udpportrange" >&5
+echo "$as_me: WARNING: *** the UDP port range should be greater than 0 in --with-udpportrange" >&2;}
+ fi
+
+cat >>confdefs.h <<_ACEOF
+#define UDPPORTRANGE $UDPPORTRANGE
+_ACEOF
+
fi
-if test "x$enable_dependency_tracking" != xno; then
- AMDEP_TRUE=
- AMDEP_FALSE='#'
+# Check whether --with-maxtapeblocksize or --without-maxtapeblocksize was given.
+if test "${with_maxtapeblocksize+set}" = set; then
+ withval="$with_maxtapeblocksize"
+
+ MAXTAPEBLOCKSIZE="$withval"
+
else
- AMDEP_TRUE='#'
- AMDEP_FALSE=
+ : ${MAXTAPEBLOCKSIZE=32}
+
+fi;
+
+
+cat >>confdefs.h <<_ACEOF
+#define MAX_TAPE_BLOCK_KB ($MAXTAPEBLOCKSIZE)
+_ACEOF
+
+
+
+
+# Check whether --with-db or --without-db was given.
+if test "${with_db+set}" = set; then
+ withval="$with_db"
+
+ case "$withval" in
+ "" | y | ye | yes | n | no)
+ { { echo "$as_me:$LINENO: error: *** You must supply an argument to the --with-db option." >&5
+echo "$as_me: error: *** You must supply an argument to the --with-db option." >&2;}
+ { (exit 1); exit 1; }; }
+ ;;
+ *) DB_STYLE="$withval"
+ ;;
+ esac
+
+
+fi;
+if test "$DB_STYLE"; then
+ case "$DB_STYLE" in
+ db | dbm | gdbm | ndbm | text) ;;
+ *)
+ { { echo "$as_me:$LINENO: error: *** Unknown argument $DB_STYLE given to --with-db. Choose from db, dbm, gdbm, ndbm, text." >&5
+echo "$as_me: error: *** Unknown argument $DB_STYLE given to --with-db. Choose from db, dbm, gdbm, ndbm, text." >&2;}
+ { (exit 1); exit 1; }; }
+ DB_STYLE=
+ ;;
+ esac
fi
+# Check whether --with-mmap or --without-mmap was given.
+if test "${with_mmap+set}" = set; then
+ withval="$with_mmap"
+ FORCE_MMAP=$withval
+else
+ : ${FORCE_MMAP=no}
+fi;
+case "$FORCE_MMAP" in
+y | ye | yes | n | no) : ;;
+*) { { echo "$as_me:$LINENO: error: *** You must not supply an argument to --with-mmap." >&5
+echo "$as_me: error: *** You must not supply an argument to --with-mmap." >&2;}
+ { (exit 1); exit 1; }; }
+ ;;
+esac
-depcc="$CC" am_compiler_list=
-echo "$as_me:$LINENO: checking dependency style of $depcc" >&5
-echo $ECHO_N "checking dependency style of $depcc... $ECHO_C" >&6
-if test "${am_cv_CC_dependencies_compiler_type+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+# Check whether --with-buffered-dump or --without-buffered-dump was given.
+if test "${with_buffered_dump+set}" = set; then
+ withval="$with_buffered_dump"
+ DUMPER_SOCKET_BUFFERING=$withval
else
- if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
- # We make a subdir and do the tests there. Otherwise we can end up
- # making bogus files that we don't know about and never remove. For
- # instance it was reported that on HP-UX the gcc test will end up
- # making a dummy file named `D' -- because `-MD' means `put the output
- # in D'.
- mkdir conftest.dir
- # Copy depcomp to subdir because otherwise we won't find it if we're
- # using a relative directory.
- cp "$am_depcomp" conftest.dir
- cd conftest.dir
- # We will build objects and dependencies in a subdirectory because
- # it helps to detect inapplicable dependency modes. For instance
- # both Tru64's cc and ICC support -MD to output dependencies as a
- # side effect of compilation, but ICC will put the dependencies in
- # the current directory while Tru64 will put them in the object
- # directory.
- mkdir sub
+ : ${DUMPER_SOCKET_BUFFERING=no}
- am_cv_CC_dependencies_compiler_type=none
- if test "$am_compiler_list" = ""; then
- am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp`
- fi
- for depmode in $am_compiler_list; do
- # Setup a source with many dependencies, because some compilers
- # like to wrap large dependency lists on column 80 (with \), and
- # we should not choose a depcomp mode which is confused by this.
- #
- # We need to recreate these files for each test, as the compiler may
- # overwrite some of them when testing with obscure command lines.
- # This happens at least with the AIX C compiler.
- : > sub/conftest.c
- for i in 1 2 3 4 5 6; do
- echo '#include "conftst'$i'.h"' >> sub/conftest.c
- # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with
- # Solaris 8's {/usr,}/bin/sh.
- touch sub/conftst$i.h
- done
- echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+fi;
+case "$DUMPER_SOCKET_BUFFERING" in
+n | no) :
+ ;;
+y | ye | yes)
+cat >>confdefs.h <<\_ACEOF
+#define DUMPER_SOCKET_BUFFERING 1
+_ACEOF
- case $depmode in
- nosideeffect)
- # after this tag, mechanisms are not by side-effect, so they'll
- # only be used when explicitly requested
- if test "x$enable_dependency_tracking" = xyes; then
- continue
- else
- break
- fi
- ;;
- none) break ;;
- esac
- # We check with `-c' and `-o' for the sake of the "dashmstdout"
- # mode. It turns out that the SunPro C++ compiler does not properly
- # handle `-M -o', and we need to detect this.
- if depmode=$depmode \
- source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \
- depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
- $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \
- >/dev/null 2>conftest.err &&
- grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
- grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 &&
- ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
- # icc doesn't choke on unknown options, it will just issue warnings
- # or remarks (even with -Werror). So we grep stderr for any message
- # that says an option was ignored or not supported.
- # When given -MP, icc 7.0 and 7.1 complain thusly:
- # icc: Command line warning: ignoring option '-M'; no argument required
- # The diagnosis changed in icc 8.0:
- # icc: Command line remark: option '-MP' not supported
- if (grep 'ignoring option' conftest.err ||
- grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
- am_cv_CC_dependencies_compiler_type=$depmode
- break
- fi
- fi
- done
+ ;;
+*) { { echo "$as_me:$LINENO: error: *** You must not supply an argument to --with-buffered-dump." >&5
+echo "$as_me: error: *** You must not supply an argument to --with-buffered-dump." >&2;}
+ { (exit 1); exit 1; }; }
+ ;;
+esac
- cd ..
- rm -rf conftest.dir
+
+# Check whether --with-assertions or --without-assertions was given.
+if test "${with_assertions+set}" = set; then
+ withval="$with_assertions"
+ ASSERTIONS="$withval"
else
- am_cv_CC_dependencies_compiler_type=none
-fi
+ : ${ASSERTIONS=no}
-fi
-echo "$as_me:$LINENO: result: $am_cv_CC_dependencies_compiler_type" >&5
-echo "${ECHO_T}$am_cv_CC_dependencies_compiler_type" >&6
-CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type
+fi;
+case "$ASSERTIONS" in
+n | no) : ;;
+y | ye | yes)
+cat >>confdefs.h <<\_ACEOF
+#define ASSERTIONS 1
+_ACEOF
+ ;;
+*) { { echo "$as_me:$LINENO: error: *** You must not supply an argument to --with-assertions option." >&5
+echo "$as_me: error: *** You must not supply an argument to --with-assertions option." >&2;}
+ { (exit 1); exit 1; }; }
+ ;;
+esac
-if
- test "x$enable_dependency_tracking" != xno \
- && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then
- am__fastdepCC_TRUE=
- am__fastdepCC_FALSE='#'
+# Check whether --with-tmpdir or --without-tmpdir was given.
+if test "${with_tmpdir+set}" = set; then
+ withval="$with_tmpdir"
+ tmpdir="$withval"
else
- am__fastdepCC_TRUE='#'
- am__fastdepCC_FALSE=
-fi
+ : ${tmpdir=yes}
+
+fi;
+tmpdir=`(
+ test "x$prefix" = xNONE && prefix=$ac_default_prefix
+ test "x$exec_prefix" = xNONE && exec_prefix=${prefix}
+ eval echo "$tmpdir"
+)`
+case "$tmpdir" in
+n | no) { { echo "$as_me:$LINENO: error: *** --without-tmpdir is not allowed." >&5
+echo "$as_me: error: *** --without-tmpdir is not allowed." >&2;}
+ { (exit 1); exit 1; }; };;
+y | ye | yes)
+ AMANDA_TMPDIR="/tmp/amanda";;
+/*)
+ AMANDA_TMPDIR="$tmpdir";;
+*) { { echo "$as_me:$LINENO: error: *** You must supply a full pathname to --with-tmpdir option." >&5
+echo "$as_me: error: *** You must supply a full pathname to --with-tmpdir option." >&2;}
+ { (exit 1); exit 1; }; };;
+esac
+
+cat >>confdefs.h <<_ACEOF
+#define AMANDA_TMPDIR "$AMANDA_TMPDIR"
+_ACEOF
+
+# Check whether --with-debugging or --without-debugging was given.
+if test "${with_debugging+set}" = set; then
+ withval="$with_debugging"
+ debugging="$withval"
+else
+ : ${debugging=yes}
+
+fi;
+debugging=`(
+ test "x$prefix" = xNONE && prefix=$ac_default_prefix
+ test "x$exec_prefix" = xNONE && exec_prefix=${prefix}
+ eval echo "$debugging"
+)`
+case "$debugging" in
+n | no) AMANDA_DBGDIR="";;
+y | ye | yes) AMANDA_DBGDIR="$AMANDA_TMPDIR";;
+/*) AMANDA_DBGDIR="$debugging";;
+*) { { echo "$as_me:$LINENO: error: *** You must supply a full pathname to --with-debugging option." >&5
+echo "$as_me: error: *** You must supply a full pathname to --with-debugging option." >&2;}
+ { (exit 1); exit 1; }; }
+ ;;
+esac
+case "$AMANDA_DBGDIR" in
+"") :;;
+*)
+cat >>confdefs.h <<\_ACEOF
+#define DEBUG_CODE 1
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define AMANDA_DBGDIR "$AMANDA_DBGDIR"
+_ACEOF
+
+ ;;
+esac
+
+
+# Check whether --with-debug_days or --without-debug_days was given.
+if test "${with_debug_days+set}" = set; then
+ withval="$with_debug_days"
+ debug_days="$withval"
+else
+ : ${debug_days=4}
+
+fi;
+case "$debug_days" in
+n | no) AMANDA_DEBUG_DAYS=0 ;;
+y | ye | yes) AMANDA_DEBUG_DAYS=4 ;;
+[0-9] | [0-9][0-9] | [0-9][0-9][0-9]) AMANDA_DEBUG_DAYS="$debug_days" ;;
+*) { { echo "$as_me:$LINENO: error: *** --with-debug-days value not numeric or out of range." >&5
+echo "$as_me: error: *** --with-debug-days value not numeric or out of range." >&2;}
+ { (exit 1); exit 1; }; }
+ ;;
+esac
+
+cat >>confdefs.h <<_ACEOF
+#define AMANDA_DEBUG_DAYS $AMANDA_DEBUG_DAYS
+_ACEOF
+
+
+
+
+# Check whether --with-testing or --without-testing was given.
+if test "${with_testing+set}" = set; then
+ withval="$with_testing"
+ TESTING="$withval"
+else
+ : ${TESTING=no}
+
+fi;
+case "$TESTING" in
+n | no) SERVICE_SUFFIX="";;
+y | ye | yes) SERVICE_SUFFIX="-test";;
+*) SERVICE_SUFFIX="-$TESTING";;
+esac
+AMANDA_SERVICE_NAME="amanda$SERVICE_SUFFIX"
+KAMANDA_SERVICE_NAME="kamanda$SERVICE_SUFFIX"
+
+
+cat >>confdefs.h <<_ACEOF
+#define SERVICE_SUFFIX "$SERVICE_SUFFIX"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define AMANDA_SERVICE_NAME "$AMANDA_SERVICE_NAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define KAMANDA_SERVICE_NAME "$KAMANDA_SERVICE_NAME"
+_ACEOF
+
+
+(
+ test "x$prefix" = xNONE && prefix=$ac_default_prefix
+ test "x$exec_prefix" = xNONE && exec_prefix=${prefix}
+
+ tmp=`eval echo "$bindir"`
+
+cat >>confdefs.h <<_ACEOF
+#define bindir "$tmp"
+_ACEOF
+
+
+ tmp=`eval echo "$sbindir"`
+
+cat >>confdefs.h <<_ACEOF
+#define sbindir "$tmp"
+_ACEOF
+
+ tmp=`eval echo "$libexecdir"`
+
+cat >>confdefs.h <<_ACEOF
+#define libexecdir "$tmp"
+_ACEOF
+
+
+ tmp=`eval echo $mandir`
+
+cat >>confdefs.h <<_ACEOF
+#define mandir "$tmp"
+_ACEOF
+
+)
DUMP_PROGRAMS="ufsdump dump backup"
GETCONF_LFS="LFS"
;;
*-pc-linux-*)
;;
+ *-redhat-linux-*)
+ ;;
x86_64-*-linux-*)
;;
alpha*-*-linux-*)
_ACEOF
-
ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
-cat >conftest.$ac_ext <<_ACEOF
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (void*))) < 0)];
+test_array [0] = 0
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_hi=-1 ac_mid=-1
+ while :; do
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (void*))) >= $ac_mid)];
+test_array [0] = 0
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_lo=$ac_mid; break
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_hi=`expr '(' $ac_mid ')' - 1`
+ if test $ac_mid -le $ac_hi; then
+ ac_lo= ac_hi=
+ break
+ fi
+ ac_mid=`expr 2 '*' $ac_mid`
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ done
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo= ac_hi=
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+# Binary search between lo and hi bounds.
+while test "x$ac_lo" != "x$ac_hi"; do
+ ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo`
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (void*))) <= $ac_mid)];
+test_array [0] = 0
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_hi=$ac_mid
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo=`expr '(' $ac_mid ')' + 1`
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+case $ac_lo in
+?*) ac_cv_sizeof_voidp=$ac_lo;;
+'') { { echo "$as_me:$LINENO: error: cannot compute sizeof (void*), 77
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute sizeof (void*), 77
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; } ;;
+esac
+else
+ if test "$cross_compiling" = yes; then
+ { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+long longval () { return (long) (sizeof (void*)); }
+unsigned long ulongval () { return (long) (sizeof (void*)); }
+#include <stdio.h>
+#include <stdlib.h>
+int
+main ()
+{
+
+ FILE *f = fopen ("conftest.val", "w");
+ if (! f)
+ exit (1);
+ if (((long) (sizeof (void*))) < 0)
+ {
+ long i = longval ();
+ if (i != ((long) (sizeof (void*))))
+ exit (1);
+ fprintf (f, "%ld\n", i);
+ }
+ else
+ {
+ unsigned long i = ulongval ();
+ if (i != ((long) (sizeof (void*))))
+ exit (1);
+ fprintf (f, "%lu\n", i);
+ }
+ exit (ferror (f) || fclose (f) != 0);
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_sizeof_voidp=`cat conftest.val`
+else
+ echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+{ { echo "$as_me:$LINENO: error: cannot compute sizeof (void*), 77
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute sizeof (void*), 77
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+rm -f conftest.val
+else
+ ac_cv_sizeof_voidp=0
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_sizeof_voidp" >&5
+echo "${ECHO_T}$ac_cv_sizeof_voidp" >&6
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_VOIDP $ac_cv_sizeof_voidp
+_ACEOF
+
+
+ ac_cv_char_data_model=""
+ ac_cv_char_data_model="$ac_cv_char_data_model$ac_cv_sizeof_char"
+ ac_cv_char_data_model="$ac_cv_char_data_model$ac_cv_sizeof_short"
+ ac_cv_char_data_model="$ac_cv_char_data_model$ac_cv_sizeof_int"
+ ac_cv_long_data_model=""
+ ac_cv_long_data_model="$ac_cv_long_data_model$ac_cv_sizeof_int"
+ ac_cv_long_data_model="$ac_cv_long_data_model$ac_cv_sizeof_long"
+ ac_cv_long_data_model="$ac_cv_long_data_model$ac_cv_sizeof_voidp"
+ echo "$as_me:$LINENO: checking data model" >&5
+echo $ECHO_N "checking data model... $ECHO_C" >&6
+ case "$ac_cv_char_data_model/$ac_cv_long_data_model" in
+ 122/242) ac_cv_data_model="IP16" ; n="standard 16bit machine" ;;
+ 122/244) ac_cv_data_model="LP32" ; n="standard 32bit machine" ;;
+ 122/*) ac_cv_data_model="i16" ; n="unusual int16 model" ;;
+ 124/444) ac_cv_data_model="ILP32" ; n="standard 32bit unixish" ;;
+ 124/488) ac_cv_data_model="LP64" ; n="standard 64bit unixish" ;;
+ 124/448) ac_cv_data_model="LLP64" ; n="unusual 64bit unixish" ;;
+ 124/*) ac_cv_data_model="i32" ; n="unusual int32 model" ;;
+ 128/888) ac_cv_data_model="ILP64" ; n="unusual 64bit numeric" ;;
+ 128/*) ac_cv_data_model="i64" ; n="unusual int64 model" ;;
+ 222/*2) ac_cv_data_model="DSP16" ; n="strict 16bit dsptype" ;;
+ 333/*3) ac_cv_data_model="DSP24" ; n="strict 24bit dsptype" ;;
+ 444/*4) ac_cv_data_model="DSP32" ; n="strict 32bit dsptype" ;;
+ 666/*6) ac_cv_data_model="DSP48" ; n="strict 48bit dsptype" ;;
+ 888/*8) ac_cv_data_model="DSP64" ; n="strict 64bit dsptype" ;;
+ 222/*|333/*|444/*|666/*|888/*) :
+ ac_cv_data_model="iDSP" ; n="unusual dsptype" ;;
+ *) ac_cv_data_model="none" ; n="very unusual model" ;;
+ esac
+ echo "$as_me:$LINENO: result: $ac_cv_data_model ($ac_cv_long_data_model, $n)" >&5
+echo "${ECHO_T}$ac_cv_data_model ($ac_cv_long_data_model, $n)" >&6
+
+fi
+
+if test "_$ac_cv_header_stdint_x" != "_" ; then
+ ac_cv_header_stdint="$ac_cv_header_stdint_x"
+elif test "_$ac_cv_header_stdint_o" != "_" ; then
+ ac_cv_header_stdint="$ac_cv_header_stdint_o"
+elif test "_$ac_cv_header_stdint_u" != "_" ; then
+ ac_cv_header_stdint="$ac_cv_header_stdint_u"
+else
+ ac_cv_header_stdint="stddef.h"
+fi
+
+echo "$as_me:$LINENO: checking for extra inttypes in chosen header" >&5
+echo $ECHO_N "checking for extra inttypes in chosen header... $ECHO_C" >&6
+echo "$as_me:$LINENO: result: ($ac_cv_header_stdint)" >&5
+echo "${ECHO_T}($ac_cv_header_stdint)" >&6
+unset ac_cv_type_int_least32_t
+unset ac_cv_type_int_fast32_t
+echo "$as_me:$LINENO: checking for int_least32_t" >&5
+echo $ECHO_N "checking for int_least32_t... $ECHO_C" >&6
+if test "${ac_cv_type_int_least32_t+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
-$ac_includes_default
+#include <$ac_cv_header_stdint>
+
int
main ()
{
-static int test_array [1 - 2 * !(((long) (sizeof (void*))) < 0)];
-test_array [0] = 0
-
+if ((int_least32_t *) 0)
+ return 0;
+if (sizeof (int_least32_t))
+ return 0;
;
return 0;
}
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
- ac_hi=-1 ac_mid=-1
- while :; do
- cat >conftest.$ac_ext <<_ACEOF
+ ac_cv_type_int_least32_t=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_int_least32_t=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_int_least32_t" >&5
+echo "${ECHO_T}$ac_cv_type_int_least32_t" >&6
+
+echo "$as_me:$LINENO: checking for int_fast32_t" >&5
+echo $ECHO_N "checking for int_fast32_t... $ECHO_C" >&6
+if test "${ac_cv_type_int_fast32_t+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
-$ac_includes_default
+#include<$ac_cv_header_stdint>
+
int
main ()
{
-static int test_array [1 - 2 * !(((long) (sizeof (void*))) >= $ac_mid)];
-test_array [0] = 0
-
+if ((int_fast32_t *) 0)
+ return 0;
+if (sizeof (int_fast32_t))
+ return 0;
;
return 0;
}
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
- ac_lo=$ac_mid; break
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_hi=`expr '(' $ac_mid ')' - 1`
- if test $ac_mid -le $ac_hi; then
- ac_lo= ac_hi=
- break
- fi
- ac_mid=`expr 2 '*' $ac_mid`
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
- done
+ ac_cv_type_int_fast32_t=yes
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
-ac_lo= ac_hi=
+ac_cv_type_int_fast32_t=no
fi
rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-# Binary search between lo and hi bounds.
-while test "x$ac_lo" != "x$ac_hi"; do
- ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo`
+echo "$as_me:$LINENO: result: $ac_cv_type_int_fast32_t" >&5
+echo "${ECHO_T}$ac_cv_type_int_fast32_t" >&6
+
+echo "$as_me:$LINENO: checking for intmax_t" >&5
+echo $ECHO_N "checking for intmax_t... $ECHO_C" >&6
+if test "${ac_cv_type_intmax_t+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
-$ac_includes_default
+#include <$ac_cv_header_stdint>
+
int
main ()
{
-static int test_array [1 - 2 * !(((long) (sizeof (void*))) <= $ac_mid)];
-test_array [0] = 0
-
+if ((intmax_t *) 0)
+ return 0;
+if (sizeof (intmax_t))
+ return 0;
;
return 0;
}
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
- ac_hi=$ac_mid
+ ac_cv_type_intmax_t=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_intmax_t=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_intmax_t" >&5
+echo "${ECHO_T}$ac_cv_type_intmax_t" >&6
+
+
+fi # shortcircut to system "stdint.h"
+# ------------------ PREPARE VARIABLES ------------------------------
+if test "$GCC" = "yes" ; then
+ac_cv_stdint_message="using gnu compiler "`$CC --version | head -1`
+else
+ac_cv_stdint_message="using $CC"
+fi
+
+echo "$as_me:$LINENO: result: make use of $ac_cv_header_stdint in $ac_stdint_h $ac_cv_stdint_result" >&5
+echo "${ECHO_T}make use of $ac_cv_header_stdint in $ac_stdint_h $ac_cv_stdint_result" >&6
+
+# ----------------- DONE inttypes.h checks START header -------------
+ ac_config_commands="$ac_config_commands $ac_stdint_h"
+
+
+
+for ac_prog in ar
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_path_AR+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ case $AR in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_AR="$AR" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $LOCSYSPATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_AR="$as_dir/$ac_word$ac_exec_ext"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+ ;;
+esac
+fi
+AR=$ac_cv_path_AR
+
+if test -n "$AR"; then
+ echo "$as_me:$LINENO: result: $AR" >&5
+echo "${ECHO_T}$AR" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ test -n "$AR" && break
+done
+
+
+for ac_prog in gawk mawk nawk awk
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_AWK+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$AWK"; then
+ ac_cv_prog_AWK="$AWK" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_AWK="$ac_prog"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+AWK=$ac_cv_prog_AWK
+if test -n "$AWK"; then
+ echo "$as_me:$LINENO: result: $AWK" >&5
+echo "${ECHO_T}$AWK" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ test -n "$AWK" && break
+done
+
+
+
+ echo "$as_me:$LINENO: checking for $AWK command line variable assignment" >&5
+echo $ECHO_N "checking for $AWK command line variable assignment... $ECHO_C" >&6
+if test "${amanda_cv_awk_var_assignment+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ echo 'BEGIN{print i; exit}' > conftest.awk
+ result=`$AWK -f conftest.awk i=xx | wc -c`
+ if test "$result" -le 1; then
+ result=`$AWK -f conftest.awk -v i=xx | wc -c`
+ if test "$result" -le 1; then
+ amanda_cv_awk_var_assignment=no
+ else
+ amanda_cv_awk_var_assignment="yes with -v"
+ fi
+ else
+ amanda_cv_awk_var_assignment="yes"
+ fi
+ rm -fr conftest.awk
+
+
+fi
+echo "$as_me:$LINENO: result: $amanda_cv_awk_var_assignment" >&5
+echo "${ECHO_T}$amanda_cv_awk_var_assignment" >&6
+ AWK_VAR_ASSIGNMENT_OPT=
+ case "$amanda_cv_awk_var_assignment" in
+ no)
+ HAVE_AWK_WITH_VAR=no
+ ;;
+ yes)
+ HAVE_AWK_WITH_VAR=yes
+ ;;
+ "yes with -v")
+ HAVE_AWK_WITH_VAR=yes
+ AWK_VAR_ASSIGNMENT_OPT=-v
+ ;;
+ esac
+
+
+
+if test "x$amanda_cv_awk_var_assignment" = xno; then
+ NO_AMPLOT_MODE=true
+ { echo "$as_me:$LINENO: WARNING: *** Your $awk cannot do command line variable assignment. Amplot will not be installed." >&5
+echo "$as_me: WARNING: *** Your $awk cannot do command line variable assignment. Amplot will not be installed." >&2;}
+fi
+
+for ac_prog in 'bison -y' byacc
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_YACC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$YACC"; then
+ ac_cv_prog_YACC="$YACC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_YACC="$ac_prog"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+YACC=$ac_cv_prog_YACC
+if test -n "$YACC"; then
+ echo "$as_me:$LINENO: result: $YACC" >&5
+echo "${ECHO_T}$YACC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ test -n "$YACC" && break
+done
+test -n "$YACC" || YACC="yacc"
+
+for ac_prog in cat
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_path_CAT+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ case $CAT in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_CAT="$CAT" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $LOCSYSPATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_CAT="$as_dir/$ac_word$ac_exec_ext"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+ ;;
+esac
+fi
+CAT=$ac_cv_path_CAT
+
+if test -n "$CAT"; then
+ echo "$as_me:$LINENO: result: $CAT" >&5
+echo "${ECHO_T}$CAT" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ test -n "$CAT" && break
+done
+
+if test -z "$CAT"; then
+ CAT=cat
+fi
+for ac_prog in compress
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_path_COMPRESS+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ case $COMPRESS in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_COMPRESS="$COMPRESS" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $LOCSYSPATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_COMPRESS="$as_dir/$ac_word$ac_exec_ext"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+ ;;
+esac
+fi
+COMPRESS=$ac_cv_path_COMPRESS
+
+if test -n "$COMPRESS"; then
+ echo "$as_me:$LINENO: result: $COMPRESS" >&5
+echo "${ECHO_T}$COMPRESS" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ test -n "$COMPRESS" && break
+done
+
+for ac_prog in dd
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_path_DD+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ case $DD in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_DD="$DD" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $LOCSYSPATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_DD="$as_dir/$ac_word$ac_exec_ext"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+ ;;
+esac
+fi
+DD=$ac_cv_path_DD
+
+if test -n "$DD"; then
+ echo "$as_me:$LINENO: result: $DD" >&5
+echo "${ECHO_T}$DD" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ test -n "$DD" && break
+done
+
+for ac_prog in getconf
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_path_GETCONF+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ case $GETCONF in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_GETCONF="$GETCONF" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $SYSPATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_GETCONF="$as_dir/$ac_word$ac_exec_ext"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+ ;;
+esac
+fi
+GETCONF=$ac_cv_path_GETCONF
+
+if test -n "$GETCONF"; then
+ echo "$as_me:$LINENO: result: $GETCONF" >&5
+echo "${ECHO_T}$GETCONF" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ test -n "$GETCONF" && break
+done
+
+
+for ac_prog in gnuplot
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_path_GNUPLOT+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ case $GNUPLOT in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_GNUPLOT="$GNUPLOT" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $LOCSYSPATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_GNUPLOT="$as_dir/$ac_word$ac_exec_ext"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+ ;;
+esac
+fi
+GNUPLOT=$ac_cv_path_GNUPLOT
+
+if test -n "$GNUPLOT"; then
+ echo "$as_me:$LINENO: result: $GNUPLOT" >&5
+echo "${ECHO_T}$GNUPLOT" >&6
else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
-ac_lo=`expr '(' $ac_mid ')' + 1`
+ test -n "$GNUPLOT" && break
+done
+
+if test -z "$GNUPLOT"; then
+ NO_AMPLOT_MODE=true
+ { echo "$as_me:$LINENO: WARNING: *** You do not have gnuplot. Amplot will not be installed." >&5
+echo "$as_me: WARNING: *** You do not have gnuplot. Amplot will not be installed." >&2;}
fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+
+for ac_prog in gtar gnutar tar
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_path_GNUTAR+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ case $GNUTAR in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_GNUTAR="$GNUTAR" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $LOCSYSPATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_GNUTAR="$as_dir/$ac_word$ac_exec_ext"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
done
-case $ac_lo in
-?*) ac_cv_sizeof_voidp=$ac_lo;;
-'') { { echo "$as_me:$LINENO: error: cannot compute sizeof (void*), 77
-See \`config.log' for more details." >&5
-echo "$as_me: error: cannot compute sizeof (void*), 77
-See \`config.log' for more details." >&2;}
- { (exit 1); exit 1; }; } ;;
+done
+
+ ;;
esac
+fi
+GNUTAR=$ac_cv_path_GNUTAR
+
+if test -n "$GNUTAR"; then
+ echo "$as_me:$LINENO: result: $GNUTAR" >&5
+echo "${ECHO_T}$GNUTAR" >&6
else
- if test "$cross_compiling" = yes; then
- { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling
-See \`config.log' for more details." >&5
-echo "$as_me: error: cannot run test program while cross compiling
-See \`config.log' for more details." >&2;}
- { (exit 1); exit 1; }; }
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-long longval () { return (long) (sizeof (void*)); }
-unsigned long ulongval () { return (long) (sizeof (void*)); }
-#include <stdio.h>
-#include <stdlib.h>
-int
-main ()
-{
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
- FILE *f = fopen ("conftest.val", "w");
- if (! f)
- exit (1);
- if (((long) (sizeof (void*))) < 0)
- {
- long i = longval ();
- if (i != ((long) (sizeof (void*))))
- exit (1);
- fprintf (f, "%ld\n", i);
- }
- else
- {
- unsigned long i = ulongval ();
- if (i != ((long) (sizeof (void*))))
- exit (1);
- fprintf (f, "%lu\n", i);
- }
- exit (ferror (f) || fclose (f) != 0);
+ test -n "$GNUTAR" && break
+done
- ;
- return 0;
-}
+if test ! -z "$GNUTAR"; then
+ case "`\"$GNUTAR\" --version 2>&1`" in
+ *GNU*tar* | *Free*paxutils* )
+
+cat >>confdefs.h <<_ACEOF
+#define GNUTAR "$GNUTAR"
_ACEOF
-rm -f conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_sizeof_voidp=`cat conftest.val`
-else
- echo "$as_me: program exited with status $ac_status" >&5
-echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-( exit $ac_status )
-{ { echo "$as_me:$LINENO: error: cannot compute sizeof (void*), 77
-See \`config.log' for more details." >&5
-echo "$as_me: error: cannot compute sizeof (void*), 77
-See \`config.log' for more details." >&2;}
- { (exit 1); exit 1; }; }
-fi
-rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
-fi
+ ;;
+ *)
+ { echo "$as_me:$LINENO: WARNING: *** $GNUTAR is not GNU tar, so it will not be used." >&5
+echo "$as_me: WARNING: *** $GNUTAR is not GNU tar, so it will not be used." >&2;}
+ GNUTAR=
+ ;;
+ esac
fi
-rm -f conftest.val
+
+for ac_prog in smbclient
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_path_SAMBA_CLIENT+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
else
- ac_cv_sizeof_voidp=0
+ case $SAMBA_CLIENT in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_SAMBA_CLIENT="$SAMBA_CLIENT" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $LOCSYSPATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_SAMBA_CLIENT="$as_dir/$ac_word$ac_exec_ext"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+ ;;
+esac
fi
+SAMBA_CLIENT=$ac_cv_path_SAMBA_CLIENT
+
+if test -n "$SAMBA_CLIENT"; then
+ echo "$as_me:$LINENO: result: $SAMBA_CLIENT" >&5
+echo "${ECHO_T}$SAMBA_CLIENT" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
fi
-echo "$as_me:$LINENO: result: $ac_cv_sizeof_voidp" >&5
-echo "${ECHO_T}$ac_cv_sizeof_voidp" >&6
+
+ test -n "$SAMBA_CLIENT" && break
+done
+
+if test ! -z "$SAMBA_CLIENT"; then
+ case "`\"$SAMBA_CLIENT\" '\\\\not.a.host.name\\notashare' -U nosuchuser -N -Tx /dev/null 2>&1`" in
+ *"Unknown host"*)
+ smbversion=1
+ ;;
+ *"Connection to not.a.host.name failed"*)
+ smbversion=2
+ ;;
+ *)
+ { echo "$as_me:$LINENO: WARNING: *** $SAMBA_CLIENT does not seem to be smbclient, so it will not be used." >&5
+echo "$as_me: WARNING: *** $SAMBA_CLIENT does not seem to be smbclient, so it will not be used." >&2;}
+ SAMBA_CLIENT=
+ ;;
+ esac
+ if test -n "$SAMBA_CLIENT"; then
+
cat >>confdefs.h <<_ACEOF
-#define SIZEOF_VOIDP $ac_cv_sizeof_voidp
+#define SAMBA_CLIENT "$SAMBA_CLIENT"
_ACEOF
- ac_cv_char_data_model=""
- ac_cv_char_data_model="$ac_cv_char_data_model$ac_cv_sizeof_char"
- ac_cv_char_data_model="$ac_cv_char_data_model$ac_cv_sizeof_short"
- ac_cv_char_data_model="$ac_cv_char_data_model$ac_cv_sizeof_int"
- ac_cv_long_data_model=""
- ac_cv_long_data_model="$ac_cv_long_data_model$ac_cv_sizeof_int"
- ac_cv_long_data_model="$ac_cv_long_data_model$ac_cv_sizeof_long"
- ac_cv_long_data_model="$ac_cv_long_data_model$ac_cv_sizeof_voidp"
- echo "$as_me:$LINENO: checking data model" >&5
-echo $ECHO_N "checking data model... $ECHO_C" >&6
- case "$ac_cv_char_data_model/$ac_cv_long_data_model" in
- 122/242) ac_cv_data_model="IP16" ; n="standard 16bit machine" ;;
- 122/244) ac_cv_data_model="LP32" ; n="standard 32bit machine" ;;
- 122/*) ac_cv_data_model="i16" ; n="unusual int16 model" ;;
- 124/444) ac_cv_data_model="ILP32" ; n="standard 32bit unixish" ;;
- 124/488) ac_cv_data_model="LP64" ; n="standard 64bit unixish" ;;
- 124/448) ac_cv_data_model="LLP64" ; n="unusual 64bit unixish" ;;
- 124/*) ac_cv_data_model="i32" ; n="unusual int32 model" ;;
- 128/888) ac_cv_data_model="ILP64" ; n="unusual 64bit numeric" ;;
- 128/*) ac_cv_data_model="i64" ; n="unusual int64 model" ;;
- 222/*2) ac_cv_data_model="DSP16" ; n="strict 16bit dsptype" ;;
- 333/*3) ac_cv_data_model="DSP24" ; n="strict 24bit dsptype" ;;
- 444/*4) ac_cv_data_model="DSP32" ; n="strict 32bit dsptype" ;;
- 666/*6) ac_cv_data_model="DSP48" ; n="strict 48bit dsptype" ;;
- 888/*8) ac_cv_data_model="DSP64" ; n="strict 64bit dsptype" ;;
- 222/*|333/*|444/*|666/*|888/*) :
- ac_cv_data_model="iDSP" ; n="unusual dsptype" ;;
- *) ac_cv_data_model="none" ; n="very unusual model" ;;
- esac
- echo "$as_me:$LINENO: result: $ac_cv_data_model ($ac_cv_long_data_model, $n)" >&5
-echo "${ECHO_T}$ac_cv_data_model ($ac_cv_long_data_model, $n)" >&6
+cat >>confdefs.h <<_ACEOF
+#define SAMBA_VERSION $smbversion
+_ACEOF
+ fi
fi
-if test "_$ac_cv_header_stdint_x" != "_" ; then
- ac_cv_header_stdint="$ac_cv_header_stdint_x"
-elif test "_$ac_cv_header_stdint_o" != "_" ; then
- ac_cv_header_stdint="$ac_cv_header_stdint_o"
-elif test "_$ac_cv_header_stdint_u" != "_" ; then
- ac_cv_header_stdint="$ac_cv_header_stdint_u"
+for ac_prog in gzip
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_path_GZIP+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
else
- ac_cv_header_stdint="stddef.h"
+ case $GZIP in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_GZIP="$GZIP" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $LOCSYSPATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_GZIP="$as_dir/$ac_word$ac_exec_ext"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+ ;;
+esac
fi
+GZIP=$ac_cv_path_GZIP
-echo "$as_me:$LINENO: checking for extra inttypes in chosen header" >&5
-echo $ECHO_N "checking for extra inttypes in chosen header... $ECHO_C" >&6
-echo "$as_me:$LINENO: result: ($ac_cv_header_stdint)" >&5
-echo "${ECHO_T}($ac_cv_header_stdint)" >&6
-unset ac_cv_type_int_least32_t
-unset ac_cv_type_int_fast32_t
-echo "$as_me:$LINENO: checking for int_least32_t" >&5
-echo $ECHO_N "checking for int_least32_t... $ECHO_C" >&6
-if test "${ac_cv_type_int_least32_t+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+if test -n "$GZIP"; then
+ echo "$as_me:$LINENO: result: $GZIP" >&5
+echo "${ECHO_T}$GZIP" >&6
else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <$ac_cv_header_stdint>
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
-int
-main ()
-{
-if ((int_least32_t *) 0)
- return 0;
-if (sizeof (int_least32_t))
- return 0;
- ;
- return 0;
-}
+ test -n "$GZIP" && break
+done
+
+if test "$GZIP"; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_GZIP 1
_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_type_int_least32_t=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-ac_cv_type_int_least32_t=no
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ COMPRESS_PATH="$GZIP"
+ COMPRESS_SUFFIX=".gz"
+ COMPRESS_FAST_OPT="--fast"
+ COMPRESS_BEST_OPT="--best"
+ UNCOMPRESS_PATH="$GZIP"
+ UNCOMPRESS_OPT="-dc"
+else
+ if test "$COMPRESS"; then
+ COMPRESS_PATH="$COMPRESS"
+ COMPRESS_SUFFIX=".Z"
+ COMPRESS_FAST_OPT="-f"
+ COMPRESS_BEST_OPT="-f"
+ UNCOMPRESS_PATH="$COMPRESS"
+ UNCOMPRESS_OPT="-dc"
+ else
+ { echo "$as_me:$LINENO: WARNING: *** Cannot find either gzip or compress. Using cat. ***" >&5
+echo "$as_me: WARNING: *** Cannot find either gzip or compress. Using cat. ***" >&2;}
+ COMPRESS_PATH="$CAT"
+ COMPRESS_SUFFIX=""
+ COMPRESS_FAST_OPT=""
+ COMPRESS_BEST_OPT=""
+ UNCOMPRESS_PATH="$CAT"
+ UNCOMPRESS_OPT=""
+ fi
fi
-echo "$as_me:$LINENO: result: $ac_cv_type_int_least32_t" >&5
-echo "${ECHO_T}$ac_cv_type_int_least32_t" >&6
-echo "$as_me:$LINENO: checking for int_fast32_t" >&5
-echo $ECHO_N "checking for int_fast32_t... $ECHO_C" >&6
-if test "${ac_cv_type_int_fast32_t+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
+cat >>confdefs.h <<_ACEOF
+#define COMPRESS_PATH "$COMPRESS_PATH"
_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include<$ac_cv_header_stdint>
-int
-main ()
-{
-if ((int_fast32_t *) 0)
- return 0;
-if (sizeof (int_fast32_t))
- return 0;
- ;
- return 0;
-}
+
+cat >>confdefs.h <<_ACEOF
+#define COMPRESS_SUFFIX "$COMPRESS_SUFFIX"
_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_type_int_fast32_t=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-ac_cv_type_int_fast32_t=no
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-echo "$as_me:$LINENO: result: $ac_cv_type_int_fast32_t" >&5
-echo "${ECHO_T}$ac_cv_type_int_fast32_t" >&6
-echo "$as_me:$LINENO: checking for intmax_t" >&5
-echo $ECHO_N "checking for intmax_t... $ECHO_C" >&6
-if test "${ac_cv_type_intmax_t+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
+cat >>confdefs.h <<_ACEOF
+#define COMPRESS_FAST_OPT "$COMPRESS_FAST_OPT"
_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <$ac_cv_header_stdint>
-int
-main ()
-{
-if ((intmax_t *) 0)
- return 0;
-if (sizeof (intmax_t))
- return 0;
- ;
- return 0;
-}
+
+cat >>confdefs.h <<_ACEOF
+#define COMPRESS_BEST_OPT "$COMPRESS_BEST_OPT"
_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_type_intmax_t=yes
+
+
+cat >>confdefs.h <<_ACEOF
+#define UNCOMPRESS_PATH "$UNCOMPRESS_PATH"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define UNCOMPRESS_OPT "$UNCOMPRESS_OPT"
+_ACEOF
+
+
+for ac_prog in Mail mailx mail
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_path_MAILER+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
+ case $MAILER in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_MAILER="$MAILER" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_MAILER="$as_dir/$ac_word$ac_exec_ext"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
-ac_cv_type_intmax_t=no
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ ;;
+esac
fi
-echo "$as_me:$LINENO: result: $ac_cv_type_intmax_t" >&5
-echo "${ECHO_T}$ac_cv_type_intmax_t" >&6
-
+MAILER=$ac_cv_path_MAILER
-fi # shortcircut to system "stdint.h"
-# ------------------ PREPARE VARIABLES ------------------------------
-if test "$GCC" = "yes" ; then
-ac_cv_stdint_message="using gnu compiler "`$CC --version | head -1`
+if test -n "$MAILER"; then
+ echo "$as_me:$LINENO: result: $MAILER" >&5
+echo "${ECHO_T}$MAILER" >&6
else
-ac_cv_stdint_message="using $CC"
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
fi
-echo "$as_me:$LINENO: result: make use of $ac_cv_header_stdint in $ac_stdint_h $ac_cv_stdint_result" >&5
-echo "${ECHO_T}make use of $ac_cv_header_stdint in $ac_stdint_h $ac_cv_stdint_result" >&6
+ test -n "$MAILER" && break
+done
-# ----------------- DONE inttypes.h checks START header -------------
- ac_config_commands="$ac_config_commands $ac_stdint_h"
+if test -z "$MAILER"; then
+ if $NO_SERVER_MODE; then
+ MAILER="NONE"
+ { echo "$as_me:$LINENO: WARNING: *** WARNING: Amanda cannot send mail reports without these programs." >&5
+echo "$as_me: WARNING: *** WARNING: Amanda cannot send mail reports without these programs." >&2;}
+ else
+ { { echo "$as_me:$LINENO: error: Set MAILER to some program that accepts -s subject user < message_file." >&5
+echo "$as_me: error: Set MAILER to some program that accepts -s subject user < message_file." >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+fi
+cat >>confdefs.h <<_ACEOF
+#define MAILER "$MAILER"
+_ACEOF
-for ac_prog in ar
+for ac_prog in mt
do
# Extract the first word of "$ac_prog", so it can be a program name with args.
set dummy $ac_prog; ac_word=$2
echo "$as_me:$LINENO: checking for $ac_word" >&5
echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_path_AR+set}" = set; then
+if test "${ac_cv_path_MT+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
- case $AR in
+ case $MT in
[\\/]* | ?:[\\/]*)
- ac_cv_path_AR="$AR" # Let the user override the test with a path.
+ ac_cv_path_MT="$MT" # Let the user override the test with a path.
;;
*)
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- ac_cv_path_AR="$as_dir/$ac_word$ac_exec_ext"
+ ac_cv_path_MT="$as_dir/$ac_word$ac_exec_ext"
echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
;;
esac
fi
-AR=$ac_cv_path_AR
+MT=$ac_cv_path_MT
-if test -n "$AR"; then
- echo "$as_me:$LINENO: result: $AR" >&5
-echo "${ECHO_T}$AR" >&6
+if test -n "$MT"; then
+ echo "$as_me:$LINENO: result: $MT" >&5
+echo "${ECHO_T}$MT" >&6
else
echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6
fi
- test -n "$AR" && break
+ test -n "$MT" && break
done
+test -n "$MT" || MT="mt"
-for ac_prog in gawk mawk nawk awk
+for ac_prog in chio
do
# Extract the first word of "$ac_prog", so it can be a program name with args.
set dummy $ac_prog; ac_word=$2
echo "$as_me:$LINENO: checking for $ac_word" >&5
echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_prog_AWK+set}" = set; then
+if test "${ac_cv_path_CHIO+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
- if test -n "$AWK"; then
- ac_cv_prog_AWK="$AWK" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
+ case $CHIO in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_CHIO="$CHIO" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $LOCSYSPATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- ac_cv_prog_AWK="$ac_prog"
+ ac_cv_path_CHIO="$as_dir/$ac_word$ac_exec_ext"
echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
done
done
+ ;;
+esac
fi
-fi
-AWK=$ac_cv_prog_AWK
-if test -n "$AWK"; then
- echo "$as_me:$LINENO: result: $AWK" >&5
-echo "${ECHO_T}$AWK" >&6
+CHIO=$ac_cv_path_CHIO
+
+if test -n "$CHIO"; then
+ echo "$as_me:$LINENO: result: $CHIO" >&5
+echo "${ECHO_T}$CHIO" >&6
else
echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6
fi
- test -n "$AWK" && break
+ test -n "$CHIO" && break
done
+test -n "$CHIO" || CHIO="chio"
-
- echo "$as_me:$LINENO: checking for $AWK command line variable assignment" >&5
-echo $ECHO_N "checking for $AWK command line variable assignment... $ECHO_C" >&6
-if test "${amanda_cv_awk_var_assignment+set}" = set; then
+for ac_prog in chs
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_path_CHS+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
+ case $CHS in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_CHS="$CHS" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $LOCSYSPATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_CHS="$as_dir/$ac_word$ac_exec_ext"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
- echo 'BEGIN{print i; exit}' > conftest.awk
- result=`$AWK -f conftest.awk i=xx | wc -c`
- if test "$result" -le 1; then
- result=`$AWK -f conftest.awk -v i=xx | wc -c`
- if test "$result" -le 1; then
- amanda_cv_awk_var_assignment=no
- else
- amanda_cv_awk_var_assignment="yes with -v"
- fi
- else
- amanda_cv_awk_var_assignment="yes"
- fi
- rm -fr conftest.awk
-
+ ;;
+esac
+fi
+CHS=$ac_cv_path_CHS
+if test -n "$CHS"; then
+ echo "$as_me:$LINENO: result: $CHS" >&5
+echo "${ECHO_T}$CHS" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
fi
-echo "$as_me:$LINENO: result: $amanda_cv_awk_var_assignment" >&5
-echo "${ECHO_T}$amanda_cv_awk_var_assignment" >&6
- AWK_VAR_ASSIGNMENT_OPT=
- case "$amanda_cv_awk_var_assignment" in
- no)
- HAVE_AWK_WITH_VAR=no
- ;;
- yes)
- HAVE_AWK_WITH_VAR=yes
- ;;
- "yes with -v")
- HAVE_AWK_WITH_VAR=yes
- AWK_VAR_ASSIGNMENT_OPT=-v
- ;;
- esac
+ test -n "$CHS" && break
+done
+test -n "$CHS" || CHS="chs"
-if test "x$amanda_cv_awk_var_assignment" = xno; then
- NO_AMPLOT_MODE=true
- { echo "$as_me:$LINENO: WARNING: *** Your $awk cannot do command line variable assignment. Amplot will not be installed." >&5
-echo "$as_me: WARNING: *** Your $awk cannot do command line variable assignment. Amplot will not be installed." >&2;}
+for ac_prog in mtx
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_path_MTX+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ case $MTX in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_MTX="$MTX" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $LOCSYSPATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_MTX="$as_dir/$ac_word$ac_exec_ext"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+ ;;
+esac
fi
+MTX=$ac_cv_path_MTX
-for ac_prog in 'bison -y' byacc
+if test -n "$MTX"; then
+ echo "$as_me:$LINENO: result: $MTX" >&5
+echo "${ECHO_T}$MTX" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ test -n "$MTX" && break
+done
+test -n "$MTX" || MTX="mtx"
+
+
+for ac_prog in mcutil
do
# Extract the first word of "$ac_prog", so it can be a program name with args.
set dummy $ac_prog; ac_word=$2
echo "$as_me:$LINENO: checking for $ac_word" >&5
echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_prog_YACC+set}" = set; then
+if test "${ac_cv_path_MCUTIL+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
- if test -n "$YACC"; then
- ac_cv_prog_YACC="$YACC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
+ case $MCUTIL in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_MCUTIL="$MCUTIL" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $LOCSYSPATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- ac_cv_prog_YACC="$ac_prog"
+ ac_cv_path_MCUTIL="$as_dir/$ac_word$ac_exec_ext"
echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
done
done
+ ;;
+esac
fi
-fi
-YACC=$ac_cv_prog_YACC
-if test -n "$YACC"; then
- echo "$as_me:$LINENO: result: $YACC" >&5
-echo "${ECHO_T}$YACC" >&6
+MCUTIL=$ac_cv_path_MCUTIL
+
+if test -n "$MCUTIL"; then
+ echo "$as_me:$LINENO: result: $MCUTIL" >&5
+echo "${ECHO_T}$MCUTIL" >&6
else
echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6
fi
- test -n "$YACC" && break
+ test -n "$MCUTIL" && break
done
-test -n "$YACC" || YACC="yacc"
+test -n "$MCUTIL" || MCUTIL="mcutil"
-for ac_prog in cat
+
+for ac_prog in lpr lp
do
# Extract the first word of "$ac_prog", so it can be a program name with args.
set dummy $ac_prog; ac_word=$2
echo "$as_me:$LINENO: checking for $ac_word" >&5
echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_path_CAT+set}" = set; then
+if test "${ac_cv_path_PRINT+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
- case $CAT in
+ case $PRINT in
[\\/]* | ?:[\\/]*)
- ac_cv_path_CAT="$CAT" # Let the user override the test with a path.
+ ac_cv_path_PRINT="$PRINT" # Let the user override the test with a path.
;;
*)
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $LOCSYSPATH
+for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- ac_cv_path_CAT="$as_dir/$ac_word$ac_exec_ext"
+ ac_cv_path_PRINT="$as_dir/$ac_word$ac_exec_ext"
echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
;;
esac
fi
-CAT=$ac_cv_path_CAT
+PRINT=$ac_cv_path_PRINT
-if test -n "$CAT"; then
- echo "$as_me:$LINENO: result: $CAT" >&5
-echo "${ECHO_T}$CAT" >&6
+if test -n "$PRINT"; then
+ echo "$as_me:$LINENO: result: $PRINT" >&5
+echo "${ECHO_T}$PRINT" >&6
else
echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6
fi
- test -n "$CAT" && break
+ test -n "$PRINT" && break
done
-if test -z "$CAT"; then
- CAT=cat
+if test ! -z "$PRINT"; then
+
+cat >>confdefs.h <<_ACEOF
+#define LPRCMD "$PRINT"
+_ACEOF
+
+ echo "$as_me:$LINENO: checking which flag to use to select a printer" >&5
+echo $ECHO_N "checking which flag to use to select a printer... $ECHO_C" >&6
+if test "${amanda_cv_printer_flag+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ amanda_cv_printer_flag=$PRINTER_FLAG
+ case "$PRINT" in
+ lpr|*/lpr) amanda_cv_printer_flag="-P";;
+ lp|*/lp) amanda_cv_printer_flag="-d";;
+ esac
+
fi
-for ac_prog in compress
+echo "$as_me:$LINENO: result: $amanda_cv_printer_flag" >&5
+echo "${ECHO_T}$amanda_cv_printer_flag" >&6
+ if test ! -z "$amanda_cv_printer_flag"; then
+
+cat >>confdefs.h <<_ACEOF
+#define LPRFLAG "$amanda_cv_printer_flag"
+_ACEOF
+
+ else
+ { echo "$as_me:$LINENO: WARNING: *** WARNING: amanda will always print to the default printer" >&5
+echo "$as_me: WARNING: *** WARNING: amanda will always print to the default printer" >&2;}
+ fi
+fi
+
+for ac_prog in pcat
do
# Extract the first word of "$ac_prog", so it can be a program name with args.
set dummy $ac_prog; ac_word=$2
echo "$as_me:$LINENO: checking for $ac_word" >&5
echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_path_COMPRESS+set}" = set; then
+if test "${ac_cv_path_PCAT+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
- case $COMPRESS in
+ case $PCAT in
[\\/]* | ?:[\\/]*)
- ac_cv_path_COMPRESS="$COMPRESS" # Let the user override the test with a path.
+ ac_cv_path_PCAT="$PCAT" # Let the user override the test with a path.
;;
*)
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- ac_cv_path_COMPRESS="$as_dir/$ac_word$ac_exec_ext"
+ ac_cv_path_PCAT="$as_dir/$ac_word$ac_exec_ext"
echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
;;
esac
fi
-COMPRESS=$ac_cv_path_COMPRESS
+PCAT=$ac_cv_path_PCAT
-if test -n "$COMPRESS"; then
- echo "$as_me:$LINENO: result: $COMPRESS" >&5
-echo "${ECHO_T}$COMPRESS" >&6
+if test -n "$PCAT"; then
+ echo "$as_me:$LINENO: result: $PCAT" >&5
+echo "${ECHO_T}$PCAT" >&6
else
echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6
fi
- test -n "$COMPRESS" && break
+ test -n "$PCAT" && break
done
-for ac_prog in dd
+for ac_prog in perl5 perl
do
# Extract the first word of "$ac_prog", so it can be a program name with args.
set dummy $ac_prog; ac_word=$2
echo "$as_me:$LINENO: checking for $ac_word" >&5
echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_path_DD+set}" = set; then
+if test "${ac_cv_path_PERL+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
- case $DD in
+ case $PERL in
[\\/]* | ?:[\\/]*)
- ac_cv_path_DD="$DD" # Let the user override the test with a path.
+ ac_cv_path_PERL="$PERL" # Let the user override the test with a path.
;;
*)
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- ac_cv_path_DD="$as_dir/$ac_word$ac_exec_ext"
+ ac_cv_path_PERL="$as_dir/$ac_word$ac_exec_ext"
echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
;;
esac
fi
-DD=$ac_cv_path_DD
+PERL=$ac_cv_path_PERL
-if test -n "$DD"; then
- echo "$as_me:$LINENO: result: $DD" >&5
-echo "${ECHO_T}$DD" >&6
+if test -n "$PERL"; then
+ echo "$as_me:$LINENO: result: $PERL" >&5
+echo "${ECHO_T}$PERL" >&6
else
echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6
fi
- test -n "$DD" && break
+ test -n "$PERL" && break
done
-for ac_prog in egrep
+
+
+for ac_prog in $DUMP_PROGRAMS
do
# Extract the first word of "$ac_prog", so it can be a program name with args.
set dummy $ac_prog; ac_word=$2
echo "$as_me:$LINENO: checking for $ac_word" >&5
echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_path_EGREP+set}" = set; then
+if test "${ac_cv_path_DUMP+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
- case $EGREP in
+ case $DUMP in
[\\/]* | ?:[\\/]*)
- ac_cv_path_EGREP="$EGREP" # Let the user override the test with a path.
+ ac_cv_path_DUMP="$DUMP" # Let the user override the test with a path.
;;
*)
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $LOCSYSPATH
+for as_dir in $SYSLOCPATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- ac_cv_path_EGREP="$as_dir/$ac_word$ac_exec_ext"
+ ac_cv_path_DUMP="$as_dir/$ac_word$ac_exec_ext"
echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
;;
esac
fi
-EGREP=$ac_cv_path_EGREP
+DUMP=$ac_cv_path_DUMP
-if test -n "$EGREP"; then
- echo "$as_me:$LINENO: result: $EGREP" >&5
-echo "${ECHO_T}$EGREP" >&6
+if test -n "$DUMP"; then
+ echo "$as_me:$LINENO: result: $DUMP" >&5
+echo "${ECHO_T}$DUMP" >&6
else
echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6
fi
- test -n "$EGREP" && break
+ test -n "$DUMP" && break
done
-for ac_prog in getconf
+for ac_prog in ufsrestore restore
do
# Extract the first word of "$ac_prog", so it can be a program name with args.
set dummy $ac_prog; ac_word=$2
echo "$as_me:$LINENO: checking for $ac_word" >&5
echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_path_GETCONF+set}" = set; then
+if test "${ac_cv_path_RESTORE+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
- case $GETCONF in
+ case $RESTORE in
[\\/]* | ?:[\\/]*)
- ac_cv_path_GETCONF="$GETCONF" # Let the user override the test with a path.
+ ac_cv_path_RESTORE="$RESTORE" # Let the user override the test with a path.
;;
*)
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $SYSPATH
+for as_dir in $SYSLOCPATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- ac_cv_path_GETCONF="$as_dir/$ac_word$ac_exec_ext"
+ ac_cv_path_RESTORE="$as_dir/$ac_word$ac_exec_ext"
echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
done
done
- ;;
-esac
+ ;;
+esac
+fi
+RESTORE=$ac_cv_path_RESTORE
+
+if test -n "$RESTORE"; then
+ echo "$as_me:$LINENO: result: $RESTORE" >&5
+echo "${ECHO_T}$RESTORE" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ test -n "$RESTORE" && break
+done
+
+if test "$DUMP" -a "$RESTORE"; then
+
+cat >>confdefs.h <<_ACEOF
+#define DUMP "$DUMP"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define RESTORE "$RESTORE"
+_ACEOF
+
+ if test -x $DUMP; then
+ echo "$as_me:$LINENO: checking whether $DUMP supports -E or -S for estimates" >&5
+echo $ECHO_N "checking whether $DUMP supports -E or -S for estimates... $ECHO_C" >&6
+if test "${amanda_cv_dump_estimate+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ case "$DUMP" in
+ *dump)
+ { ac_try='$DUMP 9Ef /dev/null /dev/null/invalid/fs 2>&1
+ | $GREP -v Dumping
+ | $GREP -v Date
+ | $GREP -v Label >conftest.d-E 2>&1'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }
+ cat conftest.d-E >&5
+ { ac_try='$DUMP 9Sf /dev/null /dev/null/invalid/fs 2>&1
+ | $GREP -v Dumping
+ | $GREP -v Date
+ | $GREP -v Label >conftest.d-S 2>&1'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }
+ cat conftest.d-S >&5
+ { ac_try='$DUMP 9f /dev/null /dev/null/invalid/fs 2>&1
+ | $GREP -v Dumping
+ | $GREP -v Date
+ | $GREP -v Label >conftest.d 2>&1'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }
+ cat conftest.d >&5
+ if { ac_try='cmp conftest.d-E conftest.d 1>&2'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ amanda_cv_dump_estimate=E
+ elif { ac_try='cmp conftest.d-S conftest.d 1>&2'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ amanda_cv_dump_estimate=S
+ else
+ amanda_cv_dump_estimate=no
+ fi
+ rm -f conftest.d conftest.d-E conftest.d-S
+ ;;
+ *) amanda_cv_dump_estimate=no
+ ;;
+ esac
+
+fi
+echo "$as_me:$LINENO: result: $amanda_cv_dump_estimate" >&5
+echo "${ECHO_T}$amanda_cv_dump_estimate" >&6
+ else
+ { echo "$as_me:$LINENO: WARNING: *** $DUMP is not executable, cannot run -E/-S test" >&5
+echo "$as_me: WARNING: *** $DUMP is not executable, cannot run -E/-S test" >&2;}
+ amanda_cv_dump_estimate=no
+ fi
+ if test "x$amanda_cv_dump_estimate" != xno; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DUMP_ESTIMATE "$amanda_cv_dump_estimate"
+_ACEOF
+
+ fi
+
+
+# Check whether --with-dump-honor-nodump or --without-dump-honor-nodump was given.
+if test "${with_dump_honor_nodump+set}" = set; then
+ withval="$with_dump_honor_nodump"
+ if test -x $DUMP; then
+ echo "$as_me:$LINENO: checking whether $DUMP supports -h (honor nodump flag)" >&5
+echo $ECHO_N "checking whether $DUMP supports -h (honor nodump flag)... $ECHO_C" >&6
+if test "${amanda_cv_honor_nodump+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ case "$DUMP" in
+ *dump)
+ { ac_try='$DUMP 9hf 0 /dev/null /dev/null/invalid/fs 2>&1
+ | $GREP -v Dumping
+ | $GREP -v Date
+ | $GREP -v Label >conftest.d-h 2>&1'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }
+ cat conftest.d-h >&5
+ { ac_try='$DUMP 9f /dev/null /dev/null/invalid/fs 2>&1
+ | $GREP -v Dumping
+ | $GREP -v Date
+ | $GREP -v Label >conftest.d 2>&1'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }
+ cat conftest.d >&5
+ if { ac_try='diff conftest.d-h conftest.d 1>&2'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ amanda_cv_honor_nodump=yes
+ else
+ amanda_cv_honor_nodump=no
+ fi
+ rm -f conftest.d conftest.d-h
+ ;;
+ *) amanda_cv_honor_nodump=no
+ ;;
+ esac
+
fi
-GETCONF=$ac_cv_path_GETCONF
+echo "$as_me:$LINENO: result: $amanda_cv_honor_nodump" >&5
+echo "${ECHO_T}$amanda_cv_honor_nodump" >&6
+ else
+ { echo "$as_me:$LINENO: WARNING: *** $DUMP is not executable, cannot run -h test" >&5
+echo "$as_me: WARNING: *** $DUMP is not executable, cannot run -h test" >&2;}
+ amanda_cv_honor_nodump=no
+ fi
+ if test "x$amanda_cv_honor_nodump" = xyes; then
-if test -n "$GETCONF"; then
- echo "$as_me:$LINENO: result: $GETCONF" >&5
-echo "${ECHO_T}$GETCONF" >&6
-else
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
-fi
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_HONOR_NODUMP 1
+_ACEOF
- test -n "$GETCONF" && break
-done
+ fi
+fi;
+fi
-for ac_prog in gnuplot
+for ac_prog in xfsdump
do
# Extract the first word of "$ac_prog", so it can be a program name with args.
set dummy $ac_prog; ac_word=$2
echo "$as_me:$LINENO: checking for $ac_word" >&5
echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_path_GNUPLOT+set}" = set; then
+if test "${ac_cv_path_XFSDUMP+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
- case $GNUPLOT in
+ case $XFSDUMP in
[\\/]* | ?:[\\/]*)
- ac_cv_path_GNUPLOT="$GNUPLOT" # Let the user override the test with a path.
+ ac_cv_path_XFSDUMP="$XFSDUMP" # Let the user override the test with a path.
;;
*)
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $LOCSYSPATH
+for as_dir in $SYSLOCPATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- ac_cv_path_GNUPLOT="$as_dir/$ac_word$ac_exec_ext"
+ ac_cv_path_XFSDUMP="$as_dir/$ac_word$ac_exec_ext"
echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
;;
esac
fi
-GNUPLOT=$ac_cv_path_GNUPLOT
+XFSDUMP=$ac_cv_path_XFSDUMP
-if test -n "$GNUPLOT"; then
- echo "$as_me:$LINENO: result: $GNUPLOT" >&5
-echo "${ECHO_T}$GNUPLOT" >&6
+if test -n "$XFSDUMP"; then
+ echo "$as_me:$LINENO: result: $XFSDUMP" >&5
+echo "${ECHO_T}$XFSDUMP" >&6
else
echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6
fi
- test -n "$GNUPLOT" && break
+ test -n "$XFSDUMP" && break
done
-if test -z "$GNUPLOT"; then
- NO_AMPLOT_MODE=true
- { echo "$as_me:$LINENO: WARNING: *** You do not have gnuplot. Amplot will not be installed." >&5
-echo "$as_me: WARNING: *** You do not have gnuplot. Amplot will not be installed." >&2;}
-fi
-
-for ac_prog in grep
+for ac_prog in xfsrestore
do
# Extract the first word of "$ac_prog", so it can be a program name with args.
set dummy $ac_prog; ac_word=$2
echo "$as_me:$LINENO: checking for $ac_word" >&5
echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_path_GREP+set}" = set; then
+if test "${ac_cv_path_XFSRESTORE+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
- case $GREP in
+ case $XFSRESTORE in
[\\/]* | ?:[\\/]*)
- ac_cv_path_GREP="$GREP" # Let the user override the test with a path.
+ ac_cv_path_XFSRESTORE="$XFSRESTORE" # Let the user override the test with a path.
;;
*)
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $LOCSYSPATH
+for as_dir in $SYSLOCPATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- ac_cv_path_GREP="$as_dir/$ac_word$ac_exec_ext"
+ ac_cv_path_XFSRESTORE="$as_dir/$ac_word$ac_exec_ext"
echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
;;
esac
fi
-GREP=$ac_cv_path_GREP
+XFSRESTORE=$ac_cv_path_XFSRESTORE
-if test -n "$GREP"; then
- echo "$as_me:$LINENO: result: $GREP" >&5
-echo "${ECHO_T}$GREP" >&6
+if test -n "$XFSRESTORE"; then
+ echo "$as_me:$LINENO: result: $XFSRESTORE" >&5
+echo "${ECHO_T}$XFSRESTORE" >&6
else
echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6
fi
- test -n "$GREP" && break
+ test -n "$XFSRESTORE" && break
done
-if test -z "$GREP"; then
- GREP=grep
-fi
+if test "$XFSDUMP" -a "$XFSRESTORE"; then
cat >>confdefs.h <<_ACEOF
-#define GREP "$GREP"
+#define XFSDUMP "$XFSDUMP"
_ACEOF
-for ac_prog in gtar gnutar tar
+cat >>confdefs.h <<_ACEOF
+#define XFSRESTORE "$XFSRESTORE"
+_ACEOF
+
+ { echo "$as_me:$LINENO: WARNING: *** xfsdump causes the setuid-root rundump program to be enabled" >&5
+echo "$as_me: WARNING: *** xfsdump causes the setuid-root rundump program to be enabled" >&2;}
+ { echo "$as_me:$LINENO: WARNING: *** to disable it, just #undef XFSDUMP in config/config.h" >&5
+echo "$as_me: WARNING: *** to disable it, just #undef XFSDUMP in config/config.h" >&2;}
+fi
+
+VXSYSLOCPATH="$SYSLOCPATH:/usr/lib/fs/vxfs"
+for ac_prog in vxdump
do
# Extract the first word of "$ac_prog", so it can be a program name with args.
set dummy $ac_prog; ac_word=$2
echo "$as_me:$LINENO: checking for $ac_word" >&5
echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_path_GNUTAR+set}" = set; then
+if test "${ac_cv_path_VXDUMP+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
- case $GNUTAR in
+ case $VXDUMP in
[\\/]* | ?:[\\/]*)
- ac_cv_path_GNUTAR="$GNUTAR" # Let the user override the test with a path.
+ ac_cv_path_VXDUMP="$VXDUMP" # Let the user override the test with a path.
;;
*)
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $LOCSYSPATH
+for as_dir in $VXSYSLOCPATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- ac_cv_path_GNUTAR="$as_dir/$ac_word$ac_exec_ext"
+ ac_cv_path_VXDUMP="$as_dir/$ac_word$ac_exec_ext"
echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
;;
esac
fi
-GNUTAR=$ac_cv_path_GNUTAR
+VXDUMP=$ac_cv_path_VXDUMP
-if test -n "$GNUTAR"; then
- echo "$as_me:$LINENO: result: $GNUTAR" >&5
-echo "${ECHO_T}$GNUTAR" >&6
+if test -n "$VXDUMP"; then
+ echo "$as_me:$LINENO: result: $VXDUMP" >&5
+echo "${ECHO_T}$VXDUMP" >&6
else
echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6
fi
- test -n "$GNUTAR" && break
+ test -n "$VXDUMP" && break
done
-if test ! -z "$GNUTAR"; then
- case "`\"$GNUTAR\" --version 2>&1`" in
- *GNU*tar* | *Free*paxutils* )
-
-cat >>confdefs.h <<_ACEOF
-#define GNUTAR "$GNUTAR"
-_ACEOF
-
- ;;
- *)
- { echo "$as_me:$LINENO: WARNING: *** $GNUTAR is not GNU tar, so it will not be used." >&5
-echo "$as_me: WARNING: *** $GNUTAR is not GNU tar, so it will not be used." >&2;}
- GNUTAR=
- ;;
- esac
-fi
-
-for ac_prog in smbclient
+for ac_prog in vxrestore
do
# Extract the first word of "$ac_prog", so it can be a program name with args.
set dummy $ac_prog; ac_word=$2
echo "$as_me:$LINENO: checking for $ac_word" >&5
echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_path_SAMBA_CLIENT+set}" = set; then
+if test "${ac_cv_path_VXRESTORE+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
- case $SAMBA_CLIENT in
+ case $VXRESTORE in
[\\/]* | ?:[\\/]*)
- ac_cv_path_SAMBA_CLIENT="$SAMBA_CLIENT" # Let the user override the test with a path.
+ ac_cv_path_VXRESTORE="$VXRESTORE" # Let the user override the test with a path.
;;
*)
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $LOCSYSPATH
+for as_dir in $VXSYSLOCPATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- ac_cv_path_SAMBA_CLIENT="$as_dir/$ac_word$ac_exec_ext"
+ ac_cv_path_VXRESTORE="$as_dir/$ac_word$ac_exec_ext"
echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
;;
esac
fi
-SAMBA_CLIENT=$ac_cv_path_SAMBA_CLIENT
+VXRESTORE=$ac_cv_path_VXRESTORE
-if test -n "$SAMBA_CLIENT"; then
- echo "$as_me:$LINENO: result: $SAMBA_CLIENT" >&5
-echo "${ECHO_T}$SAMBA_CLIENT" >&6
+if test -n "$VXRESTORE"; then
+ echo "$as_me:$LINENO: result: $VXRESTORE" >&5
+echo "${ECHO_T}$VXRESTORE" >&6
else
echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6
fi
- test -n "$SAMBA_CLIENT" && break
+ test -n "$VXRESTORE" && break
done
-if test ! -z "$SAMBA_CLIENT"; then
- case "`\"$SAMBA_CLIENT\" '\\\\not.a.host.name\\notashare' -U nosuchuser -N -Tx /dev/null 2>&1`" in
- *"Unknown host"*)
- smbversion=1
- ;;
- *"Connection to not.a.host.name failed"*)
- smbversion=2
- ;;
- *)
- { echo "$as_me:$LINENO: WARNING: *** $SAMBA_CLIENT does not seem to be smbclient, so it will not be used." >&5
-echo "$as_me: WARNING: *** $SAMBA_CLIENT does not seem to be smbclient, so it will not be used." >&2;}
- SAMBA_CLIENT=
- ;;
- esac
- if test -n "$SAMBA_CLIENT"; then
+if test "$VXDUMP" -a "$VXRESTORE"; then
cat >>confdefs.h <<_ACEOF
-#define SAMBA_CLIENT "$SAMBA_CLIENT"
+#define VXDUMP "$VXDUMP"
_ACEOF
cat >>confdefs.h <<_ACEOF
-#define SAMBA_VERSION $smbversion
+#define VXRESTORE "$VXRESTORE"
_ACEOF
- fi
fi
-for ac_prog in gzip
+for ac_prog in vdump
do
# Extract the first word of "$ac_prog", so it can be a program name with args.
set dummy $ac_prog; ac_word=$2
echo "$as_me:$LINENO: checking for $ac_word" >&5
echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_path_GZIP+set}" = set; then
+if test "${ac_cv_path_VDUMP+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
- case $GZIP in
+ case $VDUMP in
[\\/]* | ?:[\\/]*)
- ac_cv_path_GZIP="$GZIP" # Let the user override the test with a path.
+ ac_cv_path_VDUMP="$VDUMP" # Let the user override the test with a path.
;;
*)
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $LOCSYSPATH
+for as_dir in $SYSLOCPATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- ac_cv_path_GZIP="$as_dir/$ac_word$ac_exec_ext"
+ ac_cv_path_VDUMP="$as_dir/$ac_word$ac_exec_ext"
echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
;;
esac
fi
-GZIP=$ac_cv_path_GZIP
+VDUMP=$ac_cv_path_VDUMP
-if test -n "$GZIP"; then
- echo "$as_me:$LINENO: result: $GZIP" >&5
-echo "${ECHO_T}$GZIP" >&6
+if test -n "$VDUMP"; then
+ echo "$as_me:$LINENO: result: $VDUMP" >&5
+echo "${ECHO_T}$VDUMP" >&6
else
echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6
fi
- test -n "$GZIP" && break
+ test -n "$VDUMP" && break
done
-if test "$GZIP"; then
-
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_GZIP 1
-_ACEOF
-
- COMPRESS_PATH="$GZIP"
- COMPRESS_SUFFIX=".gz"
- COMPRESS_FAST_OPT="--fast"
- COMPRESS_BEST_OPT="--best"
- UNCOMPRESS_PATH="$GZIP"
- UNCOMPRESS_OPT="-dc"
-else
- if test "$COMPRESS"; then
- COMPRESS_PATH="$COMPRESS"
- COMPRESS_SUFFIX=".Z"
- COMPRESS_FAST_OPT="-f"
- COMPRESS_BEST_OPT="-f"
- UNCOMPRESS_PATH="$COMPRESS"
- UNCOMPRESS_OPT="-dc"
- else
- { echo "$as_me:$LINENO: WARNING: *** Cannot find either gzip or compress. Using cat. ***" >&5
-echo "$as_me: WARNING: *** Cannot find either gzip or compress. Using cat. ***" >&2;}
- COMPRESS_PATH="$CAT"
- COMPRESS_SUFFIX=""
- COMPRESS_FAST_OPT=""
- COMPRESS_BEST_OPT=""
- UNCOMPRESS_PATH="$CAT"
- UNCOMPRESS_OPT=""
- fi
-fi
-
-cat >>confdefs.h <<_ACEOF
-#define COMPRESS_PATH "$COMPRESS_PATH"
-_ACEOF
-
-
-cat >>confdefs.h <<_ACEOF
-#define COMPRESS_SUFFIX "$COMPRESS_SUFFIX"
-_ACEOF
-
-
-cat >>confdefs.h <<_ACEOF
-#define COMPRESS_FAST_OPT "$COMPRESS_FAST_OPT"
-_ACEOF
-
-
-cat >>confdefs.h <<_ACEOF
-#define COMPRESS_BEST_OPT "$COMPRESS_BEST_OPT"
-_ACEOF
-
-
-cat >>confdefs.h <<_ACEOF
-#define UNCOMPRESS_PATH "$UNCOMPRESS_PATH"
-_ACEOF
-
-
-cat >>confdefs.h <<_ACEOF
-#define UNCOMPRESS_OPT "$UNCOMPRESS_OPT"
-_ACEOF
-
-
-for ac_prog in Mail mailx mail
+for ac_prog in vrestore
do
# Extract the first word of "$ac_prog", so it can be a program name with args.
set dummy $ac_prog; ac_word=$2
echo "$as_me:$LINENO: checking for $ac_word" >&5
echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_path_MAILER+set}" = set; then
+if test "${ac_cv_path_VRESTORE+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
- case $MAILER in
+ case $VRESTORE in
[\\/]* | ?:[\\/]*)
- ac_cv_path_MAILER="$MAILER" # Let the user override the test with a path.
+ ac_cv_path_VRESTORE="$VRESTORE" # Let the user override the test with a path.
;;
*)
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
+for as_dir in $SYSLOCPATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- ac_cv_path_MAILER="$as_dir/$ac_word$ac_exec_ext"
+ ac_cv_path_VRESTORE="$as_dir/$ac_word$ac_exec_ext"
echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
;;
esac
fi
-MAILER=$ac_cv_path_MAILER
+VRESTORE=$ac_cv_path_VRESTORE
-if test -n "$MAILER"; then
- echo "$as_me:$LINENO: result: $MAILER" >&5
-echo "${ECHO_T}$MAILER" >&6
+if test -n "$VRESTORE"; then
+ echo "$as_me:$LINENO: result: $VRESTORE" >&5
+echo "${ECHO_T}$VRESTORE" >&6
else
echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6
fi
- test -n "$MAILER" && break
+ test -n "$VRESTORE" && break
done
-if test -z "$MAILER"; then
- if $NO_SERVER_MODE; then
- MAILER="NONE"
- { echo "$as_me:$LINENO: WARNING: *** WARNING: Amanda cannot send mail reports without these programs." >&5
-echo "$as_me: WARNING: *** WARNING: Amanda cannot send mail reports without these programs." >&2;}
- else
- { { echo "$as_me:$LINENO: error: Set MAILER to some program that accepts -s subject user < message_file." >&5
-echo "$as_me: error: Set MAILER to some program that accepts -s subject user < message_file." >&2;}
- { (exit 1); exit 1; }; }
- fi
-fi
+if test "$VDUMP" -a "$VRESTORE"; then
cat >>confdefs.h <<_ACEOF
-#define MAILER "$MAILER"
+#define VDUMP "$VDUMP"
_ACEOF
-for ac_prog in mt
-do
- # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_path_MT+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- case $MT in
- [\\/]* | ?:[\\/]*)
- ac_cv_path_MT="$MT" # Let the user override the test with a path.
- ;;
- *)
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $LOCSYSPATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- ac_cv_path_MT="$as_dir/$ac_word$ac_exec_ext"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
+cat >>confdefs.h <<_ACEOF
+#define VRESTORE "$VRESTORE"
+_ACEOF
- ;;
-esac
fi
-MT=$ac_cv_path_MT
-if test -n "$MT"; then
- echo "$as_me:$LINENO: result: $MT" >&5
-echo "${ECHO_T}$MT" >&6
+if test "$PCAT"; then
+ AMPLOT_CAT_PACK="if(o==\"z\")print \"$PCAT\"; else"
else
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
+ AMPLOT_CAT_PACK=
+fi
+if test "$COMPRESS"; then
+ AMPLOT_COMPRESS=$COMPRESS
+ AMPLOT_CAT_COMPRESS="if(o==\"Z\")print \"$COMPRESS -dc\"; else"
+else
+ AMPLOT_CAT_COMPRESS=
+fi
+if test "$GZIP"; then
+ AMPLOT_COMPRESS=$GZIP
+ AMPLOT_CAT_GZIP="if(o==\"gz\")print \"$GZIP -dc\"; else"
+else
+ AMPLOT_CAT_GZIP=
fi
- test -n "$MT" && break
-done
-test -n "$MT" || MT="mt"
-for ac_prog in chio
-do
- # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_path_CHIO+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+
+
+# Determine the printf format characters to use when printing
+# values of type long long. This will normally be "ll", but where
+# the compiler treats "long long" as a alias for "long" and printf
+# doesn't know about "long long" use "l". Hopefully the sprintf
+# will produce a inconsistant result in the later case. If the compiler
+# fails due to seeing "%lld" we fall back to "l".
+#
+# Win32 uses "%I64d", but that's defined elsewhere since we don't use
+# configure on Win32.
+#
+echo "$as_me:$LINENO: checking printf format modifier for 64-bit integers" >&5
+echo $ECHO_N "checking printf format modifier for 64-bit integers... $ECHO_C" >&6
+if test "$cross_compiling" = yes; then
+ echo "$as_me:$LINENO: result: assuming target platform uses ll" >&5
+echo "${ECHO_T}assuming target platform uses ll" >&6
+ LL_FMT="%lld"
else
- case $CHIO in
- [\\/]* | ?:[\\/]*)
- ac_cv_path_CHIO="$CHIO" # Let the user override the test with a path.
- ;;
- *)
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $LOCSYSPATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- ac_cv_path_CHIO="$as_dir/$ac_word$ac_exec_ext"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
- ;;
-esac
-fi
-CHIO=$ac_cv_path_CHIO
+#include <stdio.h>
+main() {
+ long long int j = 0;
+ char buf[100];
+ buf[0] = 0;
+ sprintf(buf, "%lld", j);
+ exit((sizeof(long long int) != sizeof(long int))? 0 :
+ (strcmp(buf, "0") != 0));
+}
-if test -n "$CHIO"; then
- echo "$as_me:$LINENO: result: $CHIO" >&5
-echo "${ECHO_T}$CHIO" >&6
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ echo "$as_me:$LINENO: result: ll" >&5
+echo "${ECHO_T}ll" >&6
+ LL_FMT="%lld"
else
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
+ echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+echo "$as_me:$LINENO: result: l" >&5
+echo "${ECHO_T}l" >&6
+ LL_FMT="%ld"
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
fi
- test -n "$CHIO" && break
-done
-test -n "$CHIO" || CHIO="chio"
+cat >>confdefs.h <<_ACEOF
+#define LL_FMT "$LL_FMT"
+_ACEOF
-for ac_prog in chs
-do
- # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_path_CHS+set}" = set; then
+
+GZIP=
+
+need_resetofs=yes
+echo "$as_me:$LINENO: checking for large file compilation CFLAGS" >&5
+echo $ECHO_N "checking for large file compilation CFLAGS... $ECHO_C" >&6
+if test "${amanda_cv_LFS_CFLAGS+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
- case $CHS in
- [\\/]* | ?:[\\/]*)
- ac_cv_path_CHS="$CHS" # Let the user override the test with a path.
- ;;
- *)
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $LOCSYSPATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- ac_cv_path_CHS="$as_dir/$ac_word$ac_exec_ext"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
- ;;
-esac
-fi
-CHS=$ac_cv_path_CHS
+ amanda_cv_LFS_CFLAGS=
+ if test "$GETCONF"; then
+ if $GETCONF ${GETCONF_LFS}_CFLAGS >/dev/null 2>&1; then
+ amanda_cv_LFS_CFLAGS=`$GETCONF ${GETCONF_LFS}_CFLAGS 2>/dev/null`
+ need_resetofs=no
+ fi
+ fi
+
-if test -n "$CHS"; then
- echo "$as_me:$LINENO: result: $CHS" >&5
-echo "${ECHO_T}$CHS" >&6
-else
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
fi
+echo "$as_me:$LINENO: result: $amanda_cv_LFS_CFLAGS" >&5
+echo "${ECHO_T}$amanda_cv_LFS_CFLAGS" >&6
+echo "$as_me:$LINENO: checking for large file compilation LDFLAGS" >&5
+echo $ECHO_N "checking for large file compilation LDFLAGS... $ECHO_C" >&6
+if test "${amanda_cv_LFS_LDFLAGS+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
- test -n "$CHS" && break
-done
-test -n "$CHS" || CHS="chs"
+ amanda_cv_LFS_LDFLAGS=
+ if test "$GETCONF"; then
+ if $GETCONF ${GETCONF_LFS}_LDFLAGS >/dev/null 2>&1; then
+ amanda_cv_LFS_LDFLAGS=`$GETCONF ${GETCONF_LFS}_LDFLAGS 2>/dev/null`
+ need_resetofs=no
+ fi
+ fi
-for ac_prog in mtx
-do
- # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_path_MTX+set}" = set; then
+fi
+echo "$as_me:$LINENO: result: $amanda_cv_LFS_LDFLAGS" >&5
+echo "${ECHO_T}$amanda_cv_LFS_LDFLAGS" >&6
+echo "$as_me:$LINENO: checking for large file compilation LIBS" >&5
+echo $ECHO_N "checking for large file compilation LIBS... $ECHO_C" >&6
+if test "${amanda_cv_LFS_LIBS+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
- case $MTX in
- [\\/]* | ?:[\\/]*)
- ac_cv_path_MTX="$MTX" # Let the user override the test with a path.
- ;;
- *)
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $LOCSYSPATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- ac_cv_path_MTX="$as_dir/$ac_word$ac_exec_ext"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
- ;;
-esac
+ amanda_cv_LFS_LIBS=
+ if test "$GETCONF"; then
+ if $GETCONF ${GETCONF_LFS}_LIBS >/dev/null 2>&1; then
+ amanda_cv_LFS_LIBS=`$GETCONF ${GETCONF_LFS}_LIBS 2>/dev/null`
+ need_resetofs=no
+ fi
+ fi
+
+
fi
-MTX=$ac_cv_path_MTX
+echo "$as_me:$LINENO: result: $amanda_cv_LFS_LIBS" >&5
+echo "${ECHO_T}$amanda_cv_LFS_LIBS" >&6
+if test "x$need_resetofs" = xyes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define NEED_RESETOFS 1
+_ACEOF
-if test -n "$MTX"; then
- echo "$as_me:$LINENO: result: $MTX" >&5
-echo "${ECHO_T}$MTX" >&6
-else
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
fi
- test -n "$MTX" && break
-done
-test -n "$MTX" || MTX="mtx"
+CFLAGS="$amanda_cv_LFS_CFLAGS $CFLAGS"
+CPPFLAGS="$amanda_cv_LFS_CPPFLAGS $CPPFLAGS"
+LDFLAGS="$amanda_cv_LFS_LDFLAGS $LDFLAGS"
+LIBS="$amanda_cv_LFS_LIBS $LIBS"
-for ac_prog in mcutil
-do
- # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_path_MCUTIL+set}" = set; then
+echo "$as_me:$LINENO: checking for int" >&5
+echo $ECHO_N "checking for int... $ECHO_C" >&6
+if test "${ac_cv_type_int+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
- case $MCUTIL in
- [\\/]* | ?:[\\/]*)
- ac_cv_path_MCUTIL="$MCUTIL" # Let the user override the test with a path.
- ;;
- *)
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $LOCSYSPATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- ac_cv_path_MCUTIL="$as_dir/$ac_word$ac_exec_ext"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+if ((int *) 0)
+ return 0;
+if (sizeof (int))
+ return 0;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_type_int=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
- ;;
-esac
+ac_cv_type_int=no
fi
-MCUTIL=$ac_cv_path_MCUTIL
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_int" >&5
+echo "${ECHO_T}$ac_cv_type_int" >&6
-if test -n "$MCUTIL"; then
- echo "$as_me:$LINENO: result: $MCUTIL" >&5
-echo "${ECHO_T}$MCUTIL" >&6
+echo "$as_me:$LINENO: checking size of int" >&5
+echo $ECHO_N "checking size of int... $ECHO_C" >&6
+if test "${ac_cv_sizeof_int+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
else
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
+ if test "$ac_cv_type_int" = yes; then
+ # The cast to unsigned long works around a bug in the HP C Compiler
+ # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+ # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+ # This bug is HP SR number 8606223364.
+ if test "$cross_compiling" = yes; then
+ # Depending upon the size, compute the lo and hi bounds.
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (int))) >= 0)];
+test_array [0] = 0
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_lo=0 ac_mid=0
+ while :; do
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (int))) <= $ac_mid)];
+test_array [0] = 0
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_hi=$ac_mid; break
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo=`expr $ac_mid + 1`
+ if test $ac_lo -le $ac_mid; then
+ ac_lo= ac_hi=
+ break
+ fi
+ ac_mid=`expr 2 '*' $ac_mid + 1`
fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ done
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
- test -n "$MCUTIL" && break
-done
-test -n "$MCUTIL" || MCUTIL="mcutil"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (int))) < 0)];
+test_array [0] = 0
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_hi=-1 ac_mid=-1
+ while :; do
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (int))) >= $ac_mid)];
+test_array [0] = 0
-for ac_prog in lpr lp
-do
- # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_path_PRINT+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_lo=$ac_mid; break
else
- case $PRINT in
- [\\/]* | ?:[\\/]*)
- ac_cv_path_PRINT="$PRINT" # Let the user override the test with a path.
- ;;
- *)
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- ac_cv_path_PRINT="$as_dir/$ac_word$ac_exec_ext"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
- ;;
-esac
+ac_hi=`expr '(' $ac_mid ')' - 1`
+ if test $ac_mid -le $ac_hi; then
+ ac_lo= ac_hi=
+ break
+ fi
+ ac_mid=`expr 2 '*' $ac_mid`
fi
-PRINT=$ac_cv_path_PRINT
-
-if test -n "$PRINT"; then
- echo "$as_me:$LINENO: result: $PRINT" >&5
-echo "${ECHO_T}$PRINT" >&6
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ done
else
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo= ac_hi=
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+# Binary search between lo and hi bounds.
+while test "x$ac_lo" != "x$ac_hi"; do
+ ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo`
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (int))) <= $ac_mid)];
+test_array [0] = 0
- test -n "$PRINT" && break
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_hi=$ac_mid
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo=`expr '(' $ac_mid ')' + 1`
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
done
+case $ac_lo in
+?*) ac_cv_sizeof_int=$ac_lo;;
+'') { { echo "$as_me:$LINENO: error: cannot compute sizeof (int), 77
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute sizeof (int), 77
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; } ;;
+esac
+else
+ if test "$cross_compiling" = yes; then
+ { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+long longval () { return (long) (sizeof (int)); }
+unsigned long ulongval () { return (long) (sizeof (int)); }
+#include <stdio.h>
+#include <stdlib.h>
+int
+main ()
+{
-if test ! -z "$PRINT"; then
+ FILE *f = fopen ("conftest.val", "w");
+ if (! f)
+ exit (1);
+ if (((long) (sizeof (int))) < 0)
+ {
+ long i = longval ();
+ if (i != ((long) (sizeof (int))))
+ exit (1);
+ fprintf (f, "%ld\n", i);
+ }
+ else
+ {
+ unsigned long i = ulongval ();
+ if (i != ((long) (sizeof (int))))
+ exit (1);
+ fprintf (f, "%lu\n", i);
+ }
+ exit (ferror (f) || fclose (f) != 0);
-cat >>confdefs.h <<_ACEOF
-#define LPRCMD "$PRINT"
+ ;
+ return 0;
+}
_ACEOF
-
- echo "$as_me:$LINENO: checking which flag to use to select a printer" >&5
-echo $ECHO_N "checking which flag to use to select a printer... $ECHO_C" >&6
-if test "${amanda_cv_printer_flag+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_sizeof_int=`cat conftest.val`
else
+ echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
- amanda_cv_printer_flag=$PRINTER_FLAG
- case "$PRINT" in
- lpr|*/lpr) amanda_cv_printer_flag="-P";;
- lp|*/lp) amanda_cv_printer_flag="-d";;
- esac
-
+( exit $ac_status )
+{ { echo "$as_me:$LINENO: error: cannot compute sizeof (int), 77
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute sizeof (int), 77
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
fi
-echo "$as_me:$LINENO: result: $amanda_cv_printer_flag" >&5
-echo "${ECHO_T}$amanda_cv_printer_flag" >&6
- if test ! -z "$amanda_cv_printer_flag"; then
-
-cat >>confdefs.h <<_ACEOF
-#define LPRFLAG "$amanda_cv_printer_flag"
-_ACEOF
-
- else
- { echo "$as_me:$LINENO: WARNING: *** WARNING: amanda will always print to the default printer" >&5
-echo "$as_me: WARNING: *** WARNING: amanda will always print to the default printer" >&2;}
- fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
fi
-
-for ac_prog in pcat
-do
- # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_path_PCAT+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- case $PCAT in
- [\\/]* | ?:[\\/]*)
- ac_cv_path_PCAT="$PCAT" # Let the user override the test with a path.
- ;;
- *)
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $LOCSYSPATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- ac_cv_path_PCAT="$as_dir/$ac_word$ac_exec_ext"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-
- ;;
-esac
fi
-PCAT=$ac_cv_path_PCAT
-
-if test -n "$PCAT"; then
- echo "$as_me:$LINENO: result: $PCAT" >&5
-echo "${ECHO_T}$PCAT" >&6
+rm -f conftest.val
else
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
+ ac_cv_sizeof_int=0
+fi
fi
+echo "$as_me:$LINENO: result: $ac_cv_sizeof_int" >&5
+echo "${ECHO_T}$ac_cv_sizeof_int" >&6
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_INT $ac_cv_sizeof_int
+_ACEOF
- test -n "$PCAT" && break
-done
-for ac_prog in perl5 perl
-do
- # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_path_PERL+set}" = set; then
+echo "$as_me:$LINENO: checking for long" >&5
+echo $ECHO_N "checking for long... $ECHO_C" >&6
+if test "${ac_cv_type_long+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
- case $PERL in
- [\\/]* | ?:[\\/]*)
- ac_cv_path_PERL="$PERL" # Let the user override the test with a path.
- ;;
- *)
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $LOCSYSPATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- ac_cv_path_PERL="$as_dir/$ac_word$ac_exec_ext"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+if ((long *) 0)
+ return 0;
+if (sizeof (long))
+ return 0;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_type_long=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
- ;;
-esac
+ac_cv_type_long=no
fi
-PERL=$ac_cv_path_PERL
-
-if test -n "$PERL"; then
- echo "$as_me:$LINENO: result: $PERL" >&5
-echo "${ECHO_T}$PERL" >&6
-else
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
fi
+echo "$as_me:$LINENO: result: $ac_cv_type_long" >&5
+echo "${ECHO_T}$ac_cv_type_long" >&6
- test -n "$PERL" && break
-done
-
-
-
-for ac_prog in $DUMP_PROGRAMS
-do
- # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_path_DUMP+set}" = set; then
+echo "$as_me:$LINENO: checking size of long" >&5
+echo $ECHO_N "checking size of long... $ECHO_C" >&6
+if test "${ac_cv_sizeof_long+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
- case $DUMP in
- [\\/]* | ?:[\\/]*)
- ac_cv_path_DUMP="$DUMP" # Let the user override the test with a path.
- ;;
- *)
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $SYSLOCPATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- ac_cv_path_DUMP="$as_dir/$ac_word$ac_exec_ext"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-
- ;;
-esac
-fi
-DUMP=$ac_cv_path_DUMP
-
-if test -n "$DUMP"; then
- echo "$as_me:$LINENO: result: $DUMP" >&5
-echo "${ECHO_T}$DUMP" >&6
-else
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
-fi
+ if test "$ac_cv_type_long" = yes; then
+ # The cast to unsigned long works around a bug in the HP C Compiler
+ # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+ # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+ # This bug is HP SR number 8606223364.
+ if test "$cross_compiling" = yes; then
+ # Depending upon the size, compute the lo and hi bounds.
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (long))) >= 0)];
+test_array [0] = 0
- test -n "$DUMP" && break
-done
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_lo=0 ac_mid=0
+ while :; do
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (long))) <= $ac_mid)];
+test_array [0] = 0
-for ac_prog in ufsrestore restore
-do
- # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_path_RESTORE+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_hi=$ac_mid; break
else
- case $RESTORE in
- [\\/]* | ?:[\\/]*)
- ac_cv_path_RESTORE="$RESTORE" # Let the user override the test with a path.
- ;;
- *)
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $SYSLOCPATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- ac_cv_path_RESTORE="$as_dir/$ac_word$ac_exec_ext"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
- ;;
-esac
+ac_lo=`expr $ac_mid + 1`
+ if test $ac_lo -le $ac_mid; then
+ ac_lo= ac_hi=
+ break
+ fi
+ ac_mid=`expr 2 '*' $ac_mid + 1`
fi
-RESTORE=$ac_cv_path_RESTORE
-
-if test -n "$RESTORE"; then
- echo "$as_me:$LINENO: result: $RESTORE" >&5
-echo "${ECHO_T}$RESTORE" >&6
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ done
else
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
-fi
-
- test -n "$RESTORE" && break
-done
-
-if test "$DUMP" -a "$RESTORE"; then
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
-cat >>confdefs.h <<_ACEOF
-#define DUMP "$DUMP"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (long))) < 0)];
+test_array [0] = 0
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_hi=-1 ac_mid=-1
+ while :; do
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (long))) >= $ac_mid)];
+test_array [0] = 0
-cat >>confdefs.h <<_ACEOF
-#define RESTORE "$RESTORE"
+ ;
+ return 0;
+}
_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_lo=$ac_mid; break
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
- if test -x $DUMP; then
- echo "$as_me:$LINENO: checking whether $DUMP supports -E or -S for estimates" >&5
-echo $ECHO_N "checking whether $DUMP supports -E or -S for estimates... $ECHO_C" >&6
-if test "${amanda_cv_dump_estimate+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+ac_hi=`expr '(' $ac_mid ')' - 1`
+ if test $ac_mid -le $ac_hi; then
+ ac_lo= ac_hi=
+ break
+ fi
+ ac_mid=`expr 2 '*' $ac_mid`
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ done
else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
- case "$DUMP" in
- *dump)
- { ac_try='$DUMP 9Ef /dev/null /dev/null/invalid/fs 2>&1
- | $GREP -v Dumping
- | $GREP -v Date
- | $GREP -v Label >conftest.d-E 2>&1'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
+ac_lo= ac_hi=
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+# Binary search between lo and hi bounds.
+while test "x$ac_lo" != "x$ac_hi"; do
+ ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo`
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (long))) <= $ac_mid)];
+test_array [0] = 0
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }
- cat conftest.d-E >&5
- { ac_try='$DUMP 9Sf /dev/null /dev/null/invalid/fs 2>&1
- | $GREP -v Dumping
- | $GREP -v Date
- | $GREP -v Label >conftest.d-S 2>&1'
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }
- cat conftest.d-S >&5
- { ac_try='$DUMP 9f /dev/null /dev/null/invalid/fs 2>&1
- | $GREP -v Dumping
- | $GREP -v Date
- | $GREP -v Label >conftest.d 2>&1'
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }
- cat conftest.d >&5
- if { ac_try='cmp conftest.d-E conftest.d 1>&2'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
+ (exit $ac_status); }; }; then
+ ac_hi=$ac_mid
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo=`expr '(' $ac_mid ')' + 1`
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+case $ac_lo in
+?*) ac_cv_sizeof_long=$ac_lo;;
+'') { { echo "$as_me:$LINENO: error: cannot compute sizeof (long), 77
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute sizeof (long), 77
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; } ;;
+esac
+else
+ if test "$cross_compiling" = yes; then
+ { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+long longval () { return (long) (sizeof (long)); }
+unsigned long ulongval () { return (long) (sizeof (long)); }
+#include <stdio.h>
+#include <stdlib.h>
+int
+main ()
+{
+
+ FILE *f = fopen ("conftest.val", "w");
+ if (! f)
+ exit (1);
+ if (((long) (sizeof (long))) < 0)
+ {
+ long i = longval ();
+ if (i != ((long) (sizeof (long))))
+ exit (1);
+ fprintf (f, "%ld\n", i);
+ }
+ else
+ {
+ unsigned long i = ulongval ();
+ if (i != ((long) (sizeof (long))))
+ exit (1);
+ fprintf (f, "%lu\n", i);
+ }
+ exit (ferror (f) || fclose (f) != 0);
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- amanda_cv_dump_estimate=E
- elif { ac_try='cmp conftest.d-S conftest.d 1>&2'
+ (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
- amanda_cv_dump_estimate=S
- else
- amanda_cv_dump_estimate=no
- fi
- rm -f conftest.d conftest.d-E conftest.d-S
- ;;
- *) amanda_cv_dump_estimate=no
- ;;
- esac
+ ac_cv_sizeof_long=`cat conftest.val`
+else
+ echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+( exit $ac_status )
+{ { echo "$as_me:$LINENO: error: cannot compute sizeof (long), 77
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute sizeof (long), 77
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
fi
-echo "$as_me:$LINENO: result: $amanda_cv_dump_estimate" >&5
-echo "${ECHO_T}$amanda_cv_dump_estimate" >&6
- else
- { echo "$as_me:$LINENO: WARNING: *** $DUMP is not executable, cannot run -E/-S test" >&5
-echo "$as_me: WARNING: *** $DUMP is not executable, cannot run -E/-S test" >&2;}
- amanda_cv_dump_estimate=no
- fi
- if test "x$amanda_cv_dump_estimate" != xno; then
-
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+rm -f conftest.val
+else
+ ac_cv_sizeof_long=0
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_sizeof_long" >&5
+echo "${ECHO_T}$ac_cv_sizeof_long" >&6
cat >>confdefs.h <<_ACEOF
-#define HAVE_DUMP_ESTIMATE "$amanda_cv_dump_estimate"
+#define SIZEOF_LONG $ac_cv_sizeof_long
_ACEOF
- fi
-
-# Check whether --with-dump-honor-nodump or --without-dump-honor-nodump was given.
-if test "${with_dump_honor_nodump+set}" = set; then
- withval="$with_dump_honor_nodump"
- if test -x $DUMP; then
- echo "$as_me:$LINENO: checking whether $DUMP supports -h (honor nodump flag)" >&5
-echo $ECHO_N "checking whether $DUMP supports -h (honor nodump flag)... $ECHO_C" >&6
-if test "${amanda_cv_honor_nodump+set}" = set; then
+echo "$as_me:$LINENO: checking for long long" >&5
+echo $ECHO_N "checking for long long... $ECHO_C" >&6
+if test "${ac_cv_type_long_long+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
-
- case "$DUMP" in
- *dump)
- { ac_try='$DUMP 9hf 0 /dev/null /dev/null/invalid/fs 2>&1
- | $GREP -v Dumping
- | $GREP -v Date
- | $GREP -v Label >conftest.d-h 2>&1'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+if ((long long *) 0)
+ return 0;
+if (sizeof (long long))
+ return 0;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }
- cat conftest.d-h >&5
- { ac_try='$DUMP 9f /dev/null /dev/null/invalid/fs 2>&1
- | $GREP -v Dumping
- | $GREP -v Date
- | $GREP -v Label >conftest.d 2>&1'
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }
- cat conftest.d >&5
- if { ac_try='diff conftest.d-h conftest.d 1>&2'
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
- amanda_cv_honor_nodump=yes
- else
- amanda_cv_honor_nodump=no
- fi
- rm -f conftest.d conftest.d-h
- ;;
- *) amanda_cv_honor_nodump=no
- ;;
- esac
-
-fi
-echo "$as_me:$LINENO: result: $amanda_cv_honor_nodump" >&5
-echo "${ECHO_T}$amanda_cv_honor_nodump" >&6
- else
- { echo "$as_me:$LINENO: WARNING: *** $DUMP is not executable, cannot run -h test" >&5
-echo "$as_me: WARNING: *** $DUMP is not executable, cannot run -h test" >&2;}
- amanda_cv_honor_nodump=no
- fi
- if test "x$amanda_cv_honor_nodump" = xyes; then
-
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_HONOR_NODUMP 1
-_ACEOF
-
- fi
-
-fi;
-fi
-
-for ac_prog in xfsdump
-do
- # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_path_XFSDUMP+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+ ac_cv_type_long_long=yes
else
- case $XFSDUMP in
- [\\/]* | ?:[\\/]*)
- ac_cv_path_XFSDUMP="$XFSDUMP" # Let the user override the test with a path.
- ;;
- *)
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $SYSLOCPATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- ac_cv_path_XFSDUMP="$as_dir/$ac_word$ac_exec_ext"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
- ;;
-esac
+ac_cv_type_long_long=no
fi
-XFSDUMP=$ac_cv_path_XFSDUMP
-
-if test -n "$XFSDUMP"; then
- echo "$as_me:$LINENO: result: $XFSDUMP" >&5
-echo "${ECHO_T}$XFSDUMP" >&6
-else
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
fi
+echo "$as_me:$LINENO: result: $ac_cv_type_long_long" >&5
+echo "${ECHO_T}$ac_cv_type_long_long" >&6
- test -n "$XFSDUMP" && break
-done
-
-for ac_prog in xfsrestore
-do
- # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_path_XFSRESTORE+set}" = set; then
+echo "$as_me:$LINENO: checking size of long long" >&5
+echo $ECHO_N "checking size of long long... $ECHO_C" >&6
+if test "${ac_cv_sizeof_long_long+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
- case $XFSRESTORE in
- [\\/]* | ?:[\\/]*)
- ac_cv_path_XFSRESTORE="$XFSRESTORE" # Let the user override the test with a path.
- ;;
- *)
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $SYSLOCPATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- ac_cv_path_XFSRESTORE="$as_dir/$ac_word$ac_exec_ext"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-
- ;;
-esac
-fi
-XFSRESTORE=$ac_cv_path_XFSRESTORE
-
-if test -n "$XFSRESTORE"; then
- echo "$as_me:$LINENO: result: $XFSRESTORE" >&5
-echo "${ECHO_T}$XFSRESTORE" >&6
-else
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
-fi
-
- test -n "$XFSRESTORE" && break
-done
-
-if test "$XFSDUMP" -a "$XFSRESTORE"; then
-
-cat >>confdefs.h <<_ACEOF
-#define XFSDUMP "$XFSDUMP"
+ if test "$ac_cv_type_long_long" = yes; then
+ # The cast to unsigned long works around a bug in the HP C Compiler
+ # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+ # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+ # This bug is HP SR number 8606223364.
+ if test "$cross_compiling" = yes; then
+ # Depending upon the size, compute the lo and hi bounds.
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (long long))) >= 0)];
+test_array [0] = 0
-
-cat >>confdefs.h <<_ACEOF
-#define XFSRESTORE "$XFSRESTORE"
+ ;
+ return 0;
+}
_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_lo=0 ac_mid=0
+ while :; do
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (long long))) <= $ac_mid)];
+test_array [0] = 0
- { echo "$as_me:$LINENO: WARNING: *** xfsdump causes the setuid-root rundump program to be enabled" >&5
-echo "$as_me: WARNING: *** xfsdump causes the setuid-root rundump program to be enabled" >&2;}
- { echo "$as_me:$LINENO: WARNING: *** to disable it, just #undef XFSDUMP in config/config.h" >&5
-echo "$as_me: WARNING: *** to disable it, just #undef XFSDUMP in config/config.h" >&2;}
-fi
-
-VXSYSLOCPATH="$SYSLOCPATH:/usr/lib/fs/vxfs"
-for ac_prog in vxdump
-do
- # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_path_VXDUMP+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- case $VXDUMP in
- [\\/]* | ?:[\\/]*)
- ac_cv_path_VXDUMP="$VXDUMP" # Let the user override the test with a path.
- ;;
- *)
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $VXSYSLOCPATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- ac_cv_path_VXDUMP="$as_dir/$ac_word$ac_exec_ext"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-
- ;;
-esac
-fi
-VXDUMP=$ac_cv_path_VXDUMP
-
-if test -n "$VXDUMP"; then
- echo "$as_me:$LINENO: result: $VXDUMP" >&5
-echo "${ECHO_T}$VXDUMP" >&6
-else
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
-fi
-
- test -n "$VXDUMP" && break
-done
-
-for ac_prog in vxrestore
-do
- # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_path_VXRESTORE+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_hi=$ac_mid; break
else
- case $VXRESTORE in
- [\\/]* | ?:[\\/]*)
- ac_cv_path_VXRESTORE="$VXRESTORE" # Let the user override the test with a path.
- ;;
- *)
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $VXSYSLOCPATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- ac_cv_path_VXRESTORE="$as_dir/$ac_word$ac_exec_ext"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-
- ;;
-esac
-fi
-VXRESTORE=$ac_cv_path_VXRESTORE
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
-if test -n "$VXRESTORE"; then
- echo "$as_me:$LINENO: result: $VXRESTORE" >&5
-echo "${ECHO_T}$VXRESTORE" >&6
-else
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
+ac_lo=`expr $ac_mid + 1`
+ if test $ac_lo -le $ac_mid; then
+ ac_lo= ac_hi=
+ break
+ fi
+ ac_mid=`expr 2 '*' $ac_mid + 1`
fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ done
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
- test -n "$VXRESTORE" && break
-done
-
-if test "$VXDUMP" -a "$VXRESTORE"; then
-
-cat >>confdefs.h <<_ACEOF
-#define VXDUMP "$VXDUMP"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (long long))) < 0)];
+test_array [0] = 0
-
-cat >>confdefs.h <<_ACEOF
-#define VXRESTORE "$VXRESTORE"
+ ;
+ return 0;
+}
_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_hi=-1 ac_mid=-1
+ while :; do
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (long long))) >= $ac_mid)];
+test_array [0] = 0
-fi
-
-for ac_prog in vdump
-do
- # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_path_VDUMP+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_lo=$ac_mid; break
else
- case $VDUMP in
- [\\/]* | ?:[\\/]*)
- ac_cv_path_VDUMP="$VDUMP" # Let the user override the test with a path.
- ;;
- *)
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $SYSLOCPATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- ac_cv_path_VDUMP="$as_dir/$ac_word$ac_exec_ext"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-
- ;;
-esac
-fi
-VDUMP=$ac_cv_path_VDUMP
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
-if test -n "$VDUMP"; then
- echo "$as_me:$LINENO: result: $VDUMP" >&5
-echo "${ECHO_T}$VDUMP" >&6
-else
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
+ac_hi=`expr '(' $ac_mid ')' - 1`
+ if test $ac_mid -le $ac_hi; then
+ ac_lo= ac_hi=
+ break
+ fi
+ ac_mid=`expr 2 '*' $ac_mid`
fi
-
- test -n "$VDUMP" && break
-done
-
-for ac_prog in vrestore
-do
- # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_path_VRESTORE+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ done
else
- case $VRESTORE in
- [\\/]* | ?:[\\/]*)
- ac_cv_path_VRESTORE="$VRESTORE" # Let the user override the test with a path.
- ;;
- *)
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $SYSLOCPATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- ac_cv_path_VRESTORE="$as_dir/$ac_word$ac_exec_ext"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
- ;;
-esac
+ac_lo= ac_hi=
fi
-VRESTORE=$ac_cv_path_VRESTORE
-
-if test -n "$VRESTORE"; then
- echo "$as_me:$LINENO: result: $VRESTORE" >&5
-echo "${ECHO_T}$VRESTORE" >&6
-else
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
fi
-
- test -n "$VRESTORE" && break
-done
-
-if test "$VDUMP" -a "$VRESTORE"; then
-
-cat >>confdefs.h <<_ACEOF
-#define VDUMP "$VDUMP"
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+# Binary search between lo and hi bounds.
+while test "x$ac_lo" != "x$ac_hi"; do
+ ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo`
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (long long))) <= $ac_mid)];
+test_array [0] = 0
-
-cat >>confdefs.h <<_ACEOF
-#define VRESTORE "$VRESTORE"
+ ;
+ return 0;
+}
_ACEOF
-
-fi
-
-if test "$PCAT"; then
- AMPLOT_CAT_PACK="if(o==\"z\")print \"$PCAT\"; else"
-else
- AMPLOT_CAT_PACK=
-fi
-if test "$COMPRESS"; then
- AMPLOT_COMPRESS=$COMPRESS
- AMPLOT_CAT_COMPRESS="if(o==\"Z\")print \"$COMPRESS -dc\"; else"
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_hi=$ac_mid
else
- AMPLOT_CAT_COMPRESS=
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo=`expr '(' $ac_mid ')' + 1`
fi
-if test "$GZIP"; then
- AMPLOT_COMPRESS=$GZIP
- AMPLOT_CAT_GZIP="if(o==\"gz\")print \"$GZIP -dc\"; else"
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+case $ac_lo in
+?*) ac_cv_sizeof_long_long=$ac_lo;;
+'') { { echo "$as_me:$LINENO: error: cannot compute sizeof (long long), 77
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute sizeof (long long), 77
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; } ;;
+esac
else
- AMPLOT_CAT_GZIP=
-fi
-
-
-
-
-
-# Determine the printf format characters to use when printing
-# values of type long long. This will normally be "ll", but where
-# the compiler treats "long long" as a alias for "long" and printf
-# doesn't know about "long long" use "l". Hopefully the sprintf
-# will produce a inconsistant result in the later case. If the compiler
-# fails due to seeing "%lld" we fall back to "l".
-#
-# Win32 uses "%I64d", but that's defined elsewhere since we don't use
-# configure on Win32.
-#
-echo "$as_me:$LINENO: checking printf format modifier for 64-bit integers" >&5
-echo $ECHO_N "checking printf format modifier for 64-bit integers... $ECHO_C" >&6
-if test "$cross_compiling" = yes; then
- echo "$as_me:$LINENO: result: assuming target platform uses ll" >&5
-echo "${ECHO_T}assuming target platform uses ll" >&6
- LL_FMT="%lld"
+ if test "$cross_compiling" = yes; then
+ { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
else
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
-
+$ac_includes_default
+long longval () { return (long) (sizeof (long long)); }
+unsigned long ulongval () { return (long) (sizeof (long long)); }
#include <stdio.h>
-main() {
- long long int j = 0;
- char buf[100];
- buf[0] = 0;
- sprintf(buf, "%lld", j);
- exit((sizeof(long long int) != sizeof(long int))? 0 :
- (strcmp(buf, "0") != 0));
-}
+#include <stdlib.h>
+int
+main ()
+{
+
+ FILE *f = fopen ("conftest.val", "w");
+ if (! f)
+ exit (1);
+ if (((long) (sizeof (long long))) < 0)
+ {
+ long i = longval ();
+ if (i != ((long) (sizeof (long long))))
+ exit (1);
+ fprintf (f, "%ld\n", i);
+ }
+ else
+ {
+ unsigned long i = ulongval ();
+ if (i != ((long) (sizeof (long long))))
+ exit (1);
+ fprintf (f, "%lu\n", i);
+ }
+ exit (ferror (f) || fclose (f) != 0);
+ ;
+ return 0;
+}
_ACEOF
rm -f conftest$ac_exeext
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
- echo "$as_me:$LINENO: result: ll" >&5
-echo "${ECHO_T}ll" >&6
- LL_FMT="%lld"
+ ac_cv_sizeof_long_long=`cat conftest.val`
else
echo "$as_me: program exited with status $ac_status" >&5
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
( exit $ac_status )
-echo "$as_me:$LINENO: result: l" >&5
-echo "${ECHO_T}l" >&6
- LL_FMT="%ld"
+{ { echo "$as_me:$LINENO: error: cannot compute sizeof (long long), 77
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute sizeof (long long), 77
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
fi
rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
fi
-
-cat >>confdefs.h <<_ACEOF
-#define LL_FMT "$LL_FMT"
-_ACEOF
-
-
-
-GZIP=
-
-need_resetofs=yes
-echo "$as_me:$LINENO: checking for large file compilation CFLAGS" >&5
-echo $ECHO_N "checking for large file compilation CFLAGS... $ECHO_C" >&6
-if test "${amanda_cv_LFS_CFLAGS+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-
- amanda_cv_LFS_CFLAGS=
- if test "$GETCONF"; then
- if $GETCONF ${GETCONF_LFS}_CFLAGS >/dev/null 2>&1; then
- amanda_cv_LFS_CFLAGS=`$GETCONF ${GETCONF_LFS}_CFLAGS 2>/dev/null`
- need_resetofs=no
- fi
- fi
-
-
fi
-echo "$as_me:$LINENO: result: $amanda_cv_LFS_CFLAGS" >&5
-echo "${ECHO_T}$amanda_cv_LFS_CFLAGS" >&6
-echo "$as_me:$LINENO: checking for large file compilation LDFLAGS" >&5
-echo $ECHO_N "checking for large file compilation LDFLAGS... $ECHO_C" >&6
-if test "${amanda_cv_LFS_LDFLAGS+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+rm -f conftest.val
else
-
- amanda_cv_LFS_LDFLAGS=
- if test "$GETCONF"; then
- if $GETCONF ${GETCONF_LFS}_LDFLAGS >/dev/null 2>&1; then
- amanda_cv_LFS_LDFLAGS=`$GETCONF ${GETCONF_LFS}_LDFLAGS 2>/dev/null`
- need_resetofs=no
- fi
- fi
-
-
+ ac_cv_sizeof_long_long=0
fi
-echo "$as_me:$LINENO: result: $amanda_cv_LFS_LDFLAGS" >&5
-echo "${ECHO_T}$amanda_cv_LFS_LDFLAGS" >&6
-echo "$as_me:$LINENO: checking for large file compilation LIBS" >&5
-echo $ECHO_N "checking for large file compilation LIBS... $ECHO_C" >&6
-if test "${amanda_cv_LFS_LIBS+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-
- amanda_cv_LFS_LIBS=
- if test "$GETCONF"; then
- if $GETCONF ${GETCONF_LFS}_LIBS >/dev/null 2>&1; then
- amanda_cv_LFS_LIBS=`$GETCONF ${GETCONF_LFS}_LIBS 2>/dev/null`
- need_resetofs=no
- fi
- fi
-
-
fi
-echo "$as_me:$LINENO: result: $amanda_cv_LFS_LIBS" >&5
-echo "${ECHO_T}$amanda_cv_LFS_LIBS" >&6
-if test "x$need_resetofs" = xyes; then
-
-cat >>confdefs.h <<\_ACEOF
-#define NEED_RESETOFS 1
+echo "$as_me:$LINENO: result: $ac_cv_sizeof_long_long" >&5
+echo "${ECHO_T}$ac_cv_sizeof_long_long" >&6
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_LONG_LONG $ac_cv_sizeof_long_long
_ACEOF
-fi
-CFLAGS="$amanda_cv_LFS_CFLAGS $CFLAGS"
-CPPFLAGS="$amanda_cv_LFS_CFLAGS $CPPFLAGS"
-LDFLAGS="$amanda_cv_LFS_LDFLAGS $LDFLAGS"
-LIBS="$amanda_cv_LFS_LIBS $LIBS"
-echo "$as_me:$LINENO: checking for int" >&5
-echo $ECHO_N "checking for int... $ECHO_C" >&6
-if test "${ac_cv_type_int+set}" = set; then
+echo "$as_me:$LINENO: checking for intmax_t" >&5
+echo $ECHO_N "checking for intmax_t... $ECHO_C" >&6
+if test "${ac_cv_type_intmax_t+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
cat >conftest.$ac_ext <<_ACEOF
int
main ()
{
-if ((int *) 0)
+if ((intmax_t *) 0)
return 0;
-if (sizeof (int))
+if (sizeof (intmax_t))
return 0;
;
return 0;
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
- ac_cv_type_int=yes
+ ac_cv_type_intmax_t=yes
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
-ac_cv_type_int=no
+ac_cv_type_intmax_t=no
fi
rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
fi
-echo "$as_me:$LINENO: result: $ac_cv_type_int" >&5
-echo "${ECHO_T}$ac_cv_type_int" >&6
+echo "$as_me:$LINENO: result: $ac_cv_type_intmax_t" >&5
+echo "${ECHO_T}$ac_cv_type_intmax_t" >&6
-echo "$as_me:$LINENO: checking size of int" >&5
-echo $ECHO_N "checking size of int... $ECHO_C" >&6
-if test "${ac_cv_sizeof_int+set}" = set; then
+echo "$as_me:$LINENO: checking size of intmax_t" >&5
+echo $ECHO_N "checking size of intmax_t... $ECHO_C" >&6
+if test "${ac_cv_sizeof_intmax_t+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
- if test "$ac_cv_type_int" = yes; then
+ if test "$ac_cv_type_intmax_t" = yes; then
# The cast to unsigned long works around a bug in the HP C Compiler
# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
int
main ()
{
-static int test_array [1 - 2 * !(((long) (sizeof (int))) >= 0)];
+static int test_array [1 - 2 * !(((long) (sizeof (intmax_t))) >= 0)];
test_array [0] = 0
;
int
main ()
{
-static int test_array [1 - 2 * !(((long) (sizeof (int))) <= $ac_mid)];
+static int test_array [1 - 2 * !(((long) (sizeof (intmax_t))) <= $ac_mid)];
test_array [0] = 0
;
int
main ()
{
-static int test_array [1 - 2 * !(((long) (sizeof (int))) < 0)];
+static int test_array [1 - 2 * !(((long) (sizeof (intmax_t))) < 0)];
test_array [0] = 0
;
int
main ()
{
-static int test_array [1 - 2 * !(((long) (sizeof (int))) >= $ac_mid)];
+static int test_array [1 - 2 * !(((long) (sizeof (intmax_t))) >= $ac_mid)];
test_array [0] = 0
;
int
main ()
{
-static int test_array [1 - 2 * !(((long) (sizeof (int))) <= $ac_mid)];
+static int test_array [1 - 2 * !(((long) (sizeof (intmax_t))) <= $ac_mid)];
test_array [0] = 0
;
rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
done
case $ac_lo in
-?*) ac_cv_sizeof_int=$ac_lo;;
-'') { { echo "$as_me:$LINENO: error: cannot compute sizeof (int), 77
+?*) ac_cv_sizeof_intmax_t=$ac_lo;;
+'') { { echo "$as_me:$LINENO: error: cannot compute sizeof (intmax_t), 77
See \`config.log' for more details." >&5
-echo "$as_me: error: cannot compute sizeof (int), 77
+echo "$as_me: error: cannot compute sizeof (intmax_t), 77
See \`config.log' for more details." >&2;}
{ (exit 1); exit 1; }; } ;;
esac
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
$ac_includes_default
-long longval () { return (long) (sizeof (int)); }
-unsigned long ulongval () { return (long) (sizeof (int)); }
+long longval () { return (long) (sizeof (intmax_t)); }
+unsigned long ulongval () { return (long) (sizeof (intmax_t)); }
#include <stdio.h>
#include <stdlib.h>
int
FILE *f = fopen ("conftest.val", "w");
if (! f)
exit (1);
- if (((long) (sizeof (int))) < 0)
+ if (((long) (sizeof (intmax_t))) < 0)
{
long i = longval ();
- if (i != ((long) (sizeof (int))))
+ if (i != ((long) (sizeof (intmax_t))))
exit (1);
fprintf (f, "%ld\n", i);
}
else
{
unsigned long i = ulongval ();
- if (i != ((long) (sizeof (int))))
+ if (i != ((long) (sizeof (intmax_t))))
exit (1);
fprintf (f, "%lu\n", i);
}
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
- ac_cv_sizeof_int=`cat conftest.val`
+ ac_cv_sizeof_intmax_t=`cat conftest.val`
else
echo "$as_me: program exited with status $ac_status" >&5
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
( exit $ac_status )
-{ { echo "$as_me:$LINENO: error: cannot compute sizeof (int), 77
+{ { echo "$as_me:$LINENO: error: cannot compute sizeof (intmax_t), 77
See \`config.log' for more details." >&5
-echo "$as_me: error: cannot compute sizeof (int), 77
+echo "$as_me: error: cannot compute sizeof (intmax_t), 77
See \`config.log' for more details." >&2;}
{ (exit 1); exit 1; }; }
fi
fi
rm -f conftest.val
else
- ac_cv_sizeof_int=0
+ ac_cv_sizeof_intmax_t=0
fi
fi
-echo "$as_me:$LINENO: result: $ac_cv_sizeof_int" >&5
-echo "${ECHO_T}$ac_cv_sizeof_int" >&6
+echo "$as_me:$LINENO: result: $ac_cv_sizeof_intmax_t" >&5
+echo "${ECHO_T}$ac_cv_sizeof_intmax_t" >&6
cat >>confdefs.h <<_ACEOF
-#define SIZEOF_INT $ac_cv_sizeof_int
+#define SIZEOF_INTMAX_T $ac_cv_sizeof_intmax_t
_ACEOF
-echo "$as_me:$LINENO: checking for long" >&5
-echo $ECHO_N "checking for long... $ECHO_C" >&6
-if test "${ac_cv_type_long+set}" = set; then
+echo "$as_me:$LINENO: checking for off_t" >&5
+echo $ECHO_N "checking for off_t... $ECHO_C" >&6
+if test "${ac_cv_type_off_t+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
cat >conftest.$ac_ext <<_ACEOF
int
main ()
{
-if ((long *) 0)
+if ((off_t *) 0)
return 0;
-if (sizeof (long))
+if (sizeof (off_t))
return 0;
;
return 0;
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
- ac_cv_type_long=yes
+ ac_cv_type_off_t=yes
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
-ac_cv_type_long=no
+ac_cv_type_off_t=no
fi
rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
fi
-echo "$as_me:$LINENO: result: $ac_cv_type_long" >&5
-echo "${ECHO_T}$ac_cv_type_long" >&6
+echo "$as_me:$LINENO: result: $ac_cv_type_off_t" >&5
+echo "${ECHO_T}$ac_cv_type_off_t" >&6
-echo "$as_me:$LINENO: checking size of long" >&5
-echo $ECHO_N "checking size of long... $ECHO_C" >&6
-if test "${ac_cv_sizeof_long+set}" = set; then
+echo "$as_me:$LINENO: checking size of off_t" >&5
+echo $ECHO_N "checking size of off_t... $ECHO_C" >&6
+if test "${ac_cv_sizeof_off_t+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
- if test "$ac_cv_type_long" = yes; then
+ if test "$ac_cv_type_off_t" = yes; then
# The cast to unsigned long works around a bug in the HP C Compiler
# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
int
main ()
{
-static int test_array [1 - 2 * !(((long) (sizeof (long))) >= 0)];
+static int test_array [1 - 2 * !(((long) (sizeof (off_t))) >= 0)];
test_array [0] = 0
;
int
main ()
{
-static int test_array [1 - 2 * !(((long) (sizeof (long))) <= $ac_mid)];
+static int test_array [1 - 2 * !(((long) (sizeof (off_t))) <= $ac_mid)];
test_array [0] = 0
;
int
main ()
{
-static int test_array [1 - 2 * !(((long) (sizeof (long))) < 0)];
+static int test_array [1 - 2 * !(((long) (sizeof (off_t))) < 0)];
test_array [0] = 0
;
int
main ()
{
-static int test_array [1 - 2 * !(((long) (sizeof (long))) >= $ac_mid)];
+static int test_array [1 - 2 * !(((long) (sizeof (off_t))) >= $ac_mid)];
test_array [0] = 0
;
int
main ()
{
-static int test_array [1 - 2 * !(((long) (sizeof (long))) <= $ac_mid)];
+static int test_array [1 - 2 * !(((long) (sizeof (off_t))) <= $ac_mid)];
test_array [0] = 0
;
rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
done
case $ac_lo in
-?*) ac_cv_sizeof_long=$ac_lo;;
-'') { { echo "$as_me:$LINENO: error: cannot compute sizeof (long), 77
+?*) ac_cv_sizeof_off_t=$ac_lo;;
+'') { { echo "$as_me:$LINENO: error: cannot compute sizeof (off_t), 77
See \`config.log' for more details." >&5
-echo "$as_me: error: cannot compute sizeof (long), 77
+echo "$as_me: error: cannot compute sizeof (off_t), 77
See \`config.log' for more details." >&2;}
{ (exit 1); exit 1; }; } ;;
esac
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
$ac_includes_default
-long longval () { return (long) (sizeof (long)); }
-unsigned long ulongval () { return (long) (sizeof (long)); }
+long longval () { return (long) (sizeof (off_t)); }
+unsigned long ulongval () { return (long) (sizeof (off_t)); }
#include <stdio.h>
#include <stdlib.h>
int
FILE *f = fopen ("conftest.val", "w");
if (! f)
exit (1);
- if (((long) (sizeof (long))) < 0)
+ if (((long) (sizeof (off_t))) < 0)
{
long i = longval ();
- if (i != ((long) (sizeof (long))))
+ if (i != ((long) (sizeof (off_t))))
exit (1);
fprintf (f, "%ld\n", i);
}
else
{
unsigned long i = ulongval ();
- if (i != ((long) (sizeof (long))))
+ if (i != ((long) (sizeof (off_t))))
exit (1);
fprintf (f, "%lu\n", i);
}
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
- ac_cv_sizeof_long=`cat conftest.val`
+ ac_cv_sizeof_off_t=`cat conftest.val`
else
echo "$as_me: program exited with status $ac_status" >&5
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
( exit $ac_status )
-{ { echo "$as_me:$LINENO: error: cannot compute sizeof (long), 77
+{ { echo "$as_me:$LINENO: error: cannot compute sizeof (off_t), 77
See \`config.log' for more details." >&5
-echo "$as_me: error: cannot compute sizeof (long), 77
+echo "$as_me: error: cannot compute sizeof (off_t), 77
See \`config.log' for more details." >&2;}
{ (exit 1); exit 1; }; }
fi
fi
rm -f conftest.val
else
- ac_cv_sizeof_long=0
+ ac_cv_sizeof_off_t=0
fi
fi
-echo "$as_me:$LINENO: result: $ac_cv_sizeof_long" >&5
-echo "${ECHO_T}$ac_cv_sizeof_long" >&6
+echo "$as_me:$LINENO: result: $ac_cv_sizeof_off_t" >&5
+echo "${ECHO_T}$ac_cv_sizeof_off_t" >&6
cat >>confdefs.h <<_ACEOF
-#define SIZEOF_LONG $ac_cv_sizeof_long
+#define SIZEOF_OFF_T $ac_cv_sizeof_off_t
_ACEOF
-echo "$as_me:$LINENO: checking for long long" >&5
-echo $ECHO_N "checking for long long... $ECHO_C" >&6
-if test "${ac_cv_type_long_long+set}" = set; then
+echo "$as_me:$LINENO: checking for size_t" >&5
+echo $ECHO_N "checking for size_t... $ECHO_C" >&6
+if test "${ac_cv_type_size_t+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
cat >conftest.$ac_ext <<_ACEOF
int
main ()
{
-if ((long long *) 0)
+if ((size_t *) 0)
return 0;
-if (sizeof (long long))
+if (sizeof (size_t))
return 0;
;
return 0;
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
- ac_cv_type_long_long=yes
+ ac_cv_type_size_t=yes
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
-ac_cv_type_long_long=no
+ac_cv_type_size_t=no
fi
rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
fi
-echo "$as_me:$LINENO: result: $ac_cv_type_long_long" >&5
-echo "${ECHO_T}$ac_cv_type_long_long" >&6
+echo "$as_me:$LINENO: result: $ac_cv_type_size_t" >&5
+echo "${ECHO_T}$ac_cv_type_size_t" >&6
-echo "$as_me:$LINENO: checking size of long long" >&5
-echo $ECHO_N "checking size of long long... $ECHO_C" >&6
-if test "${ac_cv_sizeof_long_long+set}" = set; then
+echo "$as_me:$LINENO: checking size of size_t" >&5
+echo $ECHO_N "checking size of size_t... $ECHO_C" >&6
+if test "${ac_cv_sizeof_size_t+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
- if test "$ac_cv_type_long_long" = yes; then
+ if test "$ac_cv_type_size_t" = yes; then
# The cast to unsigned long works around a bug in the HP C Compiler
# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
int
main ()
{
-static int test_array [1 - 2 * !(((long) (sizeof (long long))) >= 0)];
+static int test_array [1 - 2 * !(((long) (sizeof (size_t))) >= 0)];
test_array [0] = 0
;
int
main ()
{
-static int test_array [1 - 2 * !(((long) (sizeof (long long))) <= $ac_mid)];
+static int test_array [1 - 2 * !(((long) (sizeof (size_t))) <= $ac_mid)];
test_array [0] = 0
;
int
main ()
{
-static int test_array [1 - 2 * !(((long) (sizeof (long long))) < 0)];
+static int test_array [1 - 2 * !(((long) (sizeof (size_t))) < 0)];
test_array [0] = 0
;
int
main ()
{
-static int test_array [1 - 2 * !(((long) (sizeof (long long))) >= $ac_mid)];
+static int test_array [1 - 2 * !(((long) (sizeof (size_t))) >= $ac_mid)];
test_array [0] = 0
;
int
main ()
{
-static int test_array [1 - 2 * !(((long) (sizeof (long long))) <= $ac_mid)];
+static int test_array [1 - 2 * !(((long) (sizeof (size_t))) <= $ac_mid)];
test_array [0] = 0
;
rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
done
case $ac_lo in
-?*) ac_cv_sizeof_long_long=$ac_lo;;
-'') { { echo "$as_me:$LINENO: error: cannot compute sizeof (long long), 77
+?*) ac_cv_sizeof_size_t=$ac_lo;;
+'') { { echo "$as_me:$LINENO: error: cannot compute sizeof (size_t), 77
See \`config.log' for more details." >&5
-echo "$as_me: error: cannot compute sizeof (long long), 77
+echo "$as_me: error: cannot compute sizeof (size_t), 77
See \`config.log' for more details." >&2;}
{ (exit 1); exit 1; }; } ;;
esac
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
$ac_includes_default
-long longval () { return (long) (sizeof (long long)); }
-unsigned long ulongval () { return (long) (sizeof (long long)); }
+long longval () { return (long) (sizeof (size_t)); }
+unsigned long ulongval () { return (long) (sizeof (size_t)); }
#include <stdio.h>
#include <stdlib.h>
int
FILE *f = fopen ("conftest.val", "w");
if (! f)
exit (1);
- if (((long) (sizeof (long long))) < 0)
+ if (((long) (sizeof (size_t))) < 0)
{
long i = longval ();
- if (i != ((long) (sizeof (long long))))
+ if (i != ((long) (sizeof (size_t))))
exit (1);
fprintf (f, "%ld\n", i);
}
else
{
unsigned long i = ulongval ();
- if (i != ((long) (sizeof (long long))))
+ if (i != ((long) (sizeof (size_t))))
exit (1);
fprintf (f, "%lu\n", i);
}
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
- ac_cv_sizeof_long_long=`cat conftest.val`
+ ac_cv_sizeof_size_t=`cat conftest.val`
else
echo "$as_me: program exited with status $ac_status" >&5
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
( exit $ac_status )
-{ { echo "$as_me:$LINENO: error: cannot compute sizeof (long long), 77
+{ { echo "$as_me:$LINENO: error: cannot compute sizeof (size_t), 77
See \`config.log' for more details." >&5
-echo "$as_me: error: cannot compute sizeof (long long), 77
+echo "$as_me: error: cannot compute sizeof (size_t), 77
See \`config.log' for more details." >&2;}
{ (exit 1); exit 1; }; }
fi
fi
rm -f conftest.val
else
- ac_cv_sizeof_long_long=0
+ ac_cv_sizeof_size_t=0
fi
fi
-echo "$as_me:$LINENO: result: $ac_cv_sizeof_long_long" >&5
-echo "${ECHO_T}$ac_cv_sizeof_long_long" >&6
+echo "$as_me:$LINENO: result: $ac_cv_sizeof_size_t" >&5
+echo "${ECHO_T}$ac_cv_sizeof_size_t" >&6
cat >>confdefs.h <<_ACEOF
-#define SIZEOF_LONG_LONG $ac_cv_sizeof_long_long
+#define SIZEOF_SIZE_T $ac_cv_sizeof_size_t
_ACEOF
-echo "$as_me:$LINENO: checking for intmax_t" >&5
-echo $ECHO_N "checking for intmax_t... $ECHO_C" >&6
-if test "${ac_cv_type_intmax_t+set}" = set; then
+echo "$as_me:$LINENO: checking for ssize_t" >&5
+echo $ECHO_N "checking for ssize_t... $ECHO_C" >&6
+if test "${ac_cv_type_ssize_t+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
cat >conftest.$ac_ext <<_ACEOF
int
main ()
{
-if ((intmax_t *) 0)
+if ((ssize_t *) 0)
return 0;
-if (sizeof (intmax_t))
+if (sizeof (ssize_t))
return 0;
;
return 0;
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
- ac_cv_type_intmax_t=yes
+ ac_cv_type_ssize_t=yes
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
-ac_cv_type_intmax_t=no
+ac_cv_type_ssize_t=no
fi
rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
fi
-echo "$as_me:$LINENO: result: $ac_cv_type_intmax_t" >&5
-echo "${ECHO_T}$ac_cv_type_intmax_t" >&6
+echo "$as_me:$LINENO: result: $ac_cv_type_ssize_t" >&5
+echo "${ECHO_T}$ac_cv_type_ssize_t" >&6
-echo "$as_me:$LINENO: checking size of intmax_t" >&5
-echo $ECHO_N "checking size of intmax_t... $ECHO_C" >&6
-if test "${ac_cv_sizeof_intmax_t+set}" = set; then
+echo "$as_me:$LINENO: checking size of ssize_t" >&5
+echo $ECHO_N "checking size of ssize_t... $ECHO_C" >&6
+if test "${ac_cv_sizeof_ssize_t+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
- if test "$ac_cv_type_intmax_t" = yes; then
+ if test "$ac_cv_type_ssize_t" = yes; then
# The cast to unsigned long works around a bug in the HP C Compiler
# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
int
main ()
{
-static int test_array [1 - 2 * !(((long) (sizeof (intmax_t))) >= 0)];
+static int test_array [1 - 2 * !(((long) (sizeof (ssize_t))) >= 0)];
test_array [0] = 0
;
int
main ()
{
-static int test_array [1 - 2 * !(((long) (sizeof (intmax_t))) <= $ac_mid)];
+static int test_array [1 - 2 * !(((long) (sizeof (ssize_t))) <= $ac_mid)];
test_array [0] = 0
;
int
main ()
{
-static int test_array [1 - 2 * !(((long) (sizeof (intmax_t))) < 0)];
+static int test_array [1 - 2 * !(((long) (sizeof (ssize_t))) < 0)];
test_array [0] = 0
;
int
main ()
{
-static int test_array [1 - 2 * !(((long) (sizeof (intmax_t))) >= $ac_mid)];
+static int test_array [1 - 2 * !(((long) (sizeof (ssize_t))) >= $ac_mid)];
test_array [0] = 0
;
int
main ()
{
-static int test_array [1 - 2 * !(((long) (sizeof (intmax_t))) <= $ac_mid)];
+static int test_array [1 - 2 * !(((long) (sizeof (ssize_t))) <= $ac_mid)];
test_array [0] = 0
;
rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
done
case $ac_lo in
-?*) ac_cv_sizeof_intmax_t=$ac_lo;;
-'') { { echo "$as_me:$LINENO: error: cannot compute sizeof (intmax_t), 77
+?*) ac_cv_sizeof_ssize_t=$ac_lo;;
+'') { { echo "$as_me:$LINENO: error: cannot compute sizeof (ssize_t), 77
See \`config.log' for more details." >&5
-echo "$as_me: error: cannot compute sizeof (intmax_t), 77
+echo "$as_me: error: cannot compute sizeof (ssize_t), 77
See \`config.log' for more details." >&2;}
{ (exit 1); exit 1; }; } ;;
esac
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
$ac_includes_default
-long longval () { return (long) (sizeof (intmax_t)); }
-unsigned long ulongval () { return (long) (sizeof (intmax_t)); }
+long longval () { return (long) (sizeof (ssize_t)); }
+unsigned long ulongval () { return (long) (sizeof (ssize_t)); }
#include <stdio.h>
#include <stdlib.h>
int
FILE *f = fopen ("conftest.val", "w");
if (! f)
exit (1);
- if (((long) (sizeof (intmax_t))) < 0)
+ if (((long) (sizeof (ssize_t))) < 0)
{
long i = longval ();
- if (i != ((long) (sizeof (intmax_t))))
+ if (i != ((long) (sizeof (ssize_t))))
exit (1);
fprintf (f, "%ld\n", i);
}
else
{
unsigned long i = ulongval ();
- if (i != ((long) (sizeof (intmax_t))))
+ if (i != ((long) (sizeof (ssize_t))))
exit (1);
fprintf (f, "%lu\n", i);
}
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
- ac_cv_sizeof_intmax_t=`cat conftest.val`
+ ac_cv_sizeof_ssize_t=`cat conftest.val`
else
echo "$as_me: program exited with status $ac_status" >&5
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
( exit $ac_status )
-{ { echo "$as_me:$LINENO: error: cannot compute sizeof (intmax_t), 77
+{ { echo "$as_me:$LINENO: error: cannot compute sizeof (ssize_t), 77
See \`config.log' for more details." >&5
-echo "$as_me: error: cannot compute sizeof (intmax_t), 77
+echo "$as_me: error: cannot compute sizeof (ssize_t), 77
See \`config.log' for more details." >&2;}
{ (exit 1); exit 1; }; }
fi
fi
rm -f conftest.val
else
- ac_cv_sizeof_intmax_t=0
+ ac_cv_sizeof_ssize_t=0
fi
fi
-echo "$as_me:$LINENO: result: $ac_cv_sizeof_intmax_t" >&5
-echo "${ECHO_T}$ac_cv_sizeof_intmax_t" >&6
+echo "$as_me:$LINENO: result: $ac_cv_sizeof_ssize_t" >&5
+echo "${ECHO_T}$ac_cv_sizeof_ssize_t" >&6
cat >>confdefs.h <<_ACEOF
-#define SIZEOF_INTMAX_T $ac_cv_sizeof_intmax_t
+#define SIZEOF_SSIZE_T $ac_cv_sizeof_ssize_t
_ACEOF
-echo "$as_me:$LINENO: checking for off_t" >&5
-echo $ECHO_N "checking for off_t... $ECHO_C" >&6
-if test "${ac_cv_type_off_t+set}" = set; then
+echo "$as_me:$LINENO: checking for time_t" >&5
+echo $ECHO_N "checking for time_t... $ECHO_C" >&6
+if test "${ac_cv_type_time_t+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
cat >conftest.$ac_ext <<_ACEOF
int
main ()
{
-if ((off_t *) 0)
+if ((time_t *) 0)
return 0;
-if (sizeof (off_t))
+if (sizeof (time_t))
return 0;
;
return 0;
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
- ac_cv_type_off_t=yes
+ ac_cv_type_time_t=yes
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
-ac_cv_type_off_t=no
+ac_cv_type_time_t=no
fi
rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
fi
-echo "$as_me:$LINENO: result: $ac_cv_type_off_t" >&5
-echo "${ECHO_T}$ac_cv_type_off_t" >&6
+echo "$as_me:$LINENO: result: $ac_cv_type_time_t" >&5
+echo "${ECHO_T}$ac_cv_type_time_t" >&6
-echo "$as_me:$LINENO: checking size of off_t" >&5
-echo $ECHO_N "checking size of off_t... $ECHO_C" >&6
-if test "${ac_cv_sizeof_off_t+set}" = set; then
+echo "$as_me:$LINENO: checking size of time_t" >&5
+echo $ECHO_N "checking size of time_t... $ECHO_C" >&6
+if test "${ac_cv_sizeof_time_t+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
- if test "$ac_cv_type_off_t" = yes; then
+ if test "$ac_cv_type_time_t" = yes; then
# The cast to unsigned long works around a bug in the HP C Compiler
# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
int
main ()
{
-static int test_array [1 - 2 * !(((long) (sizeof (off_t))) >= 0)];
+static int test_array [1 - 2 * !(((long) (sizeof (time_t))) >= 0)];
test_array [0] = 0
;
int
main ()
{
-static int test_array [1 - 2 * !(((long) (sizeof (off_t))) <= $ac_mid)];
+static int test_array [1 - 2 * !(((long) (sizeof (time_t))) <= $ac_mid)];
test_array [0] = 0
;
int
main ()
{
-static int test_array [1 - 2 * !(((long) (sizeof (off_t))) < 0)];
+static int test_array [1 - 2 * !(((long) (sizeof (time_t))) < 0)];
test_array [0] = 0
;
int
main ()
{
-static int test_array [1 - 2 * !(((long) (sizeof (off_t))) >= $ac_mid)];
+static int test_array [1 - 2 * !(((long) (sizeof (time_t))) >= $ac_mid)];
test_array [0] = 0
;
int
main ()
{
-static int test_array [1 - 2 * !(((long) (sizeof (off_t))) <= $ac_mid)];
+static int test_array [1 - 2 * !(((long) (sizeof (time_t))) <= $ac_mid)];
test_array [0] = 0
;
rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
done
case $ac_lo in
-?*) ac_cv_sizeof_off_t=$ac_lo;;
-'') { { echo "$as_me:$LINENO: error: cannot compute sizeof (off_t), 77
+?*) ac_cv_sizeof_time_t=$ac_lo;;
+'') { { echo "$as_me:$LINENO: error: cannot compute sizeof (time_t), 77
See \`config.log' for more details." >&5
-echo "$as_me: error: cannot compute sizeof (off_t), 77
+echo "$as_me: error: cannot compute sizeof (time_t), 77
See \`config.log' for more details." >&2;}
{ (exit 1); exit 1; }; } ;;
esac
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
$ac_includes_default
-long longval () { return (long) (sizeof (off_t)); }
-unsigned long ulongval () { return (long) (sizeof (off_t)); }
+long longval () { return (long) (sizeof (time_t)); }
+unsigned long ulongval () { return (long) (sizeof (time_t)); }
#include <stdio.h>
#include <stdlib.h>
int
FILE *f = fopen ("conftest.val", "w");
if (! f)
exit (1);
- if (((long) (sizeof (off_t))) < 0)
+ if (((long) (sizeof (time_t))) < 0)
{
long i = longval ();
- if (i != ((long) (sizeof (off_t))))
+ if (i != ((long) (sizeof (time_t))))
exit (1);
fprintf (f, "%ld\n", i);
}
else
{
unsigned long i = ulongval ();
- if (i != ((long) (sizeof (off_t))))
+ if (i != ((long) (sizeof (time_t))))
exit (1);
fprintf (f, "%lu\n", i);
}
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
- ac_cv_sizeof_off_t=`cat conftest.val`
+ ac_cv_sizeof_time_t=`cat conftest.val`
else
echo "$as_me: program exited with status $ac_status" >&5
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
( exit $ac_status )
-{ { echo "$as_me:$LINENO: error: cannot compute sizeof (off_t), 77
+{ { echo "$as_me:$LINENO: error: cannot compute sizeof (time_t), 77
See \`config.log' for more details." >&5
-echo "$as_me: error: cannot compute sizeof (off_t), 77
+echo "$as_me: error: cannot compute sizeof (time_t), 77
See \`config.log' for more details." >&2;}
{ (exit 1); exit 1; }; }
fi
fi
rm -f conftest.val
else
- ac_cv_sizeof_off_t=0
+ ac_cv_sizeof_time_t=0
fi
fi
-echo "$as_me:$LINENO: result: $ac_cv_sizeof_off_t" >&5
-echo "${ECHO_T}$ac_cv_sizeof_off_t" >&6
+echo "$as_me:$LINENO: result: $ac_cv_sizeof_time_t" >&5
+echo "${ECHO_T}$ac_cv_sizeof_time_t" >&6
cat >>confdefs.h <<_ACEOF
-#define SIZEOF_OFF_T $ac_cv_sizeof_off_t
+#define SIZEOF_TIME_T $ac_cv_sizeof_time_t
_ACEOF
;;
*-*-irix6*)
# Find out which ABI we are using.
- echo '#line 12980 "configure"' > conftest.$ac_ext
+ echo '#line 15015 "configure"' > conftest.$ac_ext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>&5
ac_status=$?
# Provide some information about the compiler.
-echo "$as_me:14086:" \
+echo "$as_me:16121:" \
"checking for Fortran 77 compiler version" >&5
ac_compiler=`set X $ac_compile; echo $2`
{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version </dev/null >&5\"") >&5
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:15188: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:17223: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
- echo "$as_me:15192: \$? = $ac_status" >&5
+ echo "$as_me:17227: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output.
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:15450: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:17485: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
- echo "$as_me:15454: \$? = $ac_status" >&5
+ echo "$as_me:17489: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output.
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:15512: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:17547: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
- echo "$as_me:15516: \$? = $ac_status" >&5
+ echo "$as_me:17551: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<EOF
-#line 17760 "configure"
+#line 19795 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<EOF
-#line 17858 "configure"
+#line 19893 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:20117: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:22152: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
- echo "$as_me:20121: \$? = $ac_status" >&5
+ echo "$as_me:22156: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output.
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:20179: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:22214: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
- echo "$as_me:20183: \$? = $ac_status" >&5
+ echo "$as_me:22218: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<EOF
-#line 21556 "configure"
+#line 23591 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<EOF
-#line 21654 "configure"
+#line 23689 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:22539: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:24574: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
- echo "$as_me:22543: \$? = $ac_status" >&5
+ echo "$as_me:24578: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output.
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:22601: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:24636: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
- echo "$as_me:22605: \$? = $ac_status" >&5
+ echo "$as_me:24640: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:24735: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:26770: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
- echo "$as_me:24739: \$? = $ac_status" >&5
+ echo "$as_me:26774: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output.
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:24997: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:27032: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
- echo "$as_me:25001: \$? = $ac_status" >&5
+ echo "$as_me:27036: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output.
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:25059: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:27094: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
- echo "$as_me:25063: \$? = $ac_status" >&5
+ echo "$as_me:27098: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<EOF
-#line 27307 "configure"
+#line 29342 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<EOF
-#line 27405 "configure"
+#line 29440 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
LEX=${am_missing_run}flex
fi
-
-echo "$as_me:$LINENO: checking for socklen_t" >&5
-echo $ECHO_N "checking for socklen_t... $ECHO_C" >&6
-if test "${ac_cv_type_socklen_t+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <sys/types.h>
-#if STDC_HEADERS
-#include <stdlib.h>
-#include <stddef.h>
-#endif
-#include <sys/socket.h>
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- $EGREP "(^|[^a-zA-Z_0-9])socklen_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
- ac_cv_type_socklen_t=yes
-else
- ac_cv_type_socklen_t=no
-fi
-rm -f conftest*
-
-fi
-echo "$as_me:$LINENO: result: $ac_cv_type_socklen_t" >&5
-echo "${ECHO_T}$ac_cv_type_socklen_t" >&6
-if test "x$ac_cv_type_socklen_t" = xno; then
-
-cat >>confdefs.h <<\_ACEOF
-#define socklen_t int
-_ACEOF
-
-fi
-
-
echo "$as_me:$LINENO: checking for ANSI C header files" >&5
echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6
if test "${ac_cv_header_stdc+set}" = set; then
+echo "$as_me:$LINENO: checking for socklen_t" >&5
+echo $ECHO_N "checking for socklen_t... $ECHO_C" >&6
+if test "${ac_cv_type_socklen_t+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <sys/types.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#include <stddef.h>
+#endif
+#include <sys/socket.h>
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "(^|[^a-zA-Z_0-9])socklen_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
+ ac_cv_type_socklen_t=yes
+else
+ ac_cv_type_socklen_t=no
+fi
+rm -f conftest*
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_socklen_t" >&5
+echo "${ECHO_T}$ac_cv_type_socklen_t" >&6
+if test "x$ac_cv_type_socklen_t" = xno; then
+
+cat >>confdefs.h <<\_ACEOF
+#define socklen_t int
+_ACEOF
+
+fi
+
+echo "$as_me:$LINENO: checking for sa_family_t" >&5
+echo $ECHO_N "checking for sa_family_t... $ECHO_C" >&6
+if test "${ac_cv_type_sa_family_t+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <sys/types.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#include <stddef.h>
+#endif
+#include <sys/socket.h>
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "(^|[^a-zA-Z_0-9])sa_family_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
+ ac_cv_type_sa_family_t=yes
+else
+ ac_cv_type_sa_family_t=no
+fi
+rm -f conftest*
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_sa_family_t" >&5
+echo "${ECHO_T}$ac_cv_type_sa_family_t" >&6
+if test "x$ac_cv_type_sa_family_t" = xno; then
+
+cat >>confdefs.h <<\_ACEOF
+#define sa_family_t unsigned short
+_ACEOF
+
+fi
+
+
+
+
+
+
+
grp.h \
history.h \
libc.h \
+ libgen.h \
limits.h \
linux/zftape.h \
+ math.h \
mntent.h \
mnttab.h \
ndbm.h \
readline/readline.h \
scsi/sg.h \
scsi/scsi_ioctl.h \
+ stdarg.h \
stdlib.h \
string.h \
strings.h \
if test "x$ac_cv_lib_termcap_tgetent" = xyes ||
test "x$ac_cv_lib_curses_tgetent" = xyes ||
test "x$ac_cv_lib_ncurses_tgetent" = xyes; then
- echo "$as_me:$LINENO: checking for readline in -lreadline" >&5
+
+echo "$as_me:$LINENO: checking for readline in -lreadline" >&5
echo $ECHO_N "checking for readline in -lreadline... $ECHO_C" >&6
if test "${ac_cv_lib_readline_readline+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
echo "$as_me:$LINENO: result: $ac_cv_lib_readline_readline" >&5
echo "${ECHO_T}$ac_cv_lib_readline_readline" >&6
if test $ac_cv_lib_readline_readline = yes; then
- READLINE_LIBS="-lreadline";
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBREADLINE 1
+_ACEOF
+
+ LIBS="-lreadline $LIBS"
fi
- if test "x$ac_cv_lib_readline_readline" != xyes; then
+ if test "x$ac_cv_lib_readline_readline" = xyes; then
+ READLINE_LIBS="-lreadline"
+
+ else
{ echo "$as_me:$LINENO: WARNING: *** No readline library, no history and command line editing in amrecover!" >&5
echo "$as_me: WARNING: *** No readline library, no history and command line editing in amrecover!" >&2;}
fi
cat >>confdefs.h <<_ACEOF
#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
_ACEOF
- ice_have_atof=yes
+ ice_have_atof=yes
+fi
+done
+
+if test "${ice_have_atof}" = yes; then
+echo "$as_me:$LINENO: checking for atof declaration in stdlib.h" >&5
+echo $ECHO_N "checking for atof declaration in stdlib.h... $ECHO_C" >&6
+if test "${ice_cv_have_atof_decl+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ice_cv_have_atof_decl=no
+ice_re_params='[a-zA-Z_][a-zA-Z0-9_]*'
+ice_re_word='(^|[^a-zA-Z0-9_])'
+for header in stdlib.h; do
+# Check for ordinary declaration
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <$header>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "${ice_re_word}atof[ ]*\(" >/dev/null 2>&1; then
+ ice_cv_have_atof_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_atof_decl" = yes; then
+ break
+fi
+# Check for "fixed" declaration like "getpid _PARAMS((int))"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <$header>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "${ice_re_word}atof[ ]*$ice_re_params\(\(" >/dev/null 2>&1; then
+ ice_cv_have_atof_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_atof_decl" = yes; then
+ break
+fi
+done
+
+fi
+
+echo "$as_me:$LINENO: result: $ice_cv_have_atof_decl" >&5
+echo "${ECHO_T}$ice_cv_have_atof_decl" >&6
+if test "$ice_cv_have_atof_decl" = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_ATOF_DECL 1
+_ACEOF
+
+fi
+fi
+
+
+ice_have_atoi=no
+
+for ac_func in atoi
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+ ice_have_atoi=yes
+fi
+done
+
+if test "${ice_have_atoi}" = yes; then
+echo "$as_me:$LINENO: checking for atoi declaration in stdlib.h" >&5
+echo $ECHO_N "checking for atoi declaration in stdlib.h... $ECHO_C" >&6
+if test "${ice_cv_have_atoi_decl+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ice_cv_have_atoi_decl=no
+ice_re_params='[a-zA-Z_][a-zA-Z0-9_]*'
+ice_re_word='(^|[^a-zA-Z0-9_])'
+for header in stdlib.h; do
+# Check for ordinary declaration
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <$header>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "${ice_re_word}atoi[ ]*\(" >/dev/null 2>&1; then
+ ice_cv_have_atoi_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_atoi_decl" = yes; then
+ break
+fi
+# Check for "fixed" declaration like "getpid _PARAMS((int))"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <$header>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "${ice_re_word}atoi[ ]*$ice_re_params\(\(" >/dev/null 2>&1; then
+ ice_cv_have_atoi_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_atoi_decl" = yes; then
+ break
+fi
+done
+
+fi
+
+echo "$as_me:$LINENO: result: $ice_cv_have_atoi_decl" >&5
+echo "${ECHO_T}$ice_cv_have_atoi_decl" >&6
+if test "$ice_cv_have_atoi_decl" = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_ATOI_DECL 1
+_ACEOF
+
+fi
+fi
+
+
+ice_have_atol=no
+
+for ac_func in atol
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+ ice_have_atol=yes
+fi
+done
+
+if test "${ice_have_atol}" = yes; then
+echo "$as_me:$LINENO: checking for atol declaration in stdlib.h" >&5
+echo $ECHO_N "checking for atol declaration in stdlib.h... $ECHO_C" >&6
+if test "${ice_cv_have_atol_decl+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ice_cv_have_atol_decl=no
+ice_re_params='[a-zA-Z_][a-zA-Z0-9_]*'
+ice_re_word='(^|[^a-zA-Z0-9_])'
+for header in stdlib.h; do
+# Check for ordinary declaration
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <$header>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "${ice_re_word}atol[ ]*\(" >/dev/null 2>&1; then
+ ice_cv_have_atol_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_atol_decl" = yes; then
+ break
+fi
+# Check for "fixed" declaration like "getpid _PARAMS((int))"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <$header>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "${ice_re_word}atol[ ]*$ice_re_params\(\(" >/dev/null 2>&1; then
+ ice_cv_have_atol_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_atol_decl" = yes; then
+ break
+fi
+done
+
+fi
+
+echo "$as_me:$LINENO: result: $ice_cv_have_atol_decl" >&5
+echo "${ECHO_T}$ice_cv_have_atol_decl" >&6
+if test "$ice_cv_have_atol_decl" = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_ATOL_DECL 1
+_ACEOF
+
+fi
+fi
+
+
+ice_have_atoll=no
+
+for ac_func in atoll
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+ ice_have_atoll=yes
fi
done
-if test "${ice_have_atof}" = yes; then
-echo "$as_me:$LINENO: checking for atof declaration in stdlib.h" >&5
-echo $ECHO_N "checking for atof declaration in stdlib.h... $ECHO_C" >&6
-if test "${ice_cv_have_atof_decl+set}" = set; then
+if test "${ice_have_atoll}" = yes; then
+echo "$as_me:$LINENO: checking for atoll declaration in stdlib.h" >&5
+echo $ECHO_N "checking for atoll declaration in stdlib.h... $ECHO_C" >&6
+if test "${ice_cv_have_atoll_decl+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
-ice_cv_have_atof_decl=no
+ice_cv_have_atoll_decl=no
ice_re_params='[a-zA-Z_][a-zA-Z0-9_]*'
ice_re_word='(^|[^a-zA-Z0-9_])'
for header in stdlib.h; do
_ACEOF
if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- $EGREP "${ice_re_word}atof[ ]*\(" >/dev/null 2>&1; then
- ice_cv_have_atof_decl=yes
+ $EGREP "${ice_re_word}atoll[ ]*\(" >/dev/null 2>&1; then
+ ice_cv_have_atoll_decl=yes
fi
rm -f conftest*
-if test "$ice_cv_have_atof_decl" = yes; then
+if test "$ice_cv_have_atoll_decl" = yes; then
break
fi
# Check for "fixed" declaration like "getpid _PARAMS((int))"
_ACEOF
if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- $EGREP "${ice_re_word}atof[ ]*$ice_re_params\(\(" >/dev/null 2>&1; then
- ice_cv_have_atof_decl=yes
+ $EGREP "${ice_re_word}atoll[ ]*$ice_re_params\(\(" >/dev/null 2>&1; then
+ ice_cv_have_atoll_decl=yes
fi
rm -f conftest*
-if test "$ice_cv_have_atof_decl" = yes; then
+if test "$ice_cv_have_atoll_decl" = yes; then
break
fi
done
fi
-echo "$as_me:$LINENO: result: $ice_cv_have_atof_decl" >&5
-echo "${ECHO_T}$ice_cv_have_atof_decl" >&6
-if test "$ice_cv_have_atof_decl" = yes; then
+echo "$as_me:$LINENO: result: $ice_cv_have_atoll_decl" >&5
+echo "${ECHO_T}$ice_cv_have_atoll_decl" >&6
+if test "$ice_cv_have_atoll_decl" = yes; then
cat >>confdefs.h <<_ACEOF
-#define HAVE_ATOF_DECL 1
+#define HAVE_ATOLL_DECL 1
_ACEOF
fi
cat >>confdefs.h <<_ACEOF
#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
_ACEOF
- ice_have_gettimeofday=yes
-fi
-done
-
-if test "${ice_have_gettimeofday}" = yes; then
-echo "$as_me:$LINENO: checking for gettimeofday declaration in time.h sys/time.h" >&5
-echo $ECHO_N "checking for gettimeofday declaration in time.h sys/time.h... $ECHO_C" >&6
-if test "${ice_cv_have_gettimeofday_decl+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-
-ice_cv_have_gettimeofday_decl=no
-ice_re_params='[a-zA-Z_][a-zA-Z0-9_]*'
-ice_re_word='(^|[^a-zA-Z0-9_])'
-for header in time.h sys/time.h; do
-# Check for ordinary declaration
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <$header>
-
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- $EGREP "${ice_re_word}gettimeofday[ ]*\(" >/dev/null 2>&1; then
- ice_cv_have_gettimeofday_decl=yes
-fi
-rm -f conftest*
-
-if test "$ice_cv_have_gettimeofday_decl" = yes; then
- break
-fi
-# Check for "fixed" declaration like "getpid _PARAMS((int))"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <$header>
+ ice_have_gettimeofday=yes
+fi
+done
+
+if test "${ice_have_gettimeofday}" = yes; then
+echo "$as_me:$LINENO: checking for gettimeofday declaration in time.h sys/time.h" >&5
+echo $ECHO_N "checking for gettimeofday declaration in time.h sys/time.h... $ECHO_C" >&6
+if test "${ice_cv_have_gettimeofday_decl+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ice_cv_have_gettimeofday_decl=no
+ice_re_params='[a-zA-Z_][a-zA-Z0-9_]*'
+ice_re_word='(^|[^a-zA-Z0-9_])'
+for header in time.h sys/time.h; do
+# Check for ordinary declaration
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <$header>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "${ice_re_word}gettimeofday[ ]*\(" >/dev/null 2>&1; then
+ ice_cv_have_gettimeofday_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_gettimeofday_decl" = yes; then
+ break
+fi
+# Check for "fixed" declaration like "getpid _PARAMS((int))"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <$header>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "${ice_re_word}gettimeofday[ ]*$ice_re_params\(\(" >/dev/null 2>&1; then
+ ice_cv_have_gettimeofday_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_gettimeofday_decl" = yes; then
+ break
+fi
+done
+
+fi
+
+echo "$as_me:$LINENO: result: $ice_cv_have_gettimeofday_decl" >&5
+echo "${ECHO_T}$ice_cv_have_gettimeofday_decl" >&6
+if test "$ice_cv_have_gettimeofday_decl" = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_GETTIMEOFDAY_DECL 1
+_ACEOF
+
+fi
+fi
+
+
+
+ echo "$as_me:$LINENO: checking for gettimeofday number of arguments" >&5
+echo $ECHO_N "checking for gettimeofday number of arguments... $ECHO_C" >&6
+if test "${amanda_cv_gettimeofday_args+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+#ifdef TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
+#else
+# ifdef HAVE_SYS_TIME_H
+# include <sys/time.h>
+# else
+# include <time.h>
+# endif
+#endif
+
+int
+main ()
+{
+
+ struct timeval val;
+ struct timezone zone;
+ gettimeofday(&val, &zone);
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ amanda_cv_gettimeofday_args=2
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+amanda_cv_gettimeofday_args=1
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+
+
+fi
+echo "$as_me:$LINENO: result: $amanda_cv_gettimeofday_args" >&5
+echo "${ECHO_T}$amanda_cv_gettimeofday_args" >&6
+ if test "$amanda_cv_gettimeofday_args" = 2; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_TWO_ARG_GETTIMEOFDAY 1
+_ACEOF
+
+ fi
+
+
+
+
+
+for ac_func in getvfsent initgroups isascii
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- $EGREP "${ice_re_word}gettimeofday[ ]*$ice_re_params\(\(" >/dev/null 2>&1; then
- ice_cv_have_gettimeofday_decl=yes
-fi
-rm -f conftest*
-
-if test "$ice_cv_have_gettimeofday_decl" = yes; then
- break
fi
done
-fi
-
-echo "$as_me:$LINENO: result: $ice_cv_have_gettimeofday_decl" >&5
-echo "${ECHO_T}$ice_cv_have_gettimeofday_decl" >&6
-if test "$ice_cv_have_gettimeofday_decl" = yes; then
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE_GETTIMEOFDAY_DECL 1
-_ACEOF
-
-fi
-fi
-
-
-
- echo "$as_me:$LINENO: checking for gettimeofday number of arguments" >&5
-echo $ECHO_N "checking for gettimeofday number of arguments... $ECHO_C" >&6
-if test "${amanda_cv_gettimeofday_args+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-#ifdef TIME_WITH_SYS_TIME
-# include <sys/time.h>
-# include <time.h>
-#else
-# ifdef HAVE_SYS_TIME_H
-# include <sys/time.h>
-# else
-# include <time.h>
-# endif
-#endif
-
-int
-main ()
-{
-
- struct timeval val;
- struct timezone zone;
- gettimeofday(&val, &zone);
-
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- amanda_cv_gettimeofday_args=2
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-amanda_cv_gettimeofday_args=1
-
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-
-
-fi
-echo "$as_me:$LINENO: result: $amanda_cv_gettimeofday_args" >&5
-echo "${ECHO_T}$amanda_cv_gettimeofday_args" >&6
- if test "$amanda_cv_gettimeofday_args" = 2; then
-
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_TWO_ARG_GETTIMEOFDAY 1
-_ACEOF
-
- fi
-
-
-
+ice_have_initgroups=no
-for ac_func in getvfsent initgroups isascii
+for ac_func in initgroups
do
as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
echo "$as_me:$LINENO: checking for $ac_func" >&5
cat >>confdefs.h <<_ACEOF
#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
_ACEOF
+ ice_have_initgroups=yes
+fi
+done
+
+if test "${ice_have_initgroups}" = yes; then
+echo "$as_me:$LINENO: checking for initgroups declaration in grp.h sys/types.h unistd.h libc.h" >&5
+echo $ECHO_N "checking for initgroups declaration in grp.h sys/types.h unistd.h libc.h... $ECHO_C" >&6
+if test "${ice_cv_have_initgroups_decl+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ice_cv_have_initgroups_decl=no
+ice_re_params='[a-zA-Z_][a-zA-Z0-9_]*'
+ice_re_word='(^|[^a-zA-Z0-9_])'
+for header in grp.h sys/types.h unistd.h libc.h; do
+# Check for ordinary declaration
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <$header>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "${ice_re_word}initgroups[ ]*\(" >/dev/null 2>&1; then
+ ice_cv_have_initgroups_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_initgroups_decl" = yes; then
+ break
+fi
+# Check for "fixed" declaration like "getpid _PARAMS((int))"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <$header>
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "${ice_re_word}initgroups[ ]*$ice_re_params\(\(" >/dev/null 2>&1; then
+ ice_cv_have_initgroups_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_initgroups_decl" = yes; then
+ break
fi
done
+fi
-ice_have_initgroups=no
+echo "$as_me:$LINENO: result: $ice_cv_have_initgroups_decl" >&5
+echo "${ECHO_T}$ice_cv_have_initgroups_decl" >&6
+if test "$ice_cv_have_initgroups_decl" = yes; then
-for ac_func in initgroups
+cat >>confdefs.h <<_ACEOF
+#define HAVE_INITGROUPS_DECL 1
+_ACEOF
+
+fi
+fi
+
+
+ice_have_ioctl=no
+
+for ac_func in ioctl
do
as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
echo "$as_me:$LINENO: checking for $ac_func" >&5
cat >>confdefs.h <<_ACEOF
#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
_ACEOF
- ice_have_initgroups=yes
+ ice_have_ioctl=yes
fi
done
-if test "${ice_have_initgroups}" = yes; then
-echo "$as_me:$LINENO: checking for initgroups declaration in grp.h sys/types.h unistd.h libc.h" >&5
-echo $ECHO_N "checking for initgroups declaration in grp.h sys/types.h unistd.h libc.h... $ECHO_C" >&6
-if test "${ice_cv_have_initgroups_decl+set}" = set; then
+if test "${ice_have_ioctl}" = yes; then
+echo "$as_me:$LINENO: checking for ioctl declaration in sys/ioctl.h unistd.h libc.h" >&5
+echo $ECHO_N "checking for ioctl declaration in sys/ioctl.h unistd.h libc.h... $ECHO_C" >&6
+if test "${ice_cv_have_ioctl_decl+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
-ice_cv_have_initgroups_decl=no
+ice_cv_have_ioctl_decl=no
ice_re_params='[a-zA-Z_][a-zA-Z0-9_]*'
ice_re_word='(^|[^a-zA-Z0-9_])'
-for header in grp.h sys/types.h unistd.h libc.h; do
+for header in sys/ioctl.h unistd.h libc.h; do
# Check for ordinary declaration
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- $EGREP "${ice_re_word}initgroups[ ]*\(" >/dev/null 2>&1; then
- ice_cv_have_initgroups_decl=yes
+ $EGREP "${ice_re_word}ioctl[ ]*\(" >/dev/null 2>&1; then
+ ice_cv_have_ioctl_decl=yes
fi
rm -f conftest*
-if test "$ice_cv_have_initgroups_decl" = yes; then
+if test "$ice_cv_have_ioctl_decl" = yes; then
break
fi
# Check for "fixed" declaration like "getpid _PARAMS((int))"
_ACEOF
if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- $EGREP "${ice_re_word}initgroups[ ]*$ice_re_params\(\(" >/dev/null 2>&1; then
- ice_cv_have_initgroups_decl=yes
+ $EGREP "${ice_re_word}ioctl[ ]*$ice_re_params\(\(" >/dev/null 2>&1; then
+ ice_cv_have_ioctl_decl=yes
fi
rm -f conftest*
-if test "$ice_cv_have_initgroups_decl" = yes; then
+if test "$ice_cv_have_ioctl_decl" = yes; then
break
fi
done
fi
-echo "$as_me:$LINENO: result: $ice_cv_have_initgroups_decl" >&5
-echo "${ECHO_T}$ice_cv_have_initgroups_decl" >&6
-if test "$ice_cv_have_initgroups_decl" = yes; then
+echo "$as_me:$LINENO: result: $ice_cv_have_ioctl_decl" >&5
+echo "${ECHO_T}$ice_cv_have_ioctl_decl" >&6
+if test "$ice_cv_have_ioctl_decl" = yes; then
cat >>confdefs.h <<_ACEOF
-#define HAVE_INITGROUPS_DECL 1
+#define HAVE_IOCTL_DECL 1
_ACEOF
fi
fi
-ice_have_ioctl=no
+ice_have_isnormal=no
-for ac_func in ioctl
+for ac_func in isnormal
do
as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
echo "$as_me:$LINENO: checking for $ac_func" >&5
cat >>confdefs.h <<_ACEOF
#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
_ACEOF
- ice_have_ioctl=yes
+ ice_have_isnormal=yes
fi
done
-if test "${ice_have_ioctl}" = yes; then
-echo "$as_me:$LINENO: checking for ioctl declaration in sys/ioctl.h unistd.h libc.h" >&5
-echo $ECHO_N "checking for ioctl declaration in sys/ioctl.h unistd.h libc.h... $ECHO_C" >&6
-if test "${ice_cv_have_ioctl_decl+set}" = set; then
+if test "${ice_have_isnormal}" = yes; then
+echo "$as_me:$LINENO: checking for isnormal declaration in math.h" >&5
+echo $ECHO_N "checking for isnormal declaration in math.h... $ECHO_C" >&6
+if test "${ice_cv_have_isnormal_decl+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
-ice_cv_have_ioctl_decl=no
+ice_cv_have_isnormal_decl=no
ice_re_params='[a-zA-Z_][a-zA-Z0-9_]*'
ice_re_word='(^|[^a-zA-Z0-9_])'
-for header in sys/ioctl.h unistd.h libc.h; do
+for header in math.h; do
# Check for ordinary declaration
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- $EGREP "${ice_re_word}ioctl[ ]*\(" >/dev/null 2>&1; then
- ice_cv_have_ioctl_decl=yes
+ $EGREP "${ice_re_word}isnormal[ ]*\(" >/dev/null 2>&1; then
+ ice_cv_have_isnormal_decl=yes
fi
rm -f conftest*
-if test "$ice_cv_have_ioctl_decl" = yes; then
+if test "$ice_cv_have_isnormal_decl" = yes; then
break
fi
# Check for "fixed" declaration like "getpid _PARAMS((int))"
_ACEOF
if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- $EGREP "${ice_re_word}ioctl[ ]*$ice_re_params\(\(" >/dev/null 2>&1; then
- ice_cv_have_ioctl_decl=yes
+ $EGREP "${ice_re_word}isnormal[ ]*$ice_re_params\(\(" >/dev/null 2>&1; then
+ ice_cv_have_isnormal_decl=yes
fi
rm -f conftest*
-if test "$ice_cv_have_ioctl_decl" = yes; then
+if test "$ice_cv_have_isnormal_decl" = yes; then
break
fi
done
fi
-echo "$as_me:$LINENO: result: $ice_cv_have_ioctl_decl" >&5
-echo "${ECHO_T}$ice_cv_have_ioctl_decl" >&6
-if test "$ice_cv_have_ioctl_decl" = yes; then
+echo "$as_me:$LINENO: result: $ice_cv_have_isnormal_decl" >&5
+echo "${ECHO_T}$ice_cv_have_isnormal_decl" >&6
+if test "$ice_cv_have_isnormal_decl" = yes; then
cat >>confdefs.h <<_ACEOF
-#define HAVE_IOCTL_DECL 1
+#define HAVE_ISNORMAL_DECL 1
_ACEOF
fi
done
-# Check whether --enable-largefile or --disable-largefile was given.
-if test "${enable_largefile+set}" = set; then
- enableval="$enable_largefile"
-
-fi;
-if test "$enable_largefile" != no; then
-
- echo "$as_me:$LINENO: checking for special C compiler options needed for large files" >&5
-echo $ECHO_N "checking for special C compiler options needed for large files... $ECHO_C" >&6
-if test "${ac_cv_sys_largefile_CC+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_cv_sys_largefile_CC=no
- if test "$GCC" != yes; then
- ac_save_CC=$CC
- while :; do
- # IRIX 6.2 and later do not support large files by default,
- # so use the C compiler's -n32 option if that helps.
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <sys/types.h>
- /* Check that off_t can represent 2**63 - 1 correctly.
- We can't simply define LARGE_OFF_T to be 9223372036854775807,
- since some C++ compilers masquerading as C compilers
- incorrectly reject 9223372036854775807. */
-#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
- int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
- && LARGE_OFF_T % 2147483647 == 1)
- ? 1 : -1];
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
- rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- break
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-fi
-rm -f conftest.err conftest.$ac_objext
- CC="$CC -n32"
- rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_sys_largefile_CC=' -n32'; break
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-fi
-rm -f conftest.err conftest.$ac_objext
- break
- done
- CC=$ac_save_CC
- rm -f conftest.$ac_ext
- fi
-fi
-echo "$as_me:$LINENO: result: $ac_cv_sys_largefile_CC" >&5
-echo "${ECHO_T}$ac_cv_sys_largefile_CC" >&6
- if test "$ac_cv_sys_largefile_CC" != no; then
- CC=$CC$ac_cv_sys_largefile_CC
- fi
-
- echo "$as_me:$LINENO: checking for _FILE_OFFSET_BITS value needed for large files" >&5
-echo $ECHO_N "checking for _FILE_OFFSET_BITS value needed for large files... $ECHO_C" >&6
-if test "${ac_cv_sys_file_offset_bits+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- while :; do
- ac_cv_sys_file_offset_bits=no
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <sys/types.h>
- /* Check that off_t can represent 2**63 - 1 correctly.
- We can't simply define LARGE_OFF_T to be 9223372036854775807,
- since some C++ compilers masquerading as C compilers
- incorrectly reject 9223372036854775807. */
-#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
- int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
- && LARGE_OFF_T % 2147483647 == 1)
- ? 1 : -1];
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- break
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#define _FILE_OFFSET_BITS 64
-#include <sys/types.h>
- /* Check that off_t can represent 2**63 - 1 correctly.
- We can't simply define LARGE_OFF_T to be 9223372036854775807,
- since some C++ compilers masquerading as C compilers
- incorrectly reject 9223372036854775807. */
-#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
- int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
- && LARGE_OFF_T % 2147483647 == 1)
- ? 1 : -1];
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_sys_file_offset_bits=64; break
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
- break
-done
-fi
-echo "$as_me:$LINENO: result: $ac_cv_sys_file_offset_bits" >&5
-echo "${ECHO_T}$ac_cv_sys_file_offset_bits" >&6
-if test "$ac_cv_sys_file_offset_bits" != no; then
-
-cat >>confdefs.h <<_ACEOF
-#define _FILE_OFFSET_BITS $ac_cv_sys_file_offset_bits
-_ACEOF
-
-fi
-rm -f conftest*
- echo "$as_me:$LINENO: checking for _LARGE_FILES value needed for large files" >&5
-echo $ECHO_N "checking for _LARGE_FILES value needed for large files... $ECHO_C" >&6
-if test "${ac_cv_sys_large_files+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- while :; do
- ac_cv_sys_large_files=no
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <sys/types.h>
- /* Check that off_t can represent 2**63 - 1 correctly.
- We can't simply define LARGE_OFF_T to be 9223372036854775807,
- since some C++ compilers masquerading as C compilers
- incorrectly reject 9223372036854775807. */
-#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
- int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
- && LARGE_OFF_T % 2147483647 == 1)
- ? 1 : -1];
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- break
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#define _LARGE_FILES 1
-#include <sys/types.h>
- /* Check that off_t can represent 2**63 - 1 correctly.
- We can't simply define LARGE_OFF_T to be 9223372036854775807,
- since some C++ compilers masquerading as C compilers
- incorrectly reject 9223372036854775807. */
-#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
- int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
- && LARGE_OFF_T % 2147483647 == 1)
- ? 1 : -1];
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_sys_large_files=1; break
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
- break
-done
-fi
-echo "$as_me:$LINENO: result: $ac_cv_sys_large_files" >&5
-echo "${ECHO_T}$ac_cv_sys_large_files" >&6
-if test "$ac_cv_sys_large_files" != no; then
-
-cat >>confdefs.h <<_ACEOF
-#define _LARGE_FILES $ac_cv_sys_large_files
-_ACEOF
-
-fi
-rm -f conftest*
-fi
-
echo "$as_me:$LINENO: checking disk device prefixes" >&5
echo $ECHO_N "checking disk device prefixes... $ECHO_C" >&6
-# Check whether --with-xsltproc or --without-xsltproc was given.
-if test "${with_xsltproc+set}" = set; then
- withval="$with_xsltproc"
- case "$withval" in
- y | ye | yes)
- USE_XSLTPROC=yes;;
- n | no)
- USE_XSLTPROC=no;;
- *)
- USE_XSLTPROC=yes;
- XSLTPROC="$withval";;
- esac
-
+# Check whether --with-built-manpages or --without-built-manpages was given.
+if test "${with_built_manpages+set}" = set; then
+ withval="$with_built_manpages"
+ BUILDMANPAGES=$withval;
else
- USE_XSLTPROC=maybe;
+ BUILDMANPAGES=yes;
fi;
+if test "x$BUILDMANPAGES" = "xyes"; then
+ BUILD_MAN_PAGES_TRUE=
+ BUILD_MAN_PAGES_FALSE='#'
+else
+ BUILD_MAN_PAGES_TRUE='#'
+ BUILD_MAN_PAGES_FALSE=
+fi
-# This looks bad, but && and || have equal precedence in shells, so
-# actually it's all OK.
-if test "$USE_XSLTPROC" = "yes" || test "$USE_XSLTPROC" = "maybe" && \
- test -z "$XSLTPROC"; then
- # Extract the first word of "xsltproc", so it can be a program name with args.
-set dummy xsltproc; ac_word=$2
+
+for ac_prog in xsltproc
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
echo "$as_me:$LINENO: checking for $ac_word" >&5
echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
if test "${ac_cv_path_XSLTPROC+set}" = set; then
;;
*)
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
+for as_dir in $LOCSYSPATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
echo "${ECHO_T}no" >&6
fi
- if test -n "$XSLTPROC"; then
- USE_XSLTPROC=yes;
- else
- if test "$USE_XSLTPROC" = yes; then
- { { echo "$as_me:$LINENO: error: can't find xsltproc, but running with --with-xsltproc." >&5
-echo "$as_me: error: can't find xsltproc, but running with --with-xsltproc." >&2;}
- { (exit 1); exit 1; }; }
- else
- USE_XSLTPROC=no;
- fi
- fi
-fi
+ test -n "$XSLTPROC" && break
+done
+
+if test -z "$XSLTPROC"; then
+ USE_XSLTPROC=no
+ { echo "$as_me:$LINENO: WARNING: can't find xsltproc, xsltproc support is unavailable" >&5
+echo "$as_me: WARNING: can't find xsltproc, xsltproc support is unavailable" >&2;}
+else
+ USE_XSLTPROC=yes
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_XSLTPROC 1
+_ACEOF
+fi
-if test "$USE_XSLTPROC" = yes; then
+
+if test "x$USE_XSLTPROC" = "xyes"; then
HAVE_XSLTPROC_TRUE=
HAVE_XSLTPROC_FALSE='#'
else
fi
- ac_config_files="$ac_config_files amplot/amcat.awk amplot/amplot.sh amplot/Makefile changer-src/chg-manual.sh changer-src/chg-multi.sh changer-src/chg-mtx.sh changer-src/chg-chs.sh changer-src/chg-rth.pl changer-src/chg-chio.pl changer-src/chg-zd-mtx.sh changer-src/Makefile changer-src/chg-juke.sh changer-src/chg-rait.sh changer-src/chg-null.sh changer-src/chg-mcutil.sh changer-src/chg-disk.sh changer-src/chg-iomega.pl client-src/patch-system.sh client-src/Makefile dumper-src/gnutar.pl dumper-src/generic-dumper.pl dumper-src/Makefile common-src/versuff.c common-src/Makefile example/amanda.conf example/Makefile example/chg-mcutil.conf man/Makefile docs/Makefile recover-src/Makefile restore-src/Makefile server-src/amcheckdb.sh server-src/amcleanup.sh server-src/amdump.sh server-src/amfreetapes.sh server-src/amoverview.pl server-src/amrmtape.sh server-src/amtoc.pl server-src/amverify.sh server-src/Makefile server-src/amstatus.pl server-src/amverifyrun.sh server-src/amcrypt.sh server-src/amaespipe.sh tape-src/Makefile config/Makefile Makefile"
+#### Enforce amanda code cleanliness rules.
+#### Done here to allow configuration code to remain intact.
+if test "x$CC" = "xgcc"; then
+ AM_CFLAGS="$AM_CFLAGS -Wall"
+ $CC -v --help 2>&1 | $GREP -- '-Wextra ' 2>&1 > /dev/null
+ if test $? -eq 0; then
+ AM_CFLAGS="$AM_CFLAGS -Wextra"
+ else
+ AM_CFLAGS="$AM_CFLAGS -W"
+ fi
+
+ $CC -v --help 2>&1 | $GREP -- '-Wparentheses' 2>&1 > /dev/null
+ if test $? -eq 0; then
+ AM_CFLAGS="$AM_CFLAGS -Wparentheses"
+ fi
+
+ $CC -v --help 2>&1 | $GREP -- '-Wdeclaration-after-statement' 2>&1 > /dev/null
+ if test $? -eq 0; then
+ AM_CFLAGS="$AM_CFLAGS -Wdeclaration-after-statement"
+ fi
+
+ $CC -v --help 2>&1 | $GREP -- '-Wmissing-prototypes ' 2>&1 > /dev/null
+ if test $? -eq 0; then
+ AM_CFLAGS="$AM_CFLAGS -Wmissing-prototypes"
+ fi
+
+ $CC -v --help 2>&1 | $GREP -- '-Wstrict-prototypes ' 2>&1 > /dev/null
+ if test $? -eq 0; then
+ AM_CFLAGS="$AM_CFLAGS -Wstrict-prototypes"
+ fi
+
+ $CC -v --help 2>&1 | $GREP -- '-Wmissing-declarations ' 2>&1 > /dev/null
+ if test $? -eq 0; then
+ AM_CFLAGS="$AM_CFLAGS -Wmissing-declarations"
+ fi
+
+ $CC -v --help 2>&1 | $GREP -- '-Wformat' 2>&1 > /dev/null
+ if test $? -eq 0; then
+ AM_CFLAGS="$AM_CFLAGS -Wformat"
+ fi
+
+ $CC -v --help 2>&1 | $GREP -- '-Wsign-compare' 2>&1 > /dev/null
+ if test $? -eq 0; then
+ AM_CFLAGS="$AM_CFLAGS -Wsign-compare"
+ fi
+
+ $CC -v --help 2>&1 | $GREP -- '-fno-strict-aliasing' 2>&1 > /dev/null
+ if test $? -eq 0; then
+ AM_CFLAGS="$AM_CFLAGS -fno-strict-aliasing"
+ fi
+
+ $CC -v --help 2>&1 | $GREP -- '-Wfloat-equal' 2>&1 > /dev/null
+ if test $? -eq 0; then
+ AM_CFLAGS="$AM_CFLAGS -Wfloat-equal"
+ fi
+
+ $CC -v --help 2>&1 | $GREP -- '-Wold-style-definition' 2>&1 > /dev/null
+ if test $? -eq 0; then
+ AM_CFLAGS="$AM_CFLAGS -Wold-style-definition"
+ fi
+fi
+
+
+ ac_config_files="$ac_config_files amplot/amcat.awk amplot/amplot.sh amplot/Makefile amandad-src/Makefile changer-src/chg-manual.sh changer-src/chg-multi.sh changer-src/chg-mtx.sh changer-src/chg-chs.sh changer-src/chg-rth.pl changer-src/chg-chio.pl changer-src/chg-zd-mtx.sh changer-src/Makefile changer-src/chg-juke.sh changer-src/chg-rait.sh changer-src/chg-null.sh changer-src/chg-mcutil.sh changer-src/chg-disk.sh changer-src/chg-iomega.pl client-src/patch-system.sh client-src/Makefile dumper-src/gnutar.pl dumper-src/generic-dumper.pl dumper-src/Makefile common-src/versuff.c common-src/Makefile example/amanda.conf example/Makefile example/chg-mcutil.conf example/amanda-client.conf man/Makefile docs/Makefile recover-src/Makefile oldrecover-src/Makefile restore-src/Makefile server-src/amcheckdb.sh server-src/amcleanup.sh server-src/amdump.sh server-src/amfreetapes.sh server-src/amoverview.pl server-src/amrmtape.sh server-src/amtoc.pl server-src/amverify.sh server-src/Makefile server-src/amstatus.pl server-src/amverifyrun.sh server-src/amcrypt.sh server-src/amaespipe.sh server-src/amcrypt-ossl.sh server-src/amcrypt-ossl-asym.sh tape-src/Makefile config/Makefile Makefile"
+
cat >confcache <<\_ACEOF
# This file is a shell script that caches the results of configure
Usually this means the macro was only invoked conditionally." >&2;}
{ (exit 1); exit 1; }; }
fi
+if test -z "${BUILD_MAN_PAGES_TRUE}" && test -z "${BUILD_MAN_PAGES_FALSE}"; then
+ { { echo "$as_me:$LINENO: error: conditional \"BUILD_MAN_PAGES\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+echo "$as_me: error: conditional \"BUILD_MAN_PAGES\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+ { (exit 1); exit 1; }; }
+fi
if test -z "${HAVE_XSLTPROC_TRUE}" && test -z "${HAVE_XSLTPROC_FALSE}"; then
{ { echo "$as_me:$LINENO: error: conditional \"HAVE_XSLTPROC\" was never defined.
Usually this means the macro was only invoked conditionally." >&5
"amplot/amcat.awk" ) CONFIG_FILES="$CONFIG_FILES amplot/amcat.awk" ;;
"amplot/amplot.sh" ) CONFIG_FILES="$CONFIG_FILES amplot/amplot.sh" ;;
"amplot/Makefile" ) CONFIG_FILES="$CONFIG_FILES amplot/Makefile" ;;
+ "amandad-src/Makefile" ) CONFIG_FILES="$CONFIG_FILES amandad-src/Makefile" ;;
"changer-src/chg-manual.sh" ) CONFIG_FILES="$CONFIG_FILES changer-src/chg-manual.sh" ;;
"changer-src/chg-multi.sh" ) CONFIG_FILES="$CONFIG_FILES changer-src/chg-multi.sh" ;;
"changer-src/chg-mtx.sh" ) CONFIG_FILES="$CONFIG_FILES changer-src/chg-mtx.sh" ;;
"example/amanda.conf" ) CONFIG_FILES="$CONFIG_FILES example/amanda.conf" ;;
"example/Makefile" ) CONFIG_FILES="$CONFIG_FILES example/Makefile" ;;
"example/chg-mcutil.conf" ) CONFIG_FILES="$CONFIG_FILES example/chg-mcutil.conf" ;;
+ "example/amanda-client.conf" ) CONFIG_FILES="$CONFIG_FILES example/amanda-client.conf" ;;
"man/Makefile" ) CONFIG_FILES="$CONFIG_FILES man/Makefile" ;;
"docs/Makefile" ) CONFIG_FILES="$CONFIG_FILES docs/Makefile" ;;
"recover-src/Makefile" ) CONFIG_FILES="$CONFIG_FILES recover-src/Makefile" ;;
+ "oldrecover-src/Makefile" ) CONFIG_FILES="$CONFIG_FILES oldrecover-src/Makefile" ;;
"restore-src/Makefile" ) CONFIG_FILES="$CONFIG_FILES restore-src/Makefile" ;;
"server-src/amcheckdb.sh" ) CONFIG_FILES="$CONFIG_FILES server-src/amcheckdb.sh" ;;
"server-src/amcleanup.sh" ) CONFIG_FILES="$CONFIG_FILES server-src/amcleanup.sh" ;;
"server-src/amverifyrun.sh" ) CONFIG_FILES="$CONFIG_FILES server-src/amverifyrun.sh" ;;
"server-src/amcrypt.sh" ) CONFIG_FILES="$CONFIG_FILES server-src/amcrypt.sh" ;;
"server-src/amaespipe.sh" ) CONFIG_FILES="$CONFIG_FILES server-src/amaespipe.sh" ;;
+ "server-src/amcrypt-ossl.sh" ) CONFIG_FILES="$CONFIG_FILES server-src/amcrypt-ossl.sh" ;;
+ "server-src/amcrypt-ossl-asym.sh" ) CONFIG_FILES="$CONFIG_FILES server-src/amcrypt-ossl-asym.sh" ;;
"tape-src/Makefile" ) CONFIG_FILES="$CONFIG_FILES tape-src/Makefile" ;;
"config/Makefile" ) CONFIG_FILES="$CONFIG_FILES config/Makefile" ;;
"Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;;
s,@VERSION_PATCH@,$VERSION_PATCH,;t t
s,@VERSION_COMMENT@,$VERSION_COMMENT,;t t
s,@VERSION_SUFFIX@,$VERSION_SUFFIX,;t t
+s,@CC@,$CC,;t t
+s,@CFLAGS@,$CFLAGS,;t t
+s,@LDFLAGS@,$LDFLAGS,;t t
+s,@CPPFLAGS@,$CPPFLAGS,;t t
+s,@ac_ct_CC@,$ac_ct_CC,;t t
+s,@EXEEXT@,$EXEEXT,;t t
+s,@OBJEXT@,$OBJEXT,;t t
+s,@DEPDIR@,$DEPDIR,;t t
+s,@am__include@,$am__include,;t t
+s,@am__quote@,$am__quote,;t t
+s,@AMDEP_TRUE@,$AMDEP_TRUE,;t t
+s,@AMDEP_FALSE@,$AMDEP_FALSE,;t t
+s,@AMDEPBACKSLASH@,$AMDEPBACKSLASH,;t t
+s,@CCDEPMODE@,$CCDEPMODE,;t t
+s,@am__fastdepCC_TRUE@,$am__fastdepCC_TRUE,;t t
+s,@am__fastdepCC_FALSE@,$am__fastdepCC_FALSE,;t t
+s,@GREP@,$GREP,;t t
+s,@EGREP@,$EGREP,;t t
+s,@AMLINT@,$AMLINT,;t t
+s,@AMLINTFLAGS@,$AMLINTFLAGS,;t t
s,@DUMPER_DIR@,$DUMPER_DIR,;t t
s,@CONFIG_DIR@,$CONFIG_DIR,;t t
s,@USE_VERSION_SUFFIXES@,$USE_VERSION_SUFFIXES,;t t
s,@AMANDA_DBGDIR@,$AMANDA_DBGDIR,;t t
s,@AMANDA_DEBUG_DAYS@,$AMANDA_DEBUG_DAYS,;t t
s,@SERVICE_SUFFIX@,$SERVICE_SUFFIX,;t t
-s,@CC@,$CC,;t t
-s,@CFLAGS@,$CFLAGS,;t t
-s,@LDFLAGS@,$LDFLAGS,;t t
-s,@CPPFLAGS@,$CPPFLAGS,;t t
-s,@ac_ct_CC@,$ac_ct_CC,;t t
-s,@EXEEXT@,$EXEEXT,;t t
-s,@OBJEXT@,$OBJEXT,;t t
-s,@DEPDIR@,$DEPDIR,;t t
-s,@am__include@,$am__include,;t t
-s,@am__quote@,$am__quote,;t t
-s,@AMDEP_TRUE@,$AMDEP_TRUE,;t t
-s,@AMDEP_FALSE@,$AMDEP_FALSE,;t t
-s,@AMDEPBACKSLASH@,$AMDEPBACKSLASH,;t t
-s,@CCDEPMODE@,$CCDEPMODE,;t t
-s,@am__fastdepCC_TRUE@,$am__fastdepCC_TRUE,;t t
-s,@am__fastdepCC_FALSE@,$am__fastdepCC_FALSE,;t t
s,@MT_FILE_FLAG@,$MT_FILE_FLAG,;t t
s,@CPP@,$CPP,;t t
-s,@EGREP@,$EGREP,;t t
s,@AR@,$AR,;t t
s,@AWK_VAR_ASSIGNMENT_OPT@,$AWK_VAR_ASSIGNMENT_OPT,;t t
s,@YACC@,$YACC,;t t
s,@DD@,$DD,;t t
s,@GETCONF@,$GETCONF,;t t
s,@GNUPLOT@,$GNUPLOT,;t t
-s,@GREP@,$GREP,;t t
s,@GNUTAR@,$GNUTAR,;t t
s,@SAMBA_CLIENT@,$SAMBA_CLIENT,;t t
s,@GZIP@,$GZIP,;t t
s,@LTLIBOBJS@,$LTLIBOBJS,;t t
s,@LTALLOCA@,$LTALLOCA,;t t
s,@DOC_BUILD_DATE@,$DOC_BUILD_DATE,;t t
+s,@BUILD_MAN_PAGES_TRUE@,$BUILD_MAN_PAGES_TRUE,;t t
+s,@BUILD_MAN_PAGES_FALSE@,$BUILD_MAN_PAGES_FALSE,;t t
s,@XSLTPROC@,$XSLTPROC,;t t
s,@HAVE_XSLTPROC_TRUE@,$HAVE_XSLTPROC_TRUE,;t t
s,@HAVE_XSLTPROC_FALSE@,$HAVE_XSLTPROC_FALSE,;t t
+s,@AM_CFLAGS@,$AM_CFLAGS,;t t
CEOF
_ACEOF
-dnl Process this file with autoconf to produce a configure script.
AC_INIT
AC_CONFIG_SRCDIR([common-src/amanda.h])
[Saves the original ./configure command line arguments])
AC_SUBST(CONFIGURE_COMMAND)
-AM_INIT_AUTOMAKE(amanda, 2.5.0p2)
+AM_INIT_AUTOMAKE(amanda, 2.5.1)
AM_CONFIG_HEADER(config/config.h)
AC_PREREQ(2.57) dnl Minimum Autoconf version required.
AC_SUBST(VERSION_SUFFIX)
dnl
-dnl runtime and compile time
+dnl runtime and compile time paths
dnl
-SYSPATH="/bin:/usr/bin:/sbin:/usr/sbin:/usr/ucb:/usr/bsd:/etc:/usr/etc"
+SYSPATH="/bin:/usr/bin:/sbin:/usr/sbin:/opt/SUNWspro/bin:/usr/ucb:/usr/bsd:/etc:/usr/etc"
LOCPATH=`(
test "x$prefix" = xNONE && prefix=$ac_default_prefix
test "x$exec_prefix" = xNONE && exec_prefix=${prefix}
SYSLOCPATH="$SYSPATH:$LOCPATH"
LOCSYSPATH="$LOCPATH:$SYSPATH"
+dnl
+dnl Set up compiler location, basic CFLAGS, and include locations
+dnl and library locations before we start checking the system
+dnl configuration in more detail...
+dnl
+
AC_ARG_WITH(cflags,
[ --with-cflags=CFLAGS arguments to the c compiler (-Wall, -g, etc)],
[
case "$withval" in
"" | y | ye | yes | n | no)
- AC_MSG_ERROR([*** You must supply an argument to the --with-includes option.])
+ AC_MSG_ERROR([*** You must supply an argument to the --with-cflags option.])
;;
esac
CFLAGS="$withval"
])
+CFLAGS="-D_GNU_SOURCE $CFLAGS"
+
+AC_PROG_CC
+AC_OBJEXT
+AC_EXEEXT
+AC_SYS_LARGEFILE
+
+dnl
+dnl Process tool locations for tools we need right away to configure.
+dnl
+AC_PATH_PROGS(GREP,grep,,$LOCSYSPATH)
+if test -z "$GREP"; then
+ GREP=grep
+fi
+AC_DEFINE_UNQUOTED(GREP,"$GREP",[Define the location of the grep program. ])
+AC_PATH_PROGS(EGREP,egrep,,$LOCSYSPATH)
+
+AC_PATH_PROGS(AMLINT,lint,,/opt/SUNWspro/bin:$SYSLOCPATH)
+if test ! -z "$AMLINT"; then
+ $AMLINT -flags | $GREP -- '-errfmt=' 2>&1 > /dev/null
+ if test $? -eq 0; then
+ AMLINTFLAGS="-n -s -u -m -x"
+ AMLINTFLAGS="$AMLINTFLAGS -errchk=%all"
+ AMLINTFLAGS="$AMLINTFLAGS -errfmt=macro"
+ AMLINTFLAGS="$AMLINTFLAGS -errhdr=no%/usr/include"
+ AMLINTFLAGS="$AMLINTFLAGS -errhdr=%user"
+ AMLINTFLAGS="$AMLINTFLAGS -errsecurity=extended"
+ AMLINTFLAGS="$AMLINTFLAGS -errtags=yes"
+ AMLINTFLAGS="$AMLINTFLAGS -Ncheck=%all"
+ AMLINTFLAGS="$AMLINTFLAGS -Nlevel=2"
+ AMLINTFLAGS="$AMLINTFLAGS -erroff=E_ASGN_NEVER_USED"
+ AMLINTFLAGS="$AMLINTFLAGS,E_ASGN_RESET"
+ AMLINTFLAGS="$AMLINTFLAGS,E_CAST_INT_CONST_TO_SMALL_INT"
+ AMLINTFLAGS="$AMLINTFLAGS,E_CAST_INT_TO_SMALL_INT"
+ AMLINTFLAGS="$AMLINTFLAGS,E_CAST_UINT_TO_SIGNED_INT"
+ AMLINTFLAGS="$AMLINTFLAGS,E_CONSTANT_CONDITION"
+ AMLINTFLAGS="$AMLINTFLAGS,E_ENUM_UNUSE"
+ AMLINTFLAGS="$AMLINTFLAGS,E_EXPR_NULL_EFFECT"
+ AMLINTFLAGS="$AMLINTFLAGS,E_FUNC_RET_ALWAYS_IGNOR"
+ AMLINTFLAGS="$AMLINTFLAGS,E_FUNC_RET_MAYBE_IGNORED"
+ AMLINTFLAGS="$AMLINTFLAGS,E_H_C_CHECK0"
+ AMLINTFLAGS="$AMLINTFLAGS,E_H_C_CHECK1"
+ AMLINTFLAGS="$AMLINTFLAGS,E_H_C_CHECK2"
+ AMLINTFLAGS="$AMLINTFLAGS,E_INCL_MNUSD"
+ AMLINTFLAGS="$AMLINTFLAGS,E_INCL_NUSD"
+ AMLINTFLAGS="$AMLINTFLAGS,E_MCR_NODIFF"
+ AMLINTFLAGS="$AMLINTFLAGS,E_NAME_MULTIPLY_DEF"
+ AMLINTFLAGS="$AMLINTFLAGS,E_P_REF_NULL_PSBL"
+ AMLINTFLAGS="$AMLINTFLAGS,E_P_REF_SUSP"
+ AMLINTFLAGS="$AMLINTFLAGS,E_PTRDIFF_OVERFLOW"
+ AMLINTFLAGS="$AMLINTFLAGS,E_P_USE_NULL_PSBL"
+ AMLINTFLAGS="$AMLINTFLAGS,E_P_USE_SUSP"
+ AMLINTFLAGS="$AMLINTFLAGS,E_SEC_ACCESS_WARN"
+ AMLINTFLAGS="$AMLINTFLAGS,E_SEC_CHDIR_WARN"
+ AMLINTFLAGS="$AMLINTFLAGS,E_SEC_CHMOD_WARN"
+ AMLINTFLAGS="$AMLINTFLAGS,E_SEC_CREAT_WITHOUT_EXCL"
+ AMLINTFLAGS="$AMLINTFLAGS,E_SEC_EXEC_PATH"
+ AMLINTFLAGS="$AMLINTFLAGS,E_SEC_EXEC_WARN"
+ AMLINTFLAGS="$AMLINTFLAGS,E_SEC_FOPEN_MODE"
+ AMLINTFLAGS="$AMLINTFLAGS,E_SEC_GETENV_WARN"
+ AMLINTFLAGS="$AMLINTFLAGS,E_SEC_MKDIR_WARN"
+ AMLINTFLAGS="$AMLINTFLAGS,E_SEC_PRINTF_VAR_FMT"
+ AMLINTFLAGS="$AMLINTFLAGS,E_SEC_RAND_WARN"
+ AMLINTFLAGS="$AMLINTFLAGS,E_SEC_SCANF_VAR_FMT"
+ AMLINTFLAGS="$AMLINTFLAGS,E_SEC_SELECT_WARN"
+ AMLINTFLAGS="$AMLINTFLAGS,E_SEC_SHELL_WARN"
+ AMLINTFLAGS="$AMLINTFLAGS,E_SEC_STRNCPY_WARN"
+ AMLINTFLAGS="$AMLINTFLAGS,E_SEC_UMASK_WARN"
+ AMLINTFLAGS="$AMLINTFLAGS,E_SEC_USE_AFTER_STAT"
+ AMLINTFLAGS="$AMLINTFLAGS,E_SIGN_EXTENSION_PSBL"
+ AMLINTFLAGS="$AMLINTFLAGS,E_TYPEDEF_UNUSE"
+ AMLINTFLAGS="$AMLINTFLAGS,E_UNCAL_F"
+ else
+ AMLINTFLAGS=""
+ fi
+else
+ AC_PATH_PROGS(AMLINT,splint,,$SYSLOCPATH)
+ if test ! -z "$AMLINT"; then
+ AMLINT="splint"
+ fi
+ AMLINTFLAGS='+show-scan +unixlib -weak -globs +usedef +usereleased +impouts -paramimptemp -varuse -warnposix -redef -preproc -fixedformalarray -retval -unrecog -usevarargs -formatcode'
+fi
+AC_SUBST(AMLINTFLAGS)
+
AC_ARG_WITH(includes,
[ --with-includes=DIR site header files for readline, etc in DIR],
[
done
fi
+dnl
+dnl Process configuration flags
+dnl
+
AC_ARG_WITH(dumperdir,
[ --with-dumperdir=DIR where we install the dumpers [[EPREFIX/dumper]]],
[
dnl bytes are returned upon reading to the next tape mark,
dnl instead of returning an error. Look for devices that have
dnl a 'b' in their name.
- tape_dev=null:
- nr_tape_dev=null:
+ tape_dev=
+ nr_tape_dev=
if test -d /dev/rmt; then
dnl See if we can find two devices, one being the norewind
]
)
-if test -z "$DEFAULT_TAPE_DEVICE"; then
- DEFAULT_TAPE_DEVICE=/dev/null
+if test ! -z "$DEFAULT_TAPE_DEVICE"; then
+ AC_DEFINE_UNQUOTED(DEFAULT_TAPE_DEVICE,"$DEFAULT_TAPE_DEVICE",[This is the default no-rewinding tape device. ])
+ AC_SUBST(DEFAULT_TAPE_DEVICE)
fi
-AC_DEFINE_UNQUOTED(DEFAULT_TAPE_DEVICE,"$DEFAULT_TAPE_DEVICE",[This is the default no-rewinding tape device. ])
-AC_SUBST(DEFAULT_TAPE_DEVICE)
-
AC_ARG_WITH(ftape-raw-device,
[ --with-ftape-rawdevice=ARG raw device on tape server HOST's if using Linux ftape >=3.04d],
[
;;
esac
+AC_ARG_WITH(reuseports,
+ [ --without-reuseaddr Don't closed network connections to be reused until full timeout period.],
+ [ case "$withval" in
+ y | ye | yes)
+ REUSEADDR=no;;
+ n | no)
+ REUSEADDR=yes;;
+ *)
+ REUSEADDR=no;;
+ esac
+ ],
+ [ REUSEADDR=yes; ])
+case "$REUSEADDR" in
+n | no) :
+ ;;
+y | ye | yes)
+ AC_DEFINE(USE_REUSEADDR,1,[Define to set SO_REUSEADDR on network connections.])
+ ;;
+*)
+ AC_MSG_ERROR([*** You must not supply an argument to --with-reuseports option.])
+ ;;
+esac
+
AC_ARG_WITH(gnutar,
[ --with-gnutar[[=PROG]] use PROG as GNU tar executable [[default: looks for one]]],
[
DBMALLOCLIBS=""
;;
*)
- DBMALLOCCFLAGS="-I$DBMALLOC -DUSE_DBMALLOC"
- DBMALLOCLIBS="-L$DBMALLOC -ldbmalloc"
+ AC_CHECK_LIB(dbmalloc,malloc)
+ if test "x$ac_cv_lib_dbmalloc_malloc" != "xyes"; then
+ AC_MSG_WARN([*** dbmalloc library not found - no malloc debugging support!])
+ DBMALLOCCFLAGS=""
+ DBMALLOCLIBS=""
+ else
+ DBMALLOCCFLAGS="-I$DBMALLOC -DUSE_DBMALLOC"
+ DBMALLOCLIBS="-L$DBMALLOC -ldbmalloc"
+ fi
;;
esac
;;
esac
+AC_ARG_WITH(bsdtcp-security,
+ [ --with-bsdtcp-security use tcp as a transport],
+ BSDTCP_SECURITY=$withval,
+ : ${BSDTCP_SECURITY=yes}
+)
+case "$BSDTCP_SECURITY" in
+n | no) : ;;
+y | ye | yes) AC_DEFINE(BSDTCP_SECURITY,1,[Define if BSDTCP transport should be enabled. ])
+ BSDTCP_SECURITY_SET=true
+ ;;
+*) AC_MSG_ERROR([*** You must not supply an argument the to --with-bsdtcp-security option.])
+ ;;
+esac
+
+AC_ARG_WITH(bsdudp-security,
+ [ --with-bsdudp-security use tcp as a transport],
+ BSDUDP_SECURITY=$withval,
+ : ${BSDUDP_SECURITY=yes}
+)
+case "$BSDUDP_SECURITY" in
+n | no) : ;;
+y | ye | yes) AC_DEFINE(BSDUDP_SECURITY,1,[Define if BSDUDP transport should be enabled. ])
+ BSDUDP_SECURITY_SET=true
+ ;;
+*) AC_MSG_ERROR([*** You must not supply an argument the to --with-bsdudp-security option.])
+ ;;
+esac
+
AC_ARG_WITH(server-principal,
[ --with-server-principal=ARG server host principal [["amanda"]]],
[
KRB5_DIR_FOUND=""
KRB5_CFLAGS=""
for dir in $KRB5_SPOTS; do
- k5libdir=${dir}/lib
+ for lib in lib lib64; do
+ k5libdir=${dir}/${lib}
if test -f ${k5libdir}/libkrb5.a -a -f ${k5libdir}/libgssapi_krb5.a -a -f ${k5libdir}/libcom_err.a; then
- if test -f ${k5libdir}/libcrypto.a; then
- K5CRYPTO=${k5libdir}/libcrypto.a
- elif test -f ${k5libdir}/libk5crypto.a; then
+ if test -f ${k5libdir}/libk5crypto.a; then
K5CRYPTO=${k5libdir}/libk5crypto.a
+ elif test -f ${k5libdir}/libcrypto.a; then
+ K5CRYPTO=${k5libdir}/libcrypto.a
else
K5CRYPTO=""
fi
+ if test -f ${k5libdir}/libkrb5support.a; then
+ K5SUPPORT=${k5libdir}/libkrb5support.a
+ else
+ K5SUPPORT=""
+ fi
KRB5_DIR_FOUND=$dir
- KRB5LIBS="${k5libdir}/libgssapi_krb5.a ${k5libdir}/libkrb5.a $K5CRYPTO ${k5libdir}/libcom_err.a"
+ KRB5LIBS="${k5libdir}/libgssapi_krb5.a ${k5libdir}/libkrb5.a $K5CRYPTO $K5SUPPORT ${k5libdir}/libcom_err.a"
KRB5CFLAGS=""
break
elif test -f ${k5libdir}/libkrb5.a -a -f ${k5libdir}/libasn1.a -a -f ${k5libdir}/libgssapi.a; then
KRB5_CFLAGS="-DKRB5_HEIMDAL_INCLUDES"
break
fi
+ done
done
if test "$KRB5_DIR_FOUND"; then
if test "$KRB5_CFLAGS" ; then
KRB5INCLUDES="$KRB5INCLUDES $KRB5_CFLAGS"
fi
+ AC_CHECK_LIB(krb5support,main)
KRB5LDFLAGS=-L$k5libdir
break
fi
fi
-AC_ARG_WITH(portrange,
- [ --with-portrange=low,high bind unreserved TCP server sockets to ports within this range [[unlimited]]],
+AC_ARG_WITH(low-tcpportrange,
+ [ --with-low-tcpportrange=low,high bind reserved TCP server sockets to ports within this range [unlimited] (mainly for amrecover)],
[
- TCPPORTRANGE="$withval"
+ LOW_TCPPORTRANGE="$withval"
]
)
+
+if test x"${LOW_TCPPORTRANGE+set}" = x"set"; then
+ if test x`echo "$LOW_TCPPORTRANGE" | sed 's/[[0-9]][[0-9]]*,[[0-9]][[0-9]]*//'` != x""; then
+ AC_MSG_ERROR([*** --with-low-tcpportrange requires two comma-separated positive numbers])
+ fi
+ min_low_tcp_port=`echo "$LOW_TCPPORTRANGE" | sed 's/,.*//'`
+ max_low_tcp_port=`echo "$LOW_TCPPORTRANGE" | sed 's/.*,//'`
+ if test $min_low_tcp_port -gt $max_low_tcp_port; then
+ AC_MSG_ERROR([*** the second TCP port number must be greater than the first in --with-low-tcpportrange])
+ fi
+ if test $min_low_tcp_port -lt 512; then
+ AC_MSG_WARN([*** the low TCP port range should be 512 or greater in --with-low-tcpportrange])
+ fi
+ if test $max_low_tcp_port -ge 1024; then
+ AC_MSG_WARN([*** the low TCP port range should be less than 1024 in --with-low-tcpportrange])
+ fi
+ AC_DEFINE_UNQUOTED(LOW_TCPPORTRANGE,$LOW_TCPPORTRANGE,[A comma-separated list of two integers, determining the minimum and
+ maximum reserved TCP port numbers sockets should be bound to. (mainly for amrecover) ])
+fi
+
AC_ARG_WITH(tcpportrange,
[ --with-tcpportrange=low,high bind unreserved TCP server sockets to ports within this range [[unlimited]]],
[
AC_DEFINE_UNQUOTED(mandir,"$tmp",[Directory in which man-pages should be installed])
)
-AC_PROG_CC
-AC_OBJEXT
-AC_EXEEXT
-
dnl Set the order of dump programs to look for. Finding the proper file
dnl system dumping program is problematic. Some systems, notably HP-UX
dnl and AIX, have both the backup and dump programs. HP-UX can't use the
;;
*-pc-linux-*)
;;
+ *-redhat-linux-*)
+ ;;
x86_64-*-linux-*)
;;
alpha*-*-linux-*)
fi
AC_PATH_PROGS(COMPRESS,compress,,$LOCSYSPATH)
AC_PATH_PROGS(DD,dd,,$LOCSYSPATH)
-AC_PATH_PROGS(EGREP,egrep,,$LOCSYSPATH)
AC_PATH_PROGS(GETCONF,getconf,,$SYSPATH)
AC_PATH_PROGS(GNUPLOT,gnuplot,,$LOCSYSPATH)
AC_MSG_WARN([*** You do not have gnuplot. Amplot will not be installed.])
fi
-AC_PATH_PROGS(GREP,grep,,$LOCSYSPATH)
-if test -z "$GREP"; then
- GREP=grep
-fi
-AC_DEFINE_UNQUOTED(GREP,"$GREP",[Define the location of the grep program. ])
-
AC_PATH_PROGS(GNUTAR,gtar gnutar tar,,$LOCSYSPATH)
if test ! -z "$GNUTAR"; then
case "`\"$GNUTAR\" --version 2>&1`" in
if test "x$need_resetofs" = xyes; then
AC_DEFINE(NEED_RESETOFS,1,[Define if we have to reset tape offsets when reacing 2GB. ])
fi
+
+
CFLAGS="$amanda_cv_LFS_CFLAGS $CFLAGS"
-CPPFLAGS="$amanda_cv_LFS_CFLAGS $CPPFLAGS"
+CPPFLAGS="$amanda_cv_LFS_CPPFLAGS $CPPFLAGS"
LDFLAGS="$amanda_cv_LFS_LDFLAGS $LDFLAGS"
LIBS="$amanda_cv_LFS_LIBS $LIBS"
AC_CHECK_SIZEOF(long long)
AC_CHECK_SIZEOF(intmax_t)
AC_CHECK_SIZEOF(off_t)
+AC_CHECK_SIZEOF(size_t)
+AC_CHECK_SIZEOF(ssize_t)
+AC_CHECK_SIZEOF(time_t)
AM_PROG_LIBTOOL
AC_SUBST(LIBTOOL_DEPS)
AC_STRUCT_TM
AM_PROG_LEX
+dnl From here on we need to know about STDC_HEADERS
+AC_HEADER_STDC
+
dnl AC_CHECK_TYPE does not work for socklen_t because it does not look
dnl in <sys/socket.h>, so this is a variant that adds another header.
AC_DEFUN([AMANDA_CHECK_TYPE],
fi
])
AMANDA_CHECK_TYPE(socklen_t, int, sys/socket.h)
+AMANDA_CHECK_TYPE(sa_family_t, unsigned short, sys/socket.h)
dnl Checks for header files.
-AC_HEADER_STDC
AC_HEADER_DIRENT
CF_WAIT
CF_WAIT_INT
grp.h \
history.h \
libc.h \
+ libgen.h \
limits.h \
linux/zftape.h \
+ math.h \
mntent.h \
mnttab.h \
ndbm.h \
readline/readline.h \
scsi/sg.h \
scsi/scsi_ioctl.h \
+ stdarg.h \
stdlib.h \
string.h \
strings.h \
if test "x$ac_cv_lib_termcap_tgetent" = xyes ||
test "x$ac_cv_lib_curses_tgetent" = xyes ||
test "x$ac_cv_lib_ncurses_tgetent" = xyes; then
- AC_CHECK_LIB(readline,readline,
- READLINE_LIBS="-lreadline"; AC_SUBST(READLINE_LIBS)
- )
- if test "x$ac_cv_lib_readline_readline" != xyes; then
+ AC_CHECK_LIB(readline,readline)
+ if test "x$ac_cv_lib_readline_readline" = xyes; then
+ READLINE_LIBS="-lreadline"
+ AC_SUBST(READLINE_LIBS)
+ else
AC_MSG_WARN([*** No readline library, no history and command line editing in amrecover!])
fi
else
AC_FUNC_ALLOCA
AC_CHECK_FUNCS(atexit)
ICE_CHECK_DECL(atof,stdlib.h)
+ICE_CHECK_DECL(atoi,stdlib.h)
+ICE_CHECK_DECL(atol,stdlib.h)
+ICE_CHECK_DECL(atoll,stdlib.h)
AC_CHECK_FUNCS(basename)
ICE_CHECK_DECL(bind,sys/types.h sys/socket.h)
ICE_CHECK_DECL(bcopy,string.h strings.h stdlib.h)
AC_CHECK_FUNCS(getvfsent initgroups isascii)
ICE_CHECK_DECL(initgroups,grp.h sys/types.h unistd.h libc.h)
ICE_CHECK_DECL(ioctl,sys/ioctl.h unistd.h libc.h)
+ICE_CHECK_DECL(isnormal,math.h)
ICE_CHECK_DECL(listen,sys/types.h sys/socket.h)
ICE_CHECK_DECL(lstat,sys/types.h sys/stat.h)
ICE_CHECK_DECL(malloc,stdlib.h)
AC_CHECK_FUNCS(fnmatch)
-AC_SYS_LARGEFILE
dnl disk device prefixes
AC_MSG_CHECKING(disk device prefixes)
DOC_BUILD_DATE=`date '+%d-%m-%Y'`
AC_SUBST(DOC_BUILD_DATE)
-AC_ARG_WITH(xsltproc,
+AC_ARG_WITH(built-manpages,
[ --without-built-manpages Do not build manpages from XML source.],
- [ case "$withval" in
- y | ye | yes)
- USE_XSLTPROC=yes;;
- n | no)
- USE_XSLTPROC=no;;
- *)
- USE_XSLTPROC=yes;
- XSLTPROC="$withval";;
- esac
- ],
- [ USE_XSLTPROC=maybe; ])
+ [ BUILDMANPAGES=$withval; ],
+ [ BUILDMANPAGES=yes; ])
+AM_CONDITIONAL(BUILD_MAN_PAGES, test "x$BUILDMANPAGES" = "xyes")
+
+AC_PATH_PROGS(XSLTPROC,xsltproc,,$LOCSYSPATH)
+if test -z "$XSLTPROC"; then
+ USE_XSLTPROC=no
+ AC_MSG_WARN([can't find xsltproc, xsltproc support is unavailable])
+else
+ USE_XSLTPROC=yes
+ AC_DEFINE(HAVE_XSLTPROC,1,[xslt is available to generate man pages])
+fi
+AM_CONDITIONAL(HAVE_XSLTPROC, test "x$USE_XSLTPROC" = "xyes")
+
+#### Enforce amanda code cleanliness rules.
+#### Done here to allow configuration code to remain intact.
+if test "x$CC" = "xgcc"; then
+ AM_CFLAGS="$AM_CFLAGS -Wall"
+ $CC -v --help 2>&1 | $GREP -- '-Wextra ' 2>&1 > /dev/null
+ if test $? -eq 0; then
+ AM_CFLAGS="$AM_CFLAGS -Wextra"
+ else
+ AM_CFLAGS="$AM_CFLAGS -W"
+ fi
-AC_DEFUN([AC_PATH_XSLTPROC], [AC_PATH_PROG(XSLTPROC, xsltproc)])
+ $CC -v --help 2>&1 | $GREP -- '-Wparentheses' 2>&1 > /dev/null
+ if test $? -eq 0; then
+ AM_CFLAGS="$AM_CFLAGS -Wparentheses"
+ fi
-# This looks bad, but && and || have equal precedence in shells, so
-# actually it's all OK.
-if test "$USE_XSLTPROC" = "yes" || test "$USE_XSLTPROC" = "maybe" && \
- test -z "$XSLTPROC"; then
- AC_PATH_XSLTPROC
- if test -n "$XSLTPROC"; then
- USE_XSLTPROC=yes;
- else
- if test "$USE_XSLTPROC" = yes; then
- AC_MSG_ERROR([can't find xsltproc, but running with --with-xsltproc.])
- else
- USE_XSLTPROC=no;
- fi
- fi
-fi
+ $CC -v --help 2>&1 | $GREP -- '-Wdeclaration-after-statement' 2>&1 > /dev/null
+ if test $? -eq 0; then
+ AM_CFLAGS="$AM_CFLAGS -Wdeclaration-after-statement"
+ fi
+
+ $CC -v --help 2>&1 | $GREP -- '-Wmissing-prototypes ' 2>&1 > /dev/null
+ if test $? -eq 0; then
+ AM_CFLAGS="$AM_CFLAGS -Wmissing-prototypes"
+ fi
-AM_CONDITIONAL(HAVE_XSLTPROC, test "$USE_XSLTPROC" = yes)
+ $CC -v --help 2>&1 | $GREP -- '-Wstrict-prototypes ' 2>&1 > /dev/null
+ if test $? -eq 0; then
+ AM_CFLAGS="$AM_CFLAGS -Wstrict-prototypes"
+ fi
+
+ $CC -v --help 2>&1 | $GREP -- '-Wmissing-declarations ' 2>&1 > /dev/null
+ if test $? -eq 0; then
+ AM_CFLAGS="$AM_CFLAGS -Wmissing-declarations"
+ fi
+
+ $CC -v --help 2>&1 | $GREP -- '-Wformat' 2>&1 > /dev/null
+ if test $? -eq 0; then
+ AM_CFLAGS="$AM_CFLAGS -Wformat"
+ fi
+
+ $CC -v --help 2>&1 | $GREP -- '-Wsign-compare' 2>&1 > /dev/null
+ if test $? -eq 0; then
+ AM_CFLAGS="$AM_CFLAGS -Wsign-compare"
+ fi
+
+ $CC -v --help 2>&1 | $GREP -- '-fno-strict-aliasing' 2>&1 > /dev/null
+ if test $? -eq 0; then
+ AM_CFLAGS="$AM_CFLAGS -fno-strict-aliasing"
+ fi
+
+ $CC -v --help 2>&1 | $GREP -- '-Wfloat-equal' 2>&1 > /dev/null
+ if test $? -eq 0; then
+ AM_CFLAGS="$AM_CFLAGS -Wfloat-equal"
+ fi
+
+ $CC -v --help 2>&1 | $GREP -- '-Wold-style-definition' 2>&1 > /dev/null
+ if test $? -eq 0; then
+ AM_CFLAGS="$AM_CFLAGS -Wold-style-definition"
+ fi
+fi
+AC_SUBST(AM_CFLAGS)
AC_CONFIG_FILES([\
amplot/amcat.awk amplot/amplot.sh \
amplot/Makefile \
\
+ amandad-src/Makefile \
+ \
changer-src/chg-manual.sh changer-src/chg-multi.sh \
changer-src/chg-mtx.sh changer-src/chg-chs.sh \
changer-src/chg-rth.pl changer-src/chg-chio.pl \
common-src/versuff.c common-src/Makefile \
\
example/amanda.conf example/Makefile \
- example/chg-mcutil.conf \
+ example/chg-mcutil.conf example/amanda-client.conf \
\
man/Makefile \
\
docs/Makefile \
\
recover-src/Makefile \
+
+ oldrecover-src/Makefile \
\
restore-src/Makefile \
\
server-src/amtoc.pl server-src/amverify.sh \
server-src/Makefile server-src/amstatus.pl \
server-src/amverifyrun.sh server-src/amcrypt.sh \
- server-src/amaespipe.sh \
- \
+ server-src/amaespipe.sh server-src/amcrypt-ossl.sh \
+ server-src/amcrypt-ossl-asym.sh \
tape-src/Makefile \
\
config/Makefile Makefile])
+
AC_OUTPUT
#!/usr/local/bin/perl
# ========================================================================
-# @(#) $Id: set_prod_link.pl,v 1.2 1999/11/02 21:30:10 oliva Exp $
+# @(#) $Id: set_prod_link.pl,v 1.3 2006/05/25 01:47:13 johnfranks Exp $
# ------------------------------------------------------------------------
# $Source: /cvsroot/amanda/amanda/contrib/set_prod_link.pl,v $
# ------------------------------------------------------------------------
# History:
#
# $Log: set_prod_link.pl,v $
+# Revision 1.3 2006/05/25 01:47:13 johnfranks
+# Allow spaces and arbitrary binary characters in file names
+# and configuration files.
+#
+# 64-bit / type portability clean code.
+#
+# Add 'make lint' options to appropriate Makefiles.
+#
+# Fully lint clean code using Sun's lint, and splint code checkers.
+#
+# Various bug fixes that have not been pushed.
+#
+# Modified Files:
+# Modified most of the files...
+#
# Revision 1.2 1999/11/02 21:30:10 oliva
# * contrib/set_prod_link.pl: Create the links for a configuration
# with --with-suffix.
-------------------------------------------------------------------------------
-Appendixes
+Part VII. Appendixes
Table of Contents
- 35._The_AMANDA_Manual_Pages.
+ 36._The_Amanda_Manual_Pages.
+
+
+ amadmin - administrative interface to control Amanda backups
+
+ amaespipe - wrapper program for aespipe
+
+ amanda - Advanced Maryland Automatic Network Disk Archiver
+
+ amanda.conf - Main configuration file for Amanda, the Advanced Maryland
+ Automatic Network Disk Archiver
+
+ amanda-client.conf - Client configuration file for Amanda, the Advanced
+ Maryland Automatic Network Disk Archiver
+
+ amcheck - run Amanda self-checks
+
+ amcheckdb - check Amanda database for tape consistency
+
+ amcleanup - run the Amanda cleanup process after a failure
+
+ amcrypt - reference crypt program for Amanda symmetric data encryption
+
+ amcrypt-ossl - crypt program for Amanda symmetric data encryption using
+ OpenSSL
+
+ amcrypt-ossl-asym - crypt program for Amanda asymmetric data encryption
+ using OpenSSL
+
+ amdd - Amanda version of dd
+
+ amdump - back up all disks in an Amanda configuration
+
+ amfetchdump - extract backup images from multiple Amanda tapes.
+
+ amflush - flush Amanda backup files from holding disk to tape
+
+ amgetconf - look up amanda.conf variables
+
+ amlabel - label an Amanda tape
+
+ ammt - Amanda version of mt
+
+ amoverview - display file systems processed by Amanda over time
+
+ amplot - visualize the behavior of Amanda
+
+ amrecover - Amanda index database browser
+
+ amreport - generate a formatted output of statistics for an Amanda run
+
+ amrestore - extract backup images from an Amanda tape
+
+ amrmtape - remove a tape from the Amanda database
+
+ amstatus - display the state of an Amanda run
+
+ amtape - user interface to Amanda tape changer controls
+
+ amtapetype - generate a tapetype definition.
+
+ amtoc - generate TOC (Table Of Contents) for an Amanda run
+
+ amverify - check an Amanda tape for errors
+
+ amverifyrun - check the tapes written by the last Amanda run
+
- 36._Web_Ressources
+ 37._Web_Ressources
-------------------------------------------------------------------------------
-Prev Up Next
-Chapter 34. Usage of floppy tape Home Chapter 35. The AMANDA Manual Pages.
+Prev Next
+Chapter 35. Usage of floppy tape Home Chapter 36. The Amanda Manual Pages.
drives on Linux
pkgdata_DATA = \
Appendix.txt \
amadmin.8.txt \
+ amaespipe.8.txt \
amanda.8.txt \
amanda.conf.5.txt \
+ amanda-client.conf.5.txt \
amcheck.8.txt \
amcheckdb.8.txt \
amcleanup.8.txt \
+ amcrypt.8.txt \
+ amcrypt-asym-ossl.8.txt \
+ amcrypt-ossl.8.txt \
amdd.8.txt \
amdump.8.txt \
+ amfetchdump.8.txt \
amflush.8.txt \
amgetconf.8.txt \
amlabel.8.txt \
faq.txt \
historical.txt \
howto-afs.txt \
+ howto-auth.txt \
howto-cygwin.txt \
howto-filedriver.txt \
howto-wrapper.txt \
AMANDA_TMPDIR = @AMANDA_TMPDIR@
AMDEP_FALSE = @AMDEP_FALSE@
AMDEP_TRUE = @AMDEP_TRUE@
+AMLINT = @AMLINT@
+AMLINTFLAGS = @AMLINTFLAGS@
AMPLOT_CAT_COMPRESS = @AMPLOT_CAT_COMPRESS@
AMPLOT_CAT_GZIP = @AMPLOT_CAT_GZIP@
AMPLOT_CAT_PACK = @AMPLOT_CAT_PACK@
AMPLOT_COMPRESS = @AMPLOT_COMPRESS@
AMTAR = @AMTAR@
+AM_CFLAGS = @AM_CFLAGS@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AWK = @AWK@
AWK_VAR_ASSIGNMENT_OPT = @AWK_VAR_ASSIGNMENT_OPT@
BINARY_OWNER = @BINARY_OWNER@
+BUILD_MAN_PAGES_FALSE = @BUILD_MAN_PAGES_FALSE@
+BUILD_MAN_PAGES_TRUE = @BUILD_MAN_PAGES_TRUE@
CAT = @CAT@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
pkgdata_DATA = \
Appendix.txt \
amadmin.8.txt \
+ amaespipe.8.txt \
amanda.8.txt \
amanda.conf.5.txt \
+ amanda-client.conf.5.txt \
amcheck.8.txt \
amcheckdb.8.txt \
amcleanup.8.txt \
+ amcrypt.8.txt \
+ amcrypt-asym-ossl.8.txt \
+ amcrypt-ossl.8.txt \
amdd.8.txt \
amdump.8.txt \
+ amfetchdump.8.txt \
amflush.8.txt \
amgetconf.8.txt \
amlabel.8.txt \
faq.txt \
historical.txt \
howto-afs.txt \
+ howto-auth.txt \
howto-cygwin.txt \
howto-filedriver.txt \
howto-wrapper.txt \
amadmin
-Prev Chapter 35. The AMANDA Manual Pages. Next
+Prev Chapter 36. The Amanda Manual Pages. Next
-------------------------------------------------------------------------------
Name
-amadmin \14 administrative interface to control AMANDA backups
+amadmin \14 administrative interface to control Amanda backups
Synopsis
-amadmin config command [ command options ]
+amadmin config command [command options] [ -o | configoption ]*
DESCRIPTION
-Amadmin performs various administrative tasks on the config AMANDA
+Amadmin performs various administrative tasks on the config Amanda
configuration.
-See the amanda(8) man page for more details about AMANDA.
+See the amanda(8) man page for more details about Amanda.
COMMANDS
force-bump [ hostname [ disks ]* ]+
Force the disks on hostname to bump to a new incremental level during the
- next AMANDA run.
+ next Amanda run.
force-no-bump [ hostname [ disks ]* ]+
Force the disks on hostname to not bump to a new incremental level during
- the next AMANDA run.
+ the next Amanda run.
unforce-bump [ hostname [ disks ]* ]+
Undo a previous force-bump or force-no-bump command.
force [ hostname [ disks ]* ]+
Force the disks on hostname to do a full (level 0) backup during the next
- AMANDA run.
+ Amanda run.
unforce [ hostname [ disks ]* ]+
Undo a previous force command.
no-reuse tapelabel [ ... ]
The tapes listed will not be reused when their turn comes up again in the
tape cycle. Note that if this causes the number of reusable tapes to drop
- below the amanda.conf tapecycle value, AMANDA will request new tapes
+ below the amanda.conf tapecycle value, Amanda will request new tapes
until the count is satisfied again.
due [ hostname [ disks ]* ]*
Show when the next full dump is due.
- find [ --sort hkdlb ] [ hostname [ disks ]* ]*
+ find [ --sort hkdlpb ] [ hostname [ disks ]* ]*
Display all backups currently on tape or in the holding disk. The tape
label or holding disk filename, file number, and status are displayed.
The --sort option changes the sort order using the following flags:
- hhost name kdisk name ddump date lbackup level btape label
+ hhost name kdisk name ddump date lbackup level p dump part btape label
An uppercase letter reverses the sort order for that key. The default
- sort order is hkdlb.
+ sort order is hkdlpb.
delete [ hostname [ disks ]* ]+
- Delete the specified disks on hostname from the AMANDA database.
+ Delete the specified disks on hostname from the Amanda database.
Note
- If you do not also remove the disk from the disklist file, AMANDA will
+ If you do not also remove the disk from the disklist file, Amanda will
treat it as a new disk during the next run.
tape
- Display the tape(s) AMANDA expects to write to during the next run. See
+ Display the tape(s) Amanda expects to write to during the next run. See
also amcheck(8).
bumpsize
Display the distribution of full backups throughout the dump schedule.
export [ hostname [ disks ]* ]*
- Convert records from the AMANDA database to a text format that may be
- transmitted to another AMANDA machine and imported.
+ Convert records from the Amanda database to a text format that may be
+ transmitted to another Amanda machine and imported.
import
- Convert exported records read from standard input to a form AMANDA uses
+ Convert exported records read from standard input to a form Amanda uses
and insert them into the database on this machine.
disklist [ hostname [ disks ]* ]*
Display the database record for each of the disks on hostname (or all
hosts). Mostly used for debugging.
+ -o configoption
+ See the "CONFIGURATION OVERWRITE" section in amanda(8).
+
EXAMPLES
Request three specific file systems on machine-a get a full level 0 backup
-during the next AMANDA run.
+during the next Amanda run.
$ amadmin daily force machine-a / /var /usr
amadmin: machine-a:/ is set to a forced level 0 tonight.
amadmin: machine-a:/usr is set to a forced level 0 tonight.
Request all file systems on machine-b get a full level 0 backup during the next
-AMANDA run.
+Amanda run.
$ amadmin daily force machine-b
amadmin: machine-b:/ is set to a forced level 0 tonight.
had some type of error.
$ amadmin daily find machine-c /var
- date host disk lv tape or file file status
- 2000-11-09 machine-c /var 0 000110 9 OK
- 2000-11-08 machine-c /var 2 000109 2 OK
- 2000-11-07 machine-c /var 2 /amanda/20001107/machine-c._var.2 0 OK
- 2000-11-06 machine-c /var 2 000107 2 OK
- 2000-11-05 machine-c /var 2 000106 3 OK
- 2000-11-04 machine-c /var 2 000105 2 OK
- 2000-11-03 machine-c /var 2 000104 2 OK
- 2000-11-02 machine-c /var 2 000103 2 OK
- 2000-11-01 machine-c /var 1 000102 5 OK
- 2000-10-31 machine-c /var 1 000101 3 OK
+ date host disk lv tape or file file part status
+ 2000\-11\-09 machine\-c /var 0 000110 9 -- OK
+ 2000\-11\-08 machine\-c /var 2 000109 2 -- OK
+ 2000\-11\-07 machine\-c /var 2 /amanda/20001107/machine-c._var.2 0 OK
+ 2000\-11\-06 machine\-c /var 2 000107 2 -- OK
+ 2000\-11\-05 machine\-c /var 2 000106 3 -- OK
+ 2000\-11\-04 machine\-c /var 2 000105 2 -- OK
+ 2000\-11\-03 machine\-c /var 2 000104 2 -- OK
+ 2000\-11\-02 machine\-c /var 2 000103 2 -- OK
+ 2000\-11\-01 machine\-c /var 1 000102 5 -- OK
+ 2000\-10\-31 machine\-c /var 1 000101 3 -- OK
Forget about the /workspace disk on machine-d. If you do not also remove the
-disk from the disklist file, AMANDA will treat it as a new disk during the next
+disk from the disklist file, Amanda will treat it as a new disk during the next
run.
$ amadmin daily delete machine-d /workspace
amadmin: machine-d:/workspace deleted from database.
amadmin: NOTE: you'll have to remove these from the disklist yourself.
-Find the next tape AMANDA will use (in this case, 123456).
+Find the next tape Amanda will use (in this case, 123456).
$ amadmin daily tape
- The next AMANDA run should go onto tape 123456 or a new tape.
+ The next Amanda run should go onto tape 123456 or a new tape.
Show how well full backups are balanced across the dump cycle. The due-date
column is the day the backups are due for a full backup. #fs shows the number
estimated total size of the backups before and after any compression,
respectively.
The balance column shows how far off that night's backups are from the average
-size (shown at the bottom of the balance column). AMANDA tries to keep the
+size (shown at the bottom of the balance column). Amanda tries to keep the
backups within +/- 5%, but since the amount of data on each filesystem is
-always changing, and AMANDA will never delay backups just to rebalance the
+always changing, and Amanda will never delay backups just to rebalance the
schedule, it is common for the schedule to fluctuate by larger percentages. In
particular, in the case of a tape or backup failure, a bump will occur the
following night, which will not be smoothed out until the next pass through the
schedule.
-The last line also shows an estimate of how many AMANDA runs will be made
+The last line also shows an estimate of how many Amanda runs will be made
between full backups for a file system. In the example, a file system will
-probably have a full backup done every eight times AMANDA is run (e.g. every
+probably have a full backup done every eight times Amanda is run (e.g. every
eight days).
$ amadmin daily balance
AUTHOR
James da Silva, <jds@amanda.org> : Original text
-Stefan G. Weichinger, <sgw@amanda.org>, maintainer of the AMANDA-documentation:
+Stefan G. Weichinger, <sgw@amanda.org>, maintainer of the Amanda-documentation:
XML-conversion
SEE ALSO
-amanda(8), amcheck(8), amdump(8), amrestore(8)
+amanda(8), amcheck(8), amdump(8), amrestore(8), amfetchdump(8)
-------------------------------------------------------------------------------
-Prev Up Next
-Chapter 35. The AMANDA Manual Pages. Home amanda
+Prev Up Next
+Chapter 36. The Amanda Manual Pages. Home amaespipe
--- /dev/null
+
+ amaespipe
+Prev Chapter 36. The Amanda Manual Pages. Next
+
+-------------------------------------------------------------------------------
+
+Name
+
+amaespipe \14 wrapper program for aespipe
+
+Synopsis
+
+amaespipe
+
+DESCRIPTION
+
+amaespipe requires aespipe, uuencode and gpg to work. Aespipe is available from
+http://loop-aes.sourceforge.net
+amaespipe will search for the aespipe program in the following directories: /
+usr/bin:/usr/local/bin:/sbin:/usr/sbin.
+amaespipe is called by amcrypt for Amanda data encryption.
+amaespipe is based on aespipe's bzaespipe program. It calls aespipe to encrypt
+data using AES256 as the encryption and SHA256 as the hash function. GPG key
+should be stored in $AMANDA_HOME/.gnupg/am_key.gpg. amaespipe reads passphrase
+from file descriptor 3. During decryption, amaespipe autodects encryption type
+and hash function from the encrypted image.
+
+SEE ALSO
+
+amanda(8), amanda.conf(5), aespipe(1), amcrypt(8), gpg(1)
+-------------------------------------------------------------------------------
+
+Prev Up Next
+amadmin Home amanda
+
--- /dev/null
+
+ amanda-client.conf
+Prev Chapter 36. The Amanda Manual Pages. Next
+
+-------------------------------------------------------------------------------
+
+Name
+
+amanda-client.conf \14 Client configuration file for Amanda, the Advanced
+Maryland Automatic Network Disk Archiver
+
+DESCRIPTION
+
+amanda-client.conf is the client configuration file for Amanda. This manpage
+lists the relevant sections and parameters of this file for quick reference.
+
+PARAMETERS
+
+There are a number of configuration parameters that control the behavior of the
+Amanda programs. All have default values, so you need not specify the parameter
+in amanda-client.conf if the default is suitable.
+Lines starting with # are ignored, as are blank lines. Comments may be placed
+on a line with a directive by starting the comment with a #. The remainder of
+the line is ignored.
+Keywords are case insensitive, i.e. auth and Auth are treated the same.
+Integer arguments may have one of the following (case insensitive) suffixes,
+some of which have a multiplier effect:
+
+POSSIBLE SUFFIXES
+
+
+
+ b byte bytes
+ Some number of bytes.
+
+ bps
+ Some number of bytes per second.
+
+ k kb kbyte kbytes kilobyte kilobytes
+ Some number of kilobytes (bytes*1024).
+
+ kps kbps
+ Some number of kilobytes per second (bytes*1024).
+
+ m mb meg mbyte mbytes megabyte megabytes
+ Some number of megabytes (bytes*1024*1024).
+
+ mps mbps
+ Some number of megabytes per second (bytes*1024*1024).
+
+ g gb gbyte gbytes gigabyte gigabytes
+ Some number of gigabytes (bytes*1024*1024*1024).
+
+ tape tapes
+ Some number of tapes.
+
+ day days
+ Some number of days.
+
+ week weeks
+ Some number of weeks (days*7).
+
+ Note
+
+ The value inf may be used in most places where an integer is expected to
+ mean an infinite amount.
+ Boolean arguments may have any of the values y, yes, t, true or on to
+ indicate a true state, or n, no, f, false or off to indicate a false
+ state. If no argument is given, true is assumed.
+
+
+PARAMETERS
+
+
+
+ conf string
+ Default: Set by configure. The conf use by amrecover.
+
+ index_server string
+ Default: Set by configure. The amindexd server amrecover will connect to.
+
+ tape_server string
+ Default: Set by configure. The amidxtaped server amrecover will connect
+ to.
+
+ tapedev string
+ Default: Set by configure. The tapedev amrecover will use.
+
+ auth string
+ Default: bsd. Type of authorization to perform between tape server and
+ backup client hosts.
+ bsd, bsd authorization with udp initial connection and one tcp connection
+ by data stream.
+ bsdtcp, bsd authorization but use only one tcp connection.
+ bsdudp, like bsd, but will use only one tcp connection for all data
+ stream.
+ krb4 to use Kerberos-IV authorization.
+ krb5 to use Kerberos-V authorization.
+ rsh to use rsh authorization.
+ ssh to use OpenSSH authorization.
+
+ ssh_keys string
+ Default: No default. The key file the ssh auth will use, it must be the
+ private key. If this parameter is not specified, then the deafult ssh key
+ will be used.
+
+
+AUTHOR
+
+James da Silva, <jds@amanda.org>: Original text
+Stefan G. Weichinger, <sgw@amanda.org>, maintainer of the Amanda-documentation:
+XML-conversion, major update, splitting
+
+SEE ALSO
+
+amanda(8), amanda.conf(5), amcrypt(8), aespipe(1),
+-------------------------------------------------------------------------------
+
+Prev Up Next
+amanda.conf Home amcheck
+
amanda
-Prev Chapter 35. The AMANDA Manual Pages. Next
+Prev Chapter 36. The Amanda Manual Pages. Next
-------------------------------------------------------------------------------
amcheck [options] config
amcheckdb config
amcleanup config
+amcrypt
amdd [options]
amdump config
+amaespipe
amflush [-f ] config
amgetconf [config] parameter
amlabel config label [ slot slot ]
amrecover [config] [options]
amreport [config] [options]
amrestore [options] tapedevice [ hostname [diskname]]
+amfetchdump [options] config [ hostname [ diskname [ date [level]]]]
amrmtape [options] config label
amstatus config [options]
amtape config command [options]
DESCRIPTION
-AMANDA is the "Advanced Maryland Automatic Network Disk Archiver". This manual
-page gives an overview of the AMANDA commands and configuration files for quick
+Amanda is the "Advanced Maryland Automatic Network Disk Archiver". This manual
+page gives an overview of the Amanda commands and configuration files for quick
reference.
-Here are all the AMANDA commands. Each one has its own manual page. See them
+Here are all the Amanda commands. Each one has its own manual page. See them
for all the gory details.
amdump
- Take care of automatic AMANDA backups. This is normally executed by cron
+ Take care of automatic Amanda backups. This is normally executed by cron
on a computer called the tape server host and requests backups of file
systems located on backup clients. Amdump backs up all disks in the
disklist file (discussed below) to tape or, if there is a problem, to a
server host crashed while amdump was running.
amrecover
- Provides an interactive interface to browse the AMANDA index files
+ Provides an interactive interface to browse the Amanda index files
(backup image catalogues) and select which tapes to recover files from.
It can also run amrestore and a restore program (e.g. tar) to actually
recover the files.
amrestore
- Read an AMANDA tape, searching for requested backups. Amrestore is
+ Read an Amanda tape, searching for requested backups. Amrestore is
suitable for everything from interactive restores of single files to a
full restore of all partitions on a failed disk.
+ amfetchdump
+ Performs Amanda tape restoration, similar to amrestore. Additional
+ capabilities include "hands-off" searching of multiple tapes, automatic
+ retrieval of specific dump files based on dump logs, and assembly of
+ tape-spanning split dump files.
+
amlabel
- Write an AMANDA format label onto a tape. All AMANDA tapes must be
+ Write an Amanda format label onto a tape. All Amanda tapes must be
labeled with amlabel. Amdump and amflush will not write to an unlabeled
tape (see TAPE MANAGEMENT below).
tapes, ejecting tapes and scanning the tape storage slots.
amverify
- Check AMANDA backup tapes for errors.
+ Check Amanda backup tapes for errors.
amrmtape
- Delete a tape from the AMANDA databases.
+ Delete a tape from the Amanda databases.
amstatus
Report the status of a running or completed amdump.
Display a chart of hosts and file systems backed up every run.
amplot
- Generate utilization plots of AMANDA runs for performance tuning.
+ Generate utilization plots of Amanda runs for performance tuning.
amreport
- Generate an AMANDA summary E-mail report.
+ Generate an Amanda summary E-mail report.
amtoc
- Generate table of content files for AMANDA tapes.
+ Generate table of content files for Amanda tapes.
amcheckdb
- Verify every tape AMANDA knows about is consistent in the database.
+ Verify every tape Amanda knows about is consistent in the database.
amgetconf
- Look up parameters in the AMANDA configuration file.
+ Look up parameters in the Amanda configuration file.
amtapetype
Generate a tapetype definition.
+ amaespipe
+ Wrapper program from aespipe (data encryption utility)
+
+ amcrypt
+ Reference encryption program for Amanda symmetric data encryption
+
CONFIGURATION
-There are three user-editable files that control the behavior of AMANDA.
+There are three user-editable files that control the behavior of Amanda.
The first is amanda.conf, the main configuration file. It contains parameters
-to customize AMANDA for the site. Refer to the amanda.conf(5), manpage for
-details on AMANDA configuration parameters.
+to customize Amanda for the site. Refer to the amanda.conf(5), manpage for
+details on Amanda configuration parameters.
Second is the disklist file, which lists hosts and disk partitions to back up.
Third is the tapelist file, which lists tapes that are currently active. These
files are described in more detail in the following sections.
it might have a normal configuration for everyday backups and an archive
configuration for infrequent full archival backups. The configuration files
would be stored under directories /usr/local/etc/amanda/normal/ and /usr/local/
-etc/amanda/archive/, respectively. Part of the job of an AMANDA administrator
+etc/amanda/archive/, respectively. Part of the job of an Amanda administrator
is to create, populate and maintain these directories.
-All log and database files generated by AMANDA go in corresponding directories
+All log and database files generated by Amanda go in corresponding directories
somewhere. The exact location is controlled by entries in amanda.conf. A
typical location would be under /var/adm/amanda. For the above example, the
files might go in /var/adm/amanda/normal/ and /var/adm/amanda/archive/.
As log files are no longer needed (no longer contain relevant information),
-AMANDA cycles them out in various ways, depending on the type of file.
+Amanda cycles them out in various ways, depending on the type of file.
Detailed information about amdump runs are stored in files named amdump.NN
where NN is a sequence number, with 1 being the most recent file. Amdump
rotates these files each run, keeping roughly the last tapecycle (see below)
where YYYYMMDD is the datestamp of the start of the amdump run and NN is a
sequence number started at 0. At the end of each amdump run, log files for runs
whose tapes have been reused are renamed into a subdirectory of the main log
-directory (see the logdir parameter below) named oldlog. It is up to the AMANDA
+directory (see the logdir parameter below) named oldlog. It is up to the Amanda
administrator to remove them from this directory when desired.
Index (backup image catalogue) files older than the full dump matching the
oldest backup image for a given client and disk are removed by amdump at the
DISKLIST FILE
-The disklist file determines which disks will be backed up by AMANDA. The file
+The disklist file determines which disks will be backed up by Amanda. The file
usually contains one line per disk:
hostname diskname [diskdevice] dumptype [spindle [interface] ]
hostname
The name of the host to be backed up. If diskdevice refers to a PC share,
- this is the host AMANDA will run the Samba smbclient program on to back
+ this is the host Amanda will run the Samba smbclient program on to back
up the share.
diskname
the diskdevice and you don't set the diskdevice. If you want multiple
entries with the same diskdevice, you must set a different diskname for
each entry. It's the diskname that you use on the commandline for any
- AMANDA command. Look at the example/disklist file for example.
+ Amanda command. Look at the example/disklist file for example.
diskdevice
Default: same as diskname. The name of the disk device to be backed up.
priority, etc.
spindle
- Default: -1. A number used to balance backup load on a host. AMANDA will
+ Default: -1. A number used to balance backup load on a host. Amanda will
not run multiple backups at the same time on the same spindle, unless the
spindle number is -1, which means there is no spindle restriction.
TAPE MANAGEMENT
The tapelist file contains the list of tapes in active use. This file is
-maintained entirely by AMANDA and should not be created or edited during normal
+maintained entirely by Amanda and should not be created or edited during normal
operation. It contains lines of the form:
YYYYMMDD label flags
Where YYYYMMDD is the date the tape was written, label is a label for the tape
-as written by amlabel and flags tell AMANDA whether the tape may be reused, etc
+as written by amlabel and flags tell Amanda whether the tape may be reused, etc
(see the reuse options of amadmin).
Amdump and amflush will refuse to write to an unlabeled tape, or to a labeled
tape that is considered active. There must be more tapes in active rotation
The normal value for the tapedev parameter, or for what a tape changer returns,
is a full path name to a non-rewinding tape device, such as /dev/nst0 or /dev/
rmt/0mn or /dev/nst0.1 or whatever conventions the operating system uses.
-AMANDA provides additional application level drivers that support non-
+Amanda provides additional application level drivers that support non-
traditional tape-simulations or features. To access a specific output driver,
set tapedev (or configure your changer to return) a string of the form driver:
driver-info where driver is one of the supported drivers and driver-info is
null
This driver throws away anything written to it and returns EOF for any
reads except a special case is made for reading a label, in which case a
- "fake" value is returned that AMANDA checks for and allows through
+ "fake" value is returned that Amanda checks for and allows through
regardless of what you have set in labelstr. The driver-info field is not
used and may be left blank:
for the actual data. Create a symlink named data in the file directory to
one of the data directories. Set the tapetype length to whatever the
medium will hold.
- When AMANDA fills the file device, remove the symlink and (optionally)
+ When Amanda fills the file device, remove the symlink and (optionally)
create a new symlink to another data area. Use a CD writer software
package to burn the image from the first data area.
To read the CD, mount it and create the data symlink in the file device
AUTHORIZATION
-AMANDA processes on the tape server host run as the dumpuser user listed in
-amanda.conf. When they connect to a backup client, they do so with an AMANDA-
+Amanda processes on the tape server host run as the dumpuser user listed in
+amanda.conf. When they connect to a backup client, they do so with an Amanda-
specific protocol. They do not, for instance, use rsh or ssh directly.
On the client side, the amandad daemon validates the connection using one of
several methods, depending on how it was compiled and on options it is passed:
.rhosts
- Even though AMANDA does not use rsh, it can use .rhosts-style
+ Even though Amanda does not use rsh, it can use .rhosts-style
authentication and a .rhosts file.
.amandahosts
This is essentially the same as .rhosts authentication except a different
file, with almost the same format, is used. This is the default mechanism
- built into AMANDA.
+ built into Amanda.
The format of the .amandahosts file is:
- hostname [ username ]
+ hostname [ username [ service ]*]
If username is ommitted, it defaults to the user running amandad, i.e.
the user listed in the inetd or xinetd configuration file.
+ The service is a list of the service the client is authorized to execute:
+ amdump, noop, selfcheck, sendsize, sendbackup, amindexd, amidxtaped.
+ amdump is a shortcut for "noop selfcheck sendsize sendbackup"
Kerberos
- AMANDA may use the Kerberos authentication system. Further information is
- in the docs/KERBEROS file that comes with an AMANDA distribution.
- For Samba access, AMANDA needs a file on the Samba server (which may or
+ Amanda may use the Kerberos authentication system. Further information is
+ in the docs/KERBEROS file that comes with an Amanda distribution.
+ For Samba access, Amanda needs a file on the Samba server (which may or
may not also be the tape server) named /etc/amandapass with share names,
(clear text) passwords and (optional) domain names, in that order, one
per line, whitespace separated. By default, the user used to connect to
- the PC is the same for all PC's and is compiled into AMANDA. It may be
+ the PC is the same for all PC's and is compiled into Amanda. It may be
changed on a host by host basis by listing it first in the password field
followed by a percent sign and then the password. For instance:
//another-pc/disk otheruser%otherpw
With clear text passwords, this file should obviously be tightly
- protected. It only needs to be readable by the AMANDA-user on the Samba
+ protected. It only needs to be readable by the Amanda-user on the Samba
server.
You can find further information in the docs/SAMBA file that comes with
- an AMANDA distribution.
+ an Amanda distribution.
HOST & DISK EXPRESSION
'$'. The matcher is case insensitive for host but is case sensitive for disk. A
match succeeds if all words in your expression match contiguous words in the
host or disk.
- ________________________________________________________
-|._|word_separator_for_a_host____________________________|
-|/_|word_separator_for_a_disk____________________________|
-|^_|anchor_at_left_______________________________________|
-|$_|anchor_at_right______________________________________|
-|?_|match_exactly_one_character_except_the_separator_____|
-|*_|match_zero_or_more_characters_except_the_separator___|
-|**|match_zero_or_more_characters_including_the_separator|
+. word separator for a host
+/ word separator for a disk
+^ anchor at left
+$ anchor at right
+? match exactly one character except the separator
+* match zero or more characters except the separator
+** match zero or more characters including the separator
Some examples:
- ___________________________________________
-|EXPRESSION|WILL_MATCH_______|WILL_NOT_MATCH|
-|hosta_____|hosta____________|hostb_________|
-|__________|hoSTA.dOMAIna.ORG|______________|
-|__________|foo.hosta.org____|______________|
-|host______|host_____________|hosta_________|
-|host?_____|hosta____________|host__________|
-|__________|hostb____________|______________|
-|ho*na_____|hoina____________|ho.aina.org___|
-|ho**na____|hoina____________|______________|
-|__________|ho.aina.org______|______________|
-|^hosta____|hosta____________|foo.hosta.org_|
-|sda*______|/dev/sda1________|______________|
-|__________|/dev/sda12_______|______________|
-|/opt/_____|opt_(disk)_______|opt_(host)____|
-|.opt._____|opt_(host)_______|opt_(disk)____|
-|/_________|/________________|any_other_disk|
-|/usr______|/usr_____________|______________|
-|__________|/usr/opt_________|______________|
-|/usr$_____|/usr_____________|/usr/opt______|
+EXPRESSION WILL MATCH WILL NOT MATCH
+hosta hosta hostb
+ hoSTA.dOMAIna.ORG
+ foo.hosta.org
+host host hosta
+host? hosta host
+ hostb
+ho*na hoina ho.aina.org
+ho**na hoina
+ ho.aina.org
+^hosta hosta foo.hosta.org
+sda* /dev/sda1
+ /dev/sda12
+/opt/ opt (disk) opt (host)
+.opt. opt (host) opt (disk)
+/ / any other disk
+/usr /usr
+ /usr/opt
+/usr$ /usr /usr/opt
DATESTAMP EXPRESSION
|200010$____|match_only_200010____________________________________________|
+CONFIGURATION OVERWRITE
+
+Most command allow to overwrite any configuration parameter on the command line
+with the -o option.
+-o NAME=value
+eg. -o runtapes=2
+eg. -o DUMPTYPE:no-compress:compress="server fast"
+eg. -o TAPETYPE:HP-DAT:length=2000m
+eg. -o INTERFACE:local:use="2000 kbps"
+
AUTHOR
James da Silva, <jds@amanda.org> : Original text
-Stefan G. Weichinger, <sgw@amanda.org>, maintainer of the AMANDA-documentation:
+Stefan G. Weichinger, <sgw@amanda.org>, maintainer of the Amanda-documentation:
XML-conversion, major update
SEE ALSO
-amadmin(8), amanda.conf(5), amcheck(8), amcheckdb(8), amcleanup(8), amdd(8),
-amdump(8), amflush(8), amgetconf(8), amlabel(8), ammt(8), amoverview(8), amplot
-(8), amrecover(8), amreport(8), amrestore(8), amrmtape(8), amstatus(8), amtape
-(8), amtapetype(8), amtoc(8), amverify(8), amverifyrun(8)
+amadmin(8), amanda.conf(5), amanda-client.conf(5), amcheck(8), amcheckdb(8),
+amcleanup(8), amdd(8), amdump(8), amfetchdump(8) amflush(8), amgetconf(8),
+amlabel(8), ammt(8), amoverview(8), amplot(8), amrecover(8), amreport(8),
+amrestore(8), amrmtape(8), amstatus(8), amtape(8), amtapetype(8), amtoc(8),
+amverify(8), amverifyrun(8)
-------------------------------------------------------------------------------
-Prev Up Next
-amadmin Home amanda.conf
+Prev Up Next
+amaespipe Home amanda.conf
amanda.conf
-Prev Chapter 35. The AMANDA Manual Pages. Next
+Prev Chapter 36. The Amanda Manual Pages. Next
-------------------------------------------------------------------------------
Name
-amanda.conf \14 Main configuration file for AMANDA, the Advanced Maryland
+amanda.conf \14 Main configuration file for Amanda, the Advanced Maryland
Automatic Network Disk Archiver
DESCRIPTION
-amanda.conf is the main configuration file for AMANDA. This manpage lists the
+amanda.conf is the main configuration file for Amanda. This manpage lists the
relevant sections and parameters of this file for quick reference.
PARAMETERS
There are a number of configuration parameters that control the behavior of the
-AMANDA programs. All have default values, so you need not specify the parameter
+Amanda programs. All have default values, so you need not specify the parameter
in amanda.conf if the default is suitable.
Lines starting with # are ignored, as are blank lines. Comments may be placed
on a line with a directive by starting the comment with a #. The remainder of
- org string
- Default: daily. A descriptive name for the configuration. This string
- appears in the Subject line of mail reports. Each AMANDA configuration
- should have a different string to keep mail reports distinct.
-
- mailto string
- Default: operators. A space separated list of recipients for mail
- reports.
-
- dumpcycle int
- Default: 10 days. The number of days in the backup cycle. Each disk will
- get a full backup at least this often. Setting this to zero tries to do a
- full backup each run.
-
- Note
-
- This parameter may also be set in a specific dumptype (see below). This
- value sets the default for all dumptypes so must appear in amanda.conf
- before any dumptypes are defined.
-
- runspercycle int
- Default: same as dumpcycle. The number of amdump runs in dumpcycle days.
- A value of 0 means the same value as dumpcycle. A value of -1 means guess
- the number of runs from the tapelist file, which is the number of tapes
- used in the last dumpcycle days / runtapes.
-
- tapecycle int
- Default: 15 tapes. Typically tapes are used by AMANDA in an ordered
- rotation. The tapecycle parameter defines the size of that rotation. The
- number of tapes in rotation must be larger than the number of tapes
- required for a complete dump cycle (see the dumpcycle parameter).
- This is calculated by multiplying the number of amdump runs per dump
- cycle (runspercycle parameter) times the number of tapes used per run
- (runtapes parameter). Typically two to four times this calculated number
- of tapes are in rotation. While AMANDA is always willing to use a new
- tape in its rotation, it refuses to reuse a tape until at least
- 'tapecycle -1' number of other tapes have been used.
- It is considered good administrative practice to set the tapecycle
- parameter slightly lower than the actual number of tapes in rotation.
- This allows the administrator to more easily cope with damaged or
- misplaced tapes or schedule adjustments that call for slight adjustments
- in the rotation order.
-
- dumpuser string
- Default: amanda. The login name AMANDA uses to run the backups. The
- backup client hosts must allow access from the tape server host as this
- user via .rhosts or .amandahosts, depending on how the AMANDA software
- was built.
-
- printer string
- Printer to use when doing tape labels. See the lbl-templ tapetype option.
-
- tapedev string
- Default: /dev/nst0. The path name of the non-rewinding tape device. Non-
- rewinding tape device names often have an 'n' in the name, e.g. /dev/rmt/
- 0mn, however this is operating system specific and you should consult
- that documentation for detailed naming information.
- If a tape changer is configured (see the tpchanger option), this option
- might not be used.
- If the null output driver is selected (see the section OUTPUT DRIVERS in
- the amanda(8) manpage for more information), programs such as amdump will
- run normally but all images will be thrown away. This should only be used
- for debugging and testing, and probably only with the record option set
- to no.
-
- rawtapedev string
- Default: /dev/null. The path name of the raw tape device. This is only
- used if AMANDA is compiled for Linux machines with floppy tapes and is
- needed for QIC volume table operations.
-
- tpchanger string
- Default: none. The name of the tape changer. If a tape changer is not
- configured, this option is not used and should be commented out of the
- configuration file.
- If a tape changer is configured, choose one of the changer scripts (e.g.
- chg-scsi) and enter that here.
-
- changerdev string
- Default: /dev/null. A tape changer configuration parameter. Usage depends
- on the particular changer defined with the tpchanger option.
-
- changerfile string
- Default: /usr/adm/amanda/log/changer-status. A tape changer configuration
- parameter. Usage depends on the particular changer defined with the
- tpchanger option.
-
- runtapes int
- Default: 1. The maximum number of tapes used in a single run. If a tape
- changer is not configured, this option is not used and should be
- commented out of the configuration file.
- If a tape changer is configured, this may be set larger than one to let
- AMANDA write to more than one tape.
- Note that this is an upper bound on the number of tapes, and AMANDA may
- use less.
- Also note that as of this release, AMANDA does not support true tape
- overflow. When it reaches the end of one tape, the backup image AMANDA
- was processing starts over again on the next tape.
-
- maxdumpsize int
- Default: runtapes*tape_length. Maximum number of bytes the planner will
- schedule for a run.
-
- taperalgo [first|firstfit|largest|largestfit|smallest|last]
- Default: first. The algorithm used to choose which dump image to send to
- the taper.
-
-
- first
- First in, first out.
-
- firstfit
- The first dump image that will fit on the current tape.
-
- largest
- The largest dump image.
-
- largestfit
- The largest dump image that will fit on the current tape.
-
- smallest
- The smallest dump image.
-
- last
- Last in, first out.
-
-
- labelstr string
- Default: .*. The tape label constraint regular expression. All tape
- labels generated (see amlabel(8)) and used by this configuration must
- match the regular expression. If multiple configurations are run from the
- same tape server host, it is helpful to set their labels to different
- strings (for example, "DAILY[0-9][0-9]*" vs. "ARCHIVE[0-9][0-9]*") to
- avoid overwriting each other's tapes.
-
- tapetype string
- Default: EXABYTE. The type of tape drive associated with tapedev or
- tpchanger. This refers to one of the defined tapetypes in the config file
- (see below), which specify various tape parameters, like the length,
- filemark size, and speed of the tape media and device.
-
- ctimeout int
- Default: 30 seconds. Maximum amount of time that amcheck will wait for
- each client host.
-
- dtimeout int
- Default: 1800 seconds. Amount of idle time per disk on a given client
- that a dumper running from within amdump will wait before it fails with a
- data timeout error.
-
- etimeout int
- Default: 300 seconds. Amount of time per disk on a given client that the
- planner step of amdump will wait to get the dump size estimates. For
- instance, with the default of 300 seconds and four disks on client A,
- planner will wait up to 20 minutes for that machine. A negative value
- will be interpreted as a total amount of time to wait per client instead
- of per disk.
-
- netusage int
- Default: 300 Kbps. The maximum network bandwidth allocated to AMANDA, in
- Kbytes per second. See also the interface section.
-
- inparallel int
- Default: 10. The maximum number of backups that AMANDA will attempt to
- run in parallel. AMANDA will stay within the constraints of network
- bandwidth and holding disk space available, so it doesn't hurt to set
- this number a bit high. Some contention can occur with larger numbers of
- backups, but this effect is relatively small on most systems.
-
- displayunit "k|m|g|t"
- Default: "k". The unit used to print many numbers, k=kilo, m=mega,
- g=giga, t=tera.
-
- dumporder string
- Default: tttTTTTTTT. The priority order of each dumper:
-
- * s: smallest size
- * S: largest size
- * t: smallest time
- * T: largest time
- * b: smallest bandwidth
- * B: largest bandwidth
-
-
- maxdumps int
- Default: 1. The maximum number of backups from a single host that AMANDA
- will attempt to run in parallel. See also the inparallel option.
- Note that this parameter may also be set in a specific dumptype (see
- below). This value sets the default for all dumptypes so must appear in
- amanda.conf before any dumptypes are defined.
-
- bumpsize int
- Default: 10 Mbytes. The minimum savings required to trigger an automatic
- bump from one incremental level to the next, expressed as size. If AMANDA
- determines that the next higher backup level will be this much smaller
- than the current level, it will do the next level. The value of this
- parameter is used only if the parameter bumppercent is set to 0.
- The global setting of this parameter can be overwritten inside of a
- dumptype-definition.
- See also the options bumppercent, bumpmult and bumpdays.
-
- bumppercent int
- Default: 0 percent. The minimum savings required to trigger an automatic
- bump from one incremental level to the next, expressed as percentage of
- the current size of the DLE (size of current level 0). If AMANDA
- determines that the next higher backup level will be this much smaller
- than the current level, it will do the next level.
- If this parameter is set to 0, the value of the parameter bumpsize is
- used to trigger bumping.
- The global setting of this parameter can be overwritten inside of a
- dumptype-definition.
- See also the options bumpsize, bumpmult and bumpdays.
-
- bumpmult float
- Default: 1.5. The bump size multiplier. AMANDA multiplies bumpsize by
- this factor for each level. This prevents active filesystems from bumping
- too much by making it harder to bump to the next level. For example, with
- the default bumpsize and bumpmult set to 2.0, the bump threshold will be
- 10 Mbytes for level one, 20 Mbytes for level two, 40 Mbytes for level
- three, and so on.
- The global setting of this parameter can be overwritten inside of a
- dumptype-definition.
-
- bumpdays int
- Default: 2 days. To insure redundancy in the dumps, AMANDA keeps
- filesystems at the same incremental level for at least bumpdays days,
- even if the other bump threshold criteria are met.
- The global setting of this parameter can be overwritten inside of a
- dumptype-definition.
-
- diskfile string
- Default: disklist. The file name for the disklist file holding client
- hosts, disks and other client dumping information.
-
- infofile string
- Default: /usr/adm/amanda/curinfo. The file or directory name for the
- historical information database. If AMANDA was configured to use DBM
- databases, this is the base file name for them. If it was configured to
- use text formated databases (the default), this is the base directory and
- within here will be a directory per client, then a directory per disk,
- then a text file of data.
-
- logdir string
- Default: /usr/adm/amanda. The directory for the amdump and log files.
-
- indexdir string
- Default /usr/adm/amanda/index. The directory where index files (backup
- image catalogues) are stored. Index files are only generated for
- filesystems whose dumptype has the index option enabled.
-
- tapelist string
- Default: tapelist. The file name for the active tapelist file. AMANDA
- maintains this file with information about the active set of tapes.
-
- tapebufs int
- Default: 20. The number of buffers used by the taper process run by
- amdump and amflush to hold data as it is read from the network or disk
- before it is written to tape. Each buffer is a little larger than 32
- KBytes and is held in a shared memory region.
-
- reserve number
- Default: 100. The part of holding-disk space that should be reserved for
- incremental backups if no tape is available, expressed as a percentage of
- the available holding-disk space (0-100). By default, when there is no
- tape to write to, degraded mode (incremental) backups will be performed
- to the holding disk. If full backups should also be allowed in this case,
- the amount of holding disk space reserved for incrementals should be
- lowered.
-
- autoflush bool
- Default: off. Whether an amdump run will flush the dump already on
- holding disk to tape.
-
- amrecover_do_fsf bool
- Default: off. Amrecover will call amrestore with the -f flag for faster
- positioning of the tape.
-
- amrecover_check_label bool
- Default: off. Amrecover will call amrestore with the -l flag to check the
- label.
-
- amrecover_changer string
- Default: ''. Amrecover will use the changer if you use 'settape <string>'
- and that string is the same as the amrecover_changer setting.
-
- columnspec string
- Defines the width of columns amreport should use. String is a comma (',')
- separated list of triples. Each triple consists of three parts which are
- separated by a equal sign ('=') and a colon (':') (see the example).
- These three parts specify:
-
- * the name of the column, which may be:
-
- o Compress (compression ratio)
- o Disk (client disk name)
- o DumpRate (dump rate in KBytes/sec)
- o DumpTime (total dump time in hours:minutes)
- o HostName (client host name)
- o Level (dump level)
- o OrigKB (original image size in KBytes)
- o OutKB (output image size in KBytes)
- o TapeRate (tape writing rate in KBytes/sec)
- o TapeTime (total tape time in hours:minutes)
-
- * the amount of space to display before the column (used to get
- whitespace between columns).
- * the width of the column itself. If set to a negative value, the width
- will be calculated on demand to fit the largest entry in this column.
-
- Here is an example:
-
- columnspec "Disk=1:18,HostName=0:10,OutKB=1:7"
-
- The above will display the disk information in 18 characters and put one
- space before it. The hostname column will be 10 characters wide with no
- space to the left. The output KBytes column is seven characters wide with
- one space before it.
-
includefile string
- Default: none. The name of an AMANDA configuration file to include within
+ Default: none. The name of an Amanda configuration file to include within
the current file. Useful for sharing dumptypes, tapetypes and interface
definitions among several configurations.
use int
Default: 0 Gb. Amount of space that can be used in this holding disk
area. If the value is zero, all available space on the file system is
- used. If the value is negative, AMANDA will use all available space minus
+ used. If the value is negative, Amanda will use all available space minus
that value.
chunksize int
chunk will not exceed the specified value. However, even though dump
images are split in the holding disk, they are concatenated as they are
written to tape, so each dump image still corresponds to a single
- continuous tape section.
- If 0 is specified, AMANDA will create holding disk chunks as large as (
- (INT_MAX/1024)-64) Kbytes.
- Each holding disk chunk includes a 32 Kbyte header, so the minimum chunk
- size is 64 Kbytes (but that would be really silly).
- Operating systems that are limited to a maximum file size of 2 Gbytes
- actually cannot handle files that large. They must be at least one byte
- less than 2 Gbytes. Since AMANDA works with 32 Kbyte blocks, and to
- handle the final read at the end of the chunk, the chunk size should be
- at least 64 Kbytes (2 * 32 Kbytes) smaller than the maximum file size,
- e.g. 2047 Mbytes.
+ continuous tape section. If 0 is specified, Amanda will create holding
+ disk chunks as large as ((INT_MAX/1024)-64) Kbytes. Each holding disk
+ chunk includes a 32 Kbyte header, so the minimum chunk size is 64 Kbytes
+ (but that would be really silly). Operating systems that are limited to a
+ maximum file size of 2 Gbytes actually cannot handle files that large.
+ They must be at least one byte less than 2 Gbytes. Since Amanda works
+ with 32 Kbyte blocks, and to handle the final read at the end of the
+ chunk, the chunk size should be at least 64 Kbytes (2 * 32 Kbytes)
+ smaller than the maximum file size, e.g. 2047 Mbytes.
DUMPTYPE SECTION
auth string
Default: bsd. Type of authorization to perform between tape server and
- backup client hosts. May be krb4 to use Kerberos-IV authorization.
+ backup client hosts.
+ bsd, bsd authorization with udp initial connection and one tcp connection
+ by data stream.
+ bsdtcp, bsd authorization but use only one tcp connection.
+ bsdudp, like bsd, but will use only one tcp connection for all data
+ stream.
+ krb4 to use Kerberos-IV authorization.
+ krb5 to use Kerberos-V authorization.
+ rsh to use rsh authorization.
+ ssh to use OpenSSH authorization.
+
+ amandad_path string
+ Default: $libexec/amandad. Specify the amandad path of the client, only
+ use with rsh/ssh authentification.
+
+ client_username string
+ Default: CLIENT_LOGIN. Specify the username to connect on the client,
+ only use with rsh/ssh authentification.
bumpsize int
Default: 10 Mbytes. The minimum savings required to trigger an automatic
- bump from one incremental level to the next, expressed as size. If AMANDA
+ bump from one incremental level to the next, expressed as size. If Amanda
determines that the next higher backup level will be this much smaller
than the current level, it will do the next level. The value of this
parameter is used only if the parameter bumppercent is set to 0.
bumppercent int
Default: 0 percent. The minimum savings required to trigger an automatic
bump from one incremental level to the next, expressed as percentage of
- the current size of the DLE (size of current level 0). If AMANDA
+ the current size of the DLE (size of current level 0). If Amanda
determines that the next higher backup level will be this much smaller
than the current level, it will do the next level.
If this parameter is set to 0, the value of the parameter bumpsize is
See also the options bumpsize, bumpmult and bumpdays.
bumpmult float
- Default: 1.5. The bump size multiplier. AMANDA multiplies bumpsize by
+ Default: 1.5. The bump size multiplier. Amanda multiplies bumpsize by
this factor for each level. This prevents active filesystems from bumping
too much by making it harder to bump to the next level. For example, with
the default bumpsize and bumpmult set to 2.0, the bump threshold will be
three, and so on.
bumpdays int
- Default: 2 days. To insure redundancy in the dumps, AMANDA keeps
+ Default: 2 days. To insure redundancy in the dumps, Amanda keeps
filesystems at the same incremental level for at least bumpdays days,
even if the other bump threshold criteria are met.
comprate float [, float ]
Default: 0.50, 0.50. The expected full and incremental compression factor
- for dumps. It is only used if AMANDA does not have any history
+ for dumps. It is only used if Amanda does not have any history
information on compression rates for a filesystem, so should not usually
need to be set. However, it may be useful for the first time a very large
filesystem that compresses very little is backed up.
compress [client|server] string
- Default: client fast. If AMANDA does compression of the backup images, it
+ Default: client fast. If Amanda does compression of the backup images, it
can do so either on the backup client host before it crosses the network
or on the tape server host as it goes from the network into the holding
disk or to tape. Which place to do compression (if at all) depends on how
well the dump image usually compresses, the speed and load on the client
or server, network capacity, holding disk capacity, availability of tape
hardware compression, etc.
- For either type of compression, AMANDA also allows the selection of two
+ For either type of compression, Amanda also allows the selection of three
styles of compression. Best is the best compression available, often at
the expense of CPU overhead. Fast is often not as good a compression as
- best, but usually less CPU overhead.
+ best, but usually less CPU overhead. Or to specify Custom to use your own
+ compression method. (See dumptype custom-compress in example/amanda.conf
+ for reference)
So the compress options line may be one of:
* compress none
* compress [client] fast
* compress [client] best
+ * compress client custom
+ Specify client_custom_compress "PROG"
+ PROG must not contain white space and it must accept -d for uncompress.
* compress server fast
* compress server best
+ * compress server custom
+ Specify server_custom_compress "PROG"
+ PROG must not contain white space and it must accept -d for uncompress.
Note that some tape devices do compression and this option has nothing to
do with whether that is used. If hardware compression is used (usually
- via a particular tape device name or mt option), AMANDA (software)
+ via a particular tape device name or mt option), Amanda (software)
compression should be disabled.
dumpcycle int
Default: 10 days. The number of days in the backup cycle. Each disk using
- this set of options will get a full backup at least this often. Setting
+ this set of options will get a full backup at least this of ten. Setting
this to zero tries to do a full backup each run.
+ encrypt [none|client|server]
+ Default: none. To encrypt backup images, it can do so either on the
+ backup client host before it crosses the network or on the tape server
+ host as it goes from the network into the holding disk or to tape.
+ So the encrypt options line may be one of:
+
+ * encrypt none
+ * encrypt client
+ Specify client_encrypt "PROG"
+ PROG must not contain white space.
+ Specify client_decrypt_option "decryption-parameter" Default: "-d"
+ decryption-parameter must not contain white space.
+ (See dumptype server-encrypt-fast in example/amanda.conf for reference)
+ * encrypt server
+ Specify server_encrypt "PROG"
+ PROG must not contain white space.
+ Specify server_decrypt_option "decryption-parameter" Default: "-d"
+ decryption-parameter must not contain white space.
+ (See dumptype client-encrypt-nocomp in example/amanda.conf for
+ reference)
+
+
estimate client|calcsize|server
- Default: client. Determine the way AMANDA does it's estimate.
+ Default: client. Determine the way Amanda does it's estimate.
* client:
Use the same program as the dumping program, this is the most accurate
Default: file. There are two exclude lists, exclude file and exclude
list. With exclude file , the string is a GNU-tar exclude expression.
With exclude list , the string is a file name on the client containing
- GNU-tar exclude expressions.
+ GNU-tar exclude expressions. The path to the specified exclude list file,
+ if present (see description of 'optional' below), must be readable by the
+ Amanda user.
All exclude expressions are concatenated in one file and passed to GNU-
tar as an --exclude-from argument.
+ Exclude expressions must always be specified as relative to the head
+ directory of the DLE.
With the append keyword, the string is appended to the current list,
without it, the string overwrites the list.
If optional is specified for exclude list, then amcheck will not complain
holdingdisk boolean
Default: yes. Whether a holding disk should be used for these backups or
whether they should go directly to tape. If the holding disk is a portion
- of another file system that AMANDA is backing up, that file system should
+ of another file system that Amanda is backing up, that file system should
refer to a dumptype with holdingdisk set to no to avoid backing up the
holding disk into itself.
list. With include file , the string is a glob expression. With include
list , the string is a file name on the client containing glob
expressions.
- All include expressions are expanded by AMANDA, concatenated in one file
+ All include expressions are expanded by Amanda, concatenated in one file
and passed to GNU-tar as a --files-from argument. They must start with
"./" and contain no other "/".
+ Include expressions must always be specified as relative to the head
+ directory of the DLE.
+
+ Note
+
+ For globbing to work at all, even the limited single level, the top level
+ directory of the DLE must be readable by the Amanda user.
With the append keyword, the string is appended to the current list,
without it, the string overwrites the list.
If optional is specified for include list, then amcheck will not complain
server host.
maxdumps int
- Default: 1. The maximum number of backups from a single host that AMANDA
+ Default: 1. The maximum number of backups from a single host that Amanda
will attempt to run in parallel. See also the main section parameter
inparallel.
overpromoted.
priority string
- Default: medium. When there is no tape to write to, AMANDA will do
+ Default: medium. When there is no tape to write to, Amanda will do
incremental backups in priority order to the holding disk. The priority
may be high (2), medium (1), low (0) or a number of your choice.
skip-full boolean
Default: no. If true and planner has scheduled a full backup, these disks
will be skipped, and full backups should be run off-line on these days.
- It was reported that AMANDA only schedules level 1 incrementals in this
+ It was reported that Amanda only schedules level 1 incrementals in this
configuration; this is probably a bug.
skip-incr boolean
standard
- The standard AMANDA schedule.
+ The standard Amanda schedule.
nofull
Never do full backups, only level 1 incrementals.
incronly
Only do incremental dumps. amadmin force should be used to tell
- AMANDA that a full dump has been performed off-line, so that it
+ Amanda that a full dump has been performed off-line, so that it
resets to level 1. It is similar to skip-full, but with incronly
full dumps may be scheduled manually. Unfortunately, it appears
- that AMANDA will perform full backups with this configuration,
+ that Amanda will perform full backups with this configuration,
which is probably a bug.
-The following dumptype entries are predefined by AMANDA:
+ tape_splitsize int
+ Default: none. Split dump file on tape into pieces of a specified size.
+ This allows dumps to be spread across multiple tapes, and can potentially
+ make more efficient use of tape space. Note that if this value is too
+ large (more than half the size of the average dump being split),
+ substantial tape space can be wasted. If too small, large dumps will be
+ split into innumerable tiny dumpfiles, adding to restoration complexity.
+ A good rule of thumb, usually, is 1/10 of the size of your tape.
+
+ split_diskbuffer string
+ Default: none. When dumping a split dump in PORT-WRITE mode (usually
+ meaning "no holding disk"), buffer the split chunks to a file in the
+ directory specified by this option.
+
+ fallback_splitsize int
+ Default: 10M. When dumping a split dump in PORT-WRITE mode, if no
+ split_diskbuffer is specified (or if we somehow fail to use our
+ split_diskbuffer), we must buffer split chunks in memory. This specifies
+ the maximum size split chunks can be in this scenario, and thus the
+ maximum amount of memory consumed for in-memory splitting. The size of
+ this buffer can be changed from its (very conservative) default to a
+ value reflecting the amount of memory that each taper process on the dump
+ server may reasonably consume.
+
+The following dumptype entries are predefined by Amanda:
define dumptype no-compress {
compress none
record no
}
-AMANDA provides a dumptype named global in the sample amanda.conf file that all
+Amanda provides a dumptype named global in the sample amanda.conf file that all
dumptypes should reference. This provides an easy place to make changes that
will affect every dumptype.
length int
Default: 2000 kbytes. How much data will fit on a tape.
- Note that this value is only used by AMANDA to schedule which backups
- will be run. Once the backups start, AMANDA will continue to write to a
+ Note that this value is only used by Amanda to schedule which backups
+ will be run. Once the backups start, Amanda will continue to write to a
tape until it gets an error, regardless of what value is entered for
length (but see the section OUTPUT DRIVERS in the amanda(8) manpage for
exceptions).
Default: 32. How much data will be written in each tape record expressed
in KiloBytes. The tape record size (= blocksize) can not be reduced below
the default 32 KBytes. The parameter blocksize can only be raised if
- AMANDA was compiled with the configure option --with-maxtapeblocksize=N
+ Amanda was compiled with the configure option --with-maxtapeblocksize=N
set with "N" greater than 32 during configure.
file-pad boolean
Default: true. If true, every record, including the last one in the file,
- will have the same length. This matches the way AMANDA wrote tapes prior
+ will have the same length. This matches the way Amanda wrote tapes prior
to the availability of this parameter. It may also be useful on devices
that only support a fixed blocksize.
Note that the last record on the tape probably includes trailing null
speed int
Default: 200 bps. How fast the drive will accept data, in bytes per
- second. This parameter is NOT currently used by AMANDA.
+ second. This parameter is NOT currently used by Amanda.
lbl-templ string
A PostScript template file used by amreport to generate labels. Several
- sample files are provided with the AMANDA sources in the example
+ sample files are provided with the Amanda sources in the example
directory. See the amreport(8) man page for more information.
In addition to options, another tapetype name may be entered, which makes this
disklist file.
Note that these sections define network interface characteristics, not the
actual interface that will be used. Nor do they impose limits on the bandwidth
-that will actually be taken up by AMANDA. AMANDA computes the estimated
+that will actually be taken up by Amanda. Amanda computes the estimated
bandwidth each file system backup will take based on the estimated size and
time, then compares that plus any other running backups with the limit as
another of the criteria when deciding whether to start the backup. Once a
-backup starts, AMANDA will use as much of the network as it can leaving
+backup starts, Amanda will use as much of the network as it can leaving
throttling up to the operating system and network hardware.
The interface options and values are:
AUTHOR
James da Silva, <jds@amanda.org>: Original text
-Stefan G. Weichinger, <sgw@amanda.org>, maintainer of the AMANDA-documentation:
+Stefan G. Weichinger, <sgw@amanda.org>, maintainer of the Amanda-documentation:
XML-conversion, major update, splitting
SEE ALSO
-amanda(8),
+amanda(8), amanda-client.conf(5), amcrypt(8), aespipe(1),
-------------------------------------------------------------------------------
-Prev Up Next
-amanda Home amcheck
+Prev Up Next
+amanda Home amanda-client.conf
amcheck
-Prev Chapter 35. The AMANDA Manual Pages. Next
+Prev Chapter 36. The Amanda Manual Pages. Next
-------------------------------------------------------------------------------
Name
-amcheck \14 run AMANDA self-checks
+amcheck \14 run Amanda self-checks
Synopsis
-amcheck [-mwsclt ] [-Maddress ] config [ host [disk...]...]
+amcheck [-am] [-w] [-sclt] [ -M | address ]* config [ host | [disk]*]* [ -o |
+configoption ]*
DESCRIPTION
-Amcheck runs a number of self-checks on both the AMANDA tape server host and
-the AMANDA client hosts.
+Amcheck runs a number of self-checks on both the Amanda tape server host and
+the Amanda client hosts.
On the tape server host, amcheck can go through the same tape checking used at
the start of the nightly amdump run to verify the correct tape for the next run
is mounted.
running and that permissions on filesystems to be backed up are correct.
You can specify many host/disk expressions, only disks that match an expression
will be checked. All disks are checked if no expressions are given.
-See the amanda(8) man page for more details about AMANDA.
+See the amanda(8) man page for more details about Amanda.
OPTIONS
Run the tape tests on the server host.
-w
- Enables a destructive check for write-protection on the tape (which would
+ Enables a DESTRUCTIVE check for write-protection on the tape (which would
otherwise cause the subsequent amdump to fail). If the tape is writable,
- this check causes all data after the tape label to be erased (actually
- depends on the device driver: there is no portable non-destructive way to
- check for write-protection). The check implies -t and is only made if the
- tape is otherwise correct.
+ this check causes all data after the tape label to be erased. If the
+ label_new_tapes option is enabled, this check may ERASE any non-Amanda
+ tape in the drive or changer. The check enable the tape tests on the
+ server host and is only made if the tape is otherwise correct.
-m
Nothing is printed, but mail is sent if any errors are detected. The mail
-a
Like -m but the mail is always sent.
- -Maddress
+ -M address
Mail the report to address instead of the mailto value from amanda.conf.
Implies -m.
+ host [disk]*
+ Specify the host and disk on which the command will work.
+
+ -o configoption
+ See the "CONFIGURATION OVERWRITE" section in amanda(8).
+
The default is -cs.
EXAMPLES
displayed on standard output.
% amcheck daily
- AMANDA Tape Server Host Check
+ Amanda Tape Server Host Check
-----------------------------
/amanda2/amanda/work: 911475 KB disk space available, that's plenty.
NOTE: skipping tape-writable test.
Tape VOL10 label ok.
Server check took 34.966 seconds.
- AMANDA Backup Client Hosts Check
+ Amanda Backup Client Hosts Check
--------------------------------
WARNING: northstar: selfcheck request timed out. Host down?
WARNING: drinkme: selfcheck request timed out. Host down?
WARNING: scruffy: selfcheck request timed out. Host down?
Client check: 136 hosts checked in 51.945 seconds, 3 problems found.
- (brought to you by AMANDA 2.4.5)
+ (brought to you by Amanda 2.5.0)
In this example, if the line mailto csd-amanda is in amanda.conf, mail will be
sent to csd-amanda if the server check returns an error.
instead of runuser.
ERROR: program dir directory: not accessible
- (error) The directory AMANDA expects to find its auxiliary programs in,
+ (error) The directory Amanda expects to find its auxiliary programs in,
directory, is not accessible.
ERROR: program program: does not exist
log
- for the AMANDA log directory (see logdir in amanda.conf)
+ for the Amanda log directory (see logdir in amanda.conf)
oldlog
for the directory that holds the old log files (see logdir in
amanda.conf)
info
- for an AMANDA database information directory (see curinfo in
+ for an Amanda database information directory (see curinfo in
amanda.conf) or
index
- for an AMANDA index directory (see indexdir in amanda.conf)
+ for an Amanda index directory (see indexdir in amanda.conf)
tapelist
- for the AMANDA tapelist directory (see tapelist in amanda.conf)
+ for the Amanda tapelist directory (see tapelist in amanda.conf)
NOTE: XXX dir directory: does not exist
not allow search permission.
ERROR: tape list tapelist: not writable
- (error) AMANDA tape list file tapelist (see tapelist in amanda.conf) is
+ (error) Amanda tape list file tapelist (see tapelist in amanda.conf) is
not writable or was not found.
ERROR: tape list tapelist: parse error
- (error) AMANDA tape list file tapelist (see tapelist in amanda.conf)
+ (error) Amanda tape list file tapelist (see tapelist in amanda.conf)
could not be read or parsed.
WARNING: tapedev is /dev/null, dumps will be thrown away
(warning) The tapedev parameter in amanda.conf is set to /dev/null and
- AMANDA uses that when debugging to throw all the dump images away.
+ Amanda uses that when debugging to throw all the dump images away.
WARNING: hold file file exists
(info) Hold file file exists and will cause amdump to pause at the
enough for what is requested in amanda.conf.
Holding disk disk: F KB disk space available, using U KB
- (info) Holding disk disk has F KBytes of free space and AMANDA will be
+ (info) Holding disk disk has F KBytes of free space and Amanda will be
using up to U Kbytes.
WARNING: if a tape changer is not available, runtapes must be set to 1.
(info) The tape write test (see the -w option) was not enabled.
WARNING: skipping tape test because amdump or amflush seem to be running,
- WARNING: if they are not, you must run amcleanup,
+ WARNING: if they are not, you must run amcleanup
(warning) It looked to amcheck like either amdump or amflush were running
because a log file or amdump file exists. If they are not running, you
probably need to run amcleanup to clear up a previous failure. Otherwise,
ERROR: host NAK: [NAK parse failed]
(error) Amcheck could not parse the negative acknowledgment error from
- host. There might be an AMANDA version mismatch between the host running
+ host. There might be an Amanda version mismatch between the host running
amcheck and host.
ERROR: host [mutual-authentication failed]
AUTHOR
James da Silva, <jds@amanda.org> : Original text
-Stefan G. Weichinger, <sgw@amanda.org>, maintainer of the AMANDA-documentation:
+Stefan G. Weichinger, <sgw@amanda.org>, maintainer of the Amanda-documentation:
XML-conversion
SEE ALSO
amanda(8), amdump(8)
-------------------------------------------------------------------------------
-Prev Up Next
-amanda.conf Home amcheckdb
+Prev Up Next
+amanda-client.conf Home amcheckdb
amcheckdb
-Prev Chapter 35. The AMANDA Manual Pages. Next
+Prev Chapter 36. The Amanda Manual Pages. Next
-------------------------------------------------------------------------------
Name
-amcheckdb \14 check AMANDA database for tape consistency
+amcheckdb \14 check Amanda database for tape consistency
Synopsis
DESCRIPTION
-Amcheckdb verifies that every tape mentioned in the AMANDA database is still
+Amcheckdb verifies that every tape mentioned in the Amanda database is still
valid in the tapelist file.
-See the amanda(8) man page for more details about AMANDA.
+See the amanda(8) man page for more details about Amanda.
EXAMPLE
AUTHOR
Adrian T. Filipi-Martin <atf3r@cs.virginia.edu>: Original text
-Stefan G. Weichinger, <sgw@amanda.org>, maintainer of the AMANDA-documentation:
+Stefan G. Weichinger, <sgw@amanda.org>, maintainer of the Amanda-documentation:
XML-conversion
SEE ALSO
amcleanup
-Prev Chapter 35. The AMANDA Manual Pages. Next
+Prev Chapter 36. The Amanda Manual Pages. Next
-------------------------------------------------------------------------------
Name
-amcleanup \14 run the AMANDA cleanup process after a failure
+amcleanup \14 run the Amanda cleanup process after a failure
Synopsis
DESCRIPTION
-Amcleanup generates the AMANDA Mail Report and updates the AMANDA databases
+Amcleanup generates the Amanda Mail Report and updates the Amanda databases
after a system failure on a tape server host. This cleanup process is normally
done automatically as part of the amdump program, but if amdump cannot complete
for some reason (usually because of a tape server host crash), amcleanup must
be run some time later (usually during system boot).
-See the amanda(8) man page for more details about AMANDA.
+See the amanda(8) man page for more details about Amanda.
EXAMPLES
-This example runs the AMANDA cleanup process by hand after a failure.
+This example runs the Amanda cleanup process by hand after a failure.
% amcleanup daily
Putting the following line in a system boot script (e.g. /etc/rc.local) runs
-the AMANDA cleanup process as part of the reboot, eliminating the need to run
+the Amanda cleanup process as part of the reboot, eliminating the need to run
it by hand.
/usr/local/sbin/amcleanup daily
AUTHOR
James da Silva, <jds@amanda.org>: Original text
-Stefan G. Weichinger, <sgw@amanda.org>, maintainer of the AMANDA-documentation:
+Stefan G. Weichinger, <sgw@amanda.org>, maintainer of the Amanda-documentation:
XML-conversion
SEE ALSO
amanda(8), amdump(8)
-------------------------------------------------------------------------------
-Prev Up Next
-amcheckdb Home amdd
+Prev Up Next
+amcheckdb Home amcrypt
--- /dev/null
+
+ amcrypt-ossl-asym
+Prev Chapter 36. The Amanda Manual Pages. Next
+
+-------------------------------------------------------------------------------
+
+Name
+
+amcrypt-ossl-asym \14 crypt program for Amanda asymmetric data encryption using
+OpenSSL
+
+Synopsis
+
+amcrypt-ossl-asym [-d]
+
+DESCRIPTION
+
+amcrypt-ossl-asym uses OpenSSL to encrypt and decrypt data. OpenSSL is
+available from www.openssl.org. OpenSSL offers a wide variety of cipher choices
+( amcrypt-ossl-asym defaults to 256-bit AES) and can use hardware cryptographic
+accelerators on several platforms.
+amcrypt-ossl-asym will search for the OpenSSL program in the following
+directories: /bin:/usr/bin:/usr/local/bin:/usr/ssl/bin:/usr/local/ssl/bin.
+
+GENERATING PUBLIC AND PRIVATE KEYS
+
+RSA keys can be generated with the standard OpenSSL commands, e.g.:
+
+ $ cd /var/lib/amanda
+ $ openssl genrsa -aes128 -out backup-key.pem 1024
+ Generating RSA private key, 1024 bit long modulus
+ [...]
+ Enter pass phrase for backup-key.pem: ENTER YOUR PASS PHRASE
+ Verifying - Enter pass phrase for backup-key.pem: ENTER YOUR PASS PHRASE
+
+ $ openssl rsa -in backup-key.pem -pubout -out backup-pubkey.pem
+ Enter pass phrase for backup-key.pem: ENTER YOUR PASS PHRASE
+ Writing RSA key
+
+To generate a private key without a passphrase, omit the -aes128 option. See
+openssl_genrsa(1) for more key generation options.
+Note that it is always possible to generate the public key from the private
+key.
+
+KEY AND PASSPHRASE MANAGEMENT
+
+amcrypt-ossl-asym uses the public key to encrypt data. The security of the data
+does not depend on the confidentiality of the public key. The private key is
+used to decrypt data, and must be protected. Encrypted backup data cannot be
+recovered without the private key. The private key may optionally be encrypted
+with a passphrase.
+While the public key must be online at all times to perorm backups, the private
+key and optional passphrase are only needed to restore data. It is recommended
+that the latter be stored offline all other times. For example, you could keep
+the private key on removable media, and copy it into place for a restore; or
+you could keep the private key online, encrypted with a passphrase that is
+present only for a restore.
+OpenSSL's key derivation routines use a salt to guard against dictionary
+attacks on the pass phrase; still it is important to pick a pass phrase that is
+hard to guess. The Diceware method (see www.diceware.com) can be used to create
+passphrases that are difficult to guess and easy to remember.
+
+FILES
+
+
+
+ /var/lib/amanda/backup-privkey.pem
+ File containing the RSA private key. It should not be readable by any
+ user other than the Amanda user.
+
+ /var/lib/amanda/backup-pubkey.pem
+ File containing the RSA public key.
+
+ /var/lib/amanda/.pass
+ File containing the pass phrase. It should not be readable by any user
+ other than the Amanda user.
+
+
+SEE ALSO
+
+amanda(8), amanda.conf(5), openssl(1), amcrypt-ossl(8)
+-------------------------------------------------------------------------------
+
+Prev Up Next
+amcrypt-ossl Home amdd
+
--- /dev/null
+
+ amcrypt-ossl
+Prev Chapter 36. The Amanda Manual Pages. Next
+
+-------------------------------------------------------------------------------
+
+Name
+
+amcrypt-ossl \14 crypt program for Amanda symmetric data encryption using OpenSSL
+
+Synopsis
+
+amcrypt-ossl [-d]
+
+DESCRIPTION
+
+amcrypt-ossl uses OpenSSL to encrypt and decrypt data. OpenSSL is available
+from www.openssl.org. OpenSSL offers a wide variety of cipher choices
+( amcrypt-ossl defaults to 256-bit AES) and can use hardware cryptographic
+accelerators on several platforms.
+amcrypt-ossl will search for the OpenSSL program in the following directories:
+/bin:/usr/bin:/usr/local/bin:/usr/ssl/bin:/usr/local/ssl/bin.
+
+PASSPHRASE MANAGEMENT
+
+amcrypt-ossl uses the same pass phrase to encrypt and decrypt data. It is very
+important to store and protect the pass phrase properly. Encrypted backup data
+can only be recovered with the correct passphrase.
+OpenSSL's key derivation routines use a salt to guard against dictionary
+attacks on the pass phrase; still it is important to pick a pass phrase that is
+hard to guess. The Diceware method (see www.diceware.com) can be used to create
+passphrases that are difficult to guess and easy to remember.
+
+FILES
+
+
+
+ /var/lib/amanda/.am_passphrase
+ File containing the pass phrase. It should not be readable by any user
+ other than the Amanda user.
+
+
+SEE ALSO
+
+amanda(8), amanda.conf(5), openssl(1), amcrypt-ossl-asym(8)
+-------------------------------------------------------------------------------
+
+Prev Up Next
+amcrypt Home amcrypt-ossl-asym
+
--- /dev/null
+
+ amcrypt
+Prev Chapter 36. The Amanda Manual Pages. Next
+
+-------------------------------------------------------------------------------
+
+Name
+
+amcrypt \14 reference crypt program for Amanda symmetric data encryption
+
+Synopsis
+
+amcrypt
+
+DESCRIPTION
+
+amcrypt requires aespipe, uuencode and gpg to work. Aespipe is available from
+http://loop-aes.sourceforge.net
+amcrypt will search for the aespipe program in the following directories: /usr/
+bin:/usr/local/bin:/sbin:/usr/sbin.
+amcrypt calls amaespipe and pass the passphrase through file descriptor 3. The
+passphrase should be stored in ~amanda/.am_passphrase.
+
+How to create encryption keys for amcrypt
+
+1. Create 65 random encryption keys and encrypt those keys using gpg. Reading
+from /dev/random may take indefinitely long if kernel's random entropy pool is
+empty. If that happens, do some other work on some other console (use keyboard,
+mouse and disks).
+head -c 2925 /dev/random | uuencode -m - | head -n 66 | tail -n 65 \ | gpg --
+symmetric -a > ~amanda/.gnupg/am_key.gpg
+This will ask for a passphrase. Remember this passphrase as you will need it in
+the next step.
+2. Store the passphrase inside the home-directory of the AMANDA-user and
+protect it with proper permissions:
+
+ echo my_secret_passphrase > ~amanda/.am_passphrase
+ chown amanda:disk ~amanda/.am_passphrase
+ chmod 700 ~amanda/.am_passphrase
+
+
+Key and Passphrase
+
+amcrypt uses the same key to encrypt and decrypt data.
+It is very important to store and protect the key and the passphrase properly.
+Encrypted backup data can only be recovered with the correct key and
+passphrase.
+
+SEE ALSO
+
+amanda(8), amanda.conf(5), aespipe(1), amaespipe(8), gpg(1)
+-------------------------------------------------------------------------------
+
+Prev Up Next
+amcleanup Home amcrypt-ossl
+
amdd
-Prev Chapter 35. The AMANDA Manual Pages. Next
+Prev Chapter 36. The Amanda Manual Pages. Next
-------------------------------------------------------------------------------
Name
-amdd \14 AMANDA version of dd
+amdd \14 Amanda version of dd
Synopsis
DESCRIPTION
Amdd provides just enough of the standard UNIX dd command for the needs of
-AMANDA. This is handy when doing a full restore and the standard dd program has
+Amanda. This is handy when doing a full restore and the standard dd program has
not yet been found.
-Amdd also provides access to the AMANDA output drivers that support various
+Amdd also provides access to the Amanda output drivers that support various
tape simulations. This may be used for debugging or to convert from one format
to another.
-See the amanda(8) man page for more details about AMANDA. See the OUTPUT
-DRIVERS section of amanda(8) for more information on the AMANDA output drivers.
+See the amanda(8) man page for more details about Amanda. See the OUTPUT
+DRIVERS section of amanda(8) for more information on the Amanda output drivers.
OPTIONS
AUTHOR
Marc Mengel <mengel@fnal.gov>, John R. Jackson <jrj@purdue.edu> : Original text
-Stefan G. Weichinger, <sgw@amanda.org>, maintainer of the AMANDA-documentation:
+Stefan G. Weichinger, <sgw@amanda.org>, maintainer of the Amanda-documentation:
XML-conversion
SEE ALSO
amanda(8)
-------------------------------------------------------------------------------
-Prev Up Next
-amcleanup Home amdump
+Prev Up Next
+amcrypt-ossl-asym Home amdump
amdump
-Prev Chapter 35. The AMANDA Manual Pages. Next
+Prev Chapter 36. The Amanda Manual Pages. Next
-------------------------------------------------------------------------------
Name
-amdump \14 back up all disks in an AMANDA configuration
+amdump \14 back up all disks in an Amanda configuration
Synopsis
-amdump config [ host [disk...]...]
+amdump config [ host | [disk]*]* [ -o | configoption ]*
DESCRIPTION
-Amdump switches to the appropriate AMANDA configuration directory, e.g. /usr/
+Amdump switches to the appropriate Amanda configuration directory, e.g. /usr/
local/etc/amanda/config, then attempts to back up every disk specified by the
amanda.conf file. Amdump is normally run by cron.
You can specify many host/disk expressions, only disks that match an expression
delayed when circumstances warrant, for example, if the tape device is being
used for some other purpose. While waiting, amdump checks for the hold file
every minute.
-See the amanda(8) man page for more details about AMANDA.
+See the amanda(8) man page for more details about Amanda.
+
+OPTIONS
+
+
+
+ host [disk]*
+ Specify the host and disk on which the command will work.
+
+ -o configoption
+ See the "CONFIGURATION OVERWRITE" section in amanda(8).
+
EXAMPLE
AUTHOR
James da Silva, <jds@amanda.org> : Original text
-Stefan G. Weichinger, <sgw@amanda.org>, maintainer of the AMANDA-documentation:
+Stefan G. Weichinger, <sgw@amanda.org>, maintainer of the Amanda-documentation:
XML-conversion
SEE ALSO
amanda(8), amcheck(8), amcleanup(8), amrestore(8), amflush(8), cron(8)
-------------------------------------------------------------------------------
-Prev Up Next
-amdd Home amflush
+Prev Up Next
+amdd Home amfetchdump
--- /dev/null
+
+ amfetchdump
+Prev Chapter 36. The Amanda Manual Pages. Next
+
+-------------------------------------------------------------------------------
+
+Name
+
+amfetchdump \14 extract backup images from multiple Amanda tapes.
+
+Synopsis
+
+amfetchdump [-pcClawns] [-d device] [-O directory] [-i logfile] [-b blocksize]
+config hostname [ disk [ date [ level [ hostname [...] ] ] ] ] [ -o |
+configoption ]*
+
+DESCRIPTION
+
+Amfetchdump pulls one or more matching dumps from tape or from the holding
+disk, handling the reassembly of multi-tape split dump files as well as any
+tape autochanger operations.
+It will automatically use the logs created by amdump(8) to locate available
+dumps on tape, in the same way that the find feature of amadmin(8) lists
+available dumps. If these logs are unavailable, it can search tape-by-tape to
+find what it needs, and can generate new logs to serve as an emergency tape
+inventory.
+The hostname, diskname, datestamp, and level dump pattern-matching works as in
+amrestore(8), with the added requirement that at minimum a hostname must be
+specified when not in inventory mode.
+Unless -p is used, backup images are extracted to files in the current
+directory named:
+hostname.diskname.datestamp.dumplevel
+
+OPTIONS
+
+
+
+ -p
+ Pipe exactly one complete dump file to stdout, instead of writing the
+ file to disk. This will restore only the first matching dumpfile (where
+ "first" is determined by the dump log search facility).
+
+ -d device
+ Restore from this tape device instead of the default.
+
+ -O directory
+ Output restored files to this directory, instead of to the current
+ working directory.
+
+ -c
+ Compress output, fastest method available.
+
+ -C
+ Compress output, smallest file size method available.
+
+ -l
+ Leave dumps in the compressed/uncompressed state in which they were found
+ on tape. By default, amfetchdump will automatically uncompress when
+ restoring.
+
+ -a
+ Assume that all tapes are already available, via tape changer or
+ otherwise, instead of prompting the operator to ensure that all tapes are
+ loaded.
+
+ -i filename
+ Generate an inventory of all dumps "seen" on the tapes we search, for
+ later use as a log.
+
+ -w
+ Wait to put split dumps together until all chunks have been restored.
+ Normally, amfetchdump will attempt to read pieces of a split file from
+ tape in order, so that it can assemble them simply by appending each file
+ to the first. This option disables the appending behavior, and instead
+ restores each piece as an individual file and reassembles them only after
+ all have been restored.
+
+ Note
+
+ This requires at least double the size of your dump in free disk space,
+ in order to build the final assembled dumpfile.
+ This behavior is implicitly invoked in circumstances where knowing the
+ location of all dumps on tape in advance is not possible, such as when
+ you are restoring without log files.
+
+ -n
+ Do not reassemble split dump files at all, just restore each piece as an
+ individual file.
+
+ -s
+ Do not fast-forward straight to needed files on tape. This will slow down
+ most restores substantially. Only use this option if your tape drive does
+ not properly support the fast-forward operation.
+
+ -b blocksize
+ Force a particular block size when reading from tapes. This value will
+ usually be autodetected, and should not normally need to be set.
+
+ -o configoption
+ See the "CONFIGURATION OVERWRITE" section in amanda(8).
+
+
+EXAMPLES
+
+All the examples here assume your configuration is called SetA.
+Here's a simple case, restoring all known dumps of the host vanya to the
+current working directory.
+
+$ amfetchdump SetA vanya
+A more likely scenario involves restoring a particular dump from a particular
+date. We'll pipe this one to GNU-tar as well, to automatically extract the
+dump.
+
+$ amfetchdump -p SetA vanya /home 20051020 | gtar -xvpf -
+In a situation where all of our dump logs have been wiped out, we could also
+use amfetchdump to inventory our tapes and recreate an imitation of those logs,
+which we'll send to stdout for casual perusal.
+
+$ amfetchdump -i - SetA
+Note that you can specify a restore while in inventory mode, and amfetchdump
+will continue searching for more dumps from this host even after successfully
+restoring a dump, inventorying all the while. If your backup searcher has been
+trashed, this is a handy way to recover what you have.
+
+$ amfetchdump -i /var/amanda/log SetA backupserver
+
+CAVEATS
+
+Amfetchdump is dependent on accessing your server's config, tape changer, and
+(normally) dump logs. As such, it's not necessarily the most useful tool when
+those have all been wiped out and you desperately need to pull things from your
+tape. Pains have been taken to make it as capable as possible, but for
+seriously minimialist restores, look to amrestore(8) or dd(8) instead.
+
+AUTHOR
+
+John Stange, <building@nap.edu>, National Academies Press
+Ian Turner, <ian@zmanda.com>: XML-conversion
+
+SEE ALSO
+
+amanda(8), amadmin(8), amrestore(8), tar(1) restore(8)
+-------------------------------------------------------------------------------
+
+Prev Up Next
+amdump Home amflush
+
amflush
-Prev Chapter 35. The AMANDA Manual Pages. Next
+Prev Chapter 36. The Amanda Manual Pages. Next
-------------------------------------------------------------------------------
Name
-amflush \14 flush AMANDA backup files from holding disk to tape
+amflush \14 flush Amanda backup files from holding disk to tape
Synopsis
-amflush [-b ] [-f ] [-s ] [ -D datestamp ...] config [ host [disk...]...]
+amflush [-b] [-f] [-s] [ -D | datestamp ]* config [ host | [disk]*]* [ -o |
+configoption ]*
DESCRIPTION
-Amflush writes AMANDA backups from the holding disks to tape, and updates the
-AMANDA info database and tapelist accordingly. Backups may stay in a holding
+Amflush writes Amanda backups from the holding disks to tape, and updates the
+Amanda info database and tapelist accordingly. Backups may stay in a holding
disk when something is wrong with the tape at the time amdump is run. When this
happens, the problem must be corrected and amflush run by hand.
EXPRESSION" section of amanda(8) for a description. -D 20001225-7 will
flush all dumps from 25 december 2000 to 27 december 2000.
+ host [disk]*
+ Specify the host and disk on which the command will work.
+
+ -o configoption
+ See the "CONFIGURATION OVERWRITE" section in amanda(8).
+
You can specify many host/disk expressions, only disks that match an expression
will be flushed. All disks are flushed if no expressions are given. see the
"HOST & DISK EXPRESSION" section of amanda(8) for a description.
Amflush will look in the holding disks specified by the amanda.conf file in /
-usr/local/etc/amanda/config for any non-empty AMANDA work directories. It then
+usr/local/etc/amanda/config for any non-empty Amanda work directories. It then
prompts you to select a directory or to process all of the directories. The
work directories in the holding disks are named by the date at the time amdump
was run, e.g. 19910215.
-See the amanda(8) man page for more details about AMANDA.
+See the amanda(8) man page for more details about Amanda.
EXAMPLE
% amflush daily
Scanning /amanda-hold...
- 20001113: found AMANDA directory.
- 20001114: found AMANDA directory.
+ 20001113: found Amanda directory.
+ 20001114: found Amanda directory.
- Multiple AMANDA directories, please pick one by letter:
+ Multiple Amanda directories, please pick one by letter:
A. 20001113
B. 20001114
Select directories to flush [A..B]: [ALL] all
AUTHOR
James da Silva, <jds@amanda.org> : Original text
-Stefan G. Weichinger, <sgw@amanda.org>, maintainer of the AMANDA-documentation:
+Stefan G. Weichinger, <sgw@amanda.org>, maintainer of the Amanda-documentation:
XML-conversion
SEE ALSO
amanda(8), amdump(8)
-------------------------------------------------------------------------------
-Prev Up Next
-amdump Home amgetconf
+Prev Up Next
+amfetchdump Home amgetconf
amgetconf
-Prev Chapter 35. The AMANDA Manual Pages. Next
+Prev Chapter 36. The Amanda Manual Pages. Next
-------------------------------------------------------------------------------
Synopsis
-amgetconf [config] parameter
+amgetconf [config] parameter [ -o | configoption ]*
DESCRIPTION
-Amgetconf looks up parameters in amanda.conf, the AMANDA configuration file, or
+Amgetconf looks up parameters in amanda.conf, the Amanda configuration file, or
from the build and runtime environment, and returns their corresponding value.
If config is not specified, amgetconf assumes it is being run from the
configuration directory and that amanda.conf is present.
USE_AMANDAHOSTS) will return 1 if the flag is set or an empty string if it is
not.
If parameter begins with dbopen., the string following the period is a program
-name and an AMANDA debug file will be created for the caller. The name of the
+name and an Amanda debug file will be created for the caller. The name of the
file is returned.
If parameter begins with dbclose., the string following the period is a program
name previously used with dbopen., followed by a colon (:) and the previously
opened file name.
-See the amanda(8) man page for more details about AMANDA.
+See the amanda(8) man page for more details about Amanda.
+
+OPTIONS
+
+
+
+ -o configoption
+ See the "CONFIGURATION OVERWRITE" section in amanda(8).
+
EXAMPLE
amlabel
-Prev Chapter 35. The AMANDA Manual Pages. Next
+Prev Chapter 36. The Amanda Manual Pages. Next
-------------------------------------------------------------------------------
Name
-amlabel \14 label an AMANDA tape
+amlabel \14 label an Amanda tape
Synopsis
-amlabel [-f ] config label [ slot slot ]
+amlabel [-f ] config label [ slot | slot ] [ -o | configoption ]*
DESCRIPTION
-All AMANDA tapes must be pre-labeled before they are used. AMANDA verifies the
+All Amanda tapes must be pre-labeled before they are used. Amanda verifies the
label in amdump and amflush before writing to make sure the proper tape is
loaded.
-Amlabel writes an AMANDA label on the tape in the device specified by the
+Amlabel writes an Amanda label on the tape in the device specified by the
amanda.conf file in /usr/local/etc/amanda/config. Label may be any string that
does not contain whitespace and that matches the amanda.conf labelstr regular
expression option. It is up to the system administrator to define a naming
convention.
-Amlabel appends the new tape to the tapelist file so it will be used by AMANDA
+Amlabel appends the new tape to the tapelist file so it will be used by Amanda
before it reuses any other tapes. When you amlabel multiple tapes, they will be
used in the order you amlabel them.
-Amlabel will not write the label if the tape contains an active AMANDA tape or
+Amlabel will not write the label if the tape contains an active Amanda tape or
if the label specified is on an active tape. The -f (force) flag bypasses these
verifications.
An optional slot may be specified after the tape label. If a tape changer is in
use, amlabel will label the tape in the specified slot instead of the currently
loaded tape.
-See the amanda(8) man page for more details about AMANDA.
+See the amanda(8) man page for more details about Amanda.
+
+OPTIONS
+
+
+
+ -o configoption
+ See the "CONFIGURATION OVERWRITE" section in amanda(8).
+
EXAMPLE
-Write an AMANDA label with the string "DMP000" on the tape loaded in the device
+Write an Amanda label with the string "DMP000" on the tape loaded in the device
named in the tapedev option in /usr/local/etc/amanda/daily/amanda.conf:
% amlabel daily DMP000
expression str from amanda.conf.
label label already on a tape
- Label label is already listed as an active AMANDA tape.
+ Label label is already listed as an active Amanda tape.
no tpchanger specified in path , so slot command invalid
The command line has the slot parameter but the amanda.conf file in path
does not have a tape changer configured.
reading label label, tape is in another amanda configuration
- This tape appears to be a valid AMANDA tape, but label does not match
+ This tape appears to be a valid Amanda tape, but label does not match
labelstr for this configuration so it is probably part of a different
- AMANDA configuration.
+ Amanda configuration.
reading label label, tape is active
- Tape label appears to already be part of this AMANDA configuration and
+ Tape label appears to already be part of this Amanda configuration and
active, i.e. has valid data on it.
no label found, are you sure tape is non-rewinding?
While checking that the label was written correctly, amlabel got an error
- that might be caused by mis-configuring AMANDA with a rewinding tape
+ that might be caused by mis-configuring Amanda with a rewinding tape
device name instead of a non-rewinding device name for tape.
AUTHOR
James da Silva, <jds@amanda.org>: Original text
-Stefan G. Weichinger, <sgw@amanda.org>, maintainer of the AMANDA-documentation:
+Stefan G. Weichinger, <sgw@amanda.org>, maintainer of the Amanda-documentation:
XML-conversion
SEE ALSO
ammt
-Prev Chapter 35. The AMANDA Manual Pages. Next
+Prev Chapter 36. The Amanda Manual Pages. Next
-------------------------------------------------------------------------------
Name
-ammt \14 AMANDA version of mt
+ammt \14 Amanda version of mt
Synopsis
DESCRIPTION
Ammt provides just enough of the standard UNIX mt command for the needs of
-AMANDA. This is handy when doing a full restore and the standard mt program has
+Amanda. This is handy when doing a full restore and the standard mt program has
not yet been found.
-Ammt also provides access to the AMANDA output drivers that support various
+Ammt also provides access to the Amanda output drivers that support various
tape simulations.
-See the amanda(8) man page for more details about AMANDA. See the OUTPUT
-DRIVERS section of amanda(8) for more information on the AMANDA output drivers.
+See the amanda(8) man page for more details about Amanda. See the OUTPUT
+DRIVERS section of amanda(8) for more information on the Amanda output drivers.
OPTIONS
AUTHOR
Marc Mengel <mengel@fnal.gov>, John R. Jackson <jrj@purdue.edu>: Original text
-Stefan G. Weichinger, <sgw@amanda.org>, maintainer of the AMANDA-documentation:
+Stefan G. Weichinger, <sgw@amanda.org>, maintainer of the Amanda-documentation:
XML-conversion
SEE ALSO
amoverview
-Prev Chapter 35. The AMANDA Manual Pages. Next
+Prev Chapter 36. The Amanda Manual Pages. Next
-------------------------------------------------------------------------------
Name
-amoverview \14 display file systems processed by AMANDA over time
+amoverview \14 display file systems processed by Amanda over time
Synopsis
amoverview [[-config ] config ] [-hostwidth width] [-diskwidth width] [-
-skipmissed] [-verbose]
+skipmissed] [-last] [-num0] [-togo0] [-verbose]
DESCRIPTION
-Amoverview displays a chart showing hosts and file systems processed by AMANDA
+Amoverview displays a chart showing hosts and file systems processed by Amanda
along with the backup level performed each day.
-See the amanda(8) man page for more details about AMANDA.
+See the amanda(8) man page for more details about Amanda.
OPTIONS
Set disk field column width to width characters instead of 20.
-skipmissed
- Compacts the output by only printing stats for the days AMANDA actually
+ Compacts the output by only printing stats for the days Amanda actually
ran.
+ -last
+ Outputs the last status of each disk at the start. Useful for long
+ tapecycles and/or sparse reports.
+
+ -num0
+ Outputs the number of level 0 dumps for each disk.
+
+ -togo0
+ Outputs the number of runs until the last level 0 dump is overwritten.
+
-verbose
Amoverview can take a long while on large systems. This option reports
intermediate steps while it is working.
once (gives an "E", and later that day, you flush it to a second tape (a
number: the level, indicating success). If the flush failed too, you get a
double "EE" for that day.
-You can also have a double code if you have two tapes in the changer and AMANDA
+You can also have a double code if you have two tapes in the changer and Amanda
failed to write to tape the first time because it hit end of tape (resulting in
"E0", for a full, "E1" for an incremental etc.) or twice with error ("EE"), and
may a successful flush afterwards giving maybe "EE0". (Only the latest 2
amplot
-Prev Chapter 35. The AMANDA Manual Pages. Next
+Prev Chapter 36. The Amanda Manual Pages. Next
-------------------------------------------------------------------------------
Name
-amplot \14 visualize the behavior of AMANDA
+amplot \14 visualize the behavior of Amanda
Synopsis
DESCRIPTION
-Amplot reads an amdump output file that AMANDA generates each run (e.g.
+Amplot reads an amdump output file that Amanda generates each run (e.g.
amdump.1) and translates the information into a picture format that may be used
to determine how your installation is doing and if any parameters need to be
changed. Amplot also prints out amdump lines that it either does not understand
GNU awk (gawk version 2.15 or later) or nawk.
During execution, amplot generates a few temporary files that gnuplot uses.
These files are deleted at the end of execution.
-See the amanda(8) man page for more details about AMANDA.
+See the amanda(8) man page for more details about Amanda.
OPTIONS
Olafur Gudmundsson <ogud@tis.com>, Trusted Information Systems, formerly at
University of Maryland, College Park: Original text
-Stefan G. Weichinger, <sgw@amanda.org>, maintainer of the AMANDA-documentation:
+Stefan G. Weichinger, <sgw@amanda.org>, maintainer of the Amanda-documentation:
XML-conversion
BUGS
amrecover
-Prev Chapter 35. The AMANDA Manual Pages. Next
+Prev Chapter 36. The Amanda Manual Pages. Next
-------------------------------------------------------------------------------
Name
-amrecover \14 AMANDA index database browser
+amrecover \14 Amanda index database browser
Synopsis
-amrecover [[-C ] config ] [ -s index-server ] [ -t tape-server ] [ -d tape-
-device ]
+amrecover [[-C ] | config ] [ -s | index-server ] [ -t | tape-server ] [ -d |
+tape-device ] [ -o | clientconfigoption ]*
DESCRIPTION
-Amrecover browses the database of AMANDA index files to determine which tapes
+Amrecover browses the database of Amanda index files to determine which tapes
contain files to recover. Furthermore, it is able to recover files.
In order to restore files in place, you must invoke amrecover from the root of
the backed up filesystem, or use lcd to move into that directory, otherwise a
directory tree that resembles the backed up filesystem will be created in the
current directory. See the examples below for details.
-See the amanda(8) man page for more details about AMANDA.
+Amrecover will read the amanda-client.conf file and the config/amanda-
+client.conf file.
+See the amanda(8) man page for more details about Amanda.
OPTIONS
Note
-The listed defaults map to the values you ran the configure-script with.
+The Default values are those set at compile-time. Use amrestore to recover
+client-encrypted or client-custom-compressed tapes.
[ -C ] config
- AMANDA configuration (default: daily).
+ Amanda configuration.
-s index-server
- Host that runs the index daemon (default: oops).
+ Host that runs the index daemon.
-t tape-server
- Host that runs the tape server daemon (default: 192.168.0.10).
+ Host that runs the tape server daemon.
-d tape-device
- Tape device to use on the tape server host (default: /dev/nst0).
+ Tape device to use on the tape server host.
+
+ -o clientconfigoption
+ See the "CONFIGURATION OVERWRITE" section in amanda(8).
COMMANDS
Specifies which host to look at backup files for (default: the local
host).
- setdate YYYY-MM-DD
- Set the date (default: today). File listing commands only return
+ setdate YYYY-MM-DD-HH-MM[-SS] | YYYY-MM-DD
+ Set the restore time (default: now). File listing commands only return
information on backup images for this day, for the day before with the
next lower dump level, and so on, until the most recent level 0 backup on
or before the specified date is encountered.
1996-07-01 was a level 0 backup
1996-07-02 through 1996-07-05 were level 1 backups
1996-07-06 through 1997-07-08 were level 2 backups
- then if 1997-07-08 is the requested date, files from the following days
- would be used:
+ then the command setdate 1997-07-08-00 would yield files from the
+ following days:
1997-07-08 (the latest level 2 backup)
1997-07-05 (the latest level 1 backup)
- setdisk diskname mountpoint
+ setdisk diskname [mountpoint]
Specifies which disk to consider (default: the disk holding the working
directory where amrecover is started). It can only be set after the host
is set with sethost. Diskname is the device name specified in the
host. If mountpoint is not specified, all pathnames will be relative to
the (unknown) mount point instead of full pathnames.
+ listhost [diskdevice]
+ List all host
+
listdisk [diskdevice]
List all diskname
settape [[server]:][tapedev|default]
Specifies the host to use as the tape server, and which of its tape
devices to use. If the server is omitted, but the colon is not, the
- server name reverts to 192.168.0.10, the configure-time default. If the
- tape device is omitted, it remains unchanged. To use the default tape
- device selected by the tape server, the word default must be specified.
- If no argument is specified, or the argument is an empty string, no
- changes occur, and the current settings are displayed.
+ server name reverts to the configure-time default. If the tape device is
+ omitted, it remains unchanged. To use the default tape device selected by
+ the tape server, the word default must be specified. If no argument is
+ specified, or the argument is an empty string, no changes occur, and the
+ current settings are displayed.
If you want amrecover to use your changer, the tapedev must be equal to
the amrecover_changer setting on the server.
If you need to change the protocol (tape:, rait:, file:, null:) then you
list file
Display the contents of the restore list. If a file name is specified,
the restore list is written to that file. This can be used to manually
- extract the files from the AMANDA tapes with amrestore.
+ extract the files from the Amanda tapes with amrestore.
clear
Clear the restore list.
syslog.7: No such file or directory
# amrecover
AMRECOVER Version 2.4.2. Contacting server on oops ...
- 220 oops AMANDA index server (2.4.2) ready.
+ 220 oops Amanda index server (2.4.2) ready.
Setting restore date to today (1997-12-09)
200 Working date set to 1997-12-09.
200 Config set to daily.
PAGER The ls and list commands will use $PAGER to display the file lists.
Defaults to more if PAGER is not set.
+AMANDA_SERVER If set, $AMANDA_SERVER will be used as index-server. The value
+will take precedence over the compiled default, but will be overridden by the -
+s switch.
+AMANDA_TAPE_SERVER If set, $AMANDA_TAPE_SERVER will be used as tape-server. The
+value will take precedence over the compiled default, but will be overridden by
+the -t switch.
AUTHOR
Alan M. McIvor <alan@kauri.auck.irl.cri.nz> : Original text
-Stefan G. Weichinger, <sgw@amanda.org>, maintainer of the AMANDA-documentation:
+Stefan G. Weichinger, <sgw@amanda.org>, maintainer of the Amanda-documentation:
XML-conversion
SEE ALSO
-amanda(8), amrestore(8), readline(3)
+amanda(8), amanda-client.conf(5), amrestore(8), amfetchdump(8), readline(3)
-------------------------------------------------------------------------------
Prev Up Next
amreport
-Prev Chapter 35. The AMANDA Manual Pages. Next
+Prev Chapter 36. The Amanda Manual Pages. Next
-------------------------------------------------------------------------------
Name
-amreport \14 generate a formatted output of statistics for an AMANDA run
+amreport \14 generate a formatted output of statistics for an Amanda run
Synopsis
-amreport [config] [ -l logfile ] [ -f outputfile ] [ -p postscriptfile ]
+amreport [config] [-i] [ -M | address ] [ -l | logfile ] [ -f | outputfile ]
+[ -p | postscriptfile ] [ -o | configoption ]*
DESCRIPTION
Amreport generates a summary report of an amanda(8) backup run. If no
configuration name is specified, amanda.conf is read from the current
directory.
-See the amanda(8) man page for more details about AMANDA.
+See the amanda(8) man page for more details about Amanda.
OPTIONS
config
Name of the configuration to process.
+ -i
+ Don't email the report.
+
+ -M address
+ Mail the report to address instead of the mailto value from amanda.conf.
+
-l logfile
Name of the log file to parse to generate the report. If a log file is
not specified, it defaults to the file:
lpr(1) command. This option has an effect only if the lbl-templ directive
is specified in amanda.conf.
+ -o configoption
+ See the "CONFIGURATION OVERWRITE" section in amanda(8).
+
LABEL PRINTING
-AMANDA can print postscript labels describing the contents of tape(s) written
+Amanda can print postscript labels describing the contents of tape(s) written
in a run. The labels are designed to be folded and inserted into the tape case
along with the tape or hole punched and put in a 3-ring binder. Various label
templates are provided to format data for different tape sizes.
TEMPLATES
-AMANDA provides label templates for the following tape types. These are pretty
+Amanda provides label templates for the following tape types. These are pretty
generic labels and should be easy to customize for other tape types or
particular site needs.
amrestore
-Prev Chapter 35. The AMANDA Manual Pages. Next
+Prev Chapter 36. The Amanda Manual Pages. Next
-------------------------------------------------------------------------------
Name
-amrestore \14 extract backup images from an AMANDA tape
+amrestore \14 extract backup images from an Amanda tape
Synopsis
-amrestore [ -r | -c | -C ] [ -b blocksize ] [ -f fileno ] [ -l label ] [-p ] [-
-h ] tapedevice | holdingfile | [ hostname [ diskname [ datestamp [ hostname
-[ diskname [datestamp...]]]]]]
+amrestore [ -r | -c | -C ] [ -b | blocksize ] [ -f | fileno ] [ -l | label ] [-
+p] [-h] tapedevice | holdingfile [ hostname [ diskname [ datestamp [ hostname
+[ diskname [ datestamp | ... ]]]]]]
DESCRIPTION
If a header is written (-r or -h), only 32 KBytes are output regardless of the
tape blocksize. This makes the resulting image usable as a holding file.
+
+ -o configoption
+ See the "CONFIGURATION OVERWRITE" section in amanda(8).
+
+
EXAMPLES
The following does an interactive restore of disk rz3g from host seine, to
James da Silva, <jds@amanda.org>, University of Maryland, College Park:
Original text
-Stefan G. Weichinger, <sgw@amanda.org>, maintainer of the AMANDA-documentation:
+Stefan G. Weichinger, <sgw@amanda.org>, maintainer of the Amanda-documentation:
XML-conversion
SEE ALSO
amrmtape
-Prev Chapter 35. The AMANDA Manual Pages. Next
+Prev Chapter 36. The Amanda Manual Pages. Next
-------------------------------------------------------------------------------
Name
-amrmtape \14 remove a tape from the AMANDA database
+amrmtape \14 remove a tape from the Amanda database
Synopsis
configuration database. This is meant as a recovery mechanism when a good
backup is damaged either by faulty hardware or user error, e.g. the tape is
eaten by the drive or is overwritten.
-See the amanda(8) man page for more details about AMANDA.
+See the amanda(8) man page for more details about Amanda.
OPTIONS
AUTHOR
Adrian T. Filipi-Martin <atf3r@cs.virginia.edu>: Original text
-Stefan G. Weichinger, <sgw@amanda.org>, maintainer of the AMANDA-documentation:
+Stefan G. Weichinger, <sgw@amanda.org>, maintainer of the Amanda-documentation:
XML-conversion
SEE ALSO
amstatus
-Prev Chapter 35. The AMANDA Manual Pages. Next
+Prev Chapter 36. The Amanda Manual Pages. Next
-------------------------------------------------------------------------------
Name
-amstatus \14 display the state of an AMANDA run
+amstatus \14 display the state of an Amanda run
Synopsis
DESCRIPTION
-Amstatus gives the current state of the AMANDA run specified by the config
-configuration. If there is no active AMANDA running, it summarizes the result
+Amstatus gives the current state of the Amanda run specified by the config
+configuration. If there is no active Amanda running, it summarizes the result
of the last run. It may also be used to summarize the results of a previous
run.
-See the amanda(8) man page for more details about AMANDA.
+See the amanda(8) man page for more details about Amanda.
OPTIONS
[--config] config
- Specify the AMANDA configuration you want to display the state for.
+ Specify the Amanda configuration you want to display the state for.
--file amdumpfile
Specify an alternate file instead of the amdump or amflush file.
amtape
-Prev Chapter 35. The AMANDA Manual Pages. Next
+Prev Chapter 36. The Amanda Manual Pages. Next
-------------------------------------------------------------------------------
Name
-amtape \14 user interface to AMANDA tape changer controls
+amtape \14 user interface to Amanda tape changer controls
Synopsis
DESCRIPTION
Amtape performs tape changer control operations. It uses the underlying tape
-changer script defined by the tpchanger option for a particular AMANDA
+changer script defined by the tpchanger option for a particular Amanda
configuration as specified by the config argument.
Tape changers maintain a notion of the current and next slot for each
configuration. These may or may not correspond to an actual physical state of
the device, but do tend to minimize searching through the tape storage slots.
If the desired tape is in the current slot, it is likely the next tape needed
is in the next slot rather than at some random position in the storage slots.
-See the amanda(8) man page for more details about AMANDA.
+See the amanda(8) man page for more details about Amanda.
COMMANDS
Reset the tape changer to a known state. The current slot is set to the
first slot. Other device-specific side effects may occur. Some gravity
stackers need to be reset to the top position by hand. This command
- notifies AMANDA the stacker is back in that position.
+ notifies Amanda the stacker is back in that position.
eject
If a tape is loaded in the drive, it is ejected and returned to the slot
Show the contents of all slots. This can be slow.
label label
- Search for and load the AMANDA tape with label label.
+ Search for and load the Amanda tape with label label.
taper
Perform the taper scan algorithm. Load the next tape in the
tape, but do not load it.
This is useful with non-gravity stackers to unload the last tape used and set
-up AMANDA for the next run. If you just use eject, the current tape will be
+up Amanda for the next run. If you just use eject, the current tape will be
mounted again in the next run, where it will be rejected as being still in use,
ejected and the next tape requested. Using slot next followed by eject does an
unnecessary mount.
AUTHOR
James da Silva, <jds@amanda.org> : Original text
-Stefan G. Weichinger, <sgw@amanda.org>, maintainer of the AMANDA-documentation:
+Stefan G. Weichinger, <sgw@amanda.org>, maintainer of the Amanda-documentation:
XML-conversion
SEE ALSO
amtapetype
-Prev Chapter 35. The AMANDA Manual Pages. Next
+Prev Chapter 36. The Amanda Manual Pages. Next
-------------------------------------------------------------------------------
DESCRIPTION
-amtapetype generates a tapetype entry for AMANDA.
+amtapetype generates a tapetype entry for Amanda.
OPTIONS
takes a few minutes only.
-o
- Overwrite the tape, even if it's an AMANDA tape.
+ Overwrite the tape, even if it's an Amanda tape.
-bblocksize
record block size (default: 32k)
amtoc
-Prev Chapter 35. The AMANDA Manual Pages. Next
+Prev Chapter 36. The Amanda Manual Pages. Next
-------------------------------------------------------------------------------
Name
-amtoc \14 generate TOC (Table Of Contents) for an AMANDA run
+amtoc \14 generate TOC (Table Of Contents) for an Amanda run
Synopsis
DESCRIPTION
-Amtoc generates a table of contents for an AMANDA run. It's a perl script (if
+Amtoc generates a table of contents for an Amanda run. It's a perl script (if
you don't have perl, install it first!).
OPTIONS
Nicolas Mayencourt <Nicolas.Mayencourt@cui.unige.ch>, University of Geneva/
Switzerland : Original text
-Stefan G. Weichinger, <sgw@amanda.org>, maintainer of the AMANDA-documentation:
+Stefan G. Weichinger, <sgw@amanda.org>, maintainer of the Amanda-documentation:
XML-conversion
-------------------------------------------------------------------------------
amverify
-Prev Chapter 35. The AMANDA Manual Pages. Next
+Prev Chapter 36. The Amanda Manual Pages. Next
-------------------------------------------------------------------------------
AUTHOR
Axel Zinser <fifi@icem.de> : Original text
-Stefan G. Weichinger, <sgw@amanda.org>, maintainer of the AMANDA-documentation:
+Stefan G. Weichinger, <sgw@amanda.org>, maintainer of the Amanda-documentation:
XML-conversion
SEE ALSO
amverifyrun
-Prev Chapter 35. The AMANDA Manual Pages. Next
+Prev Chapter 36. The Amanda Manual Pages. Next
-------------------------------------------------------------------------------
Name
-amverifyrun \14 check the tapes written by the last AMANDA run
+amverifyrun \14 check the tapes written by the last Amanda run
Synopsis
DESCRIPTION
-Amverifyrun read the log from the last AMANDA run to find the slot of the first
+Amverifyrun read the log from the last Amanda run to find the slot of the first
tape used and the number of tapes used. It call amverify with these argument.
SEE ALSO
-------------------------------------------------------------------------------
Prev Up Next
-amverify Home Chapter 36. Web Ressources
+amverify Home Chapter 37. Web Ressources
Notes_about_changer.conf
- AMANDA's_actual_usage_of_chg-scsi
+ Amanda's_actual_usage_of_chg-scsi
Configuration_notes
Jason's new and improved chg-scsi documentation.
This documentation will also include an occasional reference to the mtx suite
as I have attempted to use chg-zd-mtx. I use mtx often as a fast query tool.
-Please also refer to AMANDA_Tape_Changer_Support for additional details.
+Please also refer to Amanda_Tape_Changer_Support for additional details.
My equipment list is as follows:
* Redhat 7.0 machine
I base this documentation on the following:
* mtx version 1.2.16rel
-* AMANDA version 2.4.3b3
+* Amanda version 2.4.3b3
* SCSI2 specification: X3T9.2/375R revision 10L
* Quantum/ATL Field Service Manual 6321101-03 Ver.3, rel.0
* Quantum DLT800 Tape system product manual 02 April, 2001 81-60118-04
Note that Quantum/ATL's L-series changers follow the SCSI command set, and do
not use any proprietary commands. Thus, it was fairly simple to make this work.
-I had to install AMANDA --with-suffixes and setup my server's client side of
-things using AMANDA-2.4.2p2 --with-suffixes.
+I had to install Amanda --with-suffixes and setup my server's client side of
+things using Amanda-2.4.2p2 --with-suffixes.
Please note that my usage of "barcode" and "barcode reader" throughout this
document really refers to "physical tape identification system". for example:
the EEPROM in the AIT cartridge.
-scan
-genconf
-Note that chg-scsi is called by AMANDA in the context of whatever AMANDA
-configuration AMANDA is currently using. In short, to call chg-scsi by hand,
-change to your AMANDA configuration directory, then run chg-scsi.
+Note that chg-scsi is called by Amanda in the context of whatever Amanda
+configuration Amanda is currently using. In short, to call chg-scsi by hand,
+change to your Amanda configuration directory, then run chg-scsi.
-slot <param> command:
this command takes either a slot number, or any one of the following: current,
next, prev, first, last, advance
-search <param> command:
this only should be used if a barcode reader is present, or emulate barcode is
turned on.
-the required parameter is an AMANDA tape label. The label searched in the
+the required parameter is an Amanda tape label. The label searched in the
labelfile. If a barcode is found, then that tape is loaded directly.
I believe the fallback is to search the entire magazine.
-status command:
-inventory: (this takes a LONG time to do)
unloads tape back to its slot issues command to changer to do an inventory of
itself (read all barcodes...)
-loads each tape, retrieves the barcode, and reads the AMANDA
+loads each tape, retrieves the barcode, and reads the Amanda
label off of the tape itself stores/updates the label database file
-dumpdb:
prints out in human readable form the label database contents from the
devices as generic, but this facility did.
USE THIS FOR FINDING VALUE OF SCSItapedev. Be certain though you have the
correct tape drive: I came close to wreaking havoc with my DDS3 drive while it
-was flushing AMANDA data...and my changer has a DLT drive! Please refer to my
+was flushing Amanda data...and my changer has a DLT drive! Please refer to my
configuration notes below.
-genconf:
prints out a SAMPLE changer.conf file. Note that I said sample. except for that
cleanmax cleancart cleanfile I have my changer set to autoclean, and the slot
the cleaning cartridge is in is not available for any other use.
- AMANDA's actual usage of chg-scsi
+ Amanda's actual usage of chg-scsi
-this should be brief: AMANDA really only issues "slot next" type commands.
-Currently AMANDA doesn't ask chg-scsi to load "tape x with label Daily_set023".
+this should be brief: Amanda really only issues "slot next" type commands.
+Currently Amanda doesn't ask chg-scsi to load "tape x with label Daily_set023".
the chg-scsi mechanism is there for use, and functions quite well for the user
-to load a particular tape. I understand they (the AMANDA team) are working on
+to load a particular tape. I understand they (the Amanda team) are working on
this.
Configuration notes
in changer.conf: set number_configs to 1 set dev to <non-rewinding tape device
eg: /dev/nst1> set debug to 9:0
-run "chg-scsi -scan" from your AMANDA configuration directory I get: name /dev/
+run "chg-scsi -scan" from your Amanda configuration directory I get: name /dev/
sg0 Tape Count 1 name /dev/sg1 Changer Count 2 name /dev/sg2 Tape Count 3
I set SCSItapedev to /dev/sg0 to test with, then ran chg-scsi -info. Check the
chg-scsi debug file for tapeidentification details. This is where I discoverd
-------------------------------------------------------------------------------
Prev Up Next
-Chapter 8. AMANDA Tape Changer Home Chapter 10. RAIT (Redundant Array of
+Chapter 8. Amanda Tape Changer Home Chapter 10. RAIT (Redundant Array of
Support Inexpensive Tape) Support
- Chapter 22. AMANDA dumper API
+ Chapter 23. Amanda dumper API
Prev Part V. Technical Background Next
-------------------------------------------------------------------------------
-Chapter 22. AMANDA dumper API
+Chapter 23. Amanda dumper API
Alexandre Oliva
Introduction
-This is a proposal of a mechanism for AMANDA to support arbitrary backup
+This is a proposal of a mechanism for Amanda to support arbitrary backup
programs, that relies on a generic backup driver and scripts or programs that
interface with backup programs such as dump, tar, smbclient, and others. It can
also be used to introduce pre- and post-backup commands.
The interface is simple, but supports everything that is currently supported by
-AMANDA, and it can be consistently extended to support new abstractions that
+Amanda, and it can be consistently extended to support new abstractions that
may be introduced in the backup driver in the future.
-This proposal does not imply any modification in the AMANDA protocol or in
-AMANDA servers; only AMANDA clients have to be modified. By AMANDA clients, we
-refer to hosts whose disks are to be backed up; an AMANDA server is a host
+This proposal does not imply any modification in the Amanda protocol or in
+Amanda servers; only Amanda clients have to be modified. By Amanda clients, we
+refer to hosts whose disks are to be backed up; an Amanda server is a host
connected to a tape unit.
-Currently (as of release 2.4.1 of AMANDA), AMANDA clients support three
+Currently (as of release 2.4.1 of Amanda), Amanda clients support three
operations: selfcheck, estimate and backup.
Selfcheck is used by the server program amcheck, to check whether a client is
responding or if there are configuration or permission problems in the client
that might prevent the backup from taking place.
-Estimates are requested by the AMANDA planner, that runs on the server and
+Estimates are requested by the Amanda planner, that runs on the server and
collects information about the expected sizes of backups of each disk at
several levels. Given this information and the amount of available tape space,
the planner can select which disks and which levels it should tell dumper to
dumps, as determined by planner, and stores these dumps in holding disks or
sends them directly to the taper program. The interaction between dumper and
taper is beyond the scope of this text.
-We are going to focus on the interaction between the AMANDA client program and
+We are going to focus on the interaction between the Amanda client program and
wrappers of dump programs. These wrappers must implement the DUMPER API. The
dumptype option `program' should name the wrapper that will be used to back up
filesystems of that dumptype. One wrapper may call another, so as to extend its
support incrementals based on a timestamp (incr/date); whereas others are based
on a limited number of incremental levels, but incrementals of the same level
can be repeated, such as dump (0-9).
-AMANDA was originally built upon DUMP incremental levels, so this is the only
+Amanda was originally built upon DUMP incremental levels, so this is the only
model it currently supports. Backup programs that use other incremental
management mechanisms had to be adapted to this policy. Wrapper scripts are
responsible for this adaptation.
Another important issue has to do with index generation. Some backup programs
can generate indexes, but each one lists files in its own particular format,
-but they must be stored in a common format, so that the AMANDA server can
+but they must be stored in a common format, so that the Amanda server can
manipulate them.
The DUMPER API must accomodate for all these variations.
The `support' command
-As a general mechanism for AMANDA to probe for features provided by a backup
+As a general mechanism for Amanda to probe for features provided by a backup
program, a wrapper script must support at least the `support' command. Some
-features must be supported, and AMANDA won't ever ask about them. Others will
-be considered as extensions, and AMANDA will ask the wrapper whether they are
+features must be supported, and Amanda won't ever ask about them. Others will
+be considered as extensions, and Amanda will ask the wrapper whether they are
supported before issuing the corresponding commands.
The `level-incrementals' subcommand
For example, before requesting for an incremental backup of a given level,
-AMANDA should ask the wrapper whether the backup program supports level-based
+Amanda should ask the wrapper whether the backup program supports level-based
incrementals. We don't currently support backup programs that don't, but we may
in the future, so it would be nice if wrappers already implemented the command
`support level-incrementals', by returning a 0 exit status, printing, say, the
The `selfcheck' command
We should support commands to perform self-checks, run estimates, backups and
-restores (for future extensions of the AMANDA protocol so as to support
+restores (for future extensions of the Amanda protocol so as to support
restores)
A selfcheck request would go like this:
DUMP selfcheck hda0 option option=value ...
ERROR [/etc/dumpdates is not writable]
A wrapper script will certainly have to figure out either the disk device name
or its mount point, given a filesystem name such as `hda0', as specified in the
-disklist. In order to help these scripts, AMANDA provides a helper program that
+disklist. In order to help these scripts, Amanda provides a helper program that
can guess device names, mount points and filesystem types, when given disklist
entries.
The filesystem type can be useful on some operation systems, in which more than
extract from its input the estimated size.
The syntax of `estimate-parse' is identical to that of `estimate'.
Both `estimate' and `estimate-parse' can output the word `KILL', after printing
-the estimate. In this case, AMANDA will send a SIGTERM signal to the process
+the estimate. In this case, Amanda will send a SIGTERM signal to the process
group of the `estimate' process. If it does not die within a few seconds, a
SIGKILL will be issued.
If `estimate' or `estimate-parse' succeed, they should exit 0, otherwise exit
-------------------------------------------------------------------------------
Prev Up Next
-Chapter 21. How AMANDA uses UDP and TCP Home Chapter 23. AMANDA Internals
+Chapter 22. How Amanda uses UDP and TCP Home Chapter 24. Amanda Internals
ports
- Chapter 24. AMANDA Event API
+ Chapter 25. Amanda Event API
Prev Part V. Technical Background Next
-------------------------------------------------------------------------------
-Chapter 24. AMANDA Event API
+Chapter 25. Amanda Event API
Mike Grupenhoff
event_loop
+ event_wait
+
event_wakeup
one pass over all pending events, and fire the ones that are immediately ready,
and then return.
+ event_wait
+
+void event_wait(event_id_t id);
+Like event_loop(0), except that it will stop as soon as the event id is
+serviced.
+
event_wakeup
int event_wakeup(event_id_t id);
-------------------------------------------------------------------------------
Prev Up Next
-Chapter 23. AMANDA Internals Home Chapter 25. AMANDA Security API
+Chapter 24. Amanda Internals Home Chapter 26. Amanda Security API
Introduction
There are times when data needs to be excluded from a backup. When these times
-arise be confident that AMANDA has this capability. (Actually it's not AMANDA,
-it's tar.) There are three ways of excluding data in an AMANDA backup:
+arise be confident that Amanda has this capability. (Actually it's not Amanda,
+it's tar.) There are three ways of excluding data in an Amanda backup:
* Exclude an individual item explicitly in the dumptype
* Utilize an "Exclude List"
* Do not include the data in the disklist
-This document is based on AMANDA 2.4.2 and some of this might not work with
+This document is based on Amanda 2.4.2 and some of this might not work with
older versions. This was compiled from my personal experience and with help
from the members of the amanda-users mailing list (mailto://amanda-
users@amanda.org) when I was originally setting this up, to whom I wish to
Please Read
As far as I am able to tell the only way to exclude files or directories with
-AMANDA is to use GNU-tar as the dump program (others?). The file system dump
+Amanda is to use GNU-tar as the dump program (others?). The file system dump
programs provided with unix systems (e.g. dump, ufsdump) get data at a raw
drive level and generally do not allow exclusion of specific files or
directories.
question in the disklist. This option may not be suitable for everyone's needs
and can confuse the issue some, so I have elected to include this mechanism in
its own section named Do_not_include_the_data_in_the_disklist.
-For the purpose of this document an AMANDA backup configuration named "exclude-
+For the purpose of this document an Amanda backup configuration named "exclude-
test" will be used. The machine that contains the tape drive which receives
data to be archived will be referred to as "SERVER". The machine that data is
being archived from will be referred to as "CLIENT". These two systems are
Note
-When AMANDA attempts to exclude a file or directory it does so relative to the
+When Amanda attempts to exclude a file or directory it does so relative to the
area being archived. For example if /var is in your disklist and you want to
exclude /var/log/somefile, then your exclude file would contain ./log/somefile.
You may use one exclude file in multiple dumptypes without any restriction.
Before We Begin
The first step that should be taken is to verify that backups are currently
-working. Connect to SERVER and run amcheck as your AMANDA user, to verify that
+working. Connect to SERVER and run amcheck as your Amanda user, to verify that
there are no errors in the current setup.
$ amcheck -cl CLIENT
Output should look something like below for success:
- AMANDA Tape Server Host Check
+ Amanda Tape Server Host Check
-----------------------------
/path/to/holding-disk: 4771300 KB disk space available, that's plenty.
- AMANDA Backup Client Hosts Check
+ Amanda Backup Client Hosts Check
--------------------------------
Client check: 1 host checked in 0.084 seconds, 0 problems found.
The easiest way to exclude a file or directory is to specify it with the
"exclude" option in the dumptype. This option accepts an argument of the file
-or directory to be excluded. AMANDA allows only one exclude option in any
+or directory to be excluded. Amanda allows only one exclude option in any
dumptype at a time.
Note
-UPDATE: Recent AMANDA-releases bring the option "exclude append" which enables
+UPDATE: Recent Amanda-releases bring the option "exclude append" which enables
the administrator to define more than one exclusion-pattern within one dumptype
without using a exclude-list. Please look at the amanda.conf.5-manpage for
details.
}
Next run amcheck again to verify that there are no problems with the revised
-AMANDA configuration. If the data is not being excluded as expected please see
+Amanda configuration. If the data is not being excluded as expected please see
the Troubleshooting section below. This completes the setup of excluding an
individual item in the dumptype.
$ mkdir -p /usr/local/etc/amanda/exclude
$ cd /usr/local/etc/amanda/exclude
-Next create the exclude list for AMANDA to use. You can name the exclude file
+Next create the exclude list for Amanda to use. You can name the exclude file
anything you wish it to be. Create a file, and in this file place all paths to
files and directories that are to be excluded. Keeping with the /var example,
assume that /var/log/XFree86.0.log, and /var/log/maillog need to be excluded.
$ chmod 644 /usr/local/etc/amanda/exclude/exclude-filename
This concludes the necessary configuration on the client.
-Connect to SERVER and cd to the exclude-test AMANDA configuration directory.
-Edit the AMANDA configuration file e.g. amanda.conf. Add an entry similar to
+Connect to SERVER and cd to the exclude-test Amanda configuration directory.
+Edit the Amanda configuration file e.g. amanda.conf. Add an entry similar to
the following line, to the dumptype for the client in question, where the
exclude-filename is the file that was created on CLIENT in the step above
including the quotes. For example:
}
Save the file. Run amcheck again to verify that there are no problems with the
-revised AMANDA configuration. If amcheck succeeds then run amdump to verify the
+revised Amanda configuration. If amcheck succeeds then run amdump to verify the
data is being excluded correctly. If the data is not being excluded as expected
please see the Troubleshooting section below. This completes the setup of an
exclude list.
Do not include the data in the disklist
-AMANDA uses disklist entries to define which directories or partitions should
+Amanda uses disklist entries to define which directories or partitions should
be archived. This allows us to exclude data by just not placing the data in
question in the disklist. Assume that there is a disk mounted on /example. The
directory /example has five subdirectories "a", "b", "c", "d", and "e". The
CLIENT /examples/b exclude-test
CLIENT /examples/c exclude-test
-Run amcheck to verify that AMANDA is working correctly. If the data is not
+Run amcheck to verify that Amanda is working correctly. If the data is not
being excluded as expected please see the Troubleshooting section below. This
completes the setup of using a disklist to exclude data.
Wildcard Expansion
-AMANDA has the ability to use wildcard expansion while excluding data as
+Amanda has the ability to use wildcard expansion while excluding data as
implemented by tar(1). The only places that wildcard expansion is allowed is in
the "exclude" option in the dumptype, or in the exclude list. Some simple
examples:
Broken gnutar?
There are versions of GNU-tar that do not correctly exclude data. Version 1.12
-(plus the AMANDA patches from http://www.amanda.org) are known to work
+(plus the Amanda patches from http://www.amanda.org) are known to work
correctly, as does version 1.13.19 (and later). Anything else is questionable.
Note
-------------------------------------------------------------------------------
Prev Up Next
-Chapter 2. AMANDA Installation Notes Home Chapter 4. Indexing with AMANDA
+Chapter 2. Amanda Installation Notes Home Chapter 4. Indexing with Amanda
- Chapter 17. AMANDA FAQ
+ Chapter 19. Amanda FAQ
Prev Part IV. Various Information Next
-------------------------------------------------------------------------------
-Chapter 17. AMANDA FAQ
+Chapter 19. Amanda FAQ
-AMANDA Core Team
+Amanda Core Team
AMANDA Core Team
Refer to http://www.amanda.org/docs/faq.html for the current version of this
document.
This file contains answers to some questions that are frequently asked in the
-AMANDA mailing lists, specially by new users. Please take a look at this file
-before posting, this can save us time that could be spent improving AMANDA and
+Amanda mailing lists, specially by new users. Please take a look at this file
+before posting, this can save us time that could be spent improving Amanda and
its documentation.
New entries and modifications are welcome; send them to mailto://amanda-
users@amanda.org or mailto://amanda-hackers@amanda.org.
-You may also want to take a look at the AMANDA FAQ-O-Matic http://
+You may also want to take a look at the Amanda FAQ-O-Matic http://
www.amanda.org/fom-serve/cache/1.html.
- Why_does_AMANDA_fail_to_build_on_my_system?
+ Why_does_Amanda_fail_to_build_on_my_system?
Why_does_amdump_report_that_all_disks_failed?
Why_does_amcheck_say_"port_NNN_is_not_secure"?
- Why_does_amcheck_claim_that_the_tape_is_"not_an_AMANDA_tape"?
+ Why_does_amcheck_claim_that_the_tape_is_"not_an_Amanda_tape"?
Why_does_amcheck_report_"selfcheck_request_timed_out"?
Which_tape_changer_configuration_should_I_use_in_amanda.conf?
+ Where_do_I_get_my_tapetype-definition_from?_Do_I_have_to_run_amtapetype?
+
Should_I_use_software_or_hardware_compression?
- How_can_I_configure_AMANDA_so_that_it_performs_full_backups_on_the_week-end
+ How_can_I_configure_Amanda_so_that_it_performs_full_backups_on_the_week-end
and_incrementals_on_weekdays?
What_if_my_tape_unit_uses_expensive_tapes,_and_I_don't_want_to_use_one_tape
- per_day?_Can't_AMANDA_append_to_tapes?
+ per_day?_Can't_Amanda_append_to_tapes?
- How_can_I_configure_AMANDA_for_long-term_archiving?
+ How_can_I_configure_Amanda_for_long-term_archiving?
Can_I_backup_separate_disks_of_the_same_host_in_different_configurations?
- Can_AMANDA_span_large_filesystems_across_multiple_tapes?
+ Can_Amanda_span_large_filesystems_across_multiple_tapes?
What's_the_difference_between_option_"skip-full"_and_"strategy_nofull"?
amdump_reported_"infofile_update_failed"._What_should_I_do?
- Why_does_AMANDA_sometimes_promote_full_dumps?
+ Why_does_Amanda_sometimes_promote_full_dumps?
Why_does_amrecover_report_"no_index_records"_or_"disk_not_found"?
- Ok,_I'm_done_with_testing_AMANDA,_now_I_want_to_put_it_in_production._How_can
+ Ok,_I'm_done_with_testing_Amanda,_now_I_want_to_put_it_in_production._How_can
I_reset_its_databases_so_as_to_start_from_scratch?
The_man-page_of_dump_says_that_active_filesystems_may_be_backed_up
- inconsistently._What_does_AMANDA_do_to_prevent_inconsistent_backups?
+ inconsistently._What_does_Amanda_do_to_prevent_inconsistent_backups?
Which_version_of_GNU-tar_should_I_use?
- What_does_"bumping"bumping_mean?
+ What_does_"bumping"_mean?
How_do_I_backup_a_Windows_server?
+ How_do_I_tell_my_iptables-based_firewall_to_allow_Amanda_through?
+
+ How_do_I_get_rid_of_pressing_"q"_to_get_rid_of_a_pager_prompt_when_using
+ amrecover?
+
+ Is_there_a_way_to_tell_the_pager_that_my_terminal_has_"y"_lines?
+
- Why does AMANDA fail to build on my system?
+ Why does Amanda fail to build on my system?
One of the most common reasons for compile-time errors is stale information in
config.cache, after a build on a different platform using the same build tree.
In order to avoid this problem, make sure you don't ever reuse build trees
in libtool that causes it to search for symbols in already-installed amanda
libraries, instead of in the just-built ones. This problem is known to affect
SunOS 4.1.3 and FreeBSD. You can usually work around it by specifying a
- different prefix when you configure the new version of AMANDA. However, it may
- not work if the previous version of AMANDA was installed in /usr/local and gcc
+ different prefix when you configure the new version of Amanda. However, it may
+ not work if the previous version of Amanda was installed in /usr/local and gcc
searches this directory by default; in this case, you must either remove the
old libraries (which you don't want to do, right? :-) or call configure with
- the flag --disable-libtool. In this case, AMANDA won't create shared
+ the flag --disable-libtool. In this case, Amanda won't create shared
libraries, so binaries will be larger, but you may worry about that later.
- You may also want to take a look at AMANDA_2.4.x_-_System-Specific
- Installation_Notes, as well as to the AMANDA Patches Page (http://
+ You may also want to take a look at Amanda_2.5.0_-_System-Specific
+ Installation_Notes, as well as to the Amanda Patches Page (http://
www.amanda.org/patches/) for other known problems. If everything fails, you
should read the manual, but since we don't have one yet, just post a help
request to the amanda-users mailing list (mailto://amanda-users@amanda.org),
showing the last few lines of the failed build.
Why does amdump report that all disks failed?
- Probably because the AMANDA clients are not properly configured. Before you
+ Probably because the Amanda clients are not properly configured. Before you
ever run amdump, make sure amcheck succeeds. When it does, so should amdump.
Make sure you run amcheck as the same user that is supposed to start amdump,
otherwise you may get incorrect results.
Why does amcheck say "port NNN is not secure"?
- Because amcheck, as some other AMANDA programs, must be installed as setuid-
- root. Run make install as "root", or chown all AMANDA setuid programs to
+ Because amcheck, as some other Amanda programs, must be installed as setuid-
+ root. Run make install as "root", or chown all Amanda setuid programs to
"root", then chown u+s them again, if chown drops the setuid bit.
- Why does amcheck claim that the tape is "not an AMANDA tape"?
- Because AMANDA requires you to label tapes before it uses them. Run amlabel in
+ Why does amcheck claim that the tape is "not an Amanda tape"?
+ Because Amanda requires you to label tapes before it uses them. Run amlabel in
order to label a tape.
If, even after labeling a tape, amcheck still complains about it, make sure
the regular expression specified in amanda.conf matches the label you have
specified, and check whether you have configured non-rewinding tape devices
- for AMANDA to use. For example, use /dev/nrst0 instead of /dev/rst0, /dev/rmt/
+ for Amanda to use. For example, use /dev/nrst0 instead of /dev/rst0, /dev/rmt/
0bn instead of /dev/rmt/0b, or some other system-dependent device name that
contains an "n", instead of one that does not. The "n" stands for non-
rewinding.
have to label them again.
Why does amcheck report "selfcheck request timed out"?
This can occur under several different situations. First, make sure this
- problem is repeatable; if AMANDA programs are NFS-auto-mounted, some clients
- may fail to mount the AMANDA binaries in time.
+ problem is repeatable; if Amanda programs are NFS-auto-mounted, some clients
+ may fail to mount the Amanda binaries in time.
If the error is repeatable, log into the client, and check whether the
directory /tmp/amanda exists, and a file named amandad.debug exists in there:
amandad will create this file whenever it starts. If this file does not exist,
amanda/amandad.debug.
In the latter case, wipe out /tmp/amanda, and amandad should create it next
time it runs. In the former case, check your inetd configuration. Make sure
- you have added the AMANDA services to /etc/services (or the NIS services map),
+ you have added the Amanda services to /etc/services (or the NIS services map),
that /etc/inetd.conf was properly configured, and that you have signalled
inetd to reread this file (some systems may need rebooting). Check section 2.2
from in the Amanda_Installation_Notes for details. Check the inetd man-page
specified at configure-time (configure --with-user=<USERNAME>) is listed in /
etc/inetd.conf. Check whether this user has permission to run amandad, as well
as any shared libraries amandad depends upon, by running the specified amandad
- command by hand, as the AMANDA user. It should just time-out after 30 seconds
+ command by hand, as the Amanda user. It should just time-out after 30 seconds
waiting for a UDP packet. If you type anything, it will abort immediately,
because it can't read a UDP packet from the keyboard.
As soon as you have properly configured /etc/inetd.conf so as to run amandad,
try to read a UDP packet from the keyboard, and this was reported not to work
on most keyboards :-). However, if you have run amandad as any user other than
the one listed in /etc/inetd.conf, it may have created a /tmp/amanda directory
- that the AMANDA user cannot write to, so you should wipe it out.
- Another possibility is that the AMANDA service was not properly configured as
+ that the Amanda user cannot write to, so you should wipe it out.
+ Another possibility is that the Amanda service was not properly configured as
a UDP service; check /etc/services and /etc/inetd.conf.
Why does amcheck say "access as <username> not allowed..."?
There must be something wrong with .amandahosts configuration (or .rhosts, if
names.
Why does amcheck report "ip address #.#.#.#" is not in the ip list list for
<hostname>'?
- Check your DNS configuration tables. In order to avoid DNS-spoofing, AMANDA
+ Check your DNS configuration tables. In order to avoid DNS-spoofing, Amanda
double-checks hostname<->IP address mapping. If the IP address the request
comes from maps to a hostname, but this hostname does not map back to the
incoming IP address, the request is denied.
Why does amcheck say "cannot overwrite active tape"?
- Because, if you configure AMANDA to use N tapes, by setting tapecycle to N in
- amanda.conf, before AMANDA overwrites a tape, it must write to at least other
- N-1 tapes. Of course, AMANDA will always refuse to overwrite a tape marked for
- `noreuse' with amadmin. Furthermore, such tapes are not counted when AMANDA
+ Because, if you configure Amanda to use N tapes, by setting tapecycle to N in
+ amanda.conf, before Amanda overwrites a tape, it must write to at least other
+ N-1 tapes. Of course, Amanda will always refuse to overwrite a tape marked for
+ `noreuse' with amadmin. Furthermore, such tapes are not counted when Amanda
computes `N-1' tapes.
- If, for some reason, you want to tell AMANDA to overwrite a particular tape,
+ If, for some reason, you want to tell Amanda to overwrite a particular tape,
regardless of its position in the cycle, use amrmtape. This command will
remove this tape from the tapelist file, that is used to manage the tape
cycle, and will delete information about backups stored in that tape from the
- AMANDA database.
+ Amanda database.
Why does amcheck tell me "DUMP program not available"?
Because configure could not find dump when it was first run. This is a common
problem on Linux hosts, because most Linux distributions do not install dump
by default.
If you don't have a DUMP program installed, install it, remove config.cache,
- run configure again and rebuild AMANDA. While configure is running, make sure
+ run configure again and rebuild Amanda. While configure is running, make sure
it can find the installed DUMP program. If it cannot, you may have to set the
environment variables DUMP and RESTORE by hand, before running configure.
If you can't or don't want to install DUMP, you may use GNU tar, but make sure
mtx, for example, is available for several platforms. However, even if you
find it for your platform, beware that there exist several different programs
named mtx, that require different command line arguments, and print different
- output, and AMANDA's chg-mtx does not support them all. You may have to edit
+ output, and Amanda's chg-mtx does not support them all. You may have to edit
the script, which shouldn't be hard to do.
- In section BUILT-IN TAPE CHANGERS of AMANDA_Tape_Changer_Support you will find
- details about the tape changer interfacing programs provided with AMANDA, that
+ In section BUILT-IN TAPE CHANGERS of Amanda_Tape_Changer_Support you will find
+ details about the tape changer interfacing programs provided with Amanda, that
can interact with common tape changer programs and with tape changer-related
system calls provided by some operating system. If none of them matches your
needs, you may have to develop your own tape changer interface script.
- Before posting a question to the AMANDA mailing lists, *please* search the
+ Before posting a question to the Amanda mailing lists, *please* search the
archives, and try to obtain as much information about driving your tape
changer hardware from the vendor of the changer hardware and of the operating
- system, rather than from the AMANDA mailing lists. We usually don't have much
+ system, rather than from the Amanda mailing lists. We usually don't have much
to say about tape changer units, and several questions about them remain
unanswered. :-(
Anyway, if you decide to post a question, make sure you specify both the tape
changer hardware *and* the OS/platform that is going to interface with it.
Good luck! :-)
+ Where do I get my tapetype-definition from? Do I have to run amtapetype?
+ It is not mandatory to run amtapetype at installation-time. It is very likely
+ that your tapedrive or -changer is one of the devices that are already covered
+ by one of the existing tapetype-definitions.
+ You may find tapetype-definitions in the example amanda.conf, in the
+ mailinglist-archives of the amanda-users-mailinglist at http://
+ marc.theaimsgroup.com/?l=amanda-users or in the Amanda-FAQ-O-Matic at http://
+ www.amanda.org/fom-serve/cache/1.html.
+ Reasons to run amtapetype for your device:
+
+ * You want to generate your own tapetype-definition because you can't find any
+ suitable tapetype-definition for your device.
+ * You want to determine the performance of your device.
+ * You want to determine if your device has hardware-compression enabled.
+
+ If you decide to run amtapetype, please refer to the chapter Tapetypes and the
+ manpage amtapetype(8).
Should I use software or hardware compression?
When you enable software compression, you drastically reduce the compression
that might be achieved by hardware. In fact, tape drives will usually use
data.
Thus, you must choose whether you're going to use software or hardware
compression; don't ever enable both unless you want to waste tape space.
- Since AMANDA prefers to have complete information about tape sizes and
+ Since Amanda prefers to have complete information about tape sizes and
compression rates, it can do a better job if you use software compression.
- However, if you can't afford the extra CPU usage, AMANDA can live with the
+ However, if you can't afford the extra CPU usage, Amanda can live with the
unpredictability of hardware compression, but you'll have to be very
conservative about the specified tape size, specially if there are filesystems
that contain mostly uncompressible data.
- How can I configure AMANDA so that it performs full backups on the week-end
+ You might want to run amtapetype to determine if you have hardware-compression
+ enabled for your tape-drive.
+ How can I configure Amanda so that it performs full backups on the week-end
and incrementals on weekdays?
- You can't. AMANDA doesn't work this way. You just have to tell AMANDA how many
+ You can't. Amanda doesn't work this way. You just have to tell Amanda how many
tapes you have (tapecycle), and how often you want it to perform full backups
of each filesystem (dumpcycle). If you don't run it once a daily (including
- Saturdays and Sundays :-), you'll also want to tell AMANDA how many times
+ Saturdays and Sundays :-), you'll also want to tell Amanda how many times
you'll run it per dumpcycle (runspercycle). It will spread full backups along
the dumpcycle, so you won't have any full-only or incremental-only runs.
Please also refer to "the friday-tape-question" in Collection_of_the_top_ten
- AMANDA_questions._And_answers..
+ Amanda_questions._And_answers..
What if my tape unit uses expensive tapes, and I don't want to use one tape
- per day? Can't AMANDA append to tapes?
+ per day? Can't Amanda append to tapes?
It can't, and this is good. Tape drives and OS drivers are (in)famous for
rewinding tapes at unexpected times, without telling the program that's
writing to them. If you have a month's worth of backups in that tape, you
- really don't want them to be overwritten, so AMANDA has taken the safe
+ really don't want them to be overwritten, so Amanda has taken the safe
approach of requiring tapes to be written from the beginning on every run.
This can be wasteful, specially if you have a small amount of data to back up,
but expensive large-capacity tapes. One possible approach is to run amdump
backs up the holding disk only, always as a full backup. You'd run this
configuration always after your regular backup, so you always have a complete
image of the holding disk on tape, just in case it fails.
- How can I configure AMANDA for long-term archiving?
+ How can I configure Amanda for long-term archiving?
The best approach is to create a separate configuration for your archive
backups. It should use a separate set of tapes, and have all dumptypes
configured with `record no', so it doesn't interfere with regular backups.
Can I backup separate disks of the same host in different configurations?
- Yes, but you have to be careful. AMANDA uses UDP to issue estimate and backup
+ Yes, but you have to be careful. Amanda uses UDP to issue estimate and backup
requests and, although replies to backup requests are immediate (so that TCP
connections for the actual backup can be established), replies to estimate
requests are not and, while one request is being processed, any other request
So, there are two easy ways out:
i. Ensure that the configurations never run concurrently, or
- ii. set up two different installations of the AMANDA server, using different
+ ii. set up two different installations of the Amanda server, using different
services names to contact the clients, i.e., different port numbers. This
- can be attained with the configure flag --with-testing=<service-suffix>i.
+ can be attained with the configure flag --with-testing=<service-suffix>.
Yes, the flag name is not appropriate, but so what?
- If you don't want to set up two installations of AMANDA (I agree, it's
+ If you don't want to set up two installations of Amanda (I agree, it's
overkill), but you still want to back up disks of the same host in separate
- configurations, you can set up AMANDA so that one configuration only starts
+ configurations, you can set up Amanda so that one configuration only starts
after the first one has already finished its One possible way to work-around
this limitation is to start one configuration only after you know the
estimates for the first one have already finished (modifying the crontab
(a dumptype option) of the disks in the first configuration, so that they
don't start backing up before the estimates of the second configuration
finish.
- Can AMANDA span large filesystems across multiple tapes?
+ Can Amanda span large filesystems across multiple tapes?
Not yet :-(
This is an open project, looking for developers. If you'd like to help, please
- take a look at the AMANDA Ongoing Projects Page (http://www.amanda.org/
+ take a look at the Amanda Ongoing Projects Page (http://www.amanda.org/
ongoing.php), where more up-to-date information is likely to be found about
this project.
Update September 2004: Refer to the archive of the amanda-hackers mailinglist
What's the difference between option "skip-full" and "strategy nofull"?
"strategy nofull" is supposed to handle the following situation: you run a
full dump off-line once a millenium :-), because that disk isn't supposed to
- change at all and, if it does, changes are minimal. AMANDA will run only level
+ change at all and, if it does, changes are minimal. Amanda will run only level
1 backups of that filesystem, to avoid the risk of overwriting a level 1
backup needed to do a restore. Remember, you run full dumps once a millenium,
and your tape cycle probably won't last that long :-)
"skip-full", OTOH, is supposed to let the user run full dumps off-line
- regularly (i.e., as often as specified in the dumpcycle), while AMANDA takes
- care of the incrementals. Currently, AMANDA will tell you when you're supposed
- to run the level 0 backups but, if you fail to do so, AMANDA will not only
+ regularly (i.e., as often as specified in the dumpcycle), while Amanda takes
+ care of the incrementals. Currently, Amanda will tell you when you're supposed
+ to run the level 0 backups but, if you fail to do so, Amanda will not only
skip a full day's worth of valuable backups of the filesystem, on the day it
told you to the full backup manually, but it will also run a level 1 backup on
the next day, even if you have not performed the full backup yet. Worse yet:
Why does amdump report "results missing"?
One of the possible reasons is that you have requested too many backups of the
host. In this case, the estimate request or the reply may not fit in a UDP
- packet. This will cause AMANDA not to perform some of the backups. Fixing this
+ packet. This will cause Amanda not to perform some of the backups. Fixing this
problem involves modifying the way estimate requests are issued, so that no
packet exceeds the maximum packet size, and issuing additional requests that
did not fit in a UDP packet after a reply for the previous set is obtained.
DUMP to crash before it estimates the backup size; a fsck may help.
Yet another possibility is that the filesystem is so large that the backup
program is incorrectly reporting the estimated size, for example, by printing
- a negative value that AMANDA will not accept as a valid estimate. If you are
+ a negative value that Amanda will not accept as a valid estimate. If you are
using dump, contact your vendor and request a patch for dump that fixes this
bug. If you are using GNU-tar, make sure it is release 1.12 or newer; 1.11.8
won't do! Even release 1.12 may require a patch to correctly report estimates
and dump sizes, as well as to handle sparse files correctly and quickly
instead of printing error messages like `Read error at byte 0, reading 512
bytes, in file ./var/log/lastlog: Bad file number' in sendsize.debug and being
- very slow. Check the patches directory of the AMANDA distribution.
+ very slow. Check the patches directory of the Amanda distribution.
What if amdump reports "dumps way too big, must skip incremental dumps"?
- It means AMANDA couldn't back up some disk because it wouldn't fit in the tape
- (s) you have configured AMANDA to use. It considered performing some
+ It means Amanda couldn't back up some disk because it wouldn't fit in the tape
+ (s) you have configured Amanda to use. It considered performing some
incrementals instead of full dumps, so that all disks would fit, but this
wouldn't be enough, so the disk really had to be dropped in this run.
In general, you can just ignore this message if it happens only once in a
while. Low-priority disks are discarded first, so you'll hardly miss really
important data.
- One real work-around is to configure AMANDA to use more tapes: increase
+ One real work-around is to configure Amanda to use more tapes: increase
`runtapes' in amanda.conf. Even if you don't have a real tape changer, you can
act yourself as a changer (`chg-manual'; more details in the question about
tape changer configuration), or use `chg-multi' with a single tape unit, and
- lie to AMANDA that it will have two tapes to use. If you have a holding disk
- as large as a tape, and configure AMANDA (2.4.1b1 or newer) not to reserve any
+ lie to Amanda that it will have two tapes to use. If you have a holding disk
+ as large as a tape, and configure Amanda (2.4.1b1 or newer) not to reserve any
space for degraded dumps, dumps that would be stored in the second tape of a
run will be performed to the holding disk, so you can flush them to tape in
the morning.
amdump reported "infofile update failed". What should I do?
- Make sure all directories and files are readable and writable by the AMANDA
+ Make sure all directories and files are readable and writable by the Amanda
user, within the directory you specified as `infofile' in amanda.conf. From
then on, only run amanda server commands ( amadmin, amdump, amflush,
- amcleanup) as the AMANDA user, not as root.
- Why does AMANDA sometimes promote full dumps?
+ amcleanup) as the Amanda user, not as root.
+ Why does Amanda sometimes promote full dumps?
To spread the full dumps along the dumpcycle, so that daily runs take roughly
- the same amount of tape and time. As soon as you start using AMANDA, it will
+ the same amount of tape and time. As soon as you start using Amanda, it will
run full dumps of all filesystems. Then, on the following runs, it will
promote some backups, so as to adjust the balance. After one or two
dumpcycles, it should stop promoting dumps. You can see how well it is doing
Another possibility is that amrecover is not selecting the configuration name
that contains the backups for the selected disk. You may specify a
configuration name with the `-C' switch, when you invoke amrecover. The
- default configuration name can only be specified at AMANDA configure time
+ default configuration name can only be specified at Amanda configure time
(configure --with-config=<name>).
Indexes are currently generated at backup-time only, so, if a backup was
performed without creating an index, you won't be able to use amrecover to
restore it, you'll have to use amrestore.
- Ok, I'm done with testing AMANDA, now I want to put it in production. How can
+ Ok, I'm done with testing Amanda, now I want to put it in production. How can
I reset its databases so as to start from scratch?
First, remove the `curinfo' database. By default, it is a directory, but, if
you have selected any other database format (don't, they're deprecated), they
on the tape changer you have selected, you may also want to reset its state
file.
The man-page of dump says that active filesystems may be backed up
- inconsistently. What does AMANDA do to prevent inconsistent backups?
+ inconsistently. What does Amanda do to prevent inconsistent backups?
Nothing. When you back up an active filesystem, there are two possibilities:
dump may print strange error messages about invalid blocks, then fail; in this
- case, AMANDA will retry the backup on the next run.
+ case, Amanda will retry the backup on the next run.
Files that are modified while dump runs may be backed up inconsistently. But
then, they will be included in the next incremental backup, which should
usually be enough.
Large, critical files such as databases should be locked somehow, to avoid
- inconsistent backups, but there's no direct support for that in AMANDA. The
- best bet is to configure AMANDA to use a wrapper to dump, that locks and
+ inconsistent backups, but there's no direct support for that in Amanda. The
+ best bet is to configure Amanda to use a wrapper to dump, that locks and
unlocks the database when appropriate.
Which version of GNU-tar should I use?
(This answer was slightly adapted from a posting by Paul Bijnens
* 1.13.19 is good.
However it still sets return code 2 for some infrequent conditions even with
- --ignore-failed-read option. This results in AMANDA thinking the total
+ --ignore-failed-read option. This results in Amanda thinking the total
archive is bad, and drops the complete archive. Those conditions are very
rare on a quiet filesystem.
* 1.13.25 is good: no problems found (yet).
What does "bumping" mean?
The term "bumping" is used to describe the change from one backup-level to the
- next higher level. If AMANDA changes from Level 0 to Level 1 for a specific
+ next higher level. If Amanda changes from Level 0 to Level 1 for a specific
DLE, it "bumps".
The basic goal of "bumping" is to save precious space on the backup media as
higher level incremental backups are smaller in size than lower level
of tape-errors and similar problems during the process of restore. So in
general it is recommended to keep the levels as low as possible with the given
hardware and data.
- There are various amanda.conf parameters to control and fine-tune AMANDA's
+ There are various amanda.conf parameters to control and fine-tune Amanda's
behavior when it comes to "bumping":
Please refer to the amanda-manpage and the example amanda.conf for details on
the parameters bumppercent, bumpsize, bumpdays and bumpmult.
How do I backup a Windows server?
- AMANDA is able to use smbclient to dump SMB/CIFS-shares. Refer to the Backup
+ Amanda is able to use smbclient to dump SMB/CIFS-shares. Refer to the Backup
PC_hosts_using_Samba for details.
+ How do I tell my iptables-based firewall to allow Amanda through?
+ posted by Matt Hyclak <hyclak@math.ohiou.edu>:
+ Use something like
+
+ iptables -A INPUT -p udp -s $AMANDA_SERVER -d $AMANDA_CLIENT --dport
+ 10080 -j ACCEPT
+
+ and load the ip_conntrack_amanda kernel module. I use the following in /etc/
+ modprobe.conf:
+
+ options ip_conntrack_amanda master_timeout=2400
+ install ip_tables /sbin/modprobe --ignore-install ip_tables && /sbin/
+ modprobe ip_conntrack_amanda
+
+ This sets the UDP timeout for Amanda packets to 2400 seconds, up from the
+ default 300 (don't hold me to that, it might be 600). I was getting estimate
+ timeouts since they were taking longer than 300/600 seconds and the firewall
+ would close the port.
+ Makes things a little more secure than opening up everything > 1024 ;-)
+ How do I get rid of pressing "q" to get rid of a pager prompt when using
+ amrecover?
+ compiled from postings by Paul Bijnens <paul.bijnens@xplanation.com> and Jon
+ LaBadie <jon@jgcomp.com>
+ Paul Bijnens wrote:
+ If you have to press "q" all the time in amrecover this is related to the
+ pager-binary you use. If you use Linux this will be most likely less. To teach
+ less to quit when hitting EOF, you need to set something like LESS=--QUIT-AT-
+ EOF; export LESS, for example in your .profile. Refer to the manpage of less
+ for details.
+ Jon LaBadie wrote:
+ If you don't like the quit at EOF behavior "except" when in amrecover create
+ an alias or a wrapper; something like:
+ alias amrecov='LESS="$LESS -E" _pathto_your_amrecover'
+ Is there a way to tell the pager that my terminal has "y" lines?
+ Jon LaBadie <jon@jgcomp.com> wrote:
+ The pager normally does it's best to find out how many lines your terminal
+ has, given the right TERM-variable. Even terminals with elastic boundaries
+ (e.g. xterms) work. But I have to admit that on Solaris the settings are not
+ always correct. You can fix it quickly by setting an environment variable to
+ e.g. LINES=24 (and export it).
-------------------------------------------------------------------------------
Prev Up Next
-Chapter 16. Using AMANDA Home Chapter 18. Collection of the top ten AMANDA
+Chapter 18. Using Amanda Home Chapter 20. Collection of the top ten Amanda
questions. And answers.
-------------------------------------------------------------------------------
-Historical files
+Part VI. Historical files
Old and outdated material, proposals and drafts.
Here you find some chapters which contain outdated informations. These chapters
-nonetheless can help to get a more complete picture of AMANDA.
+nonetheless can help to get a more complete picture of Amanda.
Note
Please realize that the following does not necessarily describe current
-features of AMANDA. There are also features described which were never added to
-AMANDA.
+features of Amanda. There are also features described which were never added to
+Amanda.
Table of Contents
- 28._Response_to_CPIO_Security_Notice_Issue_11:
+ 29._Response_to_CPIO_Security_Notice_Issue_11:
Affected_Versions
Acknowledgements
- 29._Upgrade_Issues
+ 30._Upgrade_Issues
- 30._What_once_was_new
+ 31._What_once_was_new
- What's_new_in_AMANDA_2.3
+ What's_new_in_Amanda_2.3
Indexing_backups_for_easier_restore
amadmin_import/export
- What's_new_in_AMANDA_2.2
+ What's_new_in_Amanda_2.2
Client_side_setup_has_changed
- 31._Multitape_support_in_AMANDA_2.2
+ 32._Multitape_support_in_Amanda_2.2
Introduction
- 32._Thoughts_about_a_Strategy_API
+ 33._Thoughts_about_a_Strategy_API
- 33._Y2K_Compliancy
+ 34._Y2K_Compliancy
- 34._Usage_of_floppy_tape_drives_on_Linux
+ 35._Usage_of_floppy_tape_drives_on_Linux
-------------------------------------------------------------------------------
-Prev Up Next
-Chapter 27. Using Kerberos with Home Chapter 28. Response to CPIO Security
-AMANDA Notice Issue 11:
+Prev Next
+Chapter 28. Using Kerberos with Home Chapter 29. Response to CPIO Security
+Amanda Notice Issue 11:
Chapter 14. AFS HOWTO
-AMANDA Core Team
+Amanda Core Team
AMANDA Core Team
ftp://ftp.ccmr.cornell.edu/pub/amanda-afs/amanda-afs.tar.gz
or anonymous cvs from :pserver:anonymous@cvs.ccmr.cornell.edu:/usr/common/cvs
and checkout project 'amanda-afs'
-The patch to AMANDA is already included in this distribution.
+The patch to Amanda is already included in this distribution.
-------------------------------------------------------------------------------
Prev Up Next
-Chapter 13. How to use the AMANDA file- Home Chapter 15. How to use a wrapper
+Chapter 13. How to use the Amanda file- Home Chapter 15. How to use a wrapper
driver
--- /dev/null
+
+Chapter 17. How to use different auth with Amanda
+Prev Part III. HOWTOs Next
+
+-------------------------------------------------------------------------------
+
+Chapter 17. How to use different auth with Amanda
+
+
+Jean-Louis Martineau
+
+Original text;XML-conversion;Updates
+AMANDA Core Team
+<martinea@iro.umontreal.ca>
+Table of Contents
+
+
+ Introduction
+
+ BSD
+
+ BSDTCP
+
+ BSDUDP
+
+ KRB4
+
+ KRB5
+
+ RSH
+
+ SSH
+
+
+ For_amdump:
+
+ For_amrecover:
+
+
+
+Note
+
+Refer to http://www.amanda.org/docs/howto-auth.html for the current version of
+this document.
+This document covers the use of the auth in Amanda 2.5.1 and higher.
+
+Introduction
+
+
+ BSD
+
+You must configure amanda with --with-bsd-security and --with-amandahosts.
+The xinetd.d/amanda file on the client:
+
+ service amanda
+ {
+ only_from = 127.0.0.1
+ socket_type = dgram
+ protocol = udp
+ wait = yes
+ user = amanda
+ group = amanda
+ groups = yes
+ server = /path/to/amandad
+ server_args = -auth=bsd amdump
+ disable = no
+ }
+
+The only_from line should list your tape server ip address.
+The ~amanda/.amandahosts file on the client:
+
+ tapeserver.fqdn amanda amdump
+
+If you want to also enable amindexd and amidxtaped, you must change the
+server_args line in the xinetd.d/amanda file on the tape server:
+
+ server_args = -auth=bsd amdump amindexd amidxtaped
+
+The only_from line should list all machine that can use amdump/amrecover. It's
+the .amandahosts that will limit which client can use amdump/amindexd/
+amidxtaped.
+The ~amanda/.amandahosts file on the tape server must have a line for each
+machi ne:
+
+ clientmachine1 amanda amindexd amidxtaped
+ clientmachine2 amanda amindexd amidxtaped
+
+
+ BSDTCP
+
+Like bsd but you must configure amanda with --with-bsdtcp-security and --with-
+amandahosts and do 4 changes in the xinetd.d/amanda file:
+
+ socket_type = stream
+ protocol = tcp
+ wait = no
+ server_args = -auth=bsdtcp amdump
+
+
+ BSDUDP
+
+Like bsd but you must configure amanda with --with-bsdudp-security and --with-
+amandahosts and do 1 change in the xinetd.d/amanda file:
+
+ server_args = -auth=bsdudp amdump
+
+
+ KRB4
+
+You must configure amanda with --with-krb4-security.
+
+ KRB5
+
+You must configure amanda with --with-krb5-security.
+
+ RSH
+
+You must configure amanda with --with-rsh-security.
+It's your system that should allow your server user to rsh to your client user.
+If your server username and client username are different, you must add the
+client_username option in all DLE for that host.
+
+ client_username "client_username"
+
+If your server amandad path and client amandad path are different, you must set
+the amandad_path option in all DLE for that hosts.
+
+ amandad_path "client/amandad/path"
+
+
+ SSH
+
+You must configure amanda with --with-ssh-security.
+
+ For amdump:
+
+You must create an ssh key for your server. In this example, the key is put in
+the id_rsa_amdump file:
+
+ ssh-keygen -t rsa
+ Enter file in which to save the key (/home/amanda/.ssh/id_rsa)? /home/
+ amanda/.ssh/id_rsa_amdump
+
+You must set the ssh_keys option in all DLE for that host:
+
+ ssh_keys "/home/amanda/.ssh/id_rsa_amdump"
+
+You mush append the /home/amanda/.ssh/id_rsa_amdump.pub file to the .ssh/
+authorized_keys file of all client host.
+For security reason, you must prepend the line with the following:
+
+ from="tape_server_fqdn_name",no-port-forwarding,no-X11-forwarding,no-agent-
+ forwarding,command="/path/to/amandad -auth=ssh amdump"
+
+That will limit that key to connect only from your server and only be able to
+execute amandad.
+Like rsh if your server username and client username are different, you must
+add the client_username option in all DLE for that
+host:
+
+ client_username "client_username"
+
+Like rsh, if your server amandad path and client amandad path are different,
+you must set the amandad_path option in all DLE for that hosts:
+
+ amandad_path "client/amandad/path"
+
+
+ For amrecover:
+
+You must create an ssh key for root on all clients that can use amrecover. In
+this example, the key is put in the /root/.ssh/id_ rsa_amrecover file:
+Log in as root:
+
+ ssh-keygen -t rsa
+ Enter file in which to save the key (/root/.ssh/id_rsa)? /root/.ssh/
+ id_rsa_amrecover
+
+You must set the ssh_keys option in the amanda_client.conf file
+
+ ssh_keys "/root/.ssh/id_rsa_amrecover"
+
+You mush append all client /home/root/.ssh/id_rsa_amrecover.pub file to the /
+home/amanda/.ssh/authorized_keys of the server.
+For security reason, you must prefix all lines with the following:
+
+ from="aclient_fqdn_name",no-port-forwarding,no-X11-forwarding,no-agent-
+ forwarding,command="/path/to/amandad -auth=ssh amindexd amidxtaped"
+
+That will limit every client key to connect from the client and only be able to
+execute amandad.
+-------------------------------------------------------------------------------
+
+Prev Up Next
+Chapter 16. How to do Amanda-server-side Home Part IV. Various Information
+gpg-encrypted backups.
+
-Chapter 12. AMANDA on Cygwin HOWTO
+Chapter 12. Amanda on Cygwin HOWTO
Prev Part III. HOWTOs Next
-------------------------------------------------------------------------------
-Chapter 12. AMANDA on Cygwin HOWTO
+Chapter 12. Amanda on Cygwin HOWTO
Doug Kingston
Other_Preparation
- Compile_AMANDA
+ Compile_Amanda
Configure_Cygwin_files
Windows_NT/2000/XP
- Notes_on_AMANDA_backup_options
+ Notes_on_Amanda_backup_options
Compression
Refer to http://www.amanda.org/docs/howto-cygwin.html for the current version
of this document.
-by Doug Kingston, 30 January 2003. Based on Cygwin 1.3.18, and AMANDA 2.4.3-
+by Doug Kingston, 30 January 2003. Based on Cygwin 1.3.18, and Amanda 2.4.3-
20021027 and some fixes which will be in the official release by the time you
see this.
With thanks to Enrico Bernardini from whom I have borrowed some material from
-an earlier attempt at documenting the installation of AMANDA on Cygwin in 2001.
+an earlier attempt at documenting the installation of Amanda on Cygwin in 2001.
Please send annotations and corrections to mailto://amanda-hackers@amanda.org.
I can be reached as dpk (at) randomnotes.org (do the obvious).
list, I would appreciate and email to mailto://amanda-hackers@amanda.org.
One user reported some problems with access rights when running under Cygwin,
which he solved by setting the CYGWIN environment variable to nontsec. I do not
-believe this is necessary if you run the AMANDA daemon as System (see below).
+believe this is necessary if you run the Amanda daemon as System (see below).
Other Preparation
user and group will be important if you are to properly interact with the
security mechanisms of these more modern Microsoft product. For Windows 95/98/
ME this is probably a non-issue. The most privileged account on the Windows
-systems is 'System', and I have chosen to use this account for AMANDA backups
+systems is 'System', and I have chosen to use this account for Amanda backups
to ensure that I can access the widest set of files. On Unix we would run as
root, with equivalent access permissions. I have also chose to run under the
'Administrators' group, another standard Windows group. Ensure these exist
root:*:18:18:,S-1-5-18:/home/root:
- Compile AMANDA
+ Compile Amanda
-After installing Cygwin, unpack the AMANDA sources, typically in /usr/src/
-AMANDA or something similar. In the AMANDA directory, you will need to execute:
+After installing Cygwin, unpack the Amanda sources, typically in /usr/src/
+Amanda or something similar. In the Amanda directory, you will need to execute:
automake # this may not be necessary in the official release
autoconf # this may not be necessary in the official release
* create _/home/root/.amandahosts_ (or whereever System's home directory is):
<amanda server> <amanda user>
-Then create the following AMANDA directories and the file amandates:
+Then create the following Amanda directories and the file amandates:
mkdir -p /usr/local/var/amanda/gnutar-lists
* WINDIR\Services: add
- amanda 10080/udp # AMANDA backup services
- amandaidx 10082/tcp # AMANDA backup services
- amidxtape 10083/tcp # AMANDA backup services
+ amanda 10080/udp # Amanda backup services
+ amandaidx 10082/tcp # Amanda backup services
+ amidxtape 10083/tcp # Amanda backup services
where WINDIR is C:\WINNT\system32\drivers\etc or something similar. The last
following Windows command:
net start/stop inetd
- Notes on AMANDA backup options
+ Notes on Amanda backup options
Compression
pipe emulation in Cygwin. I have not tried to debug this yet. This may be
addressed in a subsequent release, or it could be fixed in later releases of
Cygwin. Due to this issue, we recommend that if you want compressed dumps from
-Windows clients, you configure AMANDA for server compression in amanda.conf on
-your AMANDA server:
+Windows clients, you configure Amanda for server compression in amanda.conf on
+your Amanda server:
define dumptype srv-comp-tar {
global
comment "partitions dumped via tar with server compression"
program "GNUTAR"
compress server fast
- exclude list ".AMANDA.exclude"
+ exclude list ".Amanda.exclude"
}
Debugging Files
-AMANDA will leave debugging files in /tmp/amanda if it exists. I have
+Amanda will leave debugging files in /tmp/amanda if it exists. I have
recommended to create this directory above.
-------------------------------------------------------------------------------
Prev Up Next
-Part III. HOWTOs Home Chapter 13. How to use the AMANDA file-driver
+Part III. HOWTOs Home Chapter 13. How to use the Amanda file-driver
-Chapter 13. How to use the AMANDA file-driver
+Chapter 13. How to use the Amanda file-driver
Prev Part III. HOWTOs Next
-------------------------------------------------------------------------------
-Chapter 13. How to use the AMANDA file-driver
+Chapter 13. How to use the Amanda file-driver
Stefan G. Weichinger
Refer to http://www.amanda.org/docs/howto-filedriver.html for the current
version of this document.
-This document covers the use of the file-driver in AMANDA 2.4.3 and higher.
+This document covers the use of the file-driver in Amanda 2.4.3 and higher.
Examples given here have been taken from a SuSE-Linux-8.2-Pro-environment,
-using AMANDA 2.4.4p1 and the snapshot 2.4.4p1-20031202. Please adjust paths,
+using Amanda 2.4.4p1 and the snapshot 2.4.4p1-20031202. Please adjust paths,
configuration names and other parameters to your system.
Stefan G. Weichinger, November - December, 2003 ; minor updates in April, 2005.
Introduction
-Since release 2.4.3 AMANDA supports the usage of a output driver called "file".
+Since release 2.4.3 Amanda supports the usage of a output driver called "file".
See man amanda, section OUTPUT DRIVERS, for more information on its
implementation. As the name suggests, this driver uses files as virtual (or
file) tapes. Once created and labeled, these file tapes can be selected and
-changed with the standard tape-changer-interface of the AMANDA server.
+changed with the standard tape-changer-interface of the Amanda server.
Possible Uses
* test installations
- You can easily explore the rich features of AMANDA on systems without tape
+ You can easily explore the rich features of Amanda on systems without tape
drives.
* cheap installations
- Without buying a tape drive you can enjoy the benefits of AMANDA and backup
+ Without buying a tape drive you can enjoy the benefits of Amanda and backup
to a bunch of harddisks. You can create CD/DVD-sized backups which you can
burn onto optical disks later.
* disk-based installations
You can use the file-driver to backup onto a set of file tapes hosted on a
- bunch of hard-disks or a RAID-system. Combined with another AMANDA-
+ bunch of hard-disks or a RAID-system. Combined with another Amanda-
configuration that dumps the file tapes to real tapes, you can provide
reliable backup with faster tapeless recovery. This is called "disk-to-disk-
to-tape"-backup by some people today.
Basics
-This guide assumes you have setup the basic AMANDA-services as described in
+This guide assumes you have setup the basic Amanda-services as described in
Amanda_Installation_Notes
The configuration in this HOWTO is called "daily". The file tapes are also
called vtapes in this document, which stands for "virtual tapes".
several file systems and hard disks, I recommend to dedicate at least a
specific partition, better a specific physical harddisk to the task of keeping
your vtapes. The use of a dedicated disk will speed things up definitely.
-The disk space you dedicate for your vtapes should NOT be backed up by AMANDA.
+The disk space you dedicate for your vtapes should NOT be backed up by Amanda.
Also, for performance reasons there should be NO holding disks on the same
partition as the vtapes, preferably not even on the same physical drive.
If you only have one harddisk, it will work out, too, but you will suffer low
(Available Space * 0.9) >= tapelength * tapecycle
This is a very conservative approach to make sure you don´t suffer any
performance drop due to a nearly-full-filesystem.
- As it is uncommon for AMANDA to fill, or almost fill an entire tape you
+ As it is uncommon for Amanda to fill, or almost fill an entire tape you
may also wish to use more space than that.
So you could determine possible combinations of tapelength/tapecycle with
the more general formula:
You don´t have to specify the parameter speed (as it is commonly listed in
- tapetype definitions and reported by the program amtapetype). AMANDA does
+ tapetype definitions and reported by the program amtapetype). Amanda does
not use this parameter right now.
There is also an optional parameter filemark, which indicates the amount
- of space "wasted" after each tape-listitem. Leave it blank and AMANDA uses
+ of space "wasted" after each tape-listitem. Leave it blank and Amanda uses
the default of 1KB.
4. Think about tapechangers.
As you will use a set of vtapes, you have to also use a kind of vtape-
- changer. There are several tape-changer-scripts included in the AMANDA-
- tarball. Read more about tape-changer-scripts in AMANDA_Tape_Changer
+ changer. There are several tape-changer-scripts included in the Amanda-
+ tarball. Read more about tape-changer-scripts in Amanda_Tape_Changer
Support.
Right now there are two scripts that can be used with vtapes. These
scripts take different approaches to the handling of tapes.
chg-multi simulates multiple tape drives with one tape in each drive. chg-
disk simulates one tape-library with multiple tapes in.
As chg-multi exists for a much longer time than chg-disk, it is still used
- in many AMANDA-vtape-installations.
+ in many Amanda-vtape-installations.
chg-disk was introduced with the snapshot 20031202. Contrary to chg-multi,
which is a generic changer-script that must be somewhat adjusted to the
use of the file-driver, chg-disk offers exactly the behavior needed for
handling vtapes
IMHO the approach is much more logical, so I recommend to use chg-disk in
- new AMANDA-vtape-installations.
+ new Amanda-vtape-installations.
Note
This reflects the use of your defined tapetype.
- The parameter tapecycle tells AMANDA how much tapes can be used, Set this
+ The parameter tapecycle tells Amanda how much tapes can be used, Set this
value according to the number of tapes you want to use.
The parameter tapetype , points to the tapetype definition you have
created before.
- The parameter tpchanger tells AMANDA to use the generic tape-changer-
+ The parameter tpchanger tells Amanda to use the generic tape-changer-
script to handle the vtapes. You can think of it as a virtual tape-
changer-device.
The parameter changerfile is used to give chg-disk the "prefix" for the
$ ln -s /amandatapes/daily/slot1 /amandatapes/daily/data
- Make sure the AMANDA-user has write-permissions on these directories:
+ Make sure the Amanda-user has write-permissions on these directories:
$ chown -R amanda_user /amandatapes
$ chgrp -R amanda_group /amandatapes
7. Label the virtual tapes.
- As the virtual tapes are handled just like physical tapes by the AMANDA-
+ As the virtual tapes are handled just like physical tapes by the Amanda-
Server they have to be labeled before use.
Usage: amlabel [-f] <conf> <label> [slot <slot-number>]
amanda.conf. Consult the amlabel-man-page for details.
8. Test your setup with amcheck.
Run amcheck daily (or, more general, amcheck <config>) and look for
- anything AMANDA complains about.
+ anything Amanda complains about.
A proper output looks like:
$ amcheck daily
# /usr/local/amanda/sbin/amrecover woo
AMRECOVER Version 2.4.4p3. Contacting server on backupserver.local ...
- 220 backupserver AMANDA index server (2.4.4p3) ready.
+ 220 backupserver Amanda index server (2.4.4p3) ready.
200 Access OK
Setting restore date to today (2004-10-08)
200 Working date set to 2004-10-08.
200 Good bye.
Nothing spectacular? The trick is this:
-When AMANDA asks you
+When Amanda asks you
Load tape B3_14 now Continue [?/Y/n/s/t]?
-------------------------------------------------------------------------------
Prev Up Next
-Chapter 12. AMANDA on Cygwin HOWTO Home Chapter 14. AFS HOWTO
+Chapter 12. Amanda on Cygwin HOWTO Home Chapter 14. AFS HOWTO
Original text
+Paul Bijnens
+
+Original text
+
Stefan G. Weichinger
XML-conversion; Updates
AMANDA Core Team
<sgw@amanda.org>
+Table of Contents
+
+
+ Bert_de_Ridder's_suggestions
+
+ Paul_Bijnens's_suggestions
+
Note
Note
-The script used in this document is not part of the official AMANDA release.
-The AMANDA core team does not take any responsibility for this script.
+The script used in this document is not part of the official Amanda release.
+The Amanda core team does not take any responsibility for this script.
+
+Bert de Ridder's suggestions
+
This is a mini-howto explaining how to control other running tasks on a server
-where the AMANDA software is used to backup data.
+where the Amanda software is used to backup data.
Problem : Lots of software is picky about their datafiles being backed up while
the files are in use. It sometimes is even necessary to know the state of the
datafiles at the moment of backup so that when restoring you know exactly
# End script
On some systems it may be necessary to setuid root the script.
- 2. Rebuild AMANDA so that it uses your newly created script.
+ 2. Rebuild Amanda so that it uses your newly created script.
Download the sources, untar them to a directory. I'm sure there are lots
of documents already available on how to do this, so I won't go into too
much detail. (Refer to Amanda_Installation_Notes).
Now proceed as with a "normal" installation.
+
+Paul Bijnens's suggestions
+
+How do I run pre- and post dump programs, e.g. database stop/start?
+Currently (Amanda 2.4.5) there is no direct support to run a program before or
+after a backup on a client. But there is an easy workaround by using a wrapper
+for GNU-tar that does the additional tasks.
+Let's suppose you want to stop a database before the backup, and start it up
+again when the backup is finished. You have already two scripts "shutdb" and
+"startdb" to shutdown and startup the database.
+First you have to configure Amanda on the client to use the gnutar-wrapper
+instead of the real GNU-tar:
+
+ ./configure ... --with-gnutar=/usr/local/bin/amgtar ...
+
+and re-compile Amanda. The program "amgtar" can be a simple link to the real
+GNU-tar-binary on clients that don't need special handling, or it can be a
+script.
+Amanda expects that the bytestream on stdout is the backup image, and the
+bytestream on stderr are messages. The stderr messages are filtered against a
+known set of strings, and anything unexpected is flagged as "STRANGE" in the
+Amanda report. The return-codes of the program should be the same as the
+return-codes of GNU-tar:
+
+* 0 = ok (backup image will be put on tape)
+* 1 = not ok (backup image will not be put on tape, same level will be tried
+ next time).
+
+The arguments passed to the program are pretty static (see in the sources
+client-src/sendbackup-gnutar.c, line 483). To decide if you need to stop/start
+the database you have to check if:
+
+* this run makes a backup and not a restore: look for "--create"
+* this it is not an estimate run: look for "--file /dev/null" (estimate) or "--
+ file -" (real run)
+* this run is for the database directory: look for "--directory /my/data/base"
+
+In all other cases, we just pass the args and run the real GNU-tar.
+Here is an example script in Bourne shell:
+Example 15.1.
+
+ #!/bin/sh
+
+ # # uncomment next block to follow the flow
+ # LOG=/tmp/amanda/mytar.debug
+ # date >> $LOG
+ # echo "$@" >> $LOG
+ # if [ "$3" = "/dev/null" ]
+ # then echo "Estimate only" >> $LOG
+ # else echo "Real backup" >> $LOG
+ # fi
+
+ # - Avoid output to stdout! (the backup stream by tar)
+ # - Any output to stderr is flagged as "strange" by amanda
+ # and may be used to pass error messages into the report
+
+ if [ "$1" = "--create" -a "$3" = "-" -a "$5" = "/my/dir" ]
+ then
+ # echo "/my/dir: want to execute some progs first" >>$LOG
+ /usr/local/bin/shutdb thedb >&2
+ /usr/local/bin/gtar "$@"
+ rc=$?
+ # echo "Finished the real backup; some postprocessing" >>$LOG
+ /usr/local/bin/startdb thedb >&2
+ exit $rc
+ else
+ /usr/local/bin/gtar "$@"
+ fi
+
+Here is an example script in perl:
+Example 15.2.
+
+ #!/usr/bin/perl -w
+
+ use Getopt::Long qw(:config pass_through);
+
+ my @saveopts = @ARGV;
+ GetOptions (
+ 'create' => \$create,
+ 'directory=s' => \$dir,
+ 'file=s' => \$file,
+ );
+ @ARGV = @saveopts;
+
+ my $postproc = 0;
+ if ($create && $dir eq '/my/data/base' && $file ne '/dev/null') {
+ system '/usr/local/bin/dbshut thedb >/tmp/amanda/dbshut.debug 2>&1';
+ $postproc = 1;
+ }
+
+ unshift(@ARGV, "/usr/local/bin/gtar");
+ system @ARGV;
+
+ my $rc = $? >> 8;
+
+ if ($postproc) {
+ system '/usr/local/bin/dbstart thedb >/tmp/amanda/dbstart.debug 2>&1';
+ }
+
+ exit $rc;
+
-------------------------------------------------------------------------------
-Prev Up Next
-Chapter 14. AFS HOWTO Home Part IV. Various Information
+Prev Up Next
+Chapter 14. AFS HOWTO Home Chapter 16. How to do Amanda-server-side gpg-
+ encrypted backups.
-------------------------------------------------------------------------------
-HOWTOs
+Part III. HOWTOs
How to do this?
This section contains some HOWTO-style-documents which should help you to get
-AMANDA up and going with Cygwin, AFS or chg-disk ...
+Amanda up and going with Cygwin, AFS or chg-disk ...
Table of Contents
- 12._AMANDA_on_Cygwin_HOWTO
+ 12._Amanda_on_Cygwin_HOWTO
Install_Cygwin
Other_Preparation
- Compile_AMANDA
+ Compile_Amanda
Configure_Cygwin_files
Windows_NT/2000/XP
- Notes_on_AMANDA_backup_options
+ Notes_on_Amanda_backup_options
Compression
- 13._How_to_use_the_AMANDA_file-driver
+ 13._How_to_use_the_Amanda_file-driver
Introduction
15._How_to_use_a_wrapper
+
+ Bert_de_Ridder's_suggestions
+
+ Paul_Bijnens's_suggestions
+
+
+ 16._How_to_do_Amanda-server-side_gpg-encrypted_backups.
+
+
+ Setup
+
+ Test
+
+ Plans
+
+
+ 17._How_to_use_different_auth_with_Amanda
+
+
+ Introduction
+
+ BSD
+
+ BSDTCP
+
+ BSDUDP
+
+ KRB4
+
+ KRB5
+
+ RSH
+
+ SSH
+
+
+ For_amdump:
+
+ For_amrecover:
+
+
+
-------------------------------------------------------------------------------
-Prev Up Next
-Chapter 11. Printing of Labels Home Chapter 12. AMANDA on Cygwin HOWTO
+Prev Next
+Chapter 11. Printing of Labels Home Chapter 12. Amanda on Cygwin HOWTO
Stefan G. Weichinger
-AMANDA Core Team
+Amanda Core Team
-------------------------------------------------------------------------------
Table of Contents
I._Installation
- 1._AMANDA_2.4.x_-_System-Specific_Installation_Notes
+ 1._Amanda_2.5.0_-_System-Specific_Installation_Notes
Solaris_2.6
+ Solaris
+
Trusted_Solaris
SunOS_4.x
Mac_OS_X
- 2._AMANDA_Installation_Notes
+ 2._Amanda_Installation_Notes
Before_doing_anything
- Compiling_the_AMANDA_sources
+ Compiling_the_Amanda_sources
- Setting_up_your_AMANDA_Configuration
+ Setting_up_your_Amanda_Configuration
Setting_up_the_Tape_Server_Host
- 4._Indexing_with_AMANDA
+ 4._Indexing_with_Amanda
Database_Format
7._Tapetypes
- 8._AMANDA_Tape_Changer_Support
+ 8._Amanda_Tape_Changer_Support
Introduction
Notes_about_changer.conf
- AMANDA's_actual_usage_of_chg-scsi
+ Amanda's_actual_usage_of_chg-scsi
Configuration_notes
III._HOWTOs
- 12._AMANDA_on_Cygwin_HOWTO
+ 12._Amanda_on_Cygwin_HOWTO
Install_Cygwin
Other_Preparation
- Compile_AMANDA
+ Compile_Amanda
Configure_Cygwin_files
Windows_NT/2000/XP
- Notes_on_AMANDA_backup_options
+ Notes_on_Amanda_backup_options
Compression
- 13._How_to_use_the_AMANDA_file-driver
+ 13._How_to_use_the_Amanda_file-driver
Introduction
15._How_to_use_a_wrapper
+ Bert_de_Ridder's_suggestions
+
+ Paul_Bijnens's_suggestions
+
+
+ 16._How_to_do_Amanda-server-side_gpg-encrypted_backups.
+
+
+ Setup
+
+ Test
+
+ Plans
+
+
+ 17._How_to_use_different_auth_with_Amanda
+
+
+ Introduction
+
+ BSD
+
+ BSDTCP
+
+ BSDUDP
+
+ KRB4
+
+ KRB5
+
+ RSH
+
+ SSH
+
+
+ For_amdump:
+
+ For_amrecover:
+
+
+
+
IV._Various_Information
- 16._Using_AMANDA
+ 18._Using_Amanda
An_Introduction
- AMANDA_Features
+ Amanda_Features
- Future_Capabilities_of_AMANDA
+ Future_Capabilities_of_Amanda
- AMANDA_Resources
+ Amanda_Resources
- Installing_AMANDA
+ Installing_Amanda
Install_Related_Packages
Perform_Preliminary_Setup
- Configure_the_AMANDA_Build
+ Configure_the_Amanda_Build
- Build_and_Install_AMANDA
+ Build_and_Install_Amanda
- Configuring_AMANDA
+ Configuring_Amanda
Decide_on_a_Tape_Server
Run_amdump
- Read_AMANDA's_Reports
+ Read_Amanda's_Reports
Monitor_Tape_and_Holding_Disk_Status
Miscellanous_Operational_Notes
- Advanced_AMANDA_Configuration
+ Advanced_Amanda_Configuration
Adjust_the_Backup_Cycle
Excluding_Files
- Restoring_with_AMANDA
+ Restoring_with_Amanda
Configuring_and_Using_amrecover
Using_amrestore
- Restoring_Without_AMANDA
+ Restoring_Without_Amanda
- 17._AMANDA_FAQ
+ 19._Amanda_FAQ
- 18._Collection_of_the_top_ten_AMANDA_questions._And_answers.
+ 20._Collection_of_the_top_ten_Amanda_questions._And_answers.
Reason_for_starting_this_list.
...
- 19._AMANDA_WISHLIST
-
- 20._AMANDA_Survey_Results
+ 21._Amanda_WISHLIST
V._Technical_Background
- 21._How_AMANDA_uses_UDP_and_TCP_ports
+ 22._How_Amanda_uses_UDP_and_TCP_ports
TCP_port_allocation
Firewalls_and_NAT
- 22._AMANDA_dumper_API
+ 23._Amanda_dumper_API
Introduction
Conclusion
- 23._AMANDA_Internals
+ 24._Amanda_Internals
Protocols
taper(read)_and_taper(write)
- 24._AMANDA_Event_API
+ 25._Amanda_Event_API
Introduction
event_loop
+ event_wait
+
event_wakeup
- 25._AMANDA_Security_API
+ 26._Amanda_Security_API
Introduction
- 26._Virtual_Tape_API
+ 27._Virtual_Tape_API
- 27._Using_Kerberos_with_AMANDA
+ 28._Using_Kerberos_with_Amanda
- AMANDA_2.5.0_-_KERBEROS_v4_SUPPORT_NOTES
+ Amanda_2.5.0_-_KERBEROS_v4_SUPPORT_NOTES
Configuration
conf_file
- AMANDA_2.5.0_-_KERBEROS_v5_SUPPORT_NOTES
+ Amanda_2.5.0_-_KERBEROS_v5_SUPPORT_NOTES
Building
VI._Historical_files
- 28._Response_to_CPIO_Security_Notice_Issue_11:
+ 29._Response_to_CPIO_Security_Notice_Issue_11:
Affected_Versions
Acknowledgements
- 29._Upgrade_Issues
+ 30._Upgrade_Issues
- 30._What_once_was_new
+ 31._What_once_was_new
- What's_new_in_AMANDA_2.3
+ What's_new_in_Amanda_2.3
Indexing_backups_for_easier_restore
amadmin_import/export
- What's_new_in_AMANDA_2.2
+ What's_new_in_Amanda_2.2
Client_side_setup_has_changed
- 31._Multitape_support_in_AMANDA_2.2
+ 32._Multitape_support_in_Amanda_2.2
Introduction
- 32._Thoughts_about_a_Strategy_API
+ 33._Thoughts_about_a_Strategy_API
- 33._Y2K_Compliancy
+ 34._Y2K_Compliancy
- 34._Usage_of_floppy_tape_drives_on_Linux
+ 35._Usage_of_floppy_tape_drives_on_Linux
VII._Appendixes
- 35._The_AMANDA_Manual_Pages.
+ 36._The_Amanda_Manual_Pages.
+
+
+ amadmin - administrative interface to control Amanda backups
+
+ amaespipe - wrapper program for aespipe
+
+ amanda - Advanced Maryland Automatic Network Disk Archiver
+
+ amanda.conf - Main configuration file for Amanda, the Advanced
+ Maryland Automatic Network Disk Archiver
+
+ amanda-client.conf - Client configuration file for Amanda, the
+ Advanced Maryland Automatic Network Disk Archiver
+
+ amcheck - run Amanda self-checks
+
+ amcheckdb - check Amanda database for tape consistency
+
+ amcleanup - run the Amanda cleanup process after a failure
+
+ amcrypt - reference crypt program for Amanda symmetric data
+ encryption
- 36._Web_Ressources
+ amcrypt-ossl - crypt program for Amanda symmetric data encryption
+ using OpenSSL
+
+ amcrypt-ossl-asym - crypt program for Amanda asymmetric data
+ encryption using OpenSSL
+
+ amdd - Amanda version of dd
+
+ amdump - back up all disks in an Amanda configuration
+
+ amfetchdump - extract backup images from multiple Amanda tapes.
+
+ amflush - flush Amanda backup files from holding disk to tape
+
+ amgetconf - look up amanda.conf variables
+
+ amlabel - label an Amanda tape
+
+ ammt - Amanda version of mt
+
+ amoverview - display file systems processed by Amanda over time
+
+ amplot - visualize the behavior of Amanda
+
+ amrecover - Amanda index database browser
+
+ amreport - generate a formatted output of statistics for an
+ Amanda run
+
+ amrestore - extract backup images from an Amanda tape
+
+ amrmtape - remove a tape from the Amanda database
+
+ amstatus - display the state of an Amanda run
+
+ amtape - user interface to Amanda tape changer controls
+
+ amtapetype - generate a tapetype definition.
+
+ amtoc - generate TOC (Table Of Contents) for an Amanda run
+
+ amverify - check an Amanda tape for errors
+
+ amverifyrun - check the tapes written by the last Amanda run
+
+
+ 37._Web_Ressources
Index
4.1. Protocol_between_amindexd_and_amrecover
- 20.1. Operating_Systems_Running_on_AMANDA_Server_Hosts
-
List of Examples
- 16.1. A_C_Program_to_Check_the_AMANDA_Service_Numbers
+ 2.1. /etc/crontab
+
+ 2.2. /etc/services
+
+ 2.3. /etc/inetd.conf
+
+ 2.4. /etc/xinetd.d/amandaidx
+
+ 2.5. /etc/xinetd.d/amidxtape
+
+ 2.6. /etc/amanda/supervise/amandaidx/run
+
+ 2.7. /etc/amanda/supervise/amidxtape/run
+
+ 2.8. /etc/services
+
+ 2.9. /etc/inetd.conf
+
+ 2.10. /etc/xinetd.d/amanda
+
+ 2.11. /etc/amanda/supervise/amanda/run
+
+ 15.1.
+
+ 15.2.
+
+ 16.1. /usr/local/libexec/amgtar
+
+ 16.2. /usr/local/bin/amaespipe
+
+ 16.3. bz2aespipe.patch
+
+ 18.1. A_C_Program_to_Check_the_Amanda_Service_Numbers
-------------------------------------------------------------------------------
-Chapter 4. Indexing with AMANDA
+Chapter 4. Indexing with Amanda
Prev Part I. Installation Next
-------------------------------------------------------------------------------
-Chapter 4. Indexing with AMANDA
+Chapter 4. Indexing with Amanda
Alan M. McIvor
The client is called amrecover and is loosely based on the functionality of the
program recover from Backup Copilot. A user starts up amrecover. This requires
-specifying the index server and the AMANDA config name (defaults for both are
+specifying the index server and the Amanda config name (defaults for both are
compiled in as part of the installation). Then the user has to specify the name
of the host information is wanted about, the disk name, and (optionally) the
disk mount point. Finally a date needs to be specified. Given all this, the
|HOST_<host>________|set_host_to_host________________________________________|
|DISK_<disk>________|set_disk_to_disk________________________________________|
|LISTDISK_[<device>]|list_the_disks_for_the_current_host_____________________|
-|SCNF_<config>______|set_AMANDA_configuration_to_config______________________|
+|SCNF_<config>______|set_Amanda_configuration_to_config______________________|
|DATE_<date>________|set_date_to_date________________________________________|
|DHST_______________|return_dump_history_of_current_disk_____________________|
| |Opaque is directory? query. Is the directory dir present|
This cause sendbackup-dump on the client machine to generate an index file
which is stored local to the client, for later recovery by amgetidx (which
is called by amdump).
- 3. AMANDA saves all the index files under a directory specified by
+ 3. Amanda saves all the index files under a directory specified by
"indexdir" in amanda.conf. You need to create this directory by hand. It
needs to have read/write permissions set for the user you defined to run
- AMANDA.
+ Amanda.
If you are using the "text database" option you may set indexdir and
infofile to be the same directory.
4. The index browser, amrecover, currently gets installed as part of the
Permissions
-The userid chosen to run the AMANDA client code must have permission to run
+The userid chosen to run the Amanda client code must have permission to run
restore since this is used by createindex-dump to generate the index files.
For a user to be able to restore files from within amrecover, that user must
have permission to run restore.
Changes from amindex-1.0
Get index directory from amanda.conf.
-Integration into AMANDA-2.3.0.4.
+Integration into Amanda-2.3.0.4.
Rewriting of amgetidx to use amandad instead of using rsh/rcp.
Changes from amindex-0.3
-Chapter 2. AMANDA Installation Notes
+Chapter 2. Amanda Installation Notes
Prev Part I. Installation Next
-------------------------------------------------------------------------------
-Chapter 2. AMANDA Installation Notes
+Chapter 2. Amanda Installation Notes
James da Silva
Stefan G. Weichinger
-XML-conversion
+XML-conversion, Updates
AMANDA Core Team
<sgw@amanda.org>
Table of Contents
Before_doing_anything
- Compiling_the_AMANDA_sources
+ Compiling_the_Amanda_sources
- Setting_up_your_AMANDA_Configuration
+ Setting_up_your_Amanda_Configuration
Setting_up_the_Tape_Server_Host
Refer to http://www.amanda.org/docs/install.html for the current version of
this document.
-This document covers the compilation, installation, and runtime setup of AMANDA
+This document covers the compilation, installation, and runtime setup of Amanda
2.4.2 and higher.
Before doing anything
- a. Read this document all the way through.
- b. Consult AMANDA_2.4.x_-_System-Specific_Installation_Notes for installation
- notes specific to particular operating systems. There is often important
- information there, so don't forget this step.
- c. Read Upgrade_Issues if you are upgrading from a previous AMANDA version.
- There are some issues that you will need to be aware of.
- d. If you are using KERBEROS authentication, read Kerberos for details on
- installing and running the kerberized version of AMANDA.
- e. Check the AMANDA Patches Page, http://www.amanda.org/patches
+* Read this document all the way through.
+* Consult Amanda_2.4.x_-_System-Specific_Installation_Notes for installation
+ notes specific to particular operating systems. There is often important
+ information there, so don't forget this step.
+* Read Upgrade_Issues if you are upgrading from a previous Amanda version.
+ There are some issues that you will need to be aware of.
+* If you are using KERBEROS authentication, read Kerberos for details on
+ installing and running the kerberized version of Amanda.
+* Check the Amanda Patches Page, http://www.amanda.org/patches/.
- Compiling the AMANDA sources
+ Compiling the Amanda sources
-If you have multiple architectures, you only need to install the whole AMANDA
+If you have multiple architectures, you only need to install the whole Amanda
package on the tape server host (the one with tape drive). On the backup client
hosts (the ones you are going to dump), you only need to compile some of the
-AMANDA programs (see section 1.2.H below).
+Amanda programs (see section Set_up_the_Backup_Client_Hosts below).
Source configuration
- a. AMANDA can optionally make use of the following packages to back up
- different types of clients or clients with different filesystem dumping
- programs. If you wish to use GNU-tar to back up filesystems, it is
- recommended to use GNU-tar 1.13.25. Plain GNU-tar 1.12 needs to be patched
- to handle large files (> 2GB). Plain GNU-tar 1.13 creates bad index-lists
- which amrecover cannot handle, as does the rarely used GNU-tar 1.13.9x,
- which changed the index-format again in an incompatible way.
- If you need to use GNU-tar 1.12, get it at
- ftp://ftp.gnu.org/pub/gnu/tar/tar-1.12.tar.gz
- and apply the patch from patches/tar-1.12.patch. The first hunk may be
- enough, unless it's a SunOS4 host. Read more about the patches in the
- patch file itself.
- GNU-tar 1.13.25 can be found at:
- ftp://alpha.gnu.org/pub/gnu/tar/tar-1.13.25.tar.gz
- Samba allows Unix systems to talk to PC clients. AMANDA can back up
- Microsoft Windows clients using Samba:
- http://www.samba.org
- Read Backup_PC_hosts_using_Samba for configuration tips and known
- limitations.
- Look at http://www.amanda.org/patches.html for up to date information on
- patches.
- b. If you wish to make use of some of the scripts that come with AMANDA, you
- will need to install Perl. You can get Perl from any CPAN site. ftp://
- ftp.cpan.org/pub/CPAN/src/perl-5.6.1.tar.gz
- c. One of the programs included in this package is amplot, which reads a data
- file that AMANDA generates for each dump and translates that information
- in it into a nice picture that can be used to determine how your
- installation is doing and if any parameters need to be changed. To use
- amplot, you need a version of awk that understands command line variable
- substitutions, such as nawk or gawk, which is available from
- ftp://ftp.gnu.org/pub/gnu/gawk/gawk-3.1.1.tar.gz
- Amplot also required that gnuplot be installed on your system. Gnuplot is
- available at
- http://www.gnuplot.org/ ftp://ftp.gnuplot.org/pub/gnuplot
- d. The process of building AMANDA requires that some other packages be
- installed on your system. The following packages are used:
- ftp://ftp.gnu.org/pub/gnu/readline/readline-4.2.tar.gz amrecover
- optionally uses the readline library for its command-line edition
- mechanisms. This library itself requires either termcap, curses or
- ncurses. termcap is preferred, and it may be obtained from: ftp://
- ftp.gnu.org/pub/gnu/termcap/termcap-1.3.tar.gz
- If you wish to edit and enhance AMANDA, you may need to install the
- following tools. Autoconf and automake are required if you are going to
- rebuild the Makefiles and auto configuration scripts. Bison is only needed
- if you are going to work on the index server and client code.
- ftp://ftp.gnu.org/pub/gnu/autoconf/autoconf-2.53.tar.gz ftp://ftp.gnu.org/
- pub/gnu/automake/automake-1.6.3.tar.gz ftp://ftp.gnu.org/pub/gnu/bison/
- bison-1.27.tar.gz ftp://ftp.gnu.org/pub/gnu/flex/flex-2.5.4a.tar.gz
- e. Read about the different configuration options available for building and
- running AMANDA. To see the options, do both:
-
- a. Run
-
- ./configure --help
-
- to see the available options that configure takes.
- b. Read the example/config.site file which gives longer descriptions to
- the same options as in step a).
-
- f. Choose which user and group you will run the dumps under. Common choices
- for user are `bin' or another user specifically created for AMANDA, such
- as `amanda'; common choices for group are `operator' or `disk'. If you do
- not specify --with-user=<username> and --with-group=<groupname>, configure
- will abort. Also choose the default name for your configuration, such as
- `csd' or `DailySet1'). This name is used by the AMANDA commands to choose
- one of multiple possible configurations. You may specify it using the --
- with-config=<confgname>.
- g. Decide where AMANDA will live. You need to choose a root directory for
- AMANDA. Let this root directory be called $prefix. Unless you change the
- default behavior with the appropriate command line options, AMANDA will
- install itself as. Listed below each directory is the appropriate
- configure option to change the location of this part of AMANDA.
-
- --sbindir=$prefix/sbin AMANDA server side programs
- --libexecdir=$prefix/libexec AMANDA backup client programs
- --libdir=$prefix/lib AMANDA dynamic libraries
- --with-configdir=$prefix/etc/amanda Runtime configuration files
- --with-gnutar-listdir=$prefix/var/amanda/gnutar-lists Directory for
- GNUtar lists (client)
- --mandir=$prefix/man Directory for manual pages
-
- Note that the GNU-tar listdir should be a local filesystem on each client
- that is going to be backed up with GNU tar. If it really must be NFS-
- mounted, make sure the filesystem is exported so that the client has root
- access to it.
- h. Decide if you are compiling AMANDA on a server only or a client only
- platform. If you have a particular operating system that will only be a
- AMANDA client and will never run as the master tape host, then add the --
- without-server option to configure. In the unlikely case that you have a
- particular operating system that will serve as the tape host and you do
- not wish to back up any machines that run this operating system, add the -
- -without-client option to the configure options. There are many other
- configuration switches for amanda. You may learn more about them by
- running `configure --help' and by reading examples/config.site.
- i. Now configure AMANDA. There are two ways of doing this. If you are running
- AMANDA on a single OS, then probably the first method works better for
- you. If you need to support multiple platforms, then the second method
- will work better.
-
- a. Run configure as non-root-user with the appropriate command line
- options. You will probably want to remember the command line options
- for future builds of AMANDA.
- b. Edit example/config.site and install it in the directory $prefix/etc
- or $prefix/share. When `configure' runs the next time it will look
- for this file and use it to configure AMANDA.
+* Amanda can optionally make use of the following packages to back up different
+ types of clients or clients with different filesystem dumping programs.
+
+ o GNU-tar:
+ If you wish to use GNU-tar to back up filesystems, it is recommended to use
+ GNU-tar 1.13.25. Plain GNU-tar 1.12 needs to be patched to handle large
+ files (> 2GB). Plain GNU-tar 1.13 creates bad index-lists which amrecover
+ cannot handle, as does the rarely used GNU-tar 1.13.9x, which changed the
+ index-format again in an incompatible way.
+ Refer to the Amanda_FAQ for more information about issues with the various
+ releases of GNU-tar.
+ If you need to use GNU-tar 1.12, get it at
+ ftp://ftp.gnu.org/pub/gnu/tar/tar-1.12.tar.gz
+ and apply the patch from patches/tar-1.12.patch. The first hunk may be
+ enough, unless it's a SunOS4 host. Read more about the patches in the patch
+ file itself.
+ GNU-tar 1.13.25 can be found at:
+ ftp://alpha.gnu.org/pub/gnu/tar/tar-1.13.25.tar.gz
+ o Samba:
+ Samba allows Unix systems to talk to PC clients. Amanda can back up
+ Microsoft Windows clients using Samba:
+ http://www.samba.org
+ Read Backup_PC_hosts_using_Samba for configuration tips and known
+ limitations.
+ Look at http://www.amanda.org/patches/ for up to date information on
+ patches.
+ o Perl:
+ If you wish to make use of some of the scripts that come with Amanda, you
+ will need to install Perl. You can get Perl from any CPAN site.
+ ftp://ftp.cpan.org/pub/CPAN/src/perl-5.6.1.tar.gz
+ o Awk:
+ One of the programs included in this package is amplot, which reads a data
+ file that Amanda generates for each dump and translates that information in
+ it into a nice picture that can be used to determine how your installation
+ is doing and if any parameters need to be changed. To use amplot, you need
+ a version of awk that understands command line variable substitutions, such
+ as nawk or gawk, which is available from
+ ftp://ftp.gnu.org/pub/gnu/gawk/gawk-3.1.1.tar.gz
+ o GNUplot:
+ Amplot also required that gnuplot be installed on your system. Gnuplot is
+ available at
+ http://www.gnuplot.org/ ftp://ftp.gnuplot.org/pub/gnuplot
+ o Other packages:
+ The process of building Amanda requires that some other packages be
+ installed on your system. The following packages are used:
+ ftp://ftp.gnu.org/pub/gnu/readline/readline-5.0.tar.gz
+ amrecover optionally uses the readline library for its command-line edition
+ mechanisms. (If you use a package-based distribution, check for the package
+ readline-devel-X.Y.rpm.) This library itself requires either termcap,
+ curses or ncurses. termcap is preferred, and it may be obtained from:
+ ftp://ftp.gnu.org/pub/gnu/termcap/termcap-1.3.1.tar.gz.
+ If you wish to edit and enhance Amanda, you may need to install the
+ following tools. Autoconf and automake are required if you are going to
+ rebuild the Makefiles and auto configuration scripts. Bison is only needed
+ if you are going to work on the index server and client code.
+ ftp://ftp.gnu.org/pub/gnu/autoconf/autoconf-2.53.tar.gz ftp://ftp.gnu.org/
+ pub/gnu/automake/automake-1.6.3.tar.gz ftp://ftp.gnu.org/pub/gnu/bison/
+ bison-1.27.tar.gz ftp://ftp.gnu.org/pub/gnu/flex/flex-2.5.4a.tar.gz
+
+* Read about the different configuration options available for building and
+ running Amanda. To see the options, do both:
+
+ o Run ./configure --help to see the available options that configure takes.
+ o Read the file example/config.site which gives longer descriptions to the
+ same options.
+
+* Choose which user and group you will run the dumps under. Common choices for
+ user are `bin' or another user specifically created for Amanda, such as
+ `amanda'; common choices for group are `operator' or `disk'. If you do not
+ specify --with-user=<username> and --with-group=<groupname>, configure will
+ abort. Also choose the default name for your configuration, such as `csd' or
+ `DailySet1'). This name is used by the Amanda commands to choose one of
+ multiple possible configurations. You may specify it using the --with-
+ config=<confgname>.
+* Decide where Amanda will live. You need to choose a root directory for
+ Amanda. Let this root directory be called $prefix. Unless you change the
+ default behavior with the appropriate command line options, Amanda will
+ install itself as. Listed below you find the appropriate configure-option for
+ each directory to change the location of this part of Amanda.
+
+ --sbindir=$prefix/sbin Amanda server side programs
+ --libexecdir=$prefix/libexec Amanda backup client programs
+ --libdir=$prefix/lib Amanda dynamic libraries
+ --with-configdir=$prefix/etc/amanda Runtime configuration files
+ --with-gnutar-listdir=$prefix/var/amanda/gnutar-lists Directory for GNU-tar
+ lists (client)
+ --mandir=$prefix/man Directory for manual pages
+
+ Note that the GNU-tar listdir should be a local filesystem on each client
+ that is going to be backed up with GNU-tar. If it really must be NFS-mounted,
+ make sure the filesystem is exported so that the client has root access to
+ it.
+* Decide if you are compiling Amanda on a server only or a client only
+ platform. If you have a particular operating system that will only be a
+ Amanda client and will never run as the master tape host, then add the --
+ without-server option to configure. In the unlikely case that you have a
+ particular operating system that will serve as the tape host and you do not
+ wish to back up any machines that run this operating system, add the --
+ without-client option to the configure options. There are many other
+ configuration switches for Amanda. You may learn more about them by running
+ configure --help and by reading examples/config.site.
+* Now configure Amanda. There are two ways of doing this. If you are running
+ Amanda on a single OS, then probably the first method works better for you.
+ If you need to support multiple platforms, then the second method will work
+ better.
+
+ o Run configure as non-root-user with the appropriate command line options.
+ You will probably want to remember the command line options for future
+ builds of Amanda.
+ o Edit examples/config.site and install it in the directory $prefix/etc or
+ $prefix/share. When configure runs the next time it will look for this file
+ and use it to configure Amanda.
Building and installing the binaries
- a. Back at the top-level source directory, build the sources:
+* Back at the top-level source directory, build the sources:
- make
- su root; make install
+ make
+ su root; make install
- Make sure that you don't build the software as root, you may run the first
- make-command as the AMANDA-user, for example. On the other hand you have
- to run make install as root to get the binaries installed with the proper
- permissions. If you want to change the compiler flags, you can do so like
- this:
+ Make sure that you don't build the software as root, you may run the first
+ make-command as the Amanda-user, for example. On the other hand you have to
+ run make install as root to get the binaries installed with the proper
+ permissions. If you want to change the compiler flags, you can do so like
+ this:
- make CFLAGS="-O3 -Wall"
+ make CFLAGS="-O3 -Wall"
- b. If you have built with USE_VERSION_SUFFIXES, you will want to create
- symlinks to the version you wish to use, eg:
+* If you have built with USE_VERSION_SUFFIXES, you will want to create symlinks
+ to the version you wish to use, eg: ln -s amdump-x.y.z amdump This is not
+ done automatically by the install process, so that you can have multiple
+ Amanda versions co-existing, and choose yourself which to make the default
+ version. The script contrib/set_prod_link.pl may save you some keystrokes.
+* Run ldconfig as root to update the paths to the recently installed shared
+ libraries.
- ln -s amdump-x.y.z amdump
- This is not done automatically by the install process, so that you can
- have multiple AMANDA versions co-existing, and choose yourself which to
- make the default version. The script contrib/set_prod_link.pl may save you
- some keystrokes.
- c. Run `ldconfig' as root to update the paths to the recently installed
- shared libraries.
-
-
- Setting up your AMANDA Configuration
+ Setting up your Amanda Configuration
Setting up the Tape Server Host
- a. Create the config directory (eg. /usr/local/etc/amanda/confname) and copy
- the example/ files into that directory. Edit these files to be correct for
- your site, consulting the amanda(8) man page if necessary. You can also
- send mail to mailto://amanda-users@amanda.org if you are having trouble
- deciding how to set things up. You will also need to create the directory
- for the log and database files for the configuration to use (eg /usr/
- local/var/amanda/confname), and the work directory on the holding disk.
- These directories need to agree with the parameters in amanda.conf. Don't
- forget to make all these directories writable by the dump user!
- Make sure that you specify the *no-rewind* version of the tape device in
- your amanda.conf file. This is a frequently encountered problem for new
- sites.
- Note that you might want to temporarily set the option "no-record" in all
- your dumptypes when first installing AMANDA if you'd like to run tests of
- AMANDA in parallel with your existing dump scheme. AMANDA will then run
- but will not interfere with your current dumpdates. However, you don't
- want to run with "no-record" under normal operations.
- b. Put AMANDA into your crontab. Here's a sample:
-
- 0 16 * * 1-5 /usr/local/sbin/amcheck -m confname
- 45 0 * * 2-6 /usr/local/sbin/amdump confname
-
- This is for SunOS 4.x, which has a per-user crontab; most other systems
- also require a userid on each cron line. See your cron(8) for details.
- With these cron lines, AMANDA will check that the correct tape is in the
- drive every weekday afternoon at 4pm (if it isn't, all the operators will
- get mail). At 12:45am that night the dumps will be run.
- c. Put the AMANDA services into your /etc/services file. Add entries like:
-
- amanda 10080/udp
- amandaidx 10082/tcp
- amidxtape 10083/tcp
-
- You may choose a different port number if you like, but it must match that
- in the services file on the client hosts too.
- If you are running NIS (aka YP), you have to enter the AMANDA service into
- your NIS services database. Consult your NIS documentation for details.
- You may use the `patch-system' script, from client-src, in order to modify
- this file. Run it with a `-h' argument for usage.
- d. If you are going to use the indexing capabilities of AMANDA, and your
- server uses inetd, then add these to your inetd.conf on the tape server
- host:
-
- amandaidx stream tcp nowait USER AMINDEXD_PATH amindexd
- amidxtape stream tcp nowait USER AMIDXTAPED_PATH amidxtaped
-
- where AMINDEXD_PATH and AMIDXTAPED_PATH are the complete paths to where
- the amindexd and amidxtaped executables (usually libexec_dir/amindexd and
- libexec_dir/amidxtaped), and USER is the AMANDA user.
- You may use the `patch-system' script, from client-src, in order to modify
- this file. Run it with a `-h' argument for usage.
- If your tape server uses xinetd instead of inetd, then you have to add the
- following two files to your xinetd-configuration (usually /etc/xinetd.d)
- and edit the paths:
-
- #/etc/xinetd.d/amandaidx
- service amandaidx
- {
- socket_type = stream
- protocol = tcp
- wait = no
- user = USER
- group = GROUP
- groups = yes
- server = AMINDEXD_PATH/amindexd
- }
-
-
- #/etc/xinetd.d/amidxtaped
- service amidxtape
- {
- socket_type = stream
- protocol = tcp
- wait = no
- user = USER
- group = GROUP
- groups = yes
- server = AMIDXTAPED_PATH/amidxtaped
- }
-
- e. If the tape server host is itself going to be backed up (as is usually the
- case), you must also follow the client-side install instructions below on
- the server host, INCLUDING setting up the file .amandahosts so that the
- server host lets itself in. This is a frequently encountered problem for
- new sites.
+* Create the config directory (eg. /usr/local/etc/amanda/confname) and copy the
+ example/ files into that directory. Edit these files to be correct for your
+ site, consulting the amanda(8) man page if necessary. You can also send mail
+ to mailto://amanda-users@amanda.org if you are having trouble deciding how to
+ set things up. You will also need to create the directory for the log and
+ database files for the configuration to use (eg /usr/local/var/amanda/
+ confname), and the work directory on the holding disk. These directories need
+ to agree with the parameters in amanda.conf. Don't forget to make all these
+ directories writable by the dump user!
+ Make sure that you specify the *no-rewind* version of the tape device in your
+ amanda.conf file. This is a frequently encountered problem for new sites.
+ Note that you might want to temporarily set the option "no-record" in all
+ your dumptypes when first installing Amanda if you'd like to run tests of
+ Amanda in parallel with your existing dump scheme. Amanda will then run but
+ will not interfere with your current dumpdates. However, you don't want to
+ run with "no-record" under normal operations.
+* Put Amanda into your crontab. Here's a sample:
+ Example 2.1. /etc/crontab
+
+ 0 16 * * 1-5 /usr/local/sbin/amcheck -m confname
+ 45 0 * * 2-6 /usr/local/sbin/amdump confname
+
+ This is for SunOS 4.x, which has a per-user crontab; most other systems also
+ require a userid on each cron line. See your cron(8) for details. With these
+ cron lines, Amanda will check that the correct tape is in the drive every
+ weekday afternoon at 4pm (if it isn't, all the operators will get mail). At
+ 12:45am that night the dumps will be run.
+* Put the Amanda services into your /etc/services file. Add entries like:
+ Example 2.2. /etc/services
+
+ amanda 10080/udp
+ amandaidx 10082/tcp
+ amidxtape 10083/tcp
+
+ You may choose a different port number if you like, but it must match that in
+ the services file on the client hosts too.
+ If you are running NIS (aka YP), you have to enter the Amanda service into
+ your NIS services database. Consult your NIS documentation for details.
+ You may use the `patch-system' script, from client-src, in order to modify
+ this file. Run it with a `-h' argument for usage.
+* If you are going to use the indexing capabilities of Amanda, follow one of
+ the following steps:
+
+ o If your server uses inetd, then add these lines to your inetd.conf on the
+ tape server host:
+ Example 2.3. /etc/inetd.conf
+
+ amandaidx stream tcp nowait $USER $AMINDEXD_PATH amindexd
+ amidxtape stream tcp nowait $USER $AMIDXTAPED_PATH amidxtaped
+
+ where $AMINDEXD_PATH and $AMIDXTAPED_PATH are the complete paths to where
+ the amindexd and amidxtaped executables (usually libexec_dir/amindexd and
+ libexec_dir/amidxtaped), and USER is the Amanda user.
+ You may use the `patch-system' script, from client-src, in order to modify
+ this file. Run it with a `-h' argument for usage.
+ o If your tape server uses xinetd instead of inetd, then you have to add the
+ following two files to your xinetd-configuration (usually /etc/xinetd.d)
+ and edit the paths:
+ Example 2.4. /etc/xinetd.d/amandaidx
+
+ service amandaidx
+ {
+ socket_type = stream
+ protocol = tcp
+ wait = no
+ user = $USER
+ group = $GROUP
+ groups = yes
+ server = $AMINDEXD_PATH/amindexd }
+
+ Example 2.5. /etc/xinetd.d/amidxtape
+
+ service amidxtape
+ {
+ socket_type = stream
+ protocol = tcp
+ wait = no
+ user = $USER
+ group = $GROUP
+ groups = yes
+ server = $AMIDXTAPED_PATH/amidxtaped }
+
+ o If your tape server uses Dan Bernstein's daemontools http://cr.yp.to/
+ daemontools.html) instead of (x)inetd, you have to create amandaidx and
+ amidxtape services by hand.
+
+ # Create service directories:
+
+ mkdir -p $prefix/etc/amanda/supervise/amandaidx
+ mkdir -p $prefix/etc/amanda/supervise/amidxtape
+
+ # Create service startup files and make them executable:
+ Example 2.6. /etc/amanda/supervise/amandaidx/run
+
+ #!/bin/sh
+ exec /usr/local/bin/setuidgid amanda \
+ /usr/local/bin/tcpserver -DHRl0 0 10082 \
+ /usr/local/libexec/amindexd >/dev/null 2>/dev/null
+
+ Example 2.7. /etc/amanda/supervise/amidxtape/run
+
+ #!/bin/sh
+ exec /usr/local/bin/setuidgid amanda \
+ /usr/local/bin/tcpserver -DHRl0 0 10083 \
+ /usr/local/libexec/amidxtaped >/dev/null 2>/dev/null
+
+ # Link service directories into your svscan directory:
+
+ cd /service
+ ln -s $prefix/etc/amanda/supervise/amandaidx .
+ ln -s $prefix/etc/amanda/supervise/amidxtape .
+
+
+
+* If the tape server host is itself going to be backed up (as is usually the
+ case), you must also follow the client-side install instructions below on the
+ server host, INCLUDING setting up the file .amandahosts so that the server
+ host lets itself in. This is a frequently encountered problem for new sites.
Set up the Backup Client Hosts
- a. When using BSD-style security (enabled by default), set up your
- ~dumpuser/.amandahosts (or ~dumpuser/.rhosts and/or /etc/hosts.equivi, if
- you have configured --without-amandahosts) so that the dumpuser is allowed
- in from the server host. Only canonical host names will be accepted in
- .amandahosts, and usernames must be present in every line, because this is
- safer.
- b. Set up your raw disk devices so that the dumpuser can read them, and /etc/
- dumpdates so that the dumpuser can write to it. Normally this is done by
- making the disk devices readable by (and dumpdates read/writable by) group
- `operator', and putting the dumpuser into that group.
- c. Put the AMANDA service into your /etc/services file. Add entry like:
-
- amanda 10080/udp
- amandaidx 10082/tcp
- amidxtape 10083/tcp
-
- You may choose a different port number if you like, but it must match that
- in the services file on the tape server host too.
- If you are running NIS (aka YP), you have to enter the AMANDA service into
- your NIS services database. Consult your NIS documentation for details.
- You may use the `patch-system' script, from client-src, in order to modify
- this file. Run it with a `-h' argument for usage.
- d. If your AMANDA client uses inetd, put the AMANDA client service into
- inetd's config file. This file is usually found in /etc/inetd.conf, but on
- older systems it is /etc/servers. The format is different on different
- OSes, so you must consult the inetd man page for your site. Here is an
- example from our site, again from SunOS 4.x:
-
- amanda dgram udp wait USER AMANDAD_PATH amandad
-
- You may use the `patch-system' script, from client-src, in order to modify
- this file. Run it with a `-h' argument for usage.
- If your AMANDA client uses xinetd, you have to add the following file to
- your xinetd-configuration (usually /etc/xinetd.d):
-
- #/etc/xinetd.d/amanda
- service amanda
- {
- socket_type = dgram
- protocol = udp
- wait = yes
- user = USER
- group = GROUP
- groups = yes
- server = AMANDAD_PATH/amandad
- }
-
- e. Kick inetd/xinetd to make it read its config file. On most systems you can
- just execute kill -HUP inetd (or xinetd). On older systems you may have to
- kill it completely and restart it. Note that killing/restarting (x)inetd
- is not safe to do unless you are sure that no (x)inetd services (like
- rlogin) are currently in use, otherwise (x)inetd will not be able to bind
- that port and that service will be unavailable.
- f. If you intend to back up xfs filesystems on hosts running IRIX, you must
- create the directory /var/xfsdump/inventory, otherwise xfsdump will not
- work.
+* When using BSD-style security (enabled by default), set up your
+ ~dumpuser/.amandahosts (or ~dumpuser/.rhosts and/or /etc/hosts.equiv, if you
+ have configured --without-amandahosts) so that the dumpuser is allowed in
+ from the server host. Only canonical host names will be accepted in
+ .amandahosts, and usernames must be present in every line, because this is
+ safer.
+* Set up your raw disk devices so that the dumpuser can read them, and /etc/
+ dumpdates so that the dumpuser can write to it. Normally this is done by
+ making the disk devices readable by (and dumpdates read/writable by) group
+ `operator', and putting the dumpuser into that group.
+* Put the Amanda service into your /etc/services file. Add entry like:
+ Example 2.8. /etc/services
+
+ amanda 10080/udp
+ amandaidx 10082/tcp
+ amidxtape 10083/tcp
+
+ You may choose a different port number if you like, but it must match that in
+ the services file on the tape server host too.
+ If you are running NIS (aka YP), you have to enter the Amanda service into
+ your NIS services database. Consult your NIS documentation for details.
+ You may use the `patch-system' script, from client-src, in order to modify
+ this file. Run it with a `-h' argument for usage.
+* Follow one of the following steps to set up the Amanda client service:
+
+ o If your Amanda client uses inetd, put the Amanda client service into
+ inetd's config file. This file is usually found in /etc/inetd.conf, but on
+ older systems it is /etc/servers. The format is different on different
+ OSes, so you must consult the inetd man page for your site. Here is an
+ example from our site, again from SunOS 4.x:
+ Example 2.9. /etc/inetd.conf
+
+ amanda dgram udp wait USER AMANDAD_PATH amandad
+
+ You may use the `patch-system' script, from client-src, in order to modify
+ this file. Run it with a `-h' argument for usage.
+ o If your Amanda client uses xinetd, you have to add the following file to
+ your xinetd-configuration (usually /etc/xinetd.d) and edit it to reflect
+ your settings and paths:
+ Example 2.10. /etc/xinetd.d/amanda
+
+ service amanda
+ {
+ socket_type = dgram
+ protocol = udp
+ wait = yes
+ user = $USER
+ group = $GROUP
+ groups = yes
+ server = $AMANDAD_PATH/amandad
+ }
+
+ o If your Amanda client uses Dan Bernstein's daemontools (http://cr.yp.to/
+ daemontools.html) instead of (x)inetd, you have to create the amanda
+ service by hand. You will need also an UDP super-server (netcat in this
+ example).
+
+ # Create service directory:
+
+ mkdir -p /etc/amanda/supervise/amanda
+
+ # Create service startup file and make it executable:
+ Example 2.11. /etc/amanda/supervise/amanda/run
+
+ #!/bin/sh
+ exec /usr/local/bin/setuidgid amanda \
+ /usr/bin/netcat -l -u -p 10080 -q 0 \
+ -e /usr/local/libexec/amandad >/dev/null 2>/dev/null
+
+
+ Note
+
+ The netcat-binary used in this run-file might also be called /usr/bin/nc
+ on your system, depending on the OS-distribution you use. Refer to http:/
+ /netcat.sourceforge.net for details of netcat.
+ # Link service directory into your svscan directory:
+
+ cd /service
+ ln -s /etc/amanda/supervise/amanda .
+
+
+
+* If you are using (x)inetd, kick inetd/xinetd to make it read its config file.
+ On most systems you can just execute kill -HUP inetd (or xinetd). On older
+ systems you may have to kill it completely and restart it. Note that killing/
+ restarting (x)inetd is not safe to do unless you are sure that no (x)inetd
+ services (like rlogin) are currently in use, otherwise (x)inetd will not be
+ able to bind that port and that service will be unavailable.
+ If you are using the daemontools, svscan should detect and start your new
+ services automatically.
+* If you intend to back up xfs filesystems on hosts running IRIX, you must
+ create the directory /var/xfsdump/inventory, otherwise xfsdump will not work.
THAT'S IT! YOU ARE READY TO RUN, UNLESS WE FORGOT SOMETHING.
Please send mail to mailto://amanda-users@amanda.org if you have any comments
or questions. We're not afraid of negative reviews, so let us have it!
-Before writing questions, you may prefer to take a look at the AMANDA_FAQ and
-at the AMANDA home page, at http://www.amanda.org. Browsable archives of AMANDA
+Before writing questions, you may prefer to take a look at the Amanda_FAQ and
+at the Amanda home page, at http://www.amanda.org. Browsable archives of Amanda
mailing-lists are available at http://marc.theaimsgroup.com/?l=amanda-users and
http://marc.theaimsgroup.com/?l=amanda-hackers.
-------------------------------------------------------------------------------
Prev Up Next
-Chapter 1. AMANDA 2.4.x - System-Specific Home Chapter 3. Excluding
+Chapter 1. Amanda 2.5.0 - System-Specific Home Chapter 3. Excluding
Installation Notes
- Chapter 23. AMANDA Internals
+ Chapter 24. Amanda Internals
Prev Part V. Technical Background Next
-------------------------------------------------------------------------------
-Chapter 23. AMANDA Internals
+Chapter 24. Amanda Internals
George Scott
Refer to http://www.amanda.org/docs/internals.html for the current version of
this document.
-This is an attempt to document AMANDA's internals. Please feel free to make
+This is an attempt to document Amanda's internals. Please feel free to make
comments and suggest changes. Text for new sections gratefully accepted!
Protocols
The following was an ASCII-illustration in the original docs, I managed to
transfer it at last. Maybe someone will convert this to the first image in the
-AMANDA-docs ;-) . sgw.
+Amanda-docs ;-) . sgw.
Client I Server +-planner-+
-------------------------------------------------------------------------------
Prev Up Next
-Chapter 22. AMANDA dumper API Home Chapter 24. AMANDA Event API
+Chapter 23. Amanda dumper API Home Chapter 25. Amanda Event API
-------------------------------------------------------------------------------
-Installation
+Part I. Installation
Initial Installation
-This section of the AMANDA-docs contains general info on how to install AMANDA
+This section of the Amanda-docs contains general info on how to install Amanda
and how to configure its basic parts. Please read this!
Table of Contents
- 1._AMANDA_2.4.x_-_System-Specific_Installation_Notes
+ 1._Amanda_2.5.0_-_System-Specific_Installation_Notes
Solaris_2.6
+ Solaris
+
Trusted_Solaris
SunOS_4.x
Mac_OS_X
- 2._AMANDA_Installation_Notes
+ 2._Amanda_Installation_Notes
Before_doing_anything
- Compiling_the_AMANDA_sources
+ Compiling_the_Amanda_sources
- Setting_up_your_AMANDA_Configuration
+ Setting_up_your_Amanda_Configuration
Setting_up_the_Tape_Server_Host
- 4._Indexing_with_AMANDA
+ 4._Indexing_with_Amanda
Database_Format
-------------------------------------------------------------------------------
-Prev Up Next
-Attributions Home Chapter 1. AMANDA 2.4.x - System-Specific Installation
+Prev Next
+Attributions Home Chapter 1. Amanda 2.5.0 - System-Specific Installation
Notes
autoflush, the_multiple-dumps-question
-B
-
-
-
- bumping, AMANDA_FAQ
-
-
C
-------------------------------------------------------------------------------
-Prev Up
-Chapter 36. Web Ressources Home
+Prev
+Chapter 37. Web Ressources Home
- Chapter 27. Using Kerberos with AMANDA
+ Chapter 28. Using Kerberos with Amanda
Prev Part V. Technical Background Next
-------------------------------------------------------------------------------
-Chapter 27. Using Kerberos with AMANDA
+Chapter 28. Using Kerberos with Amanda
-AMANDA Core Team
+Amanda Core Team
Original text
AMANDA Core Team
Table of Contents
- AMANDA_2.5.0_-_KERBEROS_v4_SUPPORT_NOTES
+ Amanda_2.5.0_-_KERBEROS_v4_SUPPORT_NOTES
Configuration
conf_file
- AMANDA_2.5.0_-_KERBEROS_v5_SUPPORT_NOTES
+ Amanda_2.5.0_-_KERBEROS_v5_SUPPORT_NOTES
Building
Refer to http://www.amanda.org/docs/kerberos.html for the current version of
this document.
- AMANDA 2.5.0 - KERBEROS v4 SUPPORT NOTES
+ Amanda 2.5.0 - KERBEROS v4 SUPPORT NOTES
Configuration
Installation
-The kerberized AMANDA service uses a different port on the client hosts. The /
+The kerberized Amanda service uses a different port on the client hosts. The /
etc/services line is:
kamanda 10081/udp
auth=krb4
-Note that you're running this as root, rather than as your dump user. AMANDA
+Note that you're running this as root, rather than as your dump user. Amanda
will set it's uid down to the dump user at times it doesn't need to read the
srvtab file, and give up root permissions entirely before it goes off and runs
dump. Alternately you can change your srvtab files to be readable by user
- AMANDA 2.5.0 - KERBEROS v5 SUPPORT NOTES
+ Amanda 2.5.0 - KERBEROS v5 SUPPORT NOTES
Building
/*
* The lifetime of our tickets in minutes.
*/
- #define AMANDA_TKT_LIFETIME (12*60)
+ #define Amanda_TKT_LIFETIME (12*60)
/*
* The name of the service in /etc/services.
*/
- #define AMANDA_KRB5_SERVICE_NAME "k5amanda"
+ #define Amanda_KRB5_SERVICE_NAME "k5amanda"
You can currently only override these by editing the source.
Installation
-The kerberized AMANDA service uses a different port on the client hosts. The /
+The kerberized Amanda service uses a different port on the client hosts. The /
etc/services line is:
k5amanda 10082/tcp
auth=krb5
-Note that you're running this as root, rather than as your dump user. AMANDA
+Note that you're running this as root, rather than as your dump user. Amanda
will set it's uid down to the dump user at times it doesn't need to read the
keytab file, and give up root permissions entirely before it goes off and runs
dump. Alternately you can change your keytab files to be readable by user
There are several ways to go about authorizing a server to connect to a client.
The normal way is via a .k5amandausers file or a .k5login file in the client
user's home directory. The determination of which file to use is based on the
-way you ran configure on AMANDA. By default, AMANDA will use .k5amandahosts,
-but if you configured with --without-amandahosts, AMANDA will use .k5login.
+way you ran configure on Amanda. By default, Amanda will use .k5amandahosts,
+but if you configured with --without-amandahosts, Amanda will use .k5login.
(similar to the default for .rhosts/.amandahosts-style security). The .k5login
file syntax is a superset of the default krb5 .k5login. The routines to check
it are implemented in amanda rather than using krb5_kuserok because the
-------------------------------------------------------------------------------
Prev Up Next
-Chapter 26. Virtual Tape API Home Part VI. Historical files
+Chapter 27. Virtual Tape API Home Part VI. Historical files
The New Feature
-AMANDA now has the ability to print postscript paper tape labels. The labels
+Amanda now has the ability to print postscript paper tape labels. The labels
have what machines, partitions, and the level of the dump the tape has on it.
This is achieved by adding the lbl-templ field to the tapetype definition.
Since the labels are specific to the type of tape you have, that seemed to most
logical place to add it.
You can also specify an alternate "printer" definition to print the label to
other than the system default printer.
-If you don't add this line to your tapetype definition, AMANDA works as it
+If you don't add this line to your tapetype definition, Amanda works as it
always has.
Labels provided
At the University of Colorado at Boulder, we used to use some dump scripts that
printed out paper tape labels that went with the tape. When we started using
-AMANDA for our dumps, my boss insisted we still generate them, in case we
-weren't able to access the AMANDA database. The thought was that as long as we
+Amanda for our dumps, my boss insisted we still generate them, in case we
+weren't able to access the Amanda database. The thought was that as long as we
had an amrestore binary on a machine, we could just look at the label, grab the
tapes, and do the restore.
As a result of this we have had to hack this feature into every version of
-AMANDA from 2.1.1 through 2.4.0-prerelease.
+Amanda from 2.1.1 through 2.4.0-prerelease.
Our hope in adding this feature is that others find it as useful as we have.
How it works
- Chapter 36. Web Ressources
+ Chapter 37. Web Ressources
Prev Part VII. Appendixes Next
-------------------------------------------------------------------------------
-Chapter 36. Web Ressources
+Chapter 37. Web Ressources
Stefan G. Weichinger
Refer to http://www.amanda.org/docs/links.html for the current version of this
document.
-See some original AMANDA-papers by James da Silva and Olafur Gundmundsson here:
+See some original Amanda-papers by James da Silva and Olafur Gundmundsson here:
-* The presentation of AMANDA:
+* The presentation of Amanda:
Postscript: http://www.amanda.org/docs/lisa-vii.ps
PDF: http://www.amanda.org/docs/lisa-vii.pdf
-* A document about the performance of AMANDA:
+* A document about the performance of Amanda:
Postscript: http://www.amanda.org/docs/usenix92.ps
PDF: http://www.amanda.org/docs/usenix92.pdf
-Chapter 35. The AMANDA Manual Pages.
+Chapter 36. The Amanda Manual Pages.
Prev Part VII. Appendixes Next
-------------------------------------------------------------------------------
-Chapter 35. The AMANDA Manual Pages.
+Chapter 36. The Amanda Manual Pages.
Table of Contents
- amadmin - administrative interface to control AMANDA backups
+ amadmin - administrative interface to control Amanda backups
+
+ amaespipe - wrapper program for aespipe
amanda - Advanced Maryland Automatic Network Disk Archiver
- amanda.conf - Main configuration file for AMANDA, the Advanced Maryland
+ amanda.conf - Main configuration file for Amanda, the Advanced Maryland
Automatic Network Disk Archiver
- amcheck - run AMANDA self-checks
+ amanda-client.conf - Client configuration file for Amanda, the Advanced
+ Maryland Automatic Network Disk Archiver
+
+ amcheck - run Amanda self-checks
+
+ amcheckdb - check Amanda database for tape consistency
+
+ amcleanup - run the Amanda cleanup process after a failure
+
+ amcrypt - reference crypt program for Amanda symmetric data encryption
+
+ amcrypt-ossl - crypt program for Amanda symmetric data encryption using
+ OpenSSL
- amcheckdb - check AMANDA database for tape consistency
+ amcrypt-ossl-asym - crypt program for Amanda asymmetric data encryption using
+ OpenSSL
- amcleanup - run the AMANDA cleanup process after a failure
+ amdd - Amanda version of dd
- amdd - AMANDA version of dd
+ amdump - back up all disks in an Amanda configuration
- amdump - back up all disks in an AMANDA configuration
+ amfetchdump - extract backup images from multiple Amanda tapes.
- amflush - flush AMANDA backup files from holding disk to tape
+ amflush - flush Amanda backup files from holding disk to tape
amgetconf - look up amanda.conf variables
- amlabel - label an AMANDA tape
+ amlabel - label an Amanda tape
- ammt - AMANDA version of mt
+ ammt - Amanda version of mt
- amoverview - display file systems processed by AMANDA over time
+ amoverview - display file systems processed by Amanda over time
- amplot - visualize the behavior of AMANDA
+ amplot - visualize the behavior of Amanda
- amrecover - AMANDA index database browser
+ amrecover - Amanda index database browser
- amreport - generate a formatted output of statistics for an AMANDA run
+ amreport - generate a formatted output of statistics for an Amanda run
- amrestore - extract backup images from an AMANDA tape
+ amrestore - extract backup images from an Amanda tape
- amrmtape - remove a tape from the AMANDA database
+ amrmtape - remove a tape from the Amanda database
- amstatus - display the state of an AMANDA run
+ amstatus - display the state of an Amanda run
- amtape - user interface to AMANDA tape changer controls
+ amtape - user interface to Amanda tape changer controls
amtapetype - generate a tapetype definition.
- amtoc - generate TOC (Table Of Contents) for an AMANDA run
+ amtoc - generate TOC (Table Of Contents) for an Amanda run
amverify - check an Amanda tape for errors
- amverifyrun - check the tapes written by the last AMANDA run
+ amverifyrun - check the tapes written by the last Amanda run
Note
Refer to http://www.amanda.org/docs/manpages.html for the current version of
this document.
-This chapter contains the manual pages from the official AMANDA distribution.
+This chapter contains the manual pages from the official Amanda distribution.
-------------------------------------------------------------------------------
Prev Up Next
-Chapter 31. Multitape support in AMANDA 2.2
+Chapter 32. Multitape support in Amanda 2.2
Prev Part VI. Historical files Next
-------------------------------------------------------------------------------
-Chapter 31. Multitape support in AMANDA 2.2
+Chapter 32. Multitape support in Amanda 2.2
James da Silva
Introduction
-The goal of this enhancement is to make AMANDA independent of the number of
-tapes used per run or even per dump cycle. Specifically, I would like AMANDA to
+The goal of this enhancement is to make Amanda independent of the number of
+tapes used per run or even per dump cycle. Specifically, I would like Amanda to
handle the following:
* output of amdump run goes to more than one tape
Time
Previously, planner marked time by the number of amdump runs, which it equated
-with number of tapes, and number of days. In AMANDA 2.2, AMANDA keeps track of
+with number of tapes, and number of days. In Amanda 2.2, Amanda keeps track of
the real passage of time, and doesn't generally care about the number of runs
or tapes between any two events.
-While AMANDA 2.2 doesn't care about spacing between runs, dump cycles are still
+While Amanda 2.2 doesn't care about spacing between runs, dump cycles are still
in terms of days, to make things easy to understand for the user. So, time
differences are rounded to the nearest 24 hours:
days_diff(A,B) = (<B> - <A> + 86400/2) / 86400
skipped on any runs that occur on the day the full is due, but we have to do
the right thing if multiple runs are done that day, and if no runs are done
that day (in which case we should be doing an incremental). Also, the time of
-last full dump is a fiction maintained by the planner -- AMANDA has no way to
+last full dump is a fiction maintained by the planner -- Amanda has no way to
tell whether the full backup was actually done or when it was done:
if(skip-full) {
taper must now handle writing to multiple tapes in one night, but choosing the
tapes from the tape rack is done one at a time as needed, re-applying the same
-algorithm each time (see AMANDA_Tape_Changer_Support).
+algorithm each time (see Amanda_Tape_Changer_Support).
End of tape handling
-As in earlier versions of AMANDA, taper itself does not try to restrict writing
+As in earlier versions of Amanda, taper itself does not try to restrict writing
to the tape size given in the config file. It relied on planner having
correctly estimated backup sizes and limiting itself to what would fit on one
tape.
-------------------------------------------------------------------------------
Prev Up Next
-Chapter 30. What once was new Home Chapter 32. Thoughts about a Strategy API
+Chapter 31. What once was new Home Chapter 33. Thoughts about a Strategy API
-Chapter 21. How AMANDA uses UDP and TCP ports
+Chapter 22. How Amanda uses UDP and TCP ports
Prev Part V. Technical Background Next
-------------------------------------------------------------------------------
-Chapter 21. How AMANDA uses UDP and TCP ports
+Chapter 22. How Amanda uses UDP and TCP ports
John R. Jackson
Refer to http://www.amanda.org/docs/portusage.html for the current version of
this document.
-AMANDA uses both UDP and TCP ports during its operation. The amandad service is
+Amanda uses both UDP and TCP ports during its operation. The amandad service is
listening (via inetd/xinetd) at a well known (fixed) port on each client for
UDP connections. The amindexd and amidxtaped services are listening (also via
inetd/xinetd) at well known ports on the tape server for TCP connections.
contact amindexd or amidxtaped on the tape server. The port that amrecover
binds to its TCP socket must be privileged, which is one of the reasons it must
be run as root.
-AMANDA also uses TCP connections for transmitting the backup image, messages
+Amanda also uses TCP connections for transmitting the backup image, messages
and (optionally) the index list from a client back to the dumper process on the
tape server. A process called sendbackup is started by amandad on the client.
It creates two (or three, if indexing is enabled) TCP sockets and sends their
TCP port allocation
-When AMANDA creates a TCP server socket to listen for incoming connections
+When Amanda creates a TCP server socket to listen for incoming connections
( sendbackup), it goes through the following bind steps:
* try for the user TCP port range (--with-tcpportrange), if defined. If that
* get any available port.
-This sequence is implemented in stream_server().
-When AMANDA ( dumper) creates an unprivileged TCP client socket to connect to a
+In all cases, it will not use a port that has been assigned to other well-known
+services. This sequence is implemented in stream_server().
+When Amanda ( dumper) creates an unprivileged TCP client socket to connect to a
server, it goes through the following bind steps:
* try for the user TCP port range (--with-tcpportrange), if defined. If that
* get any available port.
-This sequence is implemented in stream_client().
-When AMANDA ( amrecover) creates a privileged TCP client socket to connect to a
+In all cases, it will not use a port that has been assigned to other well-known
+services. This sequence is implemented in stream_client().
+When Amanda ( amrecover) creates a privileged TCP client socket to connect to a
server, it goes through the following bind step:
* try for a privileged port (512 .. 1023). If that fails, the whole request is
UDP port allocation
-When AMANDA creates a UDP socket, the same order of assignment as above is used
+When Amanda creates a UDP socket, the same order of assignment as above is used
by dgram_bind():
* try for the user UDP port range (--with-udpportrange), if defined. If that
* get any available port.
-The dgram_bind() routine is called from three places, amcheck, planner and
-dumper. In each case, a connection to amandad on a client is being set up.
-amandad, in turn, calls security_ok(), which insists the other end of the
-connection be a privileged port, so a user UDP port range (--with-udpportrange)
-must specify privileged port numbers.
+In all cases, it will not use a port that has been assigned to other well-known
+services. The dgram_bind() routine is called from three places, amcheck,
+planner and dumper. In each case, a connection to amandad on a client is being
+set up. amandad, in turn, calls security_ok(), which insists the other end of
+the connection be a privileged port, so a user UDP port range (--with-
+udpportrange) must specify privileged port numbers.
A user UDP port range must allow for one port for each client that might be
contacted at a time. planner and amcheck use a single socket to contact all
their clients, but there may be multiple dumpers (based on "inparallel" in
University environment :-). So the following is likely to be completely wrong,
but I have tried to get the advice of folks who do really understand this
stuff.
-Firewalls and AMANDA should be pretty easy to set up. Just pick user UDP and
-TCP port ranges, build AMANDA with them (--with-udpportrange and --with-
+Firewalls and Amanda should be pretty easy to set up. Just pick user UDP and
+TCP port ranges, build Amanda with them (--with-udpportrange and --with-
tcpportrange) and let them through the firewall. You also need to let the well
-known AMANDA ports through, just as you would ftp or telnet.
-NAT has other issues. If the AMANDA client is "outside" NAT, there should not
+known Amanda ports through, just as you would ftp or telnet.
+NAT has other issues. If the Amanda client is "outside" NAT, there should not
be a problem for backups. Sendbackup will set up the ports and tell dumper what
they are. Then dumper will connect to them from "inside" and NAT should leave
that alone, although it doesn't really matter since sendbackup does not care
who connects to it (other than it not be ftp port 20).
-If the AMANDA tape server is outside, NAT will have to be told how to translate
+If the Amanda tape server is outside, NAT will have to be told how to translate
the incoming connections from dumper to the client. To do that, the UDP and TCP
port ranges will have to be known and only one client can be inside.
The reverse is true for amrecover. If amrecover is run from inside NAT, there
-------------------------------------------------------------------------------
Prev Up Next
-Part V. Technical Background Home Chapter 22. AMANDA dumper API
+Part V. Technical Background Home Chapter 23. Amanda dumper API
Note
-This is the first release of the Docbook/XML-version of the official AMANDA
-documentation. Please refer to http://www.amanda.org/docs/AMANDA-docs.html for
-the latest versions of these documents. They are available as html, ps and pdf.
-This is an effort to give the AMANDA-documentation a general overhaul. There
-are many parts that need to be reviewed and corrected, updated and added. The
-conversion of the old ASCII-formatted documentation to Docbook/XML should help
-to enhance the possibilities and to ease the generation of various output-
-formats.
-Recent changes:
-
-* addition of the AMANDA-chapter by John R. Jackson (with kind permission of W.
- Curtis Preston).
-
-Planned:
-
-* addition of some historical AMANDA-papers.
-* addition of some illustrations and charts.
-* addition of more chapters ...
+This is the Docbook/XML-version of the official Amanda documentation. Please
+refer to http://www.amanda.org/docs/AMANDA-docs.html for the latest versions of
+these documents. They are available as html, ps and pdf.
+This is the official documentation for Amanda 2.5.0. The release 2.5.0 brings
+various new features:
+
+* Communication security/authentication
+* Data security
+* Enhanced possibilities for Compression
+* Dump images spanning multiple media volumes
+* Auto tape labelling
+* Improved code quality
Feel free to contact me with corrections, additions or updates. Thank you.
-Stefan G. Weichinger, for the AMANDA Core Team, April 2005.
+Stefan G. Weichinger, for the AMANDA Core Team, March 2006.
<sgw@amanda.org>
-------------------------------------------------------------------------------
-Prev Up Next
+Prev Next
The Official AMANDA Documentation Home
Prev Next
-------------------------------------------------------------------------------
-Conversion to Docbook/XML by Stefan G. Weichinger, member of the AMANDA Core
+Conversion to Docbook/XML by Stefan G. Weichinger, member of the Amanda Core
Team.
XML-Buildtree by Jelmer R. Vernooij, member of the Samba-Team. Thanks, Jelmer
... !
-------------------------------------------------------------------------------
-Prev Up Next
+Prev Next
Abstract Home Copyright Information
WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-------------------------------------------------------------------------------
-Prev Up Next
+Prev Next
Home Attributions
Attributions
-AMANDA_2.4.x_-_System-Specific_Installation_Notes
+Amanda_2.5.0_-_System-Specific_Installation_Notes
* Stefan G. Weichinger <sgw@amanda.org> (XML-conversion;Updates)
-AMANDA_Installation_Notes
+Amanda_Installation_Notes
* James da Silva <jds@amanda.org> (Original text)
-* Stefan G. Weichinger <sgw@amanda.org> (XML-conversion)
+* Stefan G. Weichinger <sgw@amanda.org> (XML-conversion, Updates)
Excluding
* Andrew Hall (Original text)
* Stefan G. Weichinger <sgw@amanda.org> (XML-conversion;Updates)
-Indexing_with_AMANDA
+Indexing_with_Amanda
* Alan M. McIvor (Original text)
* Stefan G. Weichinger <sgw@amanda.org> (XML-conversion;Updates)
* Ralf Fassel (Corrections and additions)
* Stefan G. Weichinger <sgw@amanda.org> (XML-conversion;Updates)
-AMANDA_Tape_Changer_Support
+Amanda_Tape_Changer_Support
* James da Silva <jds@amanda.org> (Original text)
* Stefan G. Weichinger <sgw@amanda.org> (XML-conversion;Updates)
* Stefan G. Weichinger <sgw@amanda.org> (XML-conversion;Updates)
-AMANDA_on_Cygwin_HOWTO
+Amanda_on_Cygwin_HOWTO
* Doug Kingston (Original text)
* Stefan G. Weichinger <sgw@amanda.org> (XML-conversion)
-How_to_use_the_AMANDA_file-driver
+How_to_use_the_Amanda_file-driver
* Stefan G. Weichinger <sgw@amanda.org> (Original text;XML-conversion;Updates)
How_to_use_a_wrapper
* Bert de Ridder (Original text)
+* Paul Bijnens (Original text)
* Stefan G. Weichinger <sgw@amanda.org> (XML-conversion; Updates)
-Using_AMANDA
+How_to_do_Amanda-server-side_gpg-encrypted_backups.
+
+* Stefan G. Weichinger <sgw@amanda.org> (Original text)
+
+How_to_use_different_auth_with_Amanda
+
+* Jean-Louis Martineau <martinea@iro.umontreal.ca> (Original text;XML-
+ conversion;Updates)
+
+Using_Amanda
* John R. Jackson <jrj@purdue.edu> (Original text)
* Gavin Henry <ghenry@suretecsystems.com> (XML-conversion)
* Stefan G. Weichinger <sgw@amanda.org> (XML-conversion, Updates)
-AMANDA_FAQ
+Amanda_FAQ
* Stefan G. Weichinger <sgw@amanda.org> (XML-conversion;Updates)
-Collection_of_the_top_ten_AMANDA_questions._And_answers.
+Collection_of_the_top_ten_Amanda_questions._And_answers.
* Stefan G. Weichinger <sgw@amanda.org> (Original text; Conversion to Docbook/
XML)
-AMANDA_WISHLIST
+Amanda_WISHLIST
* Jean-Louis Martineau <martinea@iro.umontreal.ca> (Additions and Updates)
* Stefan G. Weichinger <sgw@amanda.org> (XML-conversion; Additions and Updates)
-AMANDA_Survey_Results
-
-* Jon LaBadie <jon@jgcomp.com> (Original text)
-* Stefan G. Weichinger <sgw@amanda.org> (XML-conversion)
-
-How_AMANDA_uses_UDP_and_TCP_ports
+How_Amanda_uses_UDP_and_TCP_ports
* John R. Jackson <jrj@purdue.edu> (Original text)
* Stefan G. Weichinger <sgw@amanda.org> (XML-conversion;Updates)
-AMANDA_dumper_API
+Amanda_dumper_API
* Alexandre Oliva <oliva@dcc.unicamp.br> (Original text)
* Stefan G. Weichinger <sgw@amanda.org> (XML-conversion;Updates)
-AMANDA_Internals
+Amanda_Internals
* George Scott (Original text)
* Stefan G. Weichinger <sgw@amanda.org> (XML-conversion)
-AMANDA_Event_API
+Amanda_Event_API
* Mike Grupenhoff <kashmir@munge.com> (Original text)
* Stefan G. Weichinger <sgw@amanda.org> (XML-conversion;Updates)
-AMANDA_Security_API
+Amanda_Security_API
* Mike Grupenhoff <kashmir@munge.com> (Original text)
* Stefan G. Weichinger <sgw@amanda.org> (XML-conversion;Updates)
* Stefan G. Weichinger <sgw@amanda.org> (XML-conversion)
-Using_Kerberos_with_AMANDA
+Using_Kerberos_with_Amanda
* Stefan G. Weichinger <sgw@amanda.org> (XML-conversion;Updates)
* Stefan G. Weichinger <sgw@amanda.org> (XML-conversion, Updates)
-Multitape_support_in_AMANDA_2.2
+Multitape_support_in_Amanda_2.2
* James da Silva <jds@amanda.org> (Original text)
* Stefan G. Weichinger <sgw@amanda.org> (XML-conversion;Updates)
-------------------------------------------------------------------------------
-Prev Up Next
+Prev Next
Copyright Information Home Part I. Installation
Similarly, a 5-drive RAIT set will give you 4 times the capacity, 4 times the
throughput (with sufficient bus bandwidth), and the square of the failure rate.
This means you can back up partitions as large as four times your tape size
-with AMANDA, with higher reliability and speed.
+with Amanda, with higher reliability and speed.
Using a RAIT
If you have several tape devices on your system [currently either 3 or 5 drive
-sets are supported] you tell AMANDA to use them as a RAIT by listing them as a
+sets are supported] you tell Amanda to use them as a RAIT by listing them as a
single tape device using /bin/csh curly-brace-and-comma notation, as in:
tapedev = "rait:/dev/rmt/tps0d{4,5,6}n"
tapetype EXB-8500x3
-to tell AMANDA about the multiple drive set.
+to tell Amanda about the multiple drive set.
Disaster Recovery
-To assist in disaster recovery (as well as changer scripts) the AMANDA package
+To assist in disaster recovery (as well as changer scripts) the Amanda package
now also includes amdd, which is a simple dd(1) replacement which supports
(only) the "if=xxx", "of=xxx", "bs=nnn[kMb]" "skip=nnn" and "count=nnn"
options, but which can read and write RAIT tapesets.
-Using amdd and your usual AMANDA unpack instructions will suffice for disaster
+Using amdd and your usual Amanda unpack instructions will suffice for disaster
recovery from RAIT tape-sets.
-------------------------------------------------------------------------------
Refer to http://www.amanda.org/docs/restore.html for the current version of
this document.
-This document describes how to restore files backed up with AMANDA either with
-or without AMANDA tools.
+This document describes how to restore files backed up with Amanda either with
+or without Amanda tools.
All these cases assume you're trying to restore a complete disk, that is,
you've replaced the lost disk with a new one, or created a new filesystem on
it. Tweaking with the arguments to restore (not amrestore), you will be able to
First of all, boot off the CD, and reinstall the system critical
partition, restoring it to vendor supplied state. Then, go through all of
Scenario 1.
- 3. Server machine fails, non-system critical, non-AMANDA disk.
+ 3. Server machine fails, non-system critical, non-Amanda disk.
Proceed just as described in Scenario 1. However, you won't have to go
through the rsh process, because you can just use amrestore to replace the
lost data directly.
- 4. Server machine fails, system critical, non-AMANDA disk.
+ 4. Server machine fails, system critical, non-Amanda disk.
Example: / on Aaron
First of all, boot off the CD, and reinstall the system critical
partition, restoring it to vendor supplied state.
Then, follow steps in Scenario 3.
- 5. Server machine fails, non-system critical, AMANDA disk, with db.
+ 5. Server machine fails, non-system critical, Amanda disk, with db.
Example: /opt on Aaron
- If the disk that contains the AMANDA database is toast, then you need to
+ If the disk that contains the Amanda database is toast, then you need to
rebuild the database. The easiest way to do it is to take the text file
that you had mailed to you via the 'amadmin export' command, and import
via the 'amadmin import' command. Then you should be able to follow the
steps outlined in Scenario 4.
- Note that AMANDA does not mail the exported database automatically; you
+ Note that Amanda does not mail the exported database automatically; you
may add this to the crontab entry that runs amanda.
Maybe it's a good idea to print out the text files as well and store the
last 2 dumpcycles worth of paper (the disc text files might have got
toasted as well). From the paper you still are able to reconstruct where
your discs are.
- 6. Server machine fails, non-system critical, AMANDA disk, with binaries.
+ 6. Server machine fails, non-system critical, Amanda disk, with binaries.
Example: /usr/local on Aaron
This is where things get hairy. If the disk with the amanda binaries on it
is toast, you have three options.
- i. reinstall the AMANDA binaries from another tape, on which you have
+ i. reinstall the Amanda binaries from another tape, on which you have
conveniently backed up the binaries within the last couple of weeks
- (not using AMANDA).
- ii. recompile AMANDA, making sure not to overwrite your db files.
- iii. use dd to read AMANDA formatted tapes. This is the option I am going
+ (not using Amanda).
+ ii. recompile Amanda, making sure not to overwrite your db files.
+ iii. use dd to read Amanda formatted tapes. This is the option I am going
to explore most fully, because this seems the most likely to occur.
- a. Find out the device name used by AMANDA, by looking in
+ a. Find out the device name used by Amanda, by looking in
amanda.conf. Turns out to be /dev/rmt/0cn for this system.
If amanda.conf isn't at hand: this must be a non-rewinding tape
device specifier (which I believe the trailing `n' stands for).
Example output:
- AMANDA: FILE 19971220 uri /root-sun4 lev 1 comp .gz program
+ Amanda: FILE 19971220 uri /root-sun4 lev 1 comp .gz program
DUMP
- AMANDA: FILE 19971220 uri /misc lev 1 comp .gz program DUMP
- AMANDA: FILE 19971220 uri / lev 1 comp .gz program DUMP
+ Amanda: FILE 19971220 uri /misc lev 1 comp .gz program DUMP
+ Amanda: FILE 19971220 uri / lev 1 comp .gz program DUMP
- g. Restore the AMANDA binaries (what else do you need??), and then
+ g. Restore the Amanda binaries (what else do you need??), and then
bail out of ufsrestore. You can use amrestore, as in Scenario 3.
Installation
-AMANDA is able to back up Microsoft Windows shared disks by using Samba, a
+Amanda is able to back up Microsoft Windows shared disks by using Samba, a
package that implements a SMB client and server for Unix:
http://www.samba.org
This is old stuff and will be (re)moved soon:
Releases from 1.9.18p5 up to 1.9.18p10 logged information in the tar files
produced, making them unusable! If you really must use a release prior to Samba
-2.0.6, a patch that fixes the problem is available in the AMANDA patches page:
+2.0.6, a patch that fixes the problem is available in the Amanda patches page:
http://www.amanda.org/patches/
-AMANDA no longer supports Samba releases prior to 1.9.18. If you're using Samba
+Amanda no longer supports Samba releases prior to 1.9.18. If you're using Samba
from 1.9.18 through 1.9.18p3, make sure you don't set a low logging/debugging
level in smb.conf. This flag may prevent estimate sizes from printing correctly
-and AMANDA will report an estimate failure.
+and Amanda will report an estimate failure.
This problem may also occur if you have large (>2GB) shares with Samba prior to
-2.0.4. In this case, apply samba2-largefs.patch from the AMANDA patches page
+2.0.4. In this case, apply samba2-largefs.patch from the Amanda patches page
(http://www.amanda.org/patches/).
-After building and installing Samba, AMANDA must be configured with support for
-smbclient. AMANDA will automatically find smbclient if it is in your PATH when
+After building and installing Samba, Amanda must be configured with support for
+smbclient. Amanda will automatically find smbclient if it is in your PATH when
you run configure, or you may add the following argument:
--with-smbclient=/full/path/to/smbclient
Setup
-Once AMANDA and Samba are installed, the only difference between a Unix client/
+Once Amanda and Samba are installed, the only difference between a Unix client/
disk and PC client/share is in how the backup disks are specified in the file
disklist. For each PC share, the entry lists the 'samba server' host (where the
patched Samba software is installed) and the disk field is the share name. The
remaining fields are like any other DLE.
A user must be created on the PC with full access rights (read/write) to the
-share. AMANDA, via the Samba server, will connect to the PC via this user. If
+share. Amanda, via the Samba server, will connect to the PC via this user. If
the user does not have full access, incremental backups will not work and the
whole share will be backed up every time (the archive bits are never reset).
The file /etc/amandapass must be created by hand. It contains share name to
password.
* Workgroup (optional).
-This file must be owned by the AMANDA-user, and disallow world access
+This file must be owned by the Amanda-user, and disallow world access
privileges. Blank lines are ignored. A "#" on a line at the start of a field
(including start of line) causes the rest of the line to be ignored.
Example
-The AMANDA client software and (patched) Samba is installed on host "pcserver".
+The Amanda client software and (patched) Samba is installed on host "pcserver".
A share to be backed up called "backupc" is on PC "thepc". The share will be
accessed via PC user "bozo" and password "f00bar" and does not require a
workgroup.
Essentially, the entry in disklist is a 'pseudo-disk' which contains all the
relevant information needed by smbclient to backup the disk, but in a way that
-is compatible to AMANDA.
+is compatible to Amanda.
amcheck does a quick check to see if smbclient exists and tries to connect to
the PC clients. It also checks for the existence and permissions of /etc/
amandapass.
Samba will not back up open files (such as PAGEFILE.SYS and registry files) nor
Access Control List data. Furthermore, at restore time, smbclient is unable to
-overwrite read-only files. Hence, AMANDA+Samba is not a perfect solution for
+overwrite read-only files. Hence, Amanda+Samba is not a perfect solution for
backing up (restoring, actually) system disks.
-Samba does not use the Windows Backup API, so configuring the AMANDA backup
+Samba does not use the Windows Backup API, so configuring the Amanda backup
user as a member of group backup on the Windows host is useless. You will
probably have to configure it as an Administrator, and make sure it can read
and change permission of all files in the share.
Note
Since Samba-3.0.2a smbclient supports multiple exclusion-patterns. It is one of
-the "Ongoing Projects" to make use of this in AMANDA. Refer to http://
+the "Ongoing Projects" to make use of this in Amanda. Refer to http://
www.amanda.org/ongoing.php for details.
The size estimate calculation does not use the same method as the dump, so it
may be inaccurate. It also does not support any type of exclusion ("exclude" is
-------------------------------------------------------------------------------
Prev Up Next
-Chapter 4. Indexing with AMANDA Home Chapter 6. Restore
+Chapter 4. Indexing with Amanda Home Chapter 6. Restore
- Chapter 25. AMANDA Security API
+ Chapter 26. Amanda Security API
Prev Part V. Technical Background Next
-------------------------------------------------------------------------------
-Chapter 25. AMANDA Security API
+Chapter 26. Amanda Security API
Mike Grupenhoff
Introduction
This is a document of the API for defining and utilizing multiple security and
-transport mechanisms for the AMANDA network protocol.
+transport mechanisms for the Amanda network protocol.
The goal of this API is to allow several different forms of communication and
-authentication to exist between the AMANDA server and its clients.
+authentication to exist between the Amanda server and its clients.
The Problem
There exist many potential ways that a user might wish to grant access to the
-AMANDA daemon. The two currently supported are BSD (reserved port) and Kerberos
+Amanda daemon. The two currently supported are BSD (reserved port) and Kerberos
IV security. The current implementation of these two methods is not very
general, and adding additional methods requires a large amount of code to be
modified.
Additionally, the current methods require the protocol and dump transport to be
-transmitted across the network using a pre-defined method. The AMANDA protocol
+transmitted across the network using a pre-defined method. The Amanda protocol
currently must be sent using udp datagrams to a well-known port, and the dumps
are transported using tcp connections between ports negotiated via the
protocol.
The API
-The security API was designed to be a layer in between the core logic of AMANDA
+The security API was designed to be a layer in between the core logic of Amanda
and the transport and authentication of the protocol and dumps.
The component server and client programs now deal with abstract concepts
instead of concrete udp and tcp handles.
(section 4.2) that can be used to communicate with that host. The status arg to
the callback is reflects the success of the request. Error messages can be had
via security_geterror().
-This is expected to be the AMANDA server's interface for setting up connections
+This is expected to be the Amanda server's interface for setting up connections
to clients.
conf_fn is used to determine configuration information. If NULL, no
configuration information is available.
descriptor, and a callback, when new connections are detected on the given file
descriptors, the function is called with a newly created security handle and
the initial packet received.
-This is expected to be the AMANDA daemon's interface for setting up incoming
-connections from the AMANDA server. The file descriptors are typically 0 and 1
+This is expected to be the Amanda daemon's interface for setting up incoming
+connections from the Amanda server. The file descriptors are typically 0 and 1
(stdin/stdout).
This function uses the event interface, and only works properly when event_loop
() is called later in the program.
-------------------------------------------------------------------------------
Prev Up Next
-Chapter 24. AMANDA Event API Home Chapter 26. Virtual Tape API
+Chapter 25. Amanda Event API Home Chapter 27. Virtual Tape API
-Chapter 28. Response to CPIO Security Notice Issue 11:
+Chapter 29. Response to CPIO Security Notice Issue 11:
Prev Part VI. Historical files Next
-------------------------------------------------------------------------------
-Chapter 28. Response to CPIO Security Notice Issue 11:
+Chapter 29. Response to CPIO Security Notice Issue 11:
-AMANDA Core Team
+Amanda Core Team
Original text
AMANDA Core Team
Refer to http://www.amanda.org/docs/security.html for the current version of
this document.
-The AMANDA development team confirms the existence of the amrecover security
-hole in recent versions of AMANDA. We have made a new release, AMANDA 2.4.0b5,
+The Amanda development team confirms the existence of the amrecover security
+hole in recent versions of Amanda. We have made a new release, Amanda 2.4.0b5,
that fixes the amrecover problem and other potential security holes, and is the
product of a security audit conducted in conjunction with the OpenBSD effort.
The new version is available at:
Affected Versions
-The AMANDA 2.3.0.x interim releases that introduced amrecover, and the 2.4.0
-beta releases by the AMANDA team are vulnerable.
-AMANDA 2.3.0 and earlier UMD releases are not affected by this particular bug,
+The Amanda 2.3.0.x interim releases that introduced amrecover, and the 2.4.0
+beta releases by the Amanda team are vulnerable.
+Amanda 2.3.0 and earlier UMD releases are not affected by this particular bug,
as amrecover was not part of those releases. However, earlier releases do have
-potential security problems and other bugs, so the AMANDA Team recommends
+potential security problems and other bugs, so the Amanda Team recommends
upgrading to the new release as soon as practicable.
Workaround
-At an active site running AMANDA 2.3.0.x or 2.4.0 beta, amrecover/ amindexd can
+At an active site running Amanda 2.3.0.x or 2.4.0 beta, amrecover/ amindexd can
be disabled by:
* removing amandaidx and amidxtape from /etc/inetd.conf
* restarting /etc/inetd.conf (kill -HUP should do)
This will avoid this particular vulnerability while continuing to run backups.
-However, other vulnerabilities might exist, so the AMANDA Team recommends
+However, other vulnerabilities might exist, so the Amanda Team recommends
upgrading to the new release as soon as practicable.
Acknowledgements
This release (2.4.0) has addressed a number of security concerns with the
assistance of Theo de Raadt, Ejovi Nuwere and David Sacerdote of the OpenBSD
project. Thanks guys! Any problems that remain are our own fault, of course.
-The AMANDA Team would also like to thank the many other people who have
-contributed suggestions, patches, and new subsystems for AMANDA. We're grateful
+The Amanda Team would also like to thank the many other people who have
+contributed suggestions, patches, and new subsystems for Amanda. We're grateful
for any contribution that helps us achieve and sustain critical mass for
-improving AMANDA.
+improving Amanda.
-------------------------------------------------------------------------------
Prev Up Next
-Part VI. Historical files Home Chapter 29. Upgrade Issues
+Part VI. Historical files Home Chapter 30. Upgrade Issues
-Chapter 32. Thoughts about a Strategy API
+Chapter 33. Thoughts about a Strategy API
Prev Part VI. Historical files Next
-------------------------------------------------------------------------------
-Chapter 32. Thoughts about a Strategy API
+Chapter 33. Thoughts about a Strategy API
Alexandre Oliva
-------------------------------------------------------------------------------
Prev Up Next
-Chapter 31. Multitape support in AMANDA 2.2 Home Chapter 33. Y2K Compliancy
+Chapter 32. Multitape support in Amanda 2.2 Home Chapter 34. Y2K Compliancy
-Chapter 1. AMANDA 2.4.x - System-Specific Installation Notes
+Chapter 1. Amanda 2.5.0 - System-Specific Installation Notes
Prev Part I. Installation Next
-------------------------------------------------------------------------------
-Chapter 1. AMANDA 2.4.x - System-Specific Installation Notes
+Chapter 1. Amanda 2.5.0 - System-Specific Installation Notes
-AMANDA Core Team
+Amanda Core Team
Original text
AMANDA Core Team
Solaris_2.6
+ Solaris
+
Trusted_Solaris
SunOS_4.x
Please read the notes that correspond to the architectures you are installing
for. If you find additional gotchas, or anything incorrect in these notes,
please send your updates to mailto://amanda-hackers@amanda.org after checking
-that they are not known/fixed problems in the AMANDA patches page: http://
+that they are not known/fixed problems in the Amanda patches page: http://
www.amanda.org/patches/.
Solaris 2.6
2.7.2.3 does not support Solaris 2.6, you should upgrade to 2.8.0 or higher, or
egcs.
+ Solaris
+
+You may get errors running make: Assure that you use the BSD-version of make,
+usually /usr/ccs/bin/make. Add /usr/ccs/bin to the path before running
+configure.
+
Trusted Solaris
According to Julian Stevens <julian.stevens@baedsl.co.uk>, the format of inetd
should insert the word `untrusted':
amanda dgram udp wait untrusted amuser /usr/local/libexec/amandad amandad
-
The patch-system script is *NOT* aware of this detail; you must fix it
yourself.
SunOS 4.x
-A bug in GNUtar 1.12 causes it to miscalculate (in fact, to misreport) the size
-of filesystems. A patch for GNUtar is available in the patches directory.
+A bug in GNU-tar 1.12 causes it to miscalculate (in fact, to misreport) the
+size of filesystems. A patch for GNU-tar is available in the patches directory.
Ultrix
The Ultrix restore program will fail if it is not connected to a tty. Since the
restore program is invoked in the clients in order to create index files, and
-it the client is not connected to a tty, index creation will fail. Using GNUTAR
-instead of DUMP is an option. Thanks to Edwin Wiles
+it the client is not connected to a tty, index creation will fail. Using GNU-
+tar instead of DUMP is an option. Thanks to Edwin Wiles
<ewiles@mclean.sterling.com> for the investigation. Another alternative
proposed by Martyn Johnson <Martyn.Johnson@cl.cam.ac.uk> is to use a modified
restore program: use a binary program editor and replace `/dev/tty' with `/dev/
running this script!):
perl -pi -e 'BEGIN { $/ = "/dev/tty" } s-$/-/dev/nul-' restore
-
-The Ultrix C compiler seems to be too broken to compile AMANDA. You are likely
+The Ultrix C compiler seems to be too broken to compile Amanda. You are likely
to need gcc or egcs.
HP/UX
The error message is:
./configure: sh internal 2K buffer overflow
-
Using /bin/posix/sh usually works around the problem. Another solution is to
install GNU bash and use it instead of /bin/sh.
implementation of mt, and edit amverify so that MT points to GNU mt and MTOPT
is `-f', or reconfigure and rebuild amanda from scratch, making sure it finds
GNU mt before the stock mt in the PATH.
-If you have vxfs filesystems to back up, AMANDA will pick vxdump automatically.
-GNU tar 1.12 will incorrectly report the size of backups. There's a patch in
+If you have vxfs filesystems to back up, Amanda will pick vxdump automatically.
+GNU-tar 1.12 will incorrectly report the size of backups. There's a patch in
the patches directory that fixes this problem.
The use of `amhpfixdevs' is deprecated, since you can list mount-points or full
device names in the disklist. The script may be removed in future releases of
-AMANDA.
+Amanda.
Sometimes you may get the error message `Link severed' from an HP/UX client.
This is just a cute name the developers of HP/UX found for `Network error'.
Reported by Michael Brehl <mbr@condor.de>
unable to perform backups, producing weird error messages such as `master/slave
protocol botched', and sometimes creating unrestorable dump images, especially
of active filesystems. The first problem can sometimes be fixed by cleaning up
-outdated entries in /etc/dumpdates, but your best bet is probably GNU tar.
+outdated entries in /etc/dumpdates, but your best bet is probably GNU-tar.
Make sure the user that runs configure has permission to run the dump program,
otherwise configure may misdetect an ability of dump to accept a -E (for
estimates) switch.
-GNUtar 1.11.8, distributed with some Linux versions, will cause index failures
-(Index returned -1). Upgrading to GNUtar 1.12 fixes this problem. This is not a
-Linux-specific problem, but it is quite common in this platform.
-AMANDA now supports the ftape driver version 3.04d. It adjusts the blocksize
+GNU-tar 1.11.8, distributed with some Linux versions, will cause index failures
+(Index returned -1). Upgrading to GNU-tar 1.12 fixes this problem. This is not
+a Linux-specific problem, but it is quite common in this platform.
+Amanda now supports the ftape driver version 3.04d. It adjusts the blocksize
automatically to 32k and supports QIC volume tables. More details con be found
in the file ZFTAPE in this directory.
Some releases of dump for Linux, such as the one distributed with Debian 2.0,
According to Michael Galloway <mgx@spruce.lsd.ornl.gov>, the stock DUX4 dump is
broken. There is a patch available at ftp://ftp.service.digital.com/public/
dunix/v4.0b/duv40bas00005-19970926.README
-When both dump and vdump are available, AMANDA will use vdump for backing up
+When both dump and vdump are available, Amanda will use vdump for backing up
advfs filesystems only, and dump will be used for the rest. If you'd rather
back up all filesystems with vdump, #undef DUMP in config/config.h after
running configure.
Unfortunately, the output of `dump -E' incorrectly matches a line of output
-from SAMBA, which gets AMANDA's estimate process confused. client-src/
+from SAMBA, which gets Amanda's estimate process confused. client-src/
sendsize.c will refuse to compile if both HAVE_DUMP_ESTIMATE and SAMBA_CLIENT
-are defined in config/config.h. AMANDA will work correctly if you undefine
+are defined in config/config.h. Amanda will work correctly if you undefine
HAVE_DUMP_ESTIMATE in config/config.h; if you prefer to have incorrect
estimates for SAMBA backups, follow the instructions in client-src/sendsize.c
on removing the compile-time error.
According to Oren Laadan <orenl@cs.huji.ac.il>, DEC compiler version "DEC C
V5.2-033 on Digital UNIX V4.0 (Rev. 564)" (obtained with "cc -V") does not
-build AMANDA properly, in particular, taper.c. Using gcc is OK.
+build Amanda properly, in particular, taper.c. Using gcc is OK.
Sinix 5.43 (Reliant Unix)
The use of `amsinixfixdevs' is deprecated, since you can list mount-points or
full device names in the disklist. The script may be removed in future releases
-of AMANDA.
+of Amanda.
Sinix port originally by Michael Schmitz <mschmitz@iname.com>.
IRIX (all)
When setting the tape device name in either amanda.conf or one of the changer
configuration files, make sure you specify the "variable" device name, which
has a 'v' on the end. If not, IRIX will write 4KByte blocks instead of the
-32KByte blocks AMANDA tells it to. This apparantly works OK unless you take the
+32KByte blocks Amanda tells it to. This apparantly works OK unless you take the
tape to a non-IRIX system, where amrestore will complain about a short (4096)
read.
If you do end up in this situation, the dd command to use to pipe into your
system restore program is:
dd if=/dev/whatever bs=4k skip=8 | ...
-
Jean-Francois Malouin <Jean-Francois.Malouin@bic.mni.mcgill.ca> reports that,
if you are going to use an IRIX host as the tape server, you *must* patch your
Seems like SGI make program is a bit broken, in a way that causes it to rebuild
some files if doesn't have to if you happen to run make again. Using GNU make
fixes this problem.
-If you have xfs filesystems to back up, AMANDA will pick xfsdump automatically.
+If you have xfs filesystems to back up, Amanda will pick xfsdump automatically.
IRIX 6.5.x
Luc Lalonde <Luc.Lalonde@polymtl.ca> contributed the following notes:
If you use a jukebox, you must set the ownership of the robot-changer device to
-the AMANDA operator:group in /etc/ioperms. Here's my configuration:
+the Amanda operator:group in /etc/ioperms. Here's my configuration:
/etc/ioperms: /dev/scsi/sc8d6l0 0600 amanda backup
you do upgrades, check the file /var/sysgen/master.d/scsi to see if it has
changed. Otherwise your jukebox could be rendered unuseable. In particular,
check if it has been replaced by a new version and renamed to "./scsi.O/.".
-If you use the AMANDA package provided by freeware.sgi.com, you are not
-affected by the first question since at compile time the AMANDA operator is
+If you use the Amanda package provided by freeware.sgi.com, you are not
+affected by the first question since at compile time the Amanda operator is
"root:sys".
SCO
-Jens Krause <jens@transcom.de> has reported some problems with GNUtar 1.12 on
-SCO Release 5. Although the `sparse' files patch was applied, GNU tar would
+Jens Krause <jens@transcom.de> has reported some problems with GNU-tar 1.12 on
+SCO Release 5. Although the `sparse' files patch was applied, GNU-tar would
consistently crash. GNUtar had to be built linked with malloc-libraries, and
the `--sparse' switches had to be removed from client-src/sendbackup-gnutar.c
and client-src/sendsize.c.
FreeBSD 4.9
Sep. 28th, 2004: Jason Miller <jwm@interlinc.net> reported problems with
-setting up the AMANDA-client on FreeBSD 4.9. He wrote:
-Due to the need for read permissions for AMANDA-client the default user and
+setting up the Amanda-client on FreeBSD 4.9. He wrote:
+Due to the need for read permissions for Amanda-client the default user and
group for this on FreeBSD 4.9 is "operator:operator" which I found a write up
on that as well. Just a note the port wanted to install it with these user
permissions by default and I initially changed them to match my Redhat 9.0
install. So just doing a
-make distclean uninstall install AMANDA_SERVER=servername
+make distclean uninstall install Amanda_SERVER=servername
fixed that for me. Then I just followed the below instructions and everything
was good to go.
Refer to this link for more details: http://www.freebsd.org/cgi/query-
To make it permanent, just add this line:
net.inet.udp.maxdgram=65535
-
in the file /etc/sysctl.conf.
AIX
sendsize is reported to coredump on AIX 4.3.3, this is a linking problem, try
-configuring AMANDA with the option "--disable-shared".
+configuring Amanda with the option "--disable-shared".
Microsoft Windows
-Although AMANDA won't run standalone on MS-Windows hosts, it is possible to use
+Although Amanda won't run standalone on MS-Windows hosts, it is possible to use
it to back up their disks, by using SAMBA. Please read Backup_PC_hosts_using
Samba for more information.
SAMBA may be unable to back up some files due to file locking restrictions.
Mac OS X
-For notes on how to setup AMANDA under Apple's OS X, please refer to http://
+For notes on how to setup Amanda under Apple's OS X, please refer to http://
web.brandeis.edu/pages/view/Bio/AmandaMacOSXCompileNotes, written by Steven
Karel<karel@brandeis.edu>. Thanks to Jose L.Hales-Garcia <jose@stat.ucla.edu>
for the tip.
-------------------------------------------------------------------------------
Prev Up Next
-Part I. Installation Home Chapter 2. AMANDA Installation Notes
+Part I. Installation Home Chapter 2. Amanda Installation Notes
- Chapter 8. AMANDA Tape Changer Support
+ Chapter 8. Amanda Tape Changer Support
Prev Part II. About Tapes and Changers Next
-------------------------------------------------------------------------------
-Chapter 8. AMANDA Tape Changer Support
+Chapter 8. Amanda Tape Changer Support
James da Silva
Introduction
-This document outlines the tape changer support design of AMANDA 2.2 and
+This document outlines the tape changer support design of Amanda 2.2 and
beyond. It defines a small interface for changer software to follow so that
-AMANDA can remain device-independent but still support the widest range of tape
+Amanda can remain device-independent but still support the widest range of tape
software and hardware possible.
The interface is a bit simplistic and has only had complications added when
there is a body of field experience.
Specifying a tape changer in amanda.conf
-All device-specifics are hidden by a glue program that the rest of AMANDA calls
+All device-specifics are hidden by a glue program that the rest of Amanda calls
to interact with the tape changer.
The name of this changer program is given by the "tpchanger" variable in the
file amanda.conf. Example entry:
the changer program itself reads tapedev from amanda.conf. The chg-multi
changer doesn't, as it reads all its configuration arguments from its own
configuration file, specified as changerfile.
-If the tpchanger program does not begin with a '/', AMANDA expects it to reside
+If the tpchanger program does not begin with a '/', Amanda expects it to reside
in libexecdir, and possibly have the version suffix appended depending on how
-AMANDA was configured.
+Amanda was configured.
Two other amanda.conf parameters are available for changer use, however their
definition is left entirely up to the changer script itself. They are
changerfile and changerdev. Typically changerfile will point to the
(0 if it can't, 1 if it can). (required)
Flag indicating whether the changer is searchable
(optional). Shows whether the changer supports the -search and -label commands
-and is able to load a tape given only the AMANDA label string (0 or omitted if
+and is able to load a tape given only the Amanda label string (0 or omitted if
it can't, 1 if it can). (optional)
Examples:
* <tpchanger> -search <labelstr>
-Loads an AMANDA tape by name (labelstr).
+Loads an Amanda tape by name (labelstr).
Output and error handling are the same as the -slot command.
taper, amcheck and amtape will use this command if the changer reports it is
searchable.
% chg-zd-mtx -search DailySet005
5 /dev/nrst8 # exitcode returned is 0
--<tpchanger> -label <labelstr> Associates the AMANDA label <labelstr> with the
+-<tpchanger> -label <labelstr> Associates the Amanda label <labelstr> with the
barcode of the currently loaded (in the tape drive) tape.
Outputs to stdout the current slot and tape device. amlabel will use this
command if your changer is searchable to build up the barcode database.
For all the commands:
An exit code of 0 implies that the operation was completely successful, and the
-output may be parsed by the AMANDA code as described above.
+output may be parsed by the Amanda code as described above.
For non-zero exit codes, the first field is still the slot name, but the actual
error messages are not fixed. They are just displayed and/or logged as-is by
-the calling AMANDA program.
+the calling Amanda program.
An exit code of 1 implies the operation failed in a benign way, for example an
empty slot or an attempt to go backwards in a gravity stacker. The calling
-AMANDA program will print the error message if appropriate and continue,
+Amanda program will print the error message if appropriate and continue,
perhaps requesting a different slot be loaded.
-Any other exit code is considered fatal and will cause AMANDA to stop
+Any other exit code is considered fatal and will cause Amanda to stop
attempting to talk to the tape changer.
Slot names and the "current" slot
notion of current position. Others have no current position when no tape is
loaded: all tapes are in their slots and the changer arm is docked away from
the slots.
-Nevertheless, AMANDA requires tape-changer scripts to maintain the notion of a
+Nevertheless, Amanda requires tape-changer scripts to maintain the notion of a
"current" position. This is for performance reasons: as tapes tend to be loaded
-into the rack in order, and AMANDA uses them in order, the next tape to use can
+into the rack in order, and Amanda uses them in order, the next tape to use can
be found much quicker if the position of the current one is remembered. As an
example, the chg-multi script maintains the current position in a chg-
multi.state file (or any other file specified in a `statefile' line in the
changer configuration file).
-AMANDA does not care how slots are available or how they are named. They could
+Amanda does not care how slots are available or how they are named. They could
be numbered 0 to N-1, numbered 1 to N, or even designated by letter, A .. Z.
The only requirement is that the names do not contain whitespace and that the
names "current", "next", "prev", "first", "last" and "advance" retain their
Operator interface
-The amtape program is the main operator interface to AMANDA's tape changer
+The amtape program is the main operator interface to Amanda's tape changer
support. The commands supported include:
amtape <conf> slot <slot-specifier> Load the tape from the specified slot into
the drive
How amdump interacts with the tape changer
-AMANDA does not require a particular tape label for a run. Any label that
+Amanda does not require a particular tape label for a run. Any label that
matches the labelstr regex and is determined to be "inactive" according to the
tapelist database, may be written to. However, there is a preferred 'next'
tape, the one that is next in the cycle implied by the current tapelist.
not active is picked.
Gravity stackers (anything that can not go backwards):
To avoid going all the way to the bottom of the stacker only to find that the
-preferred tape isn't present and nothing can be done, AMANDA picks the first
+preferred tape isn't present and nothing can be done, Amanda picks the first
tape (starting at the current position) that matches the labelstr and is not
active, regardless of whether it is the preferred tape.
* Using multiple tape drives in a single host to emulate a tape changer. This
can also be used with a single physical drive to write several tapes in an
- AMANDA run.
+ Amanda run.
* Using a gravity stacker or a real changer configured to sequentially load the
this configuration file you may specify that the tapedrive needs an eject
command and an optional waittime, necessary after inserting the tape into the
drive. You are also able to configure a range of slots which should be used by
-your configuration. The idea behind this is, that you don't want AMANDA to
-cycle all the tapes if AMANDA searches exactly one tape. If you have a library
+your configuration. The idea behind this is, that you don't want Amanda to
+cycle all the tapes if Amanda searches exactly one tape. If you have a library
which supports more than one drive you can also specify which drive to use. For
each configuration (there should be at least one) you have to specify a file,
-where AMANDA remembers which tape is actually in the drive. For future use
+where Amanda remembers which tape is actually in the drive. For future use
there is also some stuff for cleaning the drives.
In amanda.conf:
will be dumped in this file. There are 2 log pages were you can see how many
read/write errors (corrected) are processed by the tape
labelfile <filename>
-This file is used for the mapping from barcode labels to AMANDA volume labels.
+This file is used for the mapping from barcode labels to Amanda volume labels.
It is used if the changer has a barcode reader. To initialize run amtape show,
this will add the mapping for the tapes in the magazine.
eject > 1
chg-juke
A shell script that uses the Fermilab "juke" software (see http://www.fnal.gov/
-fermitools/, the "juke" link) to control tape chagners. It supports mounting
+fermitools, the "juke" link) to control tape chagners. It supports mounting
multiple tapes for RAIT tapedrive sets, both multiple jukeboxes, or one jukebox
with multiple tape drives, or combinations. 'juke' must be configured to know
-tape drives by the same name AMANDA calls them. It uses 'changerfile' to track
-AMANDA's current tape state, 'tapedev' must be the tape drive (or RAIT set)
+tape drives by the same name Amanda calls them. It uses 'changerfile' to track
+Amanda's current tape state, 'tapedev' must be the tape drive (or RAIT set)
name, and 'changerdev' is the juke software's name for the changer, or a csh-
glob that expands to several jukebox names (i.e. "changer{a,b,c}").
Where "slot_root_dir" is the tapedev "file:xxx" parameter and "n" the tapecycle
parameter.
-Please refer to How_to_use_the_AMANDA_file-driver for details of usage.
+Please refer to How_to_use_the_Amanda_file-driver for details of usage.
chg-iomega
to your amanda.conf. - Add entry to /etc/fstab to specify mount point of
removable disk and make this disk mountable by any user. - Format all disks,
add a "data" sub directory and label all disks by using amlabel. - Be aware
-that as of version 2.4.4p1, AMANDA can't handle backups that are larger than
+that as of version 2.4.4p1, Amanda can't handle backups that are larger than
the size of the removable disk media. So make sure /etc/amanda/<backup_set>/
disklist specifies chunks smaller than the disk size.
-------------------------------------------------------------------------------
-About Tapes and Changers
+Part II. About Tapes and Changers
Tape-Drives and Tape-Changers
-AMANDA is able to use a wide range of Tape-Drives and Tape-Changers. This
+Amanda is able to use a wide range of Tape-Drives and Tape-Changers. This
section contains information on the concept of the tapetypes as well as
information on how to make use of your tape-changer by using the appropriate
changer-scripts.
7._Tapetypes
- 8._AMANDA_Tape_Changer_Support
+ 8._Amanda_Tape_Changer_Support
Introduction
Notes_about_changer.conf
- AMANDA's_actual_usage_of_chg-scsi
+ Amanda's_actual_usage_of_chg-scsi
Configuration_notes
-------------------------------------------------------------------------------
-Prev Up Next
+Prev Next
Chapter 6. Restore Home Chapter 7. Tapetypes
Refer to http://www.amanda.org/docs/tapetypes.html for the current version of
this document.
-Several tapetype definitions are available in example/amanda.conf They inform
-AMANDA how much it is supposed to be able to store in a tape (length), how much
-space is wasted at the end of a dump image with the EOF mark (filemark) and how
-fast the tape unit is (speed).
-The most inportant parameter is length, since AMANDA may decide to delay a
-backup if length is too small, but, if it is too large, AMANDA may end up
+You may find tapetype-definitions in the example amanda.conf, in the
+mailinglist-archives of the amanda-users-mailinglist at http://
+marc.theaimsgroup.com/?l=amanda-users or in the Amanda-FAQ-O-Matic at http://
+www.amanda.org/fom-serve/cache/1.html. They inform Amanda how much it is
+supposed to be able to store in a tape (length), how much space is wasted at
+the end of a dump image with the EOF mark (filemark) and how fast the tape unit
+is (speed).
+The most inportant parameter is length, since Amanda may decide to delay a
+backup if length is too small, but, if it is too large, Amanda may end up
leaving dumps in the holding disk or having to abort some dump.
Filemark is important if you have many disks, particularly with small
incremental backups. The space wasted by so many filemarks may add up and
If none of the sample tapetype entries match your needs, you may search the
mailing list archives or look up the on-line list of tapetype entries. Just
follow the links from http://www.amanda.org.
-AMANDA provides the amtapetype utility to calculate the size of a tape, to
+Amanda provides the amtapetype utility to calculate the size of a tape, to
generate a "tapetype" entry for your amanda.conf.
Specifying the appropriate tape device, but beware that it may take many hours
to run (it fills the tape twice ...). Make sure you do not use hardware
-------------------------------------------------------------------------------
Prev Up Next
-Part II. About Tapes and Changers Home Chapter 8. AMANDA Tape Changer Support
+Part II. About Tapes and Changers Home Chapter 8. Amanda Tape Changer Support
-------------------------------------------------------------------------------
-Technical Background
+Part V. Technical Background
-How AMANDA really works ...
+How Amanda really works ...
This section contains some papers which describe the technical concepts behind
-AMANDA. You find descriptions of the various APIs as well as a basic draft of
-the internals of AMANDA.
+Amanda. You find descriptions of the various APIs as well as a basic draft of
+the internals of Amanda.
Table of Contents
- 21._How_AMANDA_uses_UDP_and_TCP_ports
+ 22._How_Amanda_uses_UDP_and_TCP_ports
TCP_port_allocation
Firewalls_and_NAT
- 22._AMANDA_dumper_API
+ 23._Amanda_dumper_API
Introduction
Conclusion
- 23._AMANDA_Internals
+ 24._Amanda_Internals
Protocols
taper(read)_and_taper(write)
- 24._AMANDA_Event_API
+ 25._Amanda_Event_API
Introduction
event_loop
+ event_wait
+
event_wakeup
- 25._AMANDA_Security_API
+ 26._Amanda_Security_API
Introduction
- 26._Virtual_Tape_API
+ 27._Virtual_Tape_API
- 27._Using_Kerberos_with_AMANDA
+ 28._Using_Kerberos_with_Amanda
- AMANDA_2.5.0_-_KERBEROS_v4_SUPPORT_NOTES
+ Amanda_2.5.0_-_KERBEROS_v4_SUPPORT_NOTES
Configuration
conf_file
- AMANDA_2.5.0_-_KERBEROS_v5_SUPPORT_NOTES
+ Amanda_2.5.0_-_KERBEROS_v5_SUPPORT_NOTES
Building
-------------------------------------------------------------------------------
-Prev Up Next
-Chapter 20. AMANDA Survey Results Home Chapter 21. How AMANDA uses UDP and
- TCP ports
+Prev Next
+Chapter 21. Amanda WISHLIST Home Chapter 22. How Amanda uses UDP and TCP
+ ports
-Chapter 18. Collection of the top ten AMANDA questions. And answers.
+Chapter 20. Collection of the top ten Amanda questions. And answers.
Prev Part IV. Various Information Next
-------------------------------------------------------------------------------
-Chapter 18. Collection of the top ten AMANDA questions. And answers.
+Chapter 20. Collection of the top ten Amanda questions. And answers.
Stefan G. Weichinger
Reason for starting this list.
Jon LaBadie once wrote to me:
-" I think a good "what is AMANDA", "how is it different", "can I use it in my
+" I think a good "what is Amanda", "how is it different", "can I use it in my
setup", "why is it so different" kinda document is needed to stop the constant
-"how do I put 10 dumps on one tape", or "how do I make AMANDA do full backups
+"how do I put 10 dumps on one tape", or "how do I make Amanda do full backups
on saturday and incrementals ..." queries off the list :)) "
Stefan G. Weichinger
It has become very common for regular mailinglist-participants to use the
abbreviation DLE, which means in its long form
DiskList Entry
-A DLE refers to one entry in the disklist of an AMANDA-configuration. General
+A DLE refers to one entry in the disklist of an Amanda-configuration. General
usage was to describe them as partitions, or file systems. But in fact they do
not have to be either. They can be directory trees, or multiple trees, or trees
with some branches cut off. So the more generic term DLE was coined.
SHORT ANSWER:
DO NOT USE "localhost" as host entry in your disklist entries (aka DLEs). Use
the FQDN (Fully Qualified Domain Name) instead.
-In AMANDA-releases newer than 2004-03-22 there is a WARNING issued when you use
+In Amanda-releases newer than 2004-03-22 there is a WARNING issued when you use
something like "localhost" or localhost.localdomain.net in your disklist.
Example (applies to Linux, syntax may be different on other systems):
The first thing to understand is how to read this message. When it says "access
as amanda ..." it is telling you the client side ( amandad) is running as user
"amanda". The "... from amanda@some.amanda.server" part tells you the server
-trying to connect is "some.amanda.server" and the AMANDA command (e.g. amcheck
+trying to connect is "some.amanda.server" and the Amanda command (e.g. amcheck
or amdump) is running as user "amanda".
The user names are typically the same on both client and server, but some
situations use different names and it is important to understand which is
which. For instance, amrecover connects as root ("... from
-root@some.amanda.server") regardless of what the usual AMANDA user is.
+root@some.amanda.server") regardless of what the usual Amanda user is.
Potential problems:
* "some.server" is not spelled exactly that way in ~amanda/.amandahosts. A
some amanda
does not match "some.amanda.server" even though both names may be equivalent.
-When AMANDA looks up the host name in .amandahosts, it uses the exact name it
+When Amanda looks up the host name in .amandahosts, it uses the exact name it
lists in the message. It does not try to look up abbreviations.
The only exception to this is that the lookup is case insensitive.
* The user name listed in ~amanda/.amandahosts is not the one trying to connect
from the server. In particular, watch out for the "root" case listed above
- for amrecover. The AMANDA server typically needs lines like this in its
+ for amrecover. The Amanda server typically needs lines like this in its
.amandahosts file:
name, not "localhost". The sethost command inside amrecover can "fix" this, but
why not just set it up right in the first place?
Another reason to not use "localhost" is because it helps with future changes.
-As the AMANDA configuration grows, it's not at all unusual to take a server and
+As the Amanda configuration grows, it's not at all unusual to take a server and
make it a client of a new, larger, server. But now "localhost" does not point
to the same machine it used to. If the FQDN of the machine had been used all
along, this upgrade would have been much easier.
the friday-tape-question
-"How do I make AMANDA do full backups on Saturday and incrementals ... ?"
+"How do I make Amanda do full backups on Saturday and incrementals ... ?"
"My backup screwed up on tuesday and now it keeps asking for the tuesday tape
even though it is wednesday!"
ANSWER:
The short answer is: You can't.
The longer answer is: You can. But you should not.
-The reason: AMANDA is designed to schedule your backups. Let "her" do it.
-When you want to make the best use of AMANDA, you have to let go the classic
+The reason: Amanda is designed to schedule your backups. Let "her" do it.
+When you want to make the best use of Amanda, you have to let go the classic
schedule where one used to have one tape dedicated to each day of the week, and
one for the friday.
The main difference in concept is this:
In the classic backup scheme you said:
"I want to have incremental backups from Mo-Th and a full backup on Fr."
-Using AMANDA you say:
+Using Amanda you say:
"I want to have at least one full backup in 5 days."
So you don't have to specify exactly WHEN the full backup should happen. You
-just tell AMANDA some goals it should reach and let it work out the details.
+just tell Amanda some goals it should reach and let it work out the details.
There are several advantages in this:
Imagine that you have your classic backup-schedule running fine. Everything is
calculated and designed well, so your tape gets filled well each night.
So the size of the directory raises within one day, maybe for multiple GBs.
Would your classic backup-scheme catch that? Or would it run out of tape,
simply because it was not calculated to have that filesystem with that size?
-AMANDA would try to catch it (and most of the time succeed ...).
-As there is the estimate-phase before actually dumping something, AMANDA can
+Amanda would try to catch it (and most of the time succeed ...).
+As there is the estimate-phase before actually dumping something, Amanda can
look at the DLEs and determine the actual size at the time. It also determines
the size of an incremental backup so it can test for the Plan B to just run a
level-1 if it does not work out to do a level-0 for that DLE.
-If the size of the DLE is much bigger than it has been the run before, AMANDA
+If the size of the DLE is much bigger than it has been the run before, Amanda
still tries to meet your goals. It just reschedules stuff, combining full and
incremental backups to meet the goals as good as possible.
-So you can think of it as some algorithm which lets AMANDA adapt to your data.
-If you set the goals in a reasonable way, AMANDA will just do the rest.
+So you can think of it as some algorithm which lets Amanda adapt to your data.
+If you set the goals in a reasonable way, Amanda will just do the rest.
the multiple-dumps-question
Use another backup scheduler.
This question is most often asked by individual computer users as a cost
consideration.
-AMANDA was developed at the University of Maryland Computing Center for use in
+Amanda was developed at the University of Maryland Computing Center for use in
moderately sized computer centers. That it can be used by users of small
computers is a testament to its designers and maintainers.
While it may seem cost effective to put as many dumps as possible on a single
tape, in a computing center that would be considered a very risky decision. The
loss of, or damage to, a single tape would be the loss of many days worth of
dumps. That is too much to chance.
-Thus, AMANDA was designed to never overwrite a non-AMANDA tape, nor an AMANDA
-tape from a different configuration, nor an AMANDA tape from the current
+Thus, Amanda was designed to never overwrite a non-Amanda tape, nor an Amanda
+tape from a different configuration, nor an Amanda tape from the current
configuration that is still "active", i.e. has backups on the tape more recent
than the dumpcycle length.
-If you still feel you want AMANDA to put multiple dumps on a single tape, there
+If you still feel you want Amanda to put multiple dumps on a single tape, there
is a crude way to accomplish your goal.
But first ask yourself, "If my data is worth so little that I can not afford a
few more tapes, why am I backing it up?"
tape out for a week. Then stick it in and run amflush.
(Better make sure you have sufficient disk space on your holding disk.)
Note, a slight variant of this is to have the parameter autoflush in
-amanda.conf set to "yes". (Users of older AMANDA-releases should check out if
+amanda.conf set to "yes". (Users of older Amanda-releases should check out if
their version already supports that parameter.)
Then after several dumps have collected in the holding disk, put the tape in
before that day's amdump is scheduled. amdump will both flush the holding disk
"How do i get off this damn mailing list?"
ANSWER:
-Frequent users of the AMANDA-users-mailing-list get mails like containing
+Frequent users of the Amanda-users-mailing-list get mails like containing
"unsubscribe"
as people are trying desperately to get off the list.
-Everyone that subscribes to AMANDA-users gets a mail in which the following is
+Everyone that subscribes to Amanda-users gets a mail in which the following is
contained:
>Welcome to the amanda-users mailing list!
>Please save this message for future reference. Thank you.
the distro-question
-"Where can i get binary distributions of AMANDA?"
+"Where can i get binary distributions of Amanda?"
ANSWER:
It is well known that various distributions of Linux contain precompiled
-packages of AMANDA-servers and -clients.
-Due to the design of the AMANDA source code, in which MANY features can be
+packages of Amanda-servers and -clients.
+Due to the design of the Amanda source code, in which MANY features can be
configured at compile-time, it is heavily and heartily recommended to take the
effort and roll your own special flavour.
-Thinking about these things before actually doing backups with AMANDA will help
+Thinking about these things before actually doing backups with Amanda will help
you in many ways. And you get the benefits of compiling your own paths/devices/
-configurations right into your AMANDA-binaries. You also get the benefit of a
-much more improved understanding of the way AMANDA does backups.
+configurations right into your Amanda-binaries. You also get the benefit of a
+much more improved understanding of the way Amanda does backups.
the index-question
"Why does amrecover say there are no index files?"
ANSWER:
-It is very likely that AMANDA is right about that. Check your dumptypes and
+It is very likely that Amanda is right about that. Check your dumptypes and
make sure they include the line:
index yes
the tapetype-questions
" amtapetype has been running for 9 days, is this normal?"
-"Will AMANDA work with my frozboz tape drive/library?"
+"Will Amanda work with my frozboz tape drive/library?"
"Which device is my changer?"
" amtapetype is broken, it says my 200GB tape only holds 65GB."
"My file marks are HUGE, 1.3MB (on a 200GB tape, i.e. about 0.05% of the total
capacity, or expressed another way, maybe 2 mm of a 125000 mm tape ...)"
ANSWER:
-It is crucial to tell AMANDA the truth about the tape-device(s) you want to
-use. Given the wrong values, AMANDA can't calculate proper dumpsizes, free
+It is crucial to tell Amanda the truth about the tape-device(s) you want to
+use. Given the wrong values, Amanda can't calculate proper dumpsizes, free
tape-space or make valuable use of compression.
Before you consider running amtapetype, think twice. Twice.
As tapedrives tend to be produced by not-so-small companies and as those not-
is very likely that someone else has the same device you have or at least one
that uses the same technology.
Many people have already run amtapetype to determine the proper values to fill
-in their amanda.conf-files. Browse the example amanda.conf in your AMANDA-
-tarball for various tapetypes. Browse the AMANDA-FAQ on http://www.amanda.org.
+in their amanda.conf-files. Browse the example amanda.conf in your Amanda-
+tarball for various tapetypes. Browse the Amanda-FAQ on http://www.amanda.org.
Chances are high that you find just your device described.
As in every other topic discussed in internet mailing lists, please try finding
-an answer there before asking on the AMANDA-users list.
-If your device is so exotic that even the AMANDA-users can't help you, you
+an answer there before asking on the Amanda-users list.
+If your device is so exotic that even the Amanda-users can't help you, you
still have your copy of amtapetype.
Before you start running it, note this:
"How do I back up a partition that won't fit on a tape?"
aka
-"Can AMANDA span one file over multiple tapes?"
+"Can Amanda span one file over multiple tapes?"
ANSWER:
There are two basic rules when it comes to these things:
-* AMANDA supports using more than one tape in a single run of amdump
-* AMANDA does not support splitting a dump image across tapes
+* Amanda supports using more than one tape in a single run of amdump
+* Amanda does not support splitting a dump image across tapes
The first rule lets you make use of two or more tapes for a single amdump when
using a tapechanger-robot or a tape-library. You could even use multiple tapes
exclude append "./bigdir"
}
-(example taken from a mail by Paul Bijnens on the AMANDA-users-list)
+(example taken from a mail by Paul Bijnens on the Amanda-users-list)
The trick is to form several chunks of data of which each fits on tape. In the
example above the chunks are formed by regular expressions matching files named
like file00, file123 and file9999. You have to look at your DLEs to find the
patterns describing your chunks.
-As this technique forms data-chunks that fit on your tape it also helps AMANDA
+As this technique forms data-chunks that fit on your tape it also helps Amanda
to schedule your backups more flexible. Having more and smaller DLEs, the
planner has more variations to possibly schedule your backups, so this will
help getting nice output from amadmin <conf> balance, too.
Note
-DLE-spanning might be supported by AMANDA in a future release.
+DLE-spanning might be supported by Amanda in a future release.
the GUI-question
-"Is anyone working on a GUI for AMANDA?"
+"Is anyone working on a GUI for Amanda?"
ANSWER:
-Actually there are people working on GUIs for AMANDA. Aside from that the
-question really is: "Does anyone need a GUI for AMANDA?"
+Actually there are people working on GUIs for Amanda. Aside from that the
+question really is: "Does anyone need a GUI for Amanda?"
Given the fact that backups tend to be run at night while people tend to sleep,
who would need a fancy GUI showing 3D-backup-diagrams via X11? The only part of
backups where GUIs maybe could add some comfort is recovery for unexperienced
-------------------------------------------------------------------------------
Prev Up Next
-Chapter 17. AMANDA FAQ Home Chapter 19. AMANDA WISHLIST
+Chapter 19. Amanda FAQ Home Chapter 21. Amanda WISHLIST
- Chapter 29. Upgrade Issues
+ Chapter 30. Upgrade Issues
Prev Part VI. Historical files Next
-------------------------------------------------------------------------------
-Chapter 29. Upgrade Issues
+Chapter 30. Upgrade Issues
Stefan G. Weichinger
Refer to http://www.amanda.org/docs/upgrade.html for the current version of
this document.
-AMANDA 2.4.0 has introduced a major incompatibility in the AMANDA protocol.
+Amanda 2.4.0 has introduced a major incompatibility in the Amanda protocol.
This means that pre-2.4.0 clients won't interoperate with a 2.4.0 server, nor
will 2.4.0 clients interoperate with pre-2.4.0 servers. You have to upgrade
them all at the same time.
-To ease the upgrade process AMANDA has, from release 2.4.0 on, a configure flag
-(--with-testing) that will cause AMANDA to use alternate service names (AMANDA-
+To ease the upgrade process Amanda has, from release 2.4.0 on, a configure flag
+(--with-testing) that will cause Amanda to use alternate service names (Amanda-
test) instead of the standard ones. This allows you to keep using your old
-version of AMANDA while you test the new one.
-Depending upon the version of AMANDA you are upgrading from, AMANDA may use a
-different database library to store the backup information, and the new AMANDA
-may not be able to read the old AMANDA database files. In this case, you will
+version of Amanda while you test the new one.
+Depending upon the version of Amanda you are upgrading from, Amanda may use a
+different database library to store the backup information, and the new Amanda
+may not be able to read the old Amanda database files. In this case, you will
want to do something like the following:
Before the upgrade (using the old version of amadmin):
-------------------------------------------------------------------------------
Prev Up Next
-Chapter 28. Response to CPIO Security Home Chapter 30. What once was new
+Chapter 29. Response to CPIO Security Home Chapter 31. What once was new
Notice Issue 11:
- Chapter 16. Using AMANDA
+ Chapter 18. Using Amanda
Prev Part IV. Various Information Next
-------------------------------------------------------------------------------
-Chapter 16. Using AMANDA
+Chapter 18. Using Amanda
John R. Jackson
An_Introduction
- AMANDA_Features
+ Amanda_Features
- Future_Capabilities_of_AMANDA
+ Future_Capabilities_of_Amanda
- AMANDA_Resources
+ Amanda_Resources
- Installing_AMANDA
+ Installing_Amanda
Install_Related_Packages
Perform_Preliminary_Setup
- Configure_the_AMANDA_Build
+ Configure_the_Amanda_Build
- Build_and_Install_AMANDA
+ Build_and_Install_Amanda
- Configuring_AMANDA
+ Configuring_Amanda
Decide_on_a_Tape_Server
Run_amdump
- Read_AMANDA's_Reports
+ Read_Amanda's_Reports
Monitor_Tape_and_Holding_Disk_Status
Miscellanous_Operational_Notes
- Advanced_AMANDA_Configuration
+ Advanced_Amanda_Configuration
Adjust_the_Backup_Cycle
Excluding_Files
- Restoring_with_AMANDA
+ Restoring_with_Amanda
Configuring_and_Using_amrecover
Using_amrestore
- Restoring_Without_AMANDA
+ Restoring_Without_Amanda
is part of the O'Reilly book "Unix Backup & Recovery" by W. Curtis Preston and
has been provided online at http://www.backupcentral.com/amanda.html since the
first edition of this book.
-During the Docbook-conversion of the AMANDA-docs we asked for permission to
-include this chapter in the Official AMANDA documentation and W. Curtis Preston
+During the Docbook-conversion of the Amanda-docs we asked for permission to
+include this chapter in the Official Amanda documentation and W. Curtis Preston
allowed to us to include the now converted version. There will be some updates
to this chapter in the next few months to reflect various changes and
enhancements.
You can find online versions of this chapter at http://www.amanda.org/docs/
using.html and at http://www.backupcentral.com/amanda.html.
-AMANDA, the Advanced Maryland Automated Network Disk Archiver, is a public
+Amanda, the Advanced Maryland Automated Network Disk Archiver, is a public
domain utility developed at the University of Maryland. It is as advanced as a
-free backup utility gets, and has quite a large user community. AMANDA allows
+free backup utility gets, and has quite a large user community. Amanda allows
you to set up a single master backup server to back up multiple hosts to a
-single backup drive. (It also works with a number of stackers.) AMANDA uses
+single backup drive. (It also works with a number of stackers.) Amanda uses
native dump and/or GNU-tar, and can back up a large number of workstations
running multiple versions of Unix. Recent versions can also use SAMBA to back
-up Microsoft Windows (95/98/NT/2000)-based hosts. More information about AMANDA
+up Microsoft Windows (95/98/NT/2000)-based hosts. More information about Amanda
can be found at http://www.amanda.org
-AMANDA was written primarily by James da Silva at the Department of Computer
+Amanda was written primarily by James da Silva at the Department of Computer
Science of the University of Maryland around 1992. The goal was to be able to
back up large numbers of client workstations to a single backup server machine.
-AMANDA was driven by the introduction of large capacity tape drives, such as
+Amanda was driven by the introduction of large capacity tape drives, such as
ExaByte 8mm and DAT 4mm. With these drives, and the increased number of
personal workstations, it no longer made sense to back up individual machines
to separate media. Coordinating access and providing tape hardware was
Note
-Since AMANDA is optimized to take advantage of tape drives, we will use the
+Since Amanda is optimized to take advantage of tape drives, we will use the
word tape throughout this section. However, that doesn't mean that you couldn\19t
use it with an optical or CD-R drive.
-The AMANDA approach is to use a "holding disk" on the tape server machine, do
+The Amanda approach is to use a "holding disk" on the tape server machine, do
several dumps in parallel into files in the holding disk, and have an
independent process take data out of the holding disk. Because most dumps are
small partials, even a modest amount of holding disk space can provide an
almost optimal flow of dump images onto tape.
-AMANDA also has a unique approach to scheduling dumps. A "dump cycle" is
-defined for each area to control the maximum time between full dumps. AMANDA
+Amanda also has a unique approach to scheduling dumps. A "dump cycle" is
+defined for each area to control the maximum time between full dumps. Amanda
takes that information, statistics about past dump performance, and estimates
on the size of dumps for this run to decide which backup level to do. This gets
away from the traditional static "it's Friday so do a full dump of /usr on
-client A" approach and frees AMANDA to balance the dumps so the total run time
+client A" approach and frees Amanda to balance the dumps so the total run time
is roughly constant from day to day.
-AMANDA is freely-available software maintained by the AMANDA Users Group. Based
-on membership of AMANDA-related mailing lists, there are probably well over
-1500 sites using it. This chapter is based on AMANDA version 2.4.2. Updated
-versions of this section will be available with the AMANDA source code.
+Amanda is freely-available software maintained by the Amanda Users Group. Based
+on membership of Amanda-related mailing lists, there are probably well over
+1500 sites using it. This chapter is based on Amanda version 2.4.2. Updated
+versions of this section will be available with the Amanda source code.
-AMANDA Features
+Amanda Features
-AMANDA is designed to handle large numbers of clients and data, yet is
+Amanda is designed to handle large numbers of clients and data, yet is
reasonably simple to install and maintain. It scales well, so small
configurations, even a single host, are possible. The code is portable to a
large number of Unix platforms. It calls standard backup software, such as
vendor provided dump or GNU-tar, to perform actual client dumping. There is
also support for backing up Windows-based hosts via SAMBA. There is no
Macintosh support yet.
-AMANDA provides its own network protocols on top of TCP and UDP. It does not,
+Amanda provides its own network protocols on top of TCP and UDP. It does not,
for instance, use rsh or rdump/rmt. Each client backup program is instructed to
-write to standard output, which AMANDA collects and transmits to the tape
-server host. This allows AMANDA to insert compression and encryption and also
+write to standard output, which Amanda collects and transmits to the tape
+server host. This allows Amanda to insert compression and encryption and also
gather a catalogue of the image for recovery. Multiple clients are typically
backed up in parallel to files in one or more holding disk areas. A separate
tape writing process strives to keep the tape device streaming at maximum
-throughput. AMANDA can run direct to tape without holding disks, but with
+throughput. Amanda can run direct to tape without holding disks, but with
reduced performance.
-AMANDA supports using more than one tape in a single run, but does not yet
+Amanda supports using more than one tape in a single run, but does not yet
split a dump image across tapes. This also means it does not support dump
-images larger than a single tape. AMANDA currently starts a new tape for each
+images larger than a single tape. Amanda currently starts a new tape for each
run and does not provide a mechanism to append a new run to the same tape as a
previous run, which might be an issue for small configurations.
-AMANDA supports a wide range of tape storage devices. It uses basic operations
+Amanda supports a wide range of tape storage devices. It uses basic operations
through the normal operating system I/O subsystem and a simple definition of
characteristics. New devices are usually trivial to add. Several tape changers,
stackers, and robots are supported to provide truly hands-off operation. The
-changer interface is external to AMANDA and well-documented, so unsupported
+changer interface is external to Amanda and well-documented, so unsupported
changers can be added without a lot of effort.
Either the client or tape server may do software compression, or hardware
compression may be used. On the client side, software compression reduces
compression may be selected on an image-by-image basis. If Kerberos is
available, clients may use it for authentication and dump images may be
encrypted. Without Kerberos, .amandahosts authentication (similar to .rhosts)
-is used, or AMANDA may be configured to use .rhosts (although rsh/rlogin/rexec
-are not themselves used). AMANDA works well with security tools like TCP
+is used, or Amanda may be configured to use .rhosts (although rsh/rlogin/rexec
+are not themselves used). Amanda works well with security tools like TCP
Wrappers (ftp://info.cert.org/pub/network_tools) and firewalls.
Since standard software is used for generating dump images and software
compression, only normal Unix tools such as mt, dd, and gunzip/uncompress are
-needed to recover a dump image from tape if AMANDA is not available. When
-AMANDA software is available, it locates which tapes are needed and finds
+needed to recover a dump image from tape if Amanda is not available. When
+Amanda software is available, it locates which tapes are needed and finds
images on the tapes.
-AMANDA is meant to run unattended, such as from a nightly cron job. Client
-hosts that are down or hung are noted and bypassed. Tape errors cause AMANDA to
+Amanda is meant to run unattended, such as from a nightly cron job. Client
+hosts that are down or hung are noted and bypassed. Tape errors cause Amanda to
fall back to ?degraded? mode where backups are still performed but only to the
holding disks. They may be flushed to tape by hand after the problem is
resolved.
-AMANDA has configuration options for controlling almost all aspects of the
+Amanda has configuration options for controlling almost all aspects of the
backup operation and provides several scheduling methods. A typical
configuration does periodic full dumps with partial dumps in between. There is
also support for:
* Periodic archival backup, such as taking full dumps to a vault away from the
primary site.
-* Incremental-only backups where full dumps are done outside of AMANDA, such as
+* Incremental-only backups where full dumps are done outside of Amanda, such as
very active areas that must be taken offline, or no full dumps at all for
areas that can easily be recovered from vendor media.
* Always doing full dumps, such as database areas that change completely
such as a periodic archival configuration along side a normal daily
configuration. Multiple configurations can run simultaneously on the same tape
server if there are multiple tape drives.
-Scheduling of full dumps is typically left up to AMANDA. They are scattered
+Scheduling of full dumps is typically left up to Amanda. They are scattered
throughout the dump cycle to balance the amount of data backed up each run.
It's important to keep logs of where backup images are for each area (which
-AMANDA does for you), since they are not on a specific, predictable, tape
+Amanda does for you), since they are not on a specific, predictable, tape
(e.g., the Friday tape will not always have a full dump of /usr for client A).
-The partial backup level is also left to AMANDA. History information about
+The partial backup level is also left to Amanda. History information about
previous levels is kept and the backup level automatically increases when
sufficient dump size savings will be realized.
-AMANDA uses a simple tape management system and protects itself from
+Amanda uses a simple tape management system and protects itself from
overwriting tapes that still have valid dump images and from tapes not
allocated to the configuration. Images may be overwritten when a client is down
for an extended period or if not enough tapes are allocated, but only after
-AMANDA has issued several warnings. AMANDA can also be told to not reuse
+Amanda has issued several warnings. Amanda can also be told to not reuse
specific tapes.
A validation program may be used before each run to note potential problems
during normal working hours when they are easier to correct. An activity report
-is sent via e-mail after each run. AMANDA can also send a report to a printer
+is sent via e-mail after each run. Amanda can also send a report to a printer
and even generate sticky tape labels.
There is no graphical interface. For administration, there is usually only a
single simple text file to edit, so this is not much of an issue. For security
-reasons, AMANDA does not support user controlled file recovery. There is an
+reasons, Amanda does not support user controlled file recovery. There is an
ftp-like restore utility for administrators to make searching online dump
catalogues easier when recovering individual files.
-Future Capabilities of AMANDA
+Future Capabilities of Amanda
In addition to the usual enhancements and fixes constantly being added by the
-AMANDA Core Development Team, three main changes are in various stages of
+Amanda Core Development Team, three main changes are in various stages of
development.
* A new internal security framework will make it easier for developers to add
other security methods, such as SSH (ftp://ftp.cs.hut.fi/pub/ssh/) and SSL
(Secure Socket Layer).
-* Another major project is a redesign of how AMANDA runs the client dump
+* Another major project is a redesign of how Amanda runs the client dump
program. This is currently hardcoded for a vendor dump program, GNU-tar or
SAMBA tar. The new mechanism will allow arbitrary programs such as cpio,
star, and possibly other backup systems. It will also add optional pre-dump
* In addition, the output format will be enhanced to include a file-1 and a
file-n. The idea is to put site-defined emergency recovery tools in file-1
(the first file on the output) that can be retrieved easily with standard
- non-AMANDA programs like tar, then use those tools to retrieve the rest of
+ non-Amanda programs like tar, then use those tools to retrieve the rest of
the data. The file-n area is the last file on the output and can contain
- items such as the AMANDA database, which would be complete and up to date by
+ items such as the Amanda database, which would be complete and up to date by
the time file-n is written.
-AMANDA Resources
+Amanda Resources
-AMANDA may be obtained via the web page http://www.amanda.org or with anonymous
+Amanda may be obtained via the web page http://www.amanda.org or with anonymous
ftp at ftp://ftp.amanda.org/pub/amanda.A typical release is a gzip compressed
tar file with a name like amanda-2.4.1.tar.gz, which means it is major version
2.4 and minor version 1. There are occasional patch releases that have a name
like amanda-2.4.1p1.tar.gz (release 2.4.1 plus patch set 1). Beta test pre-
releases have a names like amanda-2.5.0b3.tar.gz (third beta test pre-release
of 2.5.0).
-Some operating system distributions provide pre-compiled versions of AMANDA,
-but because AMANDA hardcodes some values into the programs, they may not match
+Some operating system distributions provide pre-compiled versions of Amanda,
+but because Amanda hardcodes some values into the programs, they may not match
the configuration. Work is being done to move these values to run-time
-configuration files, but for now AMANDA should be built from source.
-The AMANDA web page contains useful information about patches not yet part of a
+configuration files, but for now Amanda should be built from source.
+The Amanda web page contains useful information about patches not yet part of a
release, how to subscribe to related mailing lists, and pointers to mailing
list archives. Subscribe to at least amanda-announce to get new release
announcements or amanda-users to get announcements plus see problems and
-resolutions from other AMANDA users. The amanda-users mailing list is a
+resolutions from other Amanda users. The amanda-users mailing list is a
particularly good resource for help with initial setup as well as problems.
When posting to it, be sure to include the following information:
-* AMANDA version
+* Amanda version
* OS version on the server and client(s)
* Exact symptoms seen, such as error messages, relevant sections of e-mail
reports, debugging and log files
Finally, the docs directory in the release contains several files with helpful
information, such as a FAQ.
-Installing AMANDA
+Installing Amanda
-After downloading and unpacking the AMANDA release, read the README, docs/
+After downloading and unpacking the Amanda release, read the README, docs/
INSTALL, and docs/SYSTEM.NOTES files. They contain important and up-to-date
-information about how to set up AMANDA.
+information about how to set up Amanda.
Install Related Packages
-Several other packages may be required to complete an AMANDA install. Before
+Several other packages may be required to complete an Amanda install. Before
continuing, you should locate and install packages your environment will need.
In particular, consider the following:
GNU-tar 1.12 or later \14 www.gnu.org
The GNU version of the standard tar program with enhancements to do
partial backups and omit selected files. It is one of the client backup
- programs AMANDA knows how to use.
+ programs Amanda knows how to use.
Samba 1.9.18p10 or later \14 www.samba.org
SAMBA is an implementation of the System Message Block (SMB) protocol
used by Windows-based systems for file access. It contains a tool,
- smbclient, that AMANDA can use to back them up.
+ smbclient, that Amanda can use to back them up.
Perl 5.004 or later \14 www.perl.org
Perl is a scripting programming language oriented toward systems
- programming and text manipulation. It is used for a few optional AMANDA
+ programming and text manipulation. It is used for a few optional Amanda
reporting tools and by some tape changers.
GNU readline 2.2.1 or later \14 www.gnu.org
The GNU readline library may be incorporated into interactive programs to
- provide command-line history and editing. It is built into the AMANDA
+ provide command-line history and editing. It is built into the Amanda
amrecover restoration tool, if available.
GNU awk 3.0.3 or later \14 www.gnu.org
The GNU version of the awk programming language contains a common version
across platforms and some additional features. It is used for the
- optional AMANDA amplot statistics tool.
+ optional Amanda amplot statistics tool.
Gnuplot 3.5 or later \14 ftp://ftp.dartmouth.edu/pub/gnuplot/
This gnuplot library (which has nothing to do with the GNU tools, see the
accompanying README) is a graph plotting package. It is used for the
- optional AMANDA amplot statistics tool.
+ optional Amanda amplot statistics tool.
-Be sure to look in the AMANDA patches directory and the patches section on the
+Be sure to look in the Amanda patches directory and the patches section on the
web page for updates to these packages. SAMBA versions before 2.0.3, in
particular, must have patches applied to make them work properly with Amanda.
Without the patches, backups appear to work but the resulting images are
corrupt.
-When AMANDA is configured, locations of additional software used on the
-clients, such as GNU-tar and SAMBA, get built into the AMANDA programs, so
-additional software must be installed in the same place on the AMANDA build
+When Amanda is configured, locations of additional software used on the
+clients, such as GNU-tar and SAMBA, get built into the Amanda programs, so
+additional software must be installed in the same place on the Amanda build
machine and all the clients.
Perform Preliminary Setup
-A typical AMANDA configuration runs as a user other than root, such as backup
+A typical Amanda configuration runs as a user other than root, such as backup
or amanda, given just enough permissions to do backups. Often, direct login as
the user is disallowed. To use the vendor dump program instead of GNU-tar, the
-AMANDA user must be in a group with read access to the raw disk devices.
+Amanda user must be in a group with read access to the raw disk devices.
Membership in this group should be tightly controlled since it opens up every
file on the client for viewing.
-There are two ways to link AMANDA and the raw device group membership. Either
-put the AMANDA user in the group that currently owns the raw devices, as the
-primary group or as a secondary, or pick a new group for AMANDA and change the
-group ownership of the devices. AMANDA (actually, the vendor dump program)
+There are two ways to link Amanda and the raw device group membership. Either
+put the Amanda user in the group that currently owns the raw devices, as the
+primary group or as a secondary, or pick a new group for Amanda and change the
+group ownership of the devices. Amanda (actually, the vendor dump program)
needs only read access, so turn off group write permission. Turn off all
"world" access.
-To use GNU-tar, AMANDA runs it under a setuid-root program that grants the
-needed permissions. The GNU version of tar must be used with AMANDA. Vendor
+To use GNU-tar, Amanda runs it under a setuid-root program that grants the
+needed permissions. The GNU version of tar must be used with Amanda. Vendor
supplied versions (unless they originated from GNU and are at least version
-1.12) do not work because AMANDA depends on additional features.
+1.12) do not work because Amanda depends on additional features.
-Configure the AMANDA Build
+Configure the Amanda Build
-Use the AMANDA user and group for the --with-user and --with-group options to
+Use the Amanda user and group for the --with-user and --with-group options to
./configure. For instance, to use amanda for the user and backup as the group:
./configure --with-user=amanda --with-group=backup ...
No other options are required for ./configure, but all the possibilities may be
seen with ./configure --help. Don't get carried away changing options. The
-defaults are usually suitable and some require experience with AMANDA to fully
+defaults are usually suitable and some require experience with Amanda to fully
understand. Leave --with-debugging enabled so debug log files are created on
the clients. They take very little space but are often necessary for tracking
down problems.
The normal build creates both tape server and client software. The tape server
-host is often backed up by AMANDA and needs the client parts. However, the
+host is often backed up by Amanda and needs the client parts. However, the
clients usually do not need the tape server parts. A little disk space and
build time may be saved by adding --without-server to the ./configure arguments
when building for them.
The default security mechanism uses a file formatted just like .rhosts but
-called .amandahosts. This keeps AMANDA operations separate from normal rsh/rcp
+called .amandahosts. This keeps Amanda operations separate from normal rsh/rcp
work that might use the same user. It is not recommended, but .rhosts and
hosts.equiv may be used by adding --without-amandahosts to the ./configure
arguments.
The TCP ports used for data transfer may be restricted with --with-portrange to
-use AMANDA between hosts separated by a firewall. A typical entry would be: ./
+use Amanda between hosts separated by a firewall. A typical entry would be: ./
configure --with-portrange=50000,50100 ... This does not affect the initial UDP
requests made from the tape server to the clients. The amanda UDP port
(typically 10080) must be allowed through the firewall.
local/share/config.site or /usr/local/etc/config.site to keep them the same
from build to build. An example is in example/config.site.
-Build and Install AMANDA
+Build and Install Amanda
-After ./configure is done, run make to build AMANDA, then make install to
-install it. The make install step must be done as root because some AMANDA
-programs require system privileges. Unless the base location is changed, AMANDA
+After ./configure is done, run make to build Amanda, then make install to
+install it. The make install step must be done as root because some Amanda
+programs require system privileges. Unless the base location is changed, Amanda
installs into these areas:
Libraries.
/usr/local/libexec
- Private programs only AMANDA uses.
+ Private programs only Amanda uses.
/usr/local/man
Documentation.
-Now is a good time to read the main AMANDA man page. It provides an overview of
-AMANDA, a description of each program, and detailed configuration information.
+Now is a good time to read the main Amanda man page. It provides an overview of
+Amanda, a description of each program, and detailed configuration information.
The following programs must be setuid-root (which make install as root does).
The first group (amcheck,dumper, and planner) run on the tape server machine
and need a privileged network port for secure communication with the clients.
sbin/amcheck
- AMANDA sanity checker program
+ Amanda sanity checker program
libexec/dumper
Client communication program
Setuid wrapper to run GNU-tar as root
All these programs are installed with world access disabled and group access
-set to the AMANDA group from --with-group. Be sure all members of that group
+set to the Amanda group from --with-group. Be sure all members of that group
are trustworthy since rundump and runtar in particular give access to every
-file on the system. If AMANDA software is made available via NFS, be sure the
+file on the system. If Amanda software is made available via NFS, be sure the
mount options allow setuid programs. Also, if GNU-tar is used, root needs write
access to /usr/local/var/amanda/gnutar-lists (or the --with-gnutar-list value
to ./configure) to store information about each partial level.
-If the build has trouble or AMANDA needs to be rebuilt, especially with
+If the build has trouble or Amanda needs to be rebuilt, especially with
different ./configure options, the following sequence makes sure everything is
cleaned up from the previous build: make distclean ./configure ... make make
install (as root) Problems with the ./configure step can sometimes be diagnosed
rerun (see the gcc release installation notes) if the operating system is
upgraded. Running gcc --verbose shows where gcc gets its information, and
contains an indication of the operating system version expected.
-AMANDA needs changes to the network services and inetd configuration files. The
+Amanda needs changes to the network services and inetd configuration files. The
client-src/patch-system script should be able to set up systems in most cases.
It does not currently handle systems that deliver service entries via YP/NIS.
If the script does not work, add the following entries to the services file
(e.g., /etc/services) or YP/NIS map: Amanda 10080/udp Amandaidx 10082/tcp
Amidxtape 10083/tcp
Each client needs an entry in the inetd configuration file (e.g., /etc/
-inetd.conf) like this, substituting the AMANDA user for Amanda and the full
-path to the AMANDA libexec directory for PATH: amanda dgram udp wait Amanda /
+inetd.conf) like this, substituting the Amanda user for Amanda and the full
+path to the Amanda libexec directory for PATH: amanda dgram udp wait Amanda /
PATH/libexec/amandad amandad
-The amanda service is used by all AMANDA controlling programs to perform
+The amanda service is used by all Amanda controlling programs to perform
functions on the clients.
The tape server host needs entries like these if the amrecover tool is to be
used: amandaidx stream tcp nowait Amanda /PATH/libexec/amindexd amindexd
change, send a HUP signal to the inetd process and check the system logs for
errors.
-Configuring AMANDA
+Configuring Amanda
-Once installed, AMANDA must be configured to your environment.
+Once installed, Amanda must be configured to your environment.
Decide on a Tape Server
-The first thing to decide is what machine will be the AMANDA tape server.
-AMANDA can be CPU-intensive if configured to do server compression, and almost
+The first thing to decide is what machine will be the Amanda tape server.
+Amanda can be CPU-intensive if configured to do server compression, and almost
certainly network and I/O-intensive. It does not typically use much real
memory. It needs direct access to a tape device that supports media with enough
capacity to handle the expected load.
To get a rough idea of the backup sizes, take total disk usage (not capacity),
Usage, and divide it by how often full dumps will be done, Runs. Pick an
-estimated run-to-run change rate, Change. Each AMANDA run, on average, does a
+estimated run-to-run change rate, Change. Each Amanda run, on average, does a
full dump of Usage/Runs. Another Usage/Runs*Change is done of areas that got a
full dump the previous run, Usage/Runs*Change* is done of areas that got a full
dump two runs ago, and so on.
Unix operating systems typically incorporate device characteristics into the
file name used to access a tape device. The two to be concerned with are
-"rewind" and "compression." AMANDA must be configured with the non-rewinding
+"rewind" and "compression." Amanda must be configured with the non-rewinding
tape device, so called because when the device is opened and closed it stays at
the same position and does not automatically rewind. This is typically a name
with an n in it, such as /dev/rmt/0n or /dev/nst0. On AIX, it is a name with a
.1 or .5 suffix.
-Put the AMANDA user in the group that currently owns the tape device, either as
-the primary group or as a secondary, or pick a new group for AMANDA and change
-the group ownership of the device. AMANDA needs both read and write access.
+Put the Amanda user in the group that currently owns the tape device, either as
+the primary group or as a secondary, or pick a new group for Amanda and change
+the group ownership of the device. Amanda needs both read and write access.
Turn off all "world" access.
Decide Whether to Use Compression
Dump images may optionally be compressed on the client, the tape server, or the
-tape device hardware. Software compression allows AMANDA to track usage and
+tape device hardware. Software compression allows Amanda to track usage and
make better estimates of image sizes, but hardware compression is more
efficient of CPU resources. Turn off hardware compression when using software
compression on the client or server. See the operating system documentation for
Decide Where the Holding Space Will Be
-If at all possible, allocate some holding disk space for AMANDA on the tape
+If at all possible, allocate some holding disk space for Amanda on the tape
server. Holding disk space can significantly reduce backup time by allowing
several dumps to be done at once while the tape is being written. Also, for
-streaming tape devices, AMANDA keeps the device going at speed, and that may
-increase capacity. AMANDA may be configured to limit disk use to a specific
+streaming tape devices, Amanda keeps the device going at speed, and that may
+increase capacity. Amanda may be configured to limit disk use to a specific
value so it can share with other applications, but a better approach is to
-allocate one or more inexpensive disks entirely to AMANDA.
+allocate one or more inexpensive disks entirely to Amanda.
Ideally, there should be enough holding disk space for the two largest backup
images simultaneously, so one image can be coming into the holding disk while
the other is being written to tape. If that is not practical, any amount that
-holds at least a few of the smaller images helps. The AMANDA report for each
+holds at least a few of the smaller images helps. The Amanda report for each
run shows the size of the dump image after software compression (if enabled).
That, in addition to the amplot and amstatus tools, may be used to tune the
space allocated.
Compute Your Dump Cycle
- Decide how often AMANDA should do full dumps. This is the "dump cycle." Short
+ Decide how often Amanda should do full dumps. This is the "dump cycle." Short
periods make restores easier because there are fewer partials, but use more
-tape and time. Longer periods let AMANDA spread the load better but may require
+tape and time. Longer periods let Amanda spread the load better but may require
more steps during a restore.
Large amounts of data to back up or small capacity tape devices also affect the
-dump cycle. Choose a period long enough that AMANDA can do a full dump of every
+dump cycle. Choose a period long enough that Amanda can do a full dump of every
area during the dump cycle and still have room in each run for the partials.
Typical dump cycles are one or two weeks. Remember that the dump cycle is an
-upper limit on how often full dumps are done, not a strict value. AMANDA runs
+upper limit on how often full dumps are done, not a strict value. Amanda runs
them more often and at various times during the cycle as it balances the backup
load. It violates the limit only if a dump fails repeatedly, and issues
warnings in the e-mail report if that is about to happen.
-By default, AMANDA assumes it is run every day. If that is not the case, set
+By default, Amanda assumes it is run every day. If that is not the case, set
"runs per cycle" (described below) to a different value. For instance, a dump
cycle of seven days and runs per cycle of five would be used if runs are done
only on weekdays.
-Normally, AMANDA uses one tape per run. With a tape changer (even the chg-
+Normally, Amanda uses one tape per run. With a tape changer (even the chg-
manual one), the number of tapes per run may be set higher for extra capacity.
-This is an upper limit on the number of tapes. AMANDA uses only as much tape as
-it needs. AMANDA does not yet do overflow from one tape to another. If it hits
+This is an upper limit on the number of tapes. Amanda uses only as much tape as
+it needs. Amanda does not yet do overflow from one tape to another. If it hits
end of tape (or any other error) while writing an image, that tape is
unmounted, the next one is loaded, and the image starts over from the
beginning. This sequence continues if the image cannot fit on a tape.
More tapes than the minimum should be allocated to handle error situations.
Allocating at least two times the minimum allows the previous full dump to be
used if the most recent full dump cannot be read. Allocating more tapes than
-needed also goes back further in time to recover lost files. AMANDA does not
+needed also goes back further in time to recover lost files. Amanda does not
have a limit on the number of tapes in the tape cycle.
Copy and Edit the Default Configuration File
Pick a name for the configuration (the name Daily will be used for the rest of
this section). Create a directory on the tape server machine to hold the
configuration files, typically /usr/local/etc/amanda/Daily. Access to this
-directory (or perhaps its parent) should be restricted to the AMANDA group or
-even just the AMANDA user.
+directory (or perhaps its parent) should be restricted to the Amanda group or
+even just the Amanda user.
Each tape assigned to a configuration needs a unique label. For this example,
we'll use the configuration name, a dash, and a three-digit suffix, Daily-000
through Daily-999. Do not use blanks, tabs, slashes (/), shell wildcards, or
non-printable characters.
-AMANDA limits network usage so backups do not take all the capacity. This limit
-is imposed when AMANDA is deciding whether to perform a dump by estimating the
+Amanda limits network usage so backups do not take all the capacity. This limit
+is imposed when Amanda is deciding whether to perform a dump by estimating the
throughput and adding that to dumps that are already running. If the value
-exceeds the bandwidth allocated to AMANDA, the dump is deferred until enough
-others complete. Once a dump starts, AMANDA lets underlying network components
+exceeds the bandwidth allocated to Amanda, the dump is deferred until enough
+others complete. Once a dump starts, Amanda lets underlying network components
do any throttling.
Copy the template example/amanda.conf file to the configuration directory and
edit it. Full documentation is in the amanda man page. There are many
org
- This string will be in the Subject line of AMANDA e-mail reports.
+ This string will be in the Subject line of Amanda e-mail reports.
mailto
- Target address for AMANDA e-mail reports.
+ Target address for Amanda e-mail reports.
dumpuser
Same as --with-user from ./configure.
Type of tape media.
netusage
- Network bandwidth allocated to AMANDA.
+ Network bandwidth allocated to Amanda.
labelstr
A regular expression (grep pattern) used to make sure each tape is
- allocated to this AMANDA configuration. Our example might use Daily-[0-9]
+ allocated to this Amanda configuration. Our example might use Daily-[0-9]
[0-9][0-9].
The following parameters probably do not need to be changed, but look at their
-values to know where AMANDA expects to find things:
+values to know where Amanda expects to find things:
infofile
- Location of AMANDA history database. Older versions of AMANDA used this
+ Location of Amanda history database. Older versions of Amanda used this
as the base name of a database file. Newer versions use this as a
directory name.
logdir
- Directory where AMANDA logs are stored.
+ Directory where Amanda logs are stored.
indexdir
- Location of optional AMANDA catalogue database.
+ Location of optional Amanda catalogue database.
Configure the Holding Disk
Define each holding disk in an amanda.conf holdingdisk section. If partitions
-are dedicated to AMANDA, set the use value to a small negative number, such as
--10 MB. This tells AMANDA to use all but that amount of space. If space is
-shared with other applications, set the value to the amount AMANDA may use,
-create the directory and set the permissions so only the AMANDA user can access
+are dedicated to Amanda, set the use value to a small negative number, such as
+-10 MB. This tells Amanda to use all but that amount of space. If space is
+shared with other applications, set the value to the amount Amanda may use,
+create the directory and set the permissions so only the Amanda user can access
it.
-Set a chunksize value for each holding disk. Negative numbers cause AMANDA to
-write dumps larger than the absolute value directly to tape, bypassing the
-holding disk. Positive numbers split dumps in the holding disk into chunks no
-larger than the chunksize value. Even though the images are split in the
+Set a chunksize value for each holding disk. Positive numbers split dumps in
+the holding disk into chunks no larger than the chunksize value. Negative
+numbers are no longer supported. Even though the images are split in the
holding disk, they are written to tape as a single image. At the moment, all
chunks for a given image go to the same holding disk.
Older operating systems that do not support individual files larger than 2GB
Configure Tape Devices and Label Tapes
-AMANDA needs to know some characteristics of the tape media. This is set in a
+Amanda needs to know some characteristics of the tape media. This is set in a
tapetype section. The example amanda.conf, web page, and amanda-users mailing
list archives have entries for most common media. Currently, all tapes should
have the same characteristics. For instance, do not use both 60-meter and 90-
-meter DAT tapes since AMANDA must be told the smaller value, and larger tapes
+meter DAT tapes since Amanda must be told the smaller value, and larger tapes
may be underutilized.
If the media type is not listed and there are no references to it in the
mailing list archives, go to the tape-src directory, make tapetype, mount a
When using hardware compression, change the length value based on the estimated
compression rate. This typically means multiplying by something between 1.5 and
2.0.
-The length and filemark values are used by AMANDA only to plan the backup
-schedule. Once dumps start, AMANDA ignores the values and writes until it gets
+The length and filemark values are used by Amanda only to plan the backup
+schedule. Once dumps start, Amanda ignores the values and writes until it gets
an error. It does not stop writing just because it reaches the tapetype length.
-AMANDA does not currently use the tapetype speed parameter.
+Amanda does not currently use the tapetype speed parameter.
Once the tapetype definition is in amanda.conf, set the tapetype parameter to
reference it.
Without special hardware to mount tapes, such as a robot or stacker, either set
-the tapedev parameter to the no-rewind device name or set up the AMANDA chg-
+the tapedev parameter to the no-rewind device name or set up the Amanda chg-
manual changer. The manual changer script prompts for tape mounts as needed.
-The prompts normally go to the terminal of the person running AMANDA, but the
+The prompts normally go to the terminal of the person running Amanda, but the
changer may be configured to send requests via e-mail or to some other system
logging mechanism.
To configure the manual changer, set tapedev to the no-rewind tape device and
set tpchanger to chg-manual. To send tape mount prompts someplace other than
-the terminal, which is necessary if AMANDA is run from a cron job, see the
+the terminal, which is necessary if Amanda is run from a cron job, see the
request shell function comments in changer-src/chg-manual.sh.in.
Another common tape changer is chg-multi. This script can drive stackers that
advance to the next tape when the drive is unloaded or it can use multiple tape
Make any source changes to the changer-src/chg-multi.sh.in file. That file is
processed by ./configure to generate chg-multi.sh, which turns into chg-multi
with make. If chg-multi.sh or chg-multi is altered, the changes will be lost
-the next time AMANDA is rebuilt.
+the next time Amanda is rebuilt.
A third popular changer is chg-scsi. It can drive devices that have their own
SCSI interface. An operating system kernel module may need to be installed to
-control such devices, like sst for Solaris, which is released with AMANDA, or
+control such devices, like sst for Solaris, which is released with Amanda, or
chio, available for various systems. As with chg-multi, set the amanda.conf
changerfile parameter to the changer configuration file path. There is a sample
in example/chg-scsi.conf. The initial section has parameters common to the
Test any changer setup with the amtape command. Make sure it can load a
specific tape with the slot NNN suboption, eject the current tape with eject
and advance to the next slot with slot next.
-Tapes must be pre-labeled with amlabel so AMANDA can verify the tape is one it
-should use. Run amlabel as the AMANDA user, not root. For instance:
+Tapes must be pre-labeled with amlabel so Amanda can verify the tape is one it
+should use. Run amlabel as the Amanda user, not root. For instance:
# su amanda -c "amlabel Daily Daily-123 slot 123"
The indexing facility generates a compressed catalogue of each dump image.
These are useful for finding lost files and are the basis of the amrecover
program. Long dump cycles or areas with many or very active files can cause the
-catalogues to use a lot of disk space. AMANDA automatically removes catalogues
+catalogues to use a lot of disk space. Amanda automatically removes catalogues
for images that are no longer on tape.
Create a file named disklist in the same directory as amanda.conf and either
copy the file from example/disklist or start a new one. Make sure it is
-readable by the AMANDA user. Each line in disklist defines an area to be backed
+readable by the Amanda user. Each line in disklist defines an area to be backed
up. The first field is the client host name (fully qualified names are
recommended), the second is the area to be backed up on the client and the
third is the dumptype. The area may be entered as a disk name, (sd0a), a device
running SAMBA and the area to the Windows share name, such as //some-pc/C$.
Note that Unix-style forward slashes are used instead of Windows-style backward
slashes.
-Enable AMANDA access to the client from the tape server host (even if the
+Enable Amanda access to the client from the tape server host (even if the
client is the tape server host itself) by editing .amandahosts (or .rhosts,
-depending on what was set with ./configure) in the AMANDA user home directory
-on the client. Enter the fully qualified tape server host name and AMANDA user,
-separated by a blank or tab. Make sure the file is owned by the AMANDA user and
+depending on what was set with ./configure) in the Amanda user home directory
+on the client. Enter the fully qualified tape server host name and Amanda user,
+separated by a blank or tab. Make sure the file is owned by the Amanda user and
does not allow access to anyone other than the owner (e.g. mode 0600 or 0400).
For Windows clients, put the share password in /etc/amandapass on the SAMBA
host. The first field is the Windows share name, the second is the clear text
-password and the optional third field is the domain. Because this file contains
-clear text passwords, it should be carefully protected, owned by the AMANDA
-user and only allow user access. By default, AMANDA uses SAMBA user backup.
-This can be changed with --with-samba-user to ./configure.
+password and the optional third field is the domain.
+
+Note
+
+This info isn't correct anymore. Please refer to Backup_PC_hosts_using_Samba
+for details on this file.
+Because this file contains clear text passwords, it should be carefully
+protected, owned by the Amanda user and only allow user access. By default,
+Amanda uses SAMBA user backup. This can be changed with --with-samba-user to ./
+configure.
Test and Debug Setup
-Test the setup with amcheck. As with all AMANDA commands, run it as the AMANDA
+Test the setup with amcheck. As with all Amanda commands, run it as the Amanda
user, not root:
Many errors reported by amcheck are described in docs/FAQ or the amcheck man
-page. The most common error reported to the AMANDA mailing lists is selfcheck
+page. The most common error reported to the Amanda mailing lists is selfcheck
request timed out, meaning amcheck was not able to talk to amandad on the
client. In addition to the ideas in docs/FAQ, here are some other things to
try:
-* Are the AMANDA services listed properly in /etc/services or a YP/NIS map? The
- C program in Figure 4-1 uses the same system call as AMANDA to look up
+* Are the Amanda services listed properly in /etc/services or a YP/NIS map? The
+ C program in Figure 4-1 uses the same system call as Amanda to look up
entries:
-Example 16.1. A C Program to Check the AMANDA Service Numbers
+Example 18.1. A C Program to Check the Amanda Service Numbers
#include <stdio.h>
amandad?
* Was inetd sent a HUP signal after the configuration file was changed?
* Are there system log messages from inetd about amanda or amandad? For
- instance, inetd complains if it cannot look up the AMANDA services.
+ instance, inetd complains if it cannot look up the Amanda services.
* Is /tmp/amanda/amandad/debug being updated?
* Is the access time on the amandad executable (ls -lu) being updated? If not,
inetd is probably not able to run it, possibly because of an error in the
inetd configuration file or a permission problem.
-* Run the amandad program by hand as the AMANDA user on the client. It should
+* Run the amandad program by hand as the Amanda user on the client. It should
sit for about 30 seconds, then terminate. Enter the full path exactly as it
was given to inetd, perhaps by using copy/paste.
Do not proceed until amcheck is happy with the configuration.
For initial testing, set the record option to no in the global dumptype, but
-remember to set it back to yes when AMANDA goes into normal production. This
+remember to set it back to yes when Amanda goes into normal production. This
parameter controls whether the dump program on the client updates its own
database, such as /etc/dumpdates for vendor dump.
To forget about an individual test run, use amrmtape to remove references to
remove the files or directories named in the infofile and indexdir parameters,
the tapelist file named in the tapelist parameter, all amdump.* files in the
configuration directory and all log.* files in the directory named by the
-logdir parameter. These files contain history information AMANDA needs between
+logdir parameter. These files contain history information Amanda needs between
runs and also what is needed to find particular dump images for restores and
-should be protected when AMANDA goes into production.
+should be protected when Amanda goes into production.
Operating Amanda
-Once configured, you will need to setup the automated use of AMANDA.
+Once configured, you will need to setup the automated use of Amanda.
Run amdump
-The amdump script controls a normal AMANDA backup run. However, it's common to
+The amdump script controls a normal Amanda backup run. However, it's common to
do site-specific things as well with a wrapper shell script around amdump.
amdump is meant to run unattended from cron. See the operating system
-documentation for how to set up a cron task. Be sure it runs as the AMANDA
+documentation for how to set up a cron task. Be sure it runs as the Amanda
user, not root or the installer.
The amdump script does the following:
* If a file named hold is in the configuration directory, amdump pauses until
it goes away. This may be created and removed by hand to temporarily delay
- AMANDA runs without having to change the cron task.
+ Amanda runs without having to change the cron task.
* If it looks like another copy of amdump is running, or a previous run
aborted, amdump logs an error and terminates. If an earlier run aborted,
amcleanup must be run. An amcleanup step should be added to the tape server
system boot sequence to handle crashes. No backups can be performed after an
abort or crash until amcleanup is run.
-* The AMANDA planner program decides what areas to back up and at what level.
+* The Amanda planner program decides what areas to back up and at what level.
It does this by connecting to each client and getting estimated sizes of a
full dump, the same partial level that was done on the previous run and
possibly the next partial level. All clients are done in parallel, but it can
* The amtrmidx program is run to remove old catalogues if indexing has been
used.
-There are several ways to determine which tapes AMANDA will need for a run. One
-is to look at the AMANDA e-mail report from the previous run. The tapes used
+There are several ways to determine which tapes Amanda will need for a run. One
+is to look at the Amanda e-mail report from the previous run. The tapes used
during that run and those expected for the next run are listed. Another is to
run amcheck during normal working hours. In addition to showing which tapes are
needed, it makes sure things are set up properly so problems can be fixed
-before the real AMANDA run. A third is to use the tape suboption of amadmin.
-Without a tape changer, AMANDA expects the first tape to be mounted in the
+before the real Amanda run. A third is to use the tape suboption of amadmin.
+Without a tape changer, Amanda expects the first tape to be mounted in the
drive when it starts. Automated tape changers should be able to locate the
tapes. The chg-manual changer prompts for the tapes.
-Read AMANDA's Reports
+Read Amanda's Reports
-An AMANDA report has several sections:
+An Amanda report has several sections:
* gurgi.cc.purdue.edu was down, so all its backups failed.
* The /var/mail problem on pete.cc.purdue.edu and F$ problem on nt-
test.cc.purdue.edu are detailed later.
-* The /master area on mace.cc.purdue.edu is new to AMANDA so a full dump is
+* The /master area on mace.cc.purdue.edu is new to Amanda so a full dump is
required, but it would not fit in the available tape space for this run.
described further in the next section.
The dump of F$ on nt-test.cc.purdue.edu failed due to a problem with the SAMBA
configuration file. It's marked STRANGE because the line with a question mark
-does not match any of the regular expressions built into AMANDA. When dumping
+does not match any of the regular expressions built into Amanda. When dumping
Windows clients via SAMBA, it's normal to get errors about busy files, such as
PAGEFILE.SYS and the registry. Other arrangements should be made to get these
safely backed up, such as a periodic task on the PC that creates a copy that
-will not be busy at the time AMANDA runs.
+will not be busy at the time Amanda runs.
NOTES:
after a run, or amreport can generate a printed listing. By default, client
names are truncated on the right, area names on the left, to keep the report
width under 80 character. This typically leaves the unique portions of both.
-Two log files are created during an AMANDA run. One is named amdump.NN, where
+Two log files are created during an Amanda run. One is named amdump.NN, where
NN is a sequence number (1 is most recent, 2 is next most recent, etc), and is
in the same directory as amanda.conf. The file contains detailed step by step
information about the run and is used for statistics by amplot and amstatus,
and for debugging. The other file is named log.YYYYMMDD.N where YYYYMMDD is the
-date of the AMANDA run and N is a sequence number in case more than one run is
+date of the Amanda run and N is a sequence number in case more than one run is
made on the same day (0 for the first run, 1 for the second, etc). This file is
in the directory specified by the logdir amanda.conf parameter. It contains a
summary of the run and is the basis for the e-mail report. In fact, amreport
may be run by hand and given an old file to regenerate a report.
Old amdump.NN files are removed by the amdump script. Old log.YYYYMMDD.N files
are not automatically removed and should be cleared out periodically by hand.
-Keeping a full tape cycle is a good idea. If the tape cycle is 40 and AMANDA is
+Keeping a full tape cycle is a good idea. If the tape cycle is 40 and Amanda is
run once a day, the following command would do the job:
also be used afterward to generate statistics on how many dumpers were used,
what held things up and so on.
When a tape error happens on the last tape allowed in a run (as set by
-runtapes), AMANDA continues to do backups into the holding disks. This is
+runtapes), Amanda continues to do backups into the holding disks. This is
called degraded mode. By default, full dumps are not done and any that were
scheduled have a partial done instead. A portion of the holding disk area may
be allocated to do full dumps during degraded mode by reducing the value of the
parameter reserve in amanda.conf below 100%.
A tape server crash may also leave images in the holding disks. Run amflush, as
-the AMANDA user, to flush images in the holding disk to the next tape after
+the Amanda user, to flush images in the holding disk to the next tape after
correcting any problems. It goes through the same tape request mechanism as
amdump. If more than one set of dumps are in the holding disk area, amflush
prompts to choose one to write or to write them all. amflush generates an e-
cycle.
To swap out a partially bad tape, wait until it is about to be used again so
any valid images can still be retrieved. Then swap the tapes, run amrmtape on
-the old tape and run amlabel on the replacement so it has a proper AMANDA
+the old tape and run amlabel on the replacement so it has a proper Amanda
label.
If a tape is marked to not be reused with the no-reuse suboption of amadmin,
-such as one that has been removed or is failing, AMANDA may want a freshly
+such as one that has been removed or is failing, Amanda may want a freshly
labeled tape on the next run to get the number of tapes back up to the full
tape cycle.
-If a tape goes completely bad, use amrmtape to make AMANDA forget about it. As
-with marking a tape no-reuse, this may reduce the number of tapes AMANDA has in
+If a tape goes completely bad, use amrmtape to make Amanda forget about it. As
+with marking a tape no-reuse, this may reduce the number of tapes Amanda has in
use below the tape cycle and it may request a newly labeled tape on the next
run.
make them the same for Daily-099 and Daily-100.
* Update the tapecycle amanda.conf parameter if new tapes are being added.
-These steps let AMANDA know about all tapes, including those that do not have
+These steps let Amanda know about all tapes, including those that do not have
data yet. When the cycle gets to the last old tape (Daily-099), the next tape
used will be the first new one (Daily-100). A new option is planned for amlabel
to do these steps automatically.
disklist file by hand to comment out all the other entries, run amdump, then
restore the disklist file.
Use the force suboption of amadmin to schedule a full dump of an area on the
-next run. Run this as the AMANDA user, not root. AMANDA automatically detects
+next run. Run this as the Amanda user, not root. Amanda automatically detects
new disklist entries and schedules an initial full dump. But for areas that go
through a major change, such as an operating system upgrade or full restore,
-force AMANDA to do a full dump to get things back into sync.
-AMANDA does not automatically notice new client areas, so keep the disklist in
-sync by hand. AMANDA usually notices areas that are removed and reports an
+force Amanda to do a full dump to get things back into sync.
+Amanda does not automatically notice new client areas, so keep the disklist in
+sync by hand. Amanda usually notices areas that are removed and reports an
error as a reminder to remove the entry from the disklist. Use the delete
-suboption of amadmin (as the AMANDA user) to make AMANDA completely forget
+suboption of amadmin (as the Amanda user) to make Amanda completely forget
about an area, but wait until the information is not needed for restores. This
does not remove the entry from the disklist file \14 that must be done by hand.
-Non\14AMANDA backups may still be done with AMANDA installed, but do not let the
+Non\14Amanda backups may still be done with Amanda installed, but do not let the
client dump program update its database. For vendor dump programs, this usually
means not using the u flag, or saving and restoring /etc/dumpdates. For GNU-tar
it means the --listed-incremental flag (if used) should not point to the same
-file AMANDA uses.
+file Amanda uses.
As with all backup systems, verify the resulting tapes, if not each one then at
least periodically or by random sample. The amverify script does a reasonably
good job of making sure tapes are readable and images are valid. For GNU-tar
is readable from tape but not whether it is valid.
Tape drives are notorious for being able to read only what they wrote, so run
amverify on another machine with a different drive, if possible, so an
-alternate is available if the primary drive fails. Make a copy of the AMANDA
+alternate is available if the primary drive fails. Make a copy of the Amanda
configuration directory on the other machine to be able to run amverify. This
-copy is also a good way to have a backup of the AMANDA configuration and
+copy is also a good way to have a backup of the Amanda configuration and
database in case the tape server machine needs to be recovered.
-Advanced AMANDA Configuration
+Advanced Amanda Configuration
-Once you have AMANDA running for a while, you may choose to do some additional
+Once you have Amanda running for a while, you may choose to do some additional
advanced configuration.
Adjust the Backup Cycle
-Several dumptype parameters control the backup level AMANDA picks for a run:
+Several dumptype parameters control the backup level Amanda picks for a run:
dumpcycle
-To run full dumps by hand outside of AMANDA (perhaps they are too large for the
+To run full dumps by hand outside of Amanda (perhaps they are too large for the
normal tape capacity, or need special processing), create a new dumptype and
set strategy to incronly:
-Tell AMANDA when a full dump of the area has been done with the force suboption
+Tell Amanda when a full dump of the area has been done with the force suboption
of amadmin. Take care to do full dumps often enough that the tape cycle does
not wrap around and overwrite the last good non-full backups.
To never do full dumps (such as an area easily regenerated from vendor media),
Only level 1 backups of such areas are done, so wrapping around the tape cycle
is not a problem.
-To do periodic archival full dumps, create a new AMANDA configuration with its
+To do periodic archival full dumps, create a new Amanda configuration with its
own set of tapes but the same disklist as the normal configuration (e.g.
symlink them together). Copy amanda.conf, setting all dumpcycle values to 0 and
record to no, e.g. in the global dumptype. If a changer is used, set runtapes
very high so tape capacity is not a planning restriction. Disable the normal
-AMANDA run, or set the hold file as described in "Operating AMANDA", so AMANDA
+Amanda run, or set the hold file as described in "Operating Amanda", so Amanda
does not try to process the same client from two configurations at the same
time.
Adjust Parallelism
-AMANDA starts several dumper processes and keeps as many as possible running at
+Amanda starts several dumper processes and keeps as many as possible running at
once. The following options control their activity:
may be set up for each one and clients allocated to a particular interface with
field five of the disklist. Individual interfaces take precedence over the
general netusage bandwidth limit and follow the same guidelines described above
-in "Configuring AMANDA": the limit is imposed when deciding whether to start a
-dump, but once a dump starts, AMANDA lets underlying network components do any
+in "Configuring Amanda": the limit is imposed when deciding whether to start a
+dump, but once a dump starts, Amanda lets underlying network components do any
throttling.
-Individual AMANDA interface definitions do not control which physical
+Individual Amanda interface definitions do not control which physical
connection is used. That is left up to the operating system network software.
-While it's common to give an AMANDA interface definition the same name as a
+While it's common to give an Amanda interface definition the same name as a
physical connection, e.g. le0, it might be better to use logical names such as
back-door-atm to avoid confusion.
The starttime dumptype parameter delays a backup some amount of time after
-AMANDA is started. The value is entered as HHMM, so 230, for instance, would
+Amanda is started. The value is entered as HHMM, so 230, for instance, would
wait 2.5 hours. This may be used to delay backups of some areas until they are
known to be idle.
start-wait
All remaining dumps are delayed until a specific time of day.
-If the tape server machine has multiple tape drives, more than one AMANDA
+If the tape server machine has multiple tape drives, more than one Amanda
configuration may run at the same time. Clients and holding disks should be
assigned to only one configuration, however.
-AMANDA waits a fixed amount of time for a client to respond with dump size
+Amanda waits a fixed amount of time for a client to respond with dump size
estimates. The default is five minutes per area on the client. For instance, if
-a client has four areas to back up (entries in disklist), AMANDA waits at most
-20 minutes for the estimates. During dumping, AMANDA aborts a dump if the
+a client has four areas to back up (entries in disklist), Amanda waits at most
+20 minutes for the estimates. During dumping, Amanda aborts a dump if the
client stops sending data for 30 minutes. Various conditions, such as slow
clients, which dump program is used and characteristics of the area, may cause
timeouts. The values may be changed with the amanda.conf etimeout parameter for
their contents, but dump the OLD directory entry itself.
-Restoring with AMANDA
+Restoring with Amanda
Remember that no one cares if you can back up ?only if you can restore.
Configuring and Using amrecover
-One way to restore items with AMANDA is with amrecover on the client. Before
-amrecover can work, AMANDA must run with the dumptype index parameter set to
+One way to restore items with Amanda is with amrecover on the client. Before
+amrecover can work, Amanda must run with the dumptype index parameter set to
yes and the amindexd and amidxtaped services must be installed and enabled to
inetd, usually on the tape server machine (the default build sequence installs
-them). Also, add the client to .amandahosts (or .rhosts) for the AMANDA user on
+them). Also, add the client to .amandahosts (or .rhosts) for the Amanda user on
the server machine. Since amrecover must run as root on the client, the entry
-must list root as the remote user, not the AMANDA user. amrecover should not be
+must list root as the remote user, not the Amanda user. amrecover should not be
made setuid-root because it would open up catalogues of the entire system to
everyone.
For this example, user jj has requested two files, both named molecule.dat, in
# amrecover Daily
AMRECOVER Version 2.4.1p1.
Contacting server on amanda.cc.purdue.edu ...
- 220 amanda AMANDA index server (2.4.1p1) ready.
+ 220 amanda Amanda index server (2.4.1p1) ready.
200 Access OK
Setting restore date to today (1999-01-18)
200 Working date set to 1999-01-18.
configuration uses hardware compression so no software compression data are
available.
A third way to know what tape has an image is to generate a tape table of
-contents with amtoc after each AMANDA run:
+contents with amtoc after each Amanda run:
# partition lvl size[Kb] method
A printed report similar to the amtoc output may be automatically generated by
amreport for each run with the lbl-templ tapetype parameter in amanda.conf
using the example/3hole.ps template.
-The find and info suboptions to amadmin need the AMANDA log files and database.
+The find and info suboptions to amadmin need the Amanda log files and database.
These are not usually large amounts of information and a copy should be pushed
-after each amdump run to an alternate machine that also has the AMANDA tape
+after each amdump run to an alternate machine that also has the Amanda tape
server software installed so they are available if the primary tape server
machine dies. Tools like rdist (ftp://usc.edu/pub/rdist/) or rsync (ftp://
samba.anu.edu.au/pub/rsync/) are useful.
-If AMANDA was built using --with-db=text (the default), the database is stored
+If Amanda was built using --with-db=text (the default), the database is stored
in a set of text files under the directory listed in the infofile amanda.conf
parameter. Here is the file that matches the above info amadmin output:
-Restoring Without AMANDA
+Restoring Without Amanda
-The AMANDA tape format is deliberately simple and restoring data can be done
-without any AMANDA tools if necessary. The first tape file is a volume label
+The Amanda tape format is deliberately simple and restoring data can be done
+without any Amanda tools if necessary. The first tape file is a volume label
with the tape VSN and date it was written. It is not in ANSI VOL1 format, but
is plain text. Each file after that contains one image using 32 KByte blocks.
-The first block is an AMANDA header with client, area and options used to
+The first block is an Amanda header with client, area and options used to
create the image. As with the volume label, the header is not in ANSI format,
but is plain text. The image follows, starting at the next tape block, until
end of file.
-The skip=1 option tells dd to skip over the AMANDA file header. Without the of=
+The skip=1 option tells dd to skip over the Amanda file header. Without the of=
option, dd writes the image to standard output, which can be piped to the
decompression program, if needed, and then to the client restore program.
Since the image header is text, it may be viewed with:
- AMANDA: FILE 19981206 pete.cc.purdue.edu / lev 1
+ Amanda: FILE 19981206 pete.cc.purdue.edu / lev 1
comp N program /usr/sbin/ufsdump
-------------------------------------------------------------------------------
Prev Up Next
-Part IV. Various Information Home Chapter 17. AMANDA FAQ
+Part IV. Various Information Home Chapter 19. Amanda FAQ
-------------------------------------------------------------------------------
-Various Information
+Part IV. Various Information
-Additional information about AMANDA
+Additional information about Amanda
-Here you find various other documents like the AMANDA FAQ, the Top Ten
-Questions and the AMANDA-Wishlist. You can also find the last AMANDA-Survey in
+Here you find various other documents like the Amanda FAQ, the Top Ten
+Questions and the Amanda-Wishlist. You can also find the last Amanda-Survey in
here (although it still needs formatting ... sorry, Jon ...). The latest
-addition is the "famous" AMANDA-chapter by John R. Jackson.
+addition is the "famous" Amanda-chapter by John R. Jackson.
Table of Contents
- 16._Using_AMANDA
+ 18._Using_Amanda
An_Introduction
- AMANDA_Features
+ Amanda_Features
- Future_Capabilities_of_AMANDA
+ Future_Capabilities_of_Amanda
- AMANDA_Resources
+ Amanda_Resources
- Installing_AMANDA
+ Installing_Amanda
Install_Related_Packages
Perform_Preliminary_Setup
- Configure_the_AMANDA_Build
+ Configure_the_Amanda_Build
- Build_and_Install_AMANDA
+ Build_and_Install_Amanda
- Configuring_AMANDA
+ Configuring_Amanda
Decide_on_a_Tape_Server
Run_amdump
- Read_AMANDA's_Reports
+ Read_Amanda's_Reports
Monitor_Tape_and_Holding_Disk_Status
Miscellanous_Operational_Notes
- Advanced_AMANDA_Configuration
+ Advanced_Amanda_Configuration
Adjust_the_Backup_Cycle
Excluding_Files
- Restoring_with_AMANDA
+ Restoring_with_Amanda
Configuring_and_Using_amrecover
Using_amrestore
- Restoring_Without_AMANDA
+ Restoring_Without_Amanda
- 17._AMANDA_FAQ
+ 19._Amanda_FAQ
- 18._Collection_of_the_top_ten_AMANDA_questions._And_answers.
+ 20._Collection_of_the_top_ten_Amanda_questions._And_answers.
Reason_for_starting_this_list.
...
- 19._AMANDA_WISHLIST
-
- 20._AMANDA_Survey_Results
+ 21._Amanda_WISHLIST
-------------------------------------------------------------------------------
-Prev Up Next
-Chapter 15. How to use a wrapper Home Chapter 16. Using AMANDA
+Prev Next
+Chapter 17. How to use different auth with Home Chapter 18. Using Amanda
+Amanda
- Chapter 26. Virtual Tape API
+ Chapter 27. Virtual Tape API
Prev Part V. Technical Background Next
-------------------------------------------------------------------------------
-Chapter 26. Virtual Tape API
+Chapter 27. Virtual Tape API
Stefan G. Weichinger
Refer to http://www.amanda.org/docs/vtape-api.html for the current version of
this document.
-The upper level AMANDA code (including some of the other tape_xxx routines)
+The upper level Amanda code (including some of the other tape_xxx routines)
calls the following routines which implement a virtual tape table:
* int tape_access(filename, mode) Acts like access(2) on possibly virtual
-------------------------------------------------------------------------------
Prev Up Next
-Chapter 25. AMANDA Security API Home Chapter 27. Using Kerberos with AMANDA
+Chapter 26. Amanda Security API Home Chapter 28. Using Kerberos with Amanda
- Chapter 30. What once was new
+ Chapter 31. What once was new
Prev Part VI. Historical files Next
-------------------------------------------------------------------------------
-Chapter 30. What once was new
+Chapter 31. What once was new
-AMANDA Core Team
+Amanda Core Team
Original text
AMANDA Core Team
Table of Contents
- What's_new_in_AMANDA_2.3
+ What's_new_in_Amanda_2.3
Indexing_backups_for_easier_restore
amadmin_import/export
- What's_new_in_AMANDA_2.2
+ What's_new_in_Amanda_2.2
Client_side_setup_has_changed
Refer to http://www.amanda.org/docs/whatwasnew.html for the current version of
this document.
- What's new in AMANDA 2.3
+ What's new in Amanda 2.3
-This document contains notes on new features in AMANDA 2.3 that may not yet be
+This document contains notes on new features in Amanda 2.3 that may not yet be
fully documented elsewhere.
Indexing backups for easier restore
-Read more about this in the file named Indexing_with_AMANDA.
+Read more about this in the file named Indexing_with_Amanda.
Samba Support
GnuTar Support
-AMANDA now supports dumps made via GnuTAR. To use this, set your dumptypes set
+Amanda now supports dumps made via GnuTAR. To use this, set your dumptypes set
the program name to "GNUTAR":
dumptype tar-client {
Since Gnu TAR does not maintain a dumpdates file itself, nor give an estimate
-of backup size, those need to be done within AMANDA. AMANDA maintains an /etc/
+of backup size, those need to be done within Amanda. Amanda maintains an /etc/
amandates file to track the backup dates analogously to how dump does it.
NOTE: if your /etc directory is not writable by your dumpuser, you'll have to
create the empty file initially by hand, and make it writable by your dumpuser
ala /etc/dumpdates.
NOTE: Since tar traverses the directory hierarchy and reads files as a regular
-user would, it must run as root. The two new AMANDA programs calcsize and
+user would, it must run as root. The two new Amanda programs calcsize and
runtar therefore must be installed setuid root. I've made them as simple as
possible to to avoid potential security holes.
The idea is that maxdumps is set roughly proportional to the speed of the
client host. You probably wont get much benefit from setting it very high, but
all but the slowest hosts should be able to handle a maxdumps of at least 2.
-AMANDA doesn't really have any per-host parameters, just per-disk, so the per-
+Amanda doesn't really have any per-host parameters, just per-disk, so the per-
client-host maxdumps is taken from the last disk listed for that host.
Just to make things more complicated, I've added the ability to specify a
"spindle number" for each filesystem in the disklist file. For example:
The spindle number represents the disk number, eg every filesystem on sd0 can
get a spindle number of 0, everything on sd1 gets spindle 1, etc (but there's
no enforced requirement that there be a match with the underlying hardware
-situation). Now, even with a high maxdumps, AMANDA will refrain from scheduling
+situation). Now, even with a high maxdumps, Amanda will refrain from scheduling
two disks on the same spindle at the same time, which would just slow them both
down by adding a lot of seeks.
The default spindle if you don't specify one is -1, which is defined to be a
Bottleneck determination
I've made some experimental changes to driver to determine what the bottleneck
-is at any time. Since AMANDA tries to do many things at once, it's hard to
+is at any time. Since Amanda tries to do many things at once, it's hard to
pinpoint a single bottleneck, but I "think" I've got it down well enough to say
something useful. For now it just outputs the current bottleneck as part of its
"driver: state" line in the debug output, but once I'm comfortable with its
amadmin import/export
amadmin now has "import" and "export" commands, to convert the curinfo database
-to/from text format, for: moving an AMANDA server to a different arch,
+to/from text format, for: moving an Amanda server to a different arch,
compressing the database after deleting lots of hosts, or editing one or all
entries in batch form or via a script.
- What's new in AMANDA 2.2
+ What's new in Amanda 2.2
Note
Here's the old 2.2.x stuff from this file. I'm pretty sure most of this is in
the mainline documentation already.
-This document contains notes on new features in AMANDA 2.2 that may not yet be
+This document contains notes on new features in Amanda 2.2 that may not yet be
fully documented elsewhere.
Client side setup has changed
The new /etc/services lines are:
- amanda 10080/udp # bsd security AMANDA daemon
- kamanda 10081/udp # krb4 security AMANDA daemon
+ amanda 10080/udp # bsd security Amanda daemon
+ kamanda 10081/udp # krb4 security Amanda daemon
The new /etc/inetd.conf lines are:
amanda dgram udp wait /usr/local/libexec/amanda/amandad amandad
kamanda dgram udp wait /usr/local/libexec/amanda/amandad amandad -krb4
-(you don't need the vanilla AMANDA lines if you are using kerberos for
+(you don't need the vanilla Amanda lines if you are using kerberos for
everything, and vice-versa)
Version suffixes on executables
The new USE_VERSION_SUFFIXES define in options.h controls whether to install
-the AMANDA executables with the version number attached to the name, eg
+the Amanda executables with the version number attached to the name, eg
"amdump-2.2.1". I recommend that you leave this defined, since this allows
-multiple versions to co-exist - particularly important while AMANDA 2.2 is
+multiple versions to co-exist - particularly important while Amanda 2.2 is
under development. You can always symlink the names without the version suffix
to the version you want to be your "production" version.
Kerberos
-Read the comments in Using_Kerberos_with_AMANDA for how to configure the
+Read the comments in Using_Kerberos_with_Amanda for how to configure the
kerberos version. With KRB4_SECURITY defined, there are two new dumptype
options:
sgw: This is OLD syntax now ...
- diskdir "/AMANDA2/AMANDA/work" # where the holding disk is
+ diskdir "/Amanda2/Amanda/work" # where the holding disk is
disksize 880 MB # how much space can we use on it
- diskdir "/dumps/AMANDA/work" # a second holding disk!
+ diskdir "/dumps/Amanda/work" # a second holding disk!
disksize 1500 MB
-AMANDA will load-balance between the two disks as long as there is space.
-AMANDA now also actually stats files to get a more accurate view of available
+Amanda will load-balance between the two disks as long as there is space.
+Amanda now also actually stats files to get a more accurate view of available
and used disk space while running.
Remote self-checks
your system has a version of mmap() that will allocate anonymous memory. BSD
4.4 systems (and OSF/1) have an explicitly anonymous mmap() type, but others
(like SunOS) support the trick of mmap'ing /dev/zero for the same effect.
-AMANDA should work with both varieties.
+Amanda should work with both varieties.
Defined HAVE_SYSVSHM or HAVE_MMAP (or both) in config.h. If you have both,
-SYSVSHM is selected (simply because this code in AMANDA is more mature, not
+SYSVSHM is selected (simply because this code in Amanda is more mature, not
because the sysv stuff is better).
gzip support
Initial tape-changer support included
-A new amanda.conf parameter, tpchanger, controls whether AMANDA communicates
+A new amanda.conf parameter, tpchanger, controls whether Amanda communicates
with a tape changer program to load tapes rather than just opening the tapedev
itself. The tpchanger parameter is a string which specifies the name of a
-program that follows the API specified in AMANDA_Tape_Changer_Support. Read
+program that follows the API specified in Amanda_Tape_Changer_Support. Read
that for more information.
Generic tape changer wrapper script
-An initial tape-changer glue script, chg-generic.sh, implements the AMANDA
+An initial tape-changer glue script, chg-generic.sh, implements the Amanda
changer API using an array of tape devices to simulate a tape changer, with the
device names specified via a conf file. This script can be quickly customized
by inserting calls tape-changer-specific programs at appropriate places, making
support for new changers painless. If you know what command to execute to get
-your changer to put a particular tape in the drive, you can get AMANDA to
+your changer to put a particular tape in the drive, you can get Amanda to
support your changer.
The generic script works as-is for sites that want to cascade between two or
more tape drives hooked directly up to the tape server host. It also should
New command amtape
-amtape is the user front-end to the AMANDA tape changer support facilities. The
+amtape is the user front-end to the Amanda tape changer support facilities. The
operators can use amtape to load tapes for restores, position the changer, see
-what AMANDA tapes are loaded in the tape rack, and see which tape would be
+what Amanda tapes are loaded in the tape rack, and see which tape would be
picked by taper for the next amdump run.
No man page yet, but running amtape with no arguments gives a detailed usage
-statement. See AMANDA_Tape_Changer_Support for more info.
+statement. See Amanda_Tape_Changer_Support for more info.
Note
Changer support added to command amlabel
The amlabel command now takes an optional slot argument for labeling particular
-tapes in the tape rack. See AMANDA_Tape_Changer_Support for more info.
+tapes in the tape rack. See Amanda_Tape_Changer_Support for more info.
Tape changer support improved
-The specs in AMANDA_Tape_Changer_Support have been updated, and the code
-changed to match. The major difference is that AMANDA no longer assumes slots
+The specs in Amanda_Tape_Changer_Support have been updated, and the code
+changed to match. The major difference is that Amanda no longer assumes slots
in the tape rack are numbered from 0 to N-1. They can be numbered or labeled in
-any manner that suits your tape-changer, AMANDA doesn't care what the actual
+any manner that suits your tape-changer, Amanda doesn't care what the actual
slot names are. Also added "first" and "last" slot specifiers, and an -eject
command.
The chg-generic.sh tape changer script now has new "firstslot", "lastslot", and
A few words about multi-tape runs
I'm still holding back on support for multiple tapes in one run. I'm not yet
-completely happy with how AMANDA should handle splitting dumps across tapes (eg
+completely happy with how Amanda should handle splitting dumps across tapes (eg
when end-of-tape is encountered in the middle of a long dump). For example,
this creates issues for amrestore, which currently doesn't know about
configurations or tape changers --- on purpose, so that you can do restores on
with no online databases present.
However, because the current snapshot DOES support tape changers, and multiple
runs in one day, some of the benefit of multi-tape runs can be had by simply
-running AMANDA several times in a row. Eg, to fill three tapes per night, you
+running Amanda several times in a row. Eg, to fill three tapes per night, you
can put
amdump <conf>; amdump <conf>; amdump <conf>
Big planner changes
The support for writing to multiple tapes in one run is almost finished now.
-See Multitape_support_in_AMANDA_2.2 for an outline of the design. The planner
+See Multitape_support_in_Amanda_2.2 for an outline of the design. The planner
support for this is included in this snapshot, but the taper part is not.
There is a new amanda.conf variable "runtapes" which specifies the number of
tapes to use on each amdump run. For now this should stay at 1, the default.
There are two visible differences in the new planner: First, planner now thinks
in real-time, rather than by the number of tapes as before. That is, a
filesystem is due for a full backup once every <dumpcycle> days, regardless of
-how many times AMANDA is run in that interval. As a consequence, you need to
+how many times Amanda is run in that interval. As a consequence, you need to
make sure the dumpcycle variable marks real time instead of the number of days.
For example, previously "mincycle 10" worked for a two week cycle if you ran
amdump only on weekdays (for 10 runs in a cycle). Now a two week cycle must be
Level-0 dumps allowed with no tape
-If there is no tape present (or the tape drive fails during dumping), AMANDA
+If there is no tape present (or the tape drive fails during dumping), Amanda
switches to degraded mode. In degraded mode, level-0 dumps are not allowed.
This can be a pain for unattended sites over the weekend (especially when there
-is a large holding disk that can hold any necessary dumps). AMANDA now supports
-a new configuration file directive, "reserve". This tells AMANDA to reserve
+is a large holding disk that can hold any necessary dumps). Amanda now supports
+a new configuration file directive, "reserve". This tells Amanda to reserve
that percentage of total holding disk space for degraded mode dumps. Example:
your total holding disk space adds up to 8.4GB. If you specify a reserve of 50,
4.2GB (50%) of the holding disk space will be allowed to be used for regular
-dumps, but if that limit is hit, AMANDA will switch to degraded dumps. For
+dumps, but if that limit is hit, Amanda will switch to degraded dumps. For
backward compatibility, if no 'reserve' keyword is present, 100 will be assumed
(e.g. never do full dumps if degraded mode is in effect).
Note
This percentage applies from run to run, so, as in the previous example, when
-AMANDA runs the next day, if there is 3.8GB left on the holding disk, 1.9GB
+Amanda runs the next day, if there is 3.8GB left on the holding disk, 1.9GB
will be reserved for degraded mode dumps (e.g. the percentage keeps sliding).
-------------------------------------------------------------------------------
Prev Up Next
-Chapter 29. Upgrade Issues Home Chapter 31. Multitape support in AMANDA 2.2
+Chapter 30. Upgrade Issues Home Chapter 32. Multitape support in Amanda 2.2
- Chapter 19. AMANDA WISHLIST
+ Chapter 21. Amanda WISHLIST
Prev Part IV. Various Information Next
-------------------------------------------------------------------------------
-Chapter 19. AMANDA WISHLIST
+Chapter 21. Amanda WISHLIST
-AMANDA Core Team
+Amanda Core Team
Original text
AMANDA Core Team
If you have any ideas about any of the following, please send an e-mail note to
mailto://amanda-users@amanda.org or mailto://amanda-hackers@amanda.org.
Jean-Louis Martineau, Stefan G. Weichinger,
-AMANDA Core Team
+Amanda Core Team
Oct. 2004.
* Samba: Ports to non-Unix platforms, specifically Macs and PCs. The hooks are
- in the AMANDA protocol to support non-dump backup programs, but no-one has
+ in the Amanda protocol to support non-dump backup programs, but no-one has
volunteered to implement the client side. sgw: Mac OS X is able to run the
client, so only the PC is left, and I suggest that we should go the SAMBA-
way, I think. Samba is working well, is documented and developed further, so
* Samba: multiple exclusion-patterns. Since Samba 3.0.3 smbclient supports the
- usage of multiple exclude-patterns. This would enable AMANDA to exclude more
+ usage of multiple exclude-patterns. This would enable Amanda to exclude more
than one pattern per SMB-share, allowing to exclude pagefile.sys AND the
registry-files, for example.
-* Instead of hard-coding the interface with tape devices in AMANDA, there
+* Instead of hard-coding the interface with tape devices in Amanda, there
should be a higher level interface that allowed different storage devices to
- be used. AMANDA should also be able to retain backups in disk, even after
+ be used. Amanda should also be able to retain backups in disk, even after
they are taped, for faster restore of recently backed up data. It should also
be possible to store a single backup in multiple tapes, for redundancy.
periodicaly if the dumper is still alive (in case the dumper hang).
-* image span / multiple tape. John Stange <building@nap.edu> is working on it.
- His patch will very likely go into a development-branch.
-
-
* retry failed backups in a single run. If backup fails because of active
- filesystems or lack of memory, AMANDA could throw the failed backup away and
+ filesystems or lack of memory, Amanda could throw the failed backup away and
run it again, instead of trying it again in the next run only.
period of time. This could be used to back up secure hosts, for instance.
-* Backups to remote tape devices (i.e., not in the main AMANDA server), as well
+* Backups to remote tape devices (i.e., not in the main Amanda server), as well
as to remote filesystems should be supported.
-* multi-tape : AMANDA should be able to write to many tape at the same time.
+* multi-tape : Amanda should be able to write to many tape at the same time.
Need some criteria to select which dump should go on which tape? By level,
host name, ???
tape could be started first, while doing some dump to holding disk.
-* Autoflush to tape while doing estimate.
-
-
* Keep files on holding disk after taped, that will permit faster recovery
because they will be from holding disk, these dump will be erase when the
same is needed for newer dump.
* chg-disk
This script writes to disks which can be accessed in a parallel way (contrary
- to the serial access to tapes). This could enable AMANDA to do writes and
+ to the serial access to tapes). This could enable Amanda to do writes and
reads to several vtapes in parallel (e.g. doing an amrestore while the
regular amdump is running).
It would be helpful to have a script which generates the needed directory-
* It should be possible to re-generate databases and indexes from tapes.
-* AMANDA could append meta-data like databases and indexes to tape, so that
+* Amanda could append meta-data like databases and indexes to tape, so that
each tape contains its own current indexes and everything to rebuild the
server-config.
-* AMANDA should install man-pages for installed programs only.
-
-
-* We should provide for client-side configuration files, to specify default
- tape server, index server, and perhaps even pathnames to some programs.
+* Amanda should install man-pages for installed programs only.
* It should be possible to configure whether amidxtaped should decompress the
A new script to kill all process on client and server
-* Convert datestamp to timestamp everywhere, that will permit many run a day,
- and be able to recover them easily. it's already done for holding disk.
- (That's a big job, AMANDA use the datestamp sometimes as INT, sometime as
- CHAR*, converting every thing to CHAR* is probably not very difficult, what
- will be difficult will be to stay compatible with the old datestamp.)
-
-
* Enhance the protocol between client-server to allow white-space and any
character in DLE/exclude/include.
* More tools in amadmin. The administrator should be able to look at the
database in various ways. Adding / deleting / moving disks and hosts should
be done through amadmin instead of editing the disklist directly. This will
- allow AMANDA to do some sanity checks for the operators, to make sure
+ allow Amanda to do some sanity checks for the operators, to make sure
permissions are set up right, etc.
Suggested by Chris Jones <cjones@honors.montana.edu>.
shell with a help facility (ala ckermit or gnuplot, if you've seen those).
-* A tape-verify pass after the AMANDA run (we already have one, but it doesn't
+* A tape-verify pass after the Amanda run (we already have one, but it doesn't
work with dump as well as it does with GNU tar). Perhaps taper could
calculate a CRC for each file and store that in the database, to be checked
by the verifier.
-* More sophisticated tape management. Should AMANDA track tapes globally,
+* More sophisticated tape management. Should Amanda track tapes globally,
counting the number of times tapes were used, and recommending retirement for
tapes at the appropriate time?
* Automatically notice that external dumps have been done. Sendsize could also
- notice if a filesystem was dumped externally from AMANDA. Right now the
+ notice if a filesystem was dumped externally from Amanda. Right now the
planner assumes that the incrementals it is doing are relative to the full
dumps it is doing. If someone does a full dump of one of its filesystems (and
- writes /etc/dumpdates) outside of AMANDA, data could be lost. Sun's Backup-
+ writes /etc/dumpdates) outside of Amanda, data could be lost. Sun's Backup-
Copilot handles this well. We should too.
full [AUTOMATIC | SKIP | NOTIFY | FORCE | FIXED]
incr [NONE | BUMP | NOBUMP]
with the following values:
- AUTOMATIC: follow AMANDA scheduling (allow promoted and delayed)
+ AUTOMATIC: follow Amanda scheduling (allow promoted and delayed)
SKIP : full dump are done externally on an fixed schedule, dump nothing when
a full is due (like skip-full).
NOTIFY : full dumps are done externally, but are notified with the NOTIFY
* Remove all compiled options that can be moved to a (the?) configuration file.
- (eg. GNU tar path, if configure can't find it, AMANDA should be able to use
+ (eg. GNU tar path, if configure can't find it, Amanda should be able to use
GNU tar if the path is specified on a client config file) Many people would
like this, it would maybe also bring us closer to the possibility of working
and usable rpms?
* Documentation:
- There is pretty much going on with the AMANDA-docs. The docs have been
- converted to Docbook/XML and form the new module xml-docs in the AMANDA-CVS-
+ There is pretty much going on with the Amanda-docs. The docs have been
+ converted to Docbook/XML and form the new module xml-docs in the Amanda-CVS-
repository.
The FAQ-O-Matic could be replaced by a Wiki. Suggested by Harlan Stenn
<Harlan.Stenn@pfcs.com>.
The WISHLIST should get shortened.
-------------------------------------------------------------------------------
-Prev Up Next
-Chapter 18. Collection of the top ten Home Chapter 20. AMANDA Survey Results
-AMANDA questions. And answers.
+Prev Up Next
+Chapter 20. Collection of the top ten Amanda Home Part V. Technical Background
+questions. And answers.
- Chapter 33. Y2K Compliance
+ Chapter 34. Y2K Compliancy
Prev Part VI. Historical files Next
-------------------------------------------------------------------------------
-Chapter 33. Y2K Compliance
+Chapter 34. Y2K Compliancy
-AMANDA Core Team
+Amanda Core Team
Original text
AMANDA Core Team
Refer to http://www.amanda.org/docs/y2k.html for the current version of this
document.
-The AMANDA developers believe AMANDA is Y2K-compliant, as long as the
+The Amanda developers believe Amanda is Y2K-compliant, as long as the
underlying operating system and C library are. The only date manipulations
-performed by AMANDA use C-language time manipulation functions and/or strings
+performed by Amanda use C-language time manipulation functions and/or strings
where years are represented with the century-included notation.
-------------------------------------------------------------------------------
Prev Up Next
-Chapter 32. Thoughts about a Strategy Home Chapter 34. Usage of floppy tape
+Chapter 33. Thoughts about a Strategy Home Chapter 35. Usage of floppy tape
API drives on Linux
-Chapter 34. Usage of floppy tape drives on Linux
+Chapter 35. Usage of floppy tape drives on Linux
Prev Part VI. Historical files Next
-------------------------------------------------------------------------------
-Chapter 34. Usage of floppy tape drives on Linux
+Chapter 35. Usage of floppy tape drives on Linux
Albrecht Gebhardt
Refer to http://www.amanda.org/docs/zftape.html for the current version of this
document.
-AMANDA now supports the ftape driver version 3.04d (see http://www-
+Amanda now supports the ftape driver version 3.04d (see http://www-
math.math.rwth-aachen.de/~LBFM/claus/ftape ). It adjusts the blocksize
automatically to 32k and supports QIC volume tables.
It uses only one open() call for writing backups to one tape, so the "busy"-
-lamp of the drive will be on all the time. (With normal AMANDA code it would be
+lamp of the drive will be on all the time. (With normal Amanda code it would be
off in pauses between two files written to tape.)
For volume table support you have to get libvtblc first (available at ftp://
pc02-stat.sci.uni-klu.ac.at/pub/Linux/libvtblc.) This library contains the
%
4 VTBL alpha sda6 0 00:00:00 03/15/98 1907 8092 11.45
%
- 5 VTBL AMANDA Tape End 01:45:15 03/16/98 8093 8094 0.00
+ 5 VTBL Amanda Tape End 01:45:15 03/16/98 8093 8094 0.00
%
With lvtblc, currently available with the libvtblc library, you can list the
2 VTBL gamma sda2 0 00:00:00 03/15/98
3 VTBL alpha sda2 0 00:00:00 03/15/98
4 VTBL alpha sda6 0 00:00:00 03/15/98
- 5 VTBL AMANDA Tape End 01:45:15 03/16/98
+ 5 VTBL Amanda Tape End 01:45:15 03/16/98
-Note on datestamps: volume 0 (AMANDA label): reflects the time of starting the
-backup volume i (backup files): AMANDA datestamps of the backup files last
+Note on datestamps: volume 0 (Amanda label): reflects the time of starting the
+backup volume i (backup files): Amanda datestamps of the backup files last
volume (end marker) : reflects the time of finishing the backup
I tested this on a Linux machine (P90 / 96Mb RAM / 256 Mb swap) with two other
clients (Linux / WfW) using
* Linux Kernel 2.0.33,
* ftape 3.04d,
-* AMANDA 2.4.0b6p4
+* Amanda 2.4.0b6p4
with an internal Iomega Ditto 3200 (TR-3) drive attached to an Iomega Ditto
Dash controller (at 2000 Kbps). My tapetype follows:
-------------------------------------------------------------------------------
Prev Up Next
-Chapter 33. Y2K Compliancy Home Part VII. Appendixes
+Chapter 34. Y2K Compliancy Home Part VII. Appendixes
AMANDA_TMPDIR = @AMANDA_TMPDIR@
AMDEP_FALSE = @AMDEP_FALSE@
AMDEP_TRUE = @AMDEP_TRUE@
+AMLINT = @AMLINT@
+AMLINTFLAGS = @AMLINTFLAGS@
AMPLOT_CAT_COMPRESS = @AMPLOT_CAT_COMPRESS@
AMPLOT_CAT_GZIP = @AMPLOT_CAT_GZIP@
AMPLOT_CAT_PACK = @AMPLOT_CAT_PACK@
AMPLOT_COMPRESS = @AMPLOT_COMPRESS@
AMTAR = @AMTAR@
+AM_CFLAGS = @AM_CFLAGS@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AWK = @AWK@
AWK_VAR_ASSIGNMENT_OPT = @AWK_VAR_ASSIGNMENT_OPT@
BINARY_OWNER = @BINARY_OWNER@
+BUILD_MAN_PAGES_FALSE = @BUILD_MAN_PAGES_FALSE@
+BUILD_MAN_PAGES_TRUE = @BUILD_MAN_PAGES_TRUE@
CAT = @CAT@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
# Makefile for sample configuration files
-noinst_DATA = amanda.conf
+noinst_DATA = amanda.conf \
+ amanda-client.conf
EXTRA_DIST = chg-multi.conf chg-scsi.conf config.site disklist \
DLT.ps EXB-8500.ps HP-DAT.ps 8.5x11.ps 3hole.ps DIN-A4.ps \
chg-mcutil.conf
+
+
target_triplet = @target@
subdir = example
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
- $(srcdir)/amanda.conf.in $(srcdir)/chg-mcutil.conf.in
+ $(srcdir)/amanda-client.conf.in $(srcdir)/amanda.conf.in \
+ $(srcdir)/chg-mcutil.conf.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
$(top_srcdir)/configure.in
$(ACLOCAL_M4)
mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs
CONFIG_HEADER = $(top_builddir)/config/config.h
-CONFIG_CLEAN_FILES = amanda.conf chg-mcutil.conf
+CONFIG_CLEAN_FILES = amanda.conf chg-mcutil.conf amanda-client.conf
SOURCES =
DIST_SOURCES =
DATA = $(noinst_DATA)
AMANDA_TMPDIR = @AMANDA_TMPDIR@
AMDEP_FALSE = @AMDEP_FALSE@
AMDEP_TRUE = @AMDEP_TRUE@
+AMLINT = @AMLINT@
+AMLINTFLAGS = @AMLINTFLAGS@
AMPLOT_CAT_COMPRESS = @AMPLOT_CAT_COMPRESS@
AMPLOT_CAT_GZIP = @AMPLOT_CAT_GZIP@
AMPLOT_CAT_PACK = @AMPLOT_CAT_PACK@
AMPLOT_COMPRESS = @AMPLOT_COMPRESS@
AMTAR = @AMTAR@
+AM_CFLAGS = @AM_CFLAGS@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AWK = @AWK@
AWK_VAR_ASSIGNMENT_OPT = @AWK_VAR_ASSIGNMENT_OPT@
BINARY_OWNER = @BINARY_OWNER@
+BUILD_MAN_PAGES_FALSE = @BUILD_MAN_PAGES_FALSE@
+BUILD_MAN_PAGES_TRUE = @BUILD_MAN_PAGES_TRUE@
CAT = @CAT@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
target_cpu = @target_cpu@
target_os = @target_os@
target_vendor = @target_vendor@
-noinst_DATA = amanda.conf
+noinst_DATA = amanda.conf \
+ amanda-client.conf
+
EXTRA_DIST = chg-multi.conf chg-scsi.conf config.site disklist \
DLT.ps EXB-8500.ps HP-DAT.ps 8.5x11.ps 3hole.ps DIN-A4.ps \
chg-mcutil.conf
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
chg-mcutil.conf: $(top_builddir)/config.status $(srcdir)/chg-mcutil.conf.in
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+amanda-client.conf: $(top_builddir)/config.status $(srcdir)/amanda-client.conf.in
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
mostlyclean-libtool:
-rm -f *.lo
--- /dev/null
+### !!! WARNING !!! !!! WARNING !!! !!! WARNING !!! !!! WARNING !!! ###
+### ###
+### This file is not meant to be installed "as is", and in fact, it ###
+### WILL NOT WORK! You must go through it and make changes appropriate ###
+### to your own situation. See the documentation in this file, in the ###
+### "man amanda" man page, in the "docs" directory and at the Amanda ###
+### web page (www.amanda.org). ###
+### ###
+### !!! WARNING !!! !!! WARNING !!! !!! WARNING !!! !!! WARNING !!! ###
+
+#
+# amanda.conf - sample Amanda client configuration file.
+#
+# This file normally goes in @CONFIG_DIR@/amanda-client.conf.
+#
+
+conf "@DEFAULT_CONFIG@" # your config name
+
+index_server "@DEFAULT_SERVER@" # your amindexd server
+tape_server "@DEFAULT_TAPE_SERVER@" # your amidxtaped server
+tapedev "@DEFAULT_TAPE_DEVICE@" # your tape device
+
+# auth - authentication scheme to use between server and client.
+# Valid values are "bsd", "krb4", "krb5" and "ssh".
+# Default: [auth "bsd"]
+auth "bsd"
+
+ssh_keys "" # your ssh keys file if you use ssh auth
+
+# You may include other amanda configuration files, so you can share
+# dumptypes, tapetypes and interface definitions among several
+# configurations.
+
+#includefile "@CONFIG_DIR@/amanda-client.conf.main"
-### !!! WARNING !!! !!! WARNING !!! !!! WARNING !!! !!! WARNING !!! ###
-### ###
-### This file is not meant to be installed "as is", and in fact, it ###
-### WILL NOT WORK! You must go through it and make changes appropriate ###
-### to your own situation. See the documentation in this file, in the ###
-### "man amanda" man page, in the "docs" directory and at the Amanda ###
-### web page (www.amanda.org). ###
-### ###
-### !!! WARNING !!! !!! WARNING !!! !!! WARNING !!! !!! WARNING !!! ###
+# amanda.conf - sample Amanda configuration file. See amanda.conf(5) for
+# details
-#
-# amanda.conf - sample Amanda configuration file. This started off life as
-# the actual config file in use at CS.UMD.EDU.
-#
-# If your configuration is called, say, "csd", then this file normally goes
-# in @CONFIG_DIR@/csd/amanda.conf.
-#
-
-org "@DEFAULT_CONFIG@" # your organization name for reports
-mailto "@CLIENT_LOGIN@" # space separated list of operators at your site
+org "@DEFAULT_CONFIG@" # your organization name for reports
+mailto "@CLIENT_LOGIN@" # space separated list of operators at your site
dumpuser "@CLIENT_LOGIN@" # the user to run dumps under
inparallel 4 # maximum dumpers that will run in parallel (max 63)
taperalgo first # The algorithm used to choose which dump image to send
# to the taper.
-
- # Possible values: [first|firstfit|largest|largestfit|smallest|last]
+ # Possible values:
+ # [first|firstfit|largest|largestfit|smallest|last]
# Default: first.
-
# first First in - first out.
- # firstfit The first dump image that will fit on the current tape.
+ # firstfit The first dump image that will fit
+ # on the current tape.
# largest The largest dump image.
- # largestfit The largest dump image that will fit on the current tape.
+ # largestfit The largest dump image that will fit
+ # on the current tape.
# smallest The smallest dump image.
# last Last in - first out.
bumpmult 4 # threshold = bumpsize * bumpmult^(level-1)
etimeout 300 # number of seconds per filesystem for estimates.
-#etimeout -600 # total number of seconds for estimates.
-# a positive number will be multiplied by the number of filesystems on
-# each host; a negative number will be taken as an absolute total time-out.
-# The default is 5 minutes per filesystem.
-
dtimeout 1800 # number of idle seconds before a dump is aborted.
-
ctimeout 30 # maximum number of seconds that amcheck waits
# for each client host
-tapebufs 20
-# A positive integer telling taper how many 32k buffers to allocate.
-# WARNING! If this is set too high, taper will not be able to allocate
-# the memory and will die. The default is 20 (640k).
+tapebufs 20 # A positive integer telling taper how many
+ # 32k buffers to allocate. The default is 20 (640k).
+
+# By default, Amanda can only track at most one run per calendar day. When
+# the usetimestamps option is enabled, however, Amanda can track as many
+# runs as you care to make.
+# WARNING: This option is not backward-compatible. Do not enable it if you
+# intend to downgrade your server installation to Amanda community
+# edition 2.5
+usetimestamps yes
# Specify tape device and/or tape changer. If you don't have a tape
# parameter. Some rely on a configuration file (changerfile) to
# obtain more information about tape devices, number of slots, etc;
# others just need to store some data in files, whose names will start
-# with changerfile. For more information about individual tape
-# changers, read docs/TAPE.CHANGERS.
+# with changerfile.
# At most one changerfile entry must be defined; select the most
# appropriate one for your configuration. If you select man-changer,
# keep the first one; if you decide not to use a tape changer, you may
# comment them all out.
-runtapes 1 # number of tapes to be used in a single run of amdump
-tpchanger "chg-manual" # the tape-changer glue script
+runtapes 1 # number of tapes to be used in a single run of amdump
+tpchanger "chg-manual" # the tape-changer glue script
tapedev "@DEFAULT_TAPE_DEVICE@" # the no-rewind tape device to be used
rawtapedev "@DEFAULT_RAW_TAPE_DEVICE@" # the raw device to be used (ftape only)
#changerfile "@CONFIG_DIR@/@DEFAULT_CONFIG@/changer"
holdingdisk hd1 {
comment "main holding disk"
directory "/dumps/amanda" # where the holding disk is
- use -100 Mb # how much space can we use on it
- # a non-positive value means:
- # use all space but that value
+ use -100 Mb # how much space can we use on it
+ # a non-positive value means:
+ # use all space but that value
chunksize 1Gb # size of chunk if you want big dump to be
# dumped on multiple files on holding disks
# N Kb/Mb/Gb split images in chunks of size N
# you have selected some database format other than the `text' default)
infofile "@CONFIG_DIR@/@DEFAULT_CONFIG@/curinfo" # database DIRECTORY
logdir "@CONFIG_DIR@/@DEFAULT_CONFIG@" # log directory
-indexdir "@CONFIG_DIR@/@DEFAULT_CONFIG@/index" # index directory
-#tapelist "@CONFIG_DIR/@DEFAULT_CONFIG@/tapelist" # list of used tapes
+indexdir "@CONFIG_DIR@/@DEFAULT_CONFIG@/index" # index directory
+#tapelist "@CONFIG_DIR@/@DEFAULT_CONFIG@/tapelist" # list of used tapes
# tapelist is stored, by default, in the directory that contains amanda.conf
# tapetypes
# it takes only a few seconds but the result is not
# accurate if your disk usage changes from day to day.
# Default: [client]
-# encrypt - specify encryption of the backed up data. Valid values are:
+# encrypt - specify encryption of the backed up data. Valid values are:
# "none" - don't encrypt the dump output.
# "client" - encrypt on the client using the program specified by
# client_encrypt "PROG".
# going to be backed up.
# Default: include all files
# holdingdisk - should the holding disk be used for this dump. Useful for
-# dumping the holding disk itself. Default: [holdingdisk yes]
+# dumping the holding disk itself. Default: [holdingdisk auto]
+# "never" - Never use the holding disk.
+# "auto" - Use the holding disk if possible.
+# "required" - Always use the holding disk.
# ignore - do not back this filesystem up. Useful for sharing a single
# disklist in several configurations.
# index - keep an index of the files backed up. Default: [index no]
# mode", as many incrementals as will fit on the holding disk
# are done, higher priority first, to insure the important
# disks are at least dumped. Default: [priority medium]
-# program - specify the dump system to use. Valid values are "DUMP" and
-# "GNUTAR". Default: [program "DUMP"].
+# program - specify the dump system to use. Valid values are "DUMP",
+# or "GNUTAR". Default: [program "DUMP"].
# record - record the backup in the time-stamp-database of the backup
# program (e.g. /etc/dumpdates for DUMP or
# @GNUTAR_LISTED_INCREMENTAL_DIRX@ for GNUTAR.).
dumpcycle 0
}
+# Dumptypes for gnutar
define dumptype root-tar {
global
program "GNUTAR"
define dumptype holding-disk {
global
comment "The master-host holding disk itself"
- holdingdisk no # do not use the holding disk
+ holdingdisk never # do not use the holding disk
priority medium
}
define dumptype custom-compress {
global
program "GNUTAR"
- comment "test dump with custom client compression"
+ comment "custom client compression dumped with tar"
compress client custom
client_custom_compress "/usr/bin/bzip2"
}
-define dumptype encrypt-fast {
+define dumptype server-encrypt-fast {
global
program "GNUTAR"
- comment "test dump with fast client compression and server symmetric encryption"
+ comment "fast client compression and server symmetric encryption"
compress client fast
encrypt server
- server_encrypt "/usr/local/sbin/amcrypt"
+ server_encrypt "/usr/sbin/amcrypt"
server_decrypt_option "-d"
}
+define dumptype client-encrypt-nocomp {
+ global
+ program "GNUTAR"
+ comment "no compression and client symmetric encryption"
+ compress none
+ encrypt client
+ client_encrypt "/usr/sbin/amcrypt"
+ client_decrypt_option "-d"
+}
+
+
+# To use gpg public-key encryption, gpg does compress with zlib by default.
+# Thus, no need to specify compress
+
+#define dumptype gpg-encrypt {
+# global
+# program "GNUTAR"
+# comment "server public-key encryption, dumped with tar"
+# compress none
+# encrypt server
+# server_encrypt "/usr/sbin/amgpgcrypt"
+# server_decrypt_option "-d"
+#}
+
+
# network interfaces
#
# These are referred to by the disklist file. They define the attributes
#
mcutil mcutil #location of the mcutil program
-tape null: # use ntape for norewind
+tape # use ntape for norewind
# {a|m|h|c} suffixes should NOT
# be tape device since they all
# implement hardware compression
transform = s,x,x,;
+if WANT_AMPLOT
AMPLOT_MAN8_PAGES = amplot.8
+endif
COMMON_MAN8_PAGES = amanda.8
-COMMON_MAN5_PAGES = amanda.conf.5
+COMMON_MAN5_PAGES = amanda.conf.5 \
+ amanda-client.conf.5
+#if WANT_SERVER
SERVER_MAN8_PAGES = amadmin.8 \
amcheck.8 \
amcheckdb.8 \
amverifyrun.8 \
amfetchdump.8 \
amcrypt.8 \
- amaespipe.8
+ amaespipe.8 \
+ amcrypt-ossl.8 \
+ amcrypt-ossl-asym.8
+#endif
if WANT_RECOVER
RECOVER_MAN8_PAGES = amrecover.8
RESTORE_MAN8_PAGES = amrestore.8
endif
-man8_MANS = $(COMMON_MAN8_PAGES)
+man8_MANS = $(COMMON_MAN8_PAGES) \
+ $(AMPLOT_MAN8_PAGES) \
+ $(SERVER_MAN8_PAGES) \
+ $(RECOVER_MAN8_PAGES) \
+ $(RESTORE_MAN8_PAGES)
man5_MANS = $(COMMON_MAN5_PAGES)
-if WANT_AMPLOT
-man8_MANS += $(AMPLOT_MAN8_PAGES)
-endif
-
-if WANT_SERVER
-man8_MANS += $(SERVER_MAN8_PAGES)
-endif
-
-if WANT_RECOVER
-man8_MANS += $(RECOVER_MAN8_PAGES)
-endif
-
-if WANT_RESTORE
-man8_MANS += $(RESTORE_MAN8_PAGES)
-endif
-
ALL_MAN_PAGES = $(AMPLOT_MAN8_PAGES) \
$(COMMON_MAN5_PAGES) \
$(COMMON_MAN8_PAGES) \
xslt/settings.xsl \
entities/global.entities \
entities/xinclude.dtd
-
EXTRA_DIST = $(ALL_MAN_PAGES) $(MAN_XML) $(EXTRA_XML)
-if HAVE_XSLTPROC
-
GEN_XML = $(ALL_MAN_PAGES:%=xml-source/%.proc.xml)
MOSTLYCLEANFILES = $(GEN_XML)
MAINTAINERCLEANFILES = $(ALL_MAN_PAGES)
+if BUILD_MAN_PAGES
+if HAVE_XSLTPROC
xml-source/%.proc.xml: $(SRCMANPAGEDIR)/%.xml $(srcdir)/xslt/expand-sambadoc.xsl
$(XSLTPROC) --path $(srcdir)/xslt/ --xinclude --stringparam latex.imagebasedir "$*/" --stringparam noreference 1 --output $@ $(srcdir)/xslt/expand-sambadoc.xsl $<
%: xml-source/%.proc.xml $(srcdir)/xslt/man.xsl
$(XSLTPROC) --path $(srcdir)/xslt/ --output $@ man.xsl $<
-endif
-# ^- HAVE_XSLTPROC
+else # !HAVE_XSLTPROC
+xml-source/%.proc.xml: $(SRCMANPAGEDIR)/%.xml $(srcdir)/xslt/expand-sambadoc.xsl
+ @echo WARNING: $@ can not be generated: xsltproc is not available.
+
+%: xml-source/%.proc.xml $(srcdir)/xslt/man.xsl
+ @echo WARNING: $@ can not be generated: xsltproc is not available.
+
+endif # HAVE_XSLTPROC
+
+else # !BUILD_MAN_PAGES
+
+xml-source/%.proc.xml: $(SRCMANPAGEDIR)/%.xml $(srcdir)/xslt/expand-sambadoc.xsl
+ @echo Build of $@ skipped.
+
+%: xml-source/%.proc.xml $(srcdir)/xslt/man.xsl
+ @echo Build of $@ skipped.
+
+endif # BUILD_MAN_PAGES
+
+if BUILD_MAN_PAGES
install-data-hook:
@list="$(man8_MANS)"; \
for p in $$list; do \
chgrp $(SETUID_GROUP) $$pa; \
done
+else # !BUILD_MAN_PAGES
+
+install:
+ @echo Skipping man page installation.
+
+endif
+
build_triplet = @build@
host_triplet = @host@
target_triplet = @target@
-@WANT_AMPLOT_TRUE@am__append_1 = $(AMPLOT_MAN8_PAGES)
-@WANT_SERVER_TRUE@am__append_2 = $(SERVER_MAN8_PAGES)
-@WANT_RECOVER_TRUE@am__append_3 = $(RECOVER_MAN8_PAGES)
-@WANT_RESTORE_TRUE@am__append_4 = $(RESTORE_MAN8_PAGES)
subdir = man
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
AMANDA_TMPDIR = @AMANDA_TMPDIR@
AMDEP_FALSE = @AMDEP_FALSE@
AMDEP_TRUE = @AMDEP_TRUE@
+AMLINT = @AMLINT@
+AMLINTFLAGS = @AMLINTFLAGS@
AMPLOT_CAT_COMPRESS = @AMPLOT_CAT_COMPRESS@
AMPLOT_CAT_GZIP = @AMPLOT_CAT_GZIP@
AMPLOT_CAT_PACK = @AMPLOT_CAT_PACK@
AMPLOT_COMPRESS = @AMPLOT_COMPRESS@
AMTAR = @AMTAR@
+AM_CFLAGS = @AM_CFLAGS@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AWK = @AWK@
AWK_VAR_ASSIGNMENT_OPT = @AWK_VAR_ASSIGNMENT_OPT@
BINARY_OWNER = @BINARY_OWNER@
+BUILD_MAN_PAGES_FALSE = @BUILD_MAN_PAGES_FALSE@
+BUILD_MAN_PAGES_TRUE = @BUILD_MAN_PAGES_TRUE@
CAT = @CAT@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
target_cpu = @target_cpu@
target_os = @target_os@
target_vendor = @target_vendor@
-AMPLOT_MAN8_PAGES = amplot.8
+@WANT_AMPLOT_TRUE@AMPLOT_MAN8_PAGES = amplot.8
COMMON_MAN8_PAGES = amanda.8
-COMMON_MAN5_PAGES = amanda.conf.5
+COMMON_MAN5_PAGES = amanda.conf.5 \
+ amanda-client.conf.5
+
+
+#if WANT_SERVER
SERVER_MAN8_PAGES = amadmin.8 \
amcheck.8 \
amcheckdb.8 \
amverifyrun.8 \
amfetchdump.8 \
amcrypt.8 \
- amaespipe.8
+ amaespipe.8 \
+ amcrypt-ossl.8 \
+ amcrypt-ossl-asym.8
+#endif
@WANT_RECOVER_TRUE@RECOVER_MAN8_PAGES = amrecover.8
@WANT_RESTORE_TRUE@RESTORE_MAN8_PAGES = amrestore.8
-man8_MANS = $(COMMON_MAN8_PAGES) $(am__append_1) $(am__append_2) \
- $(am__append_3) $(am__append_4)
+man8_MANS = $(COMMON_MAN8_PAGES) \
+ $(AMPLOT_MAN8_PAGES) \
+ $(SERVER_MAN8_PAGES) \
+ $(RECOVER_MAN8_PAGES) \
+ $(RESTORE_MAN8_PAGES)
+
man5_MANS = $(COMMON_MAN5_PAGES)
ALL_MAN_PAGES = $(AMPLOT_MAN8_PAGES) \
$(COMMON_MAN5_PAGES) \
entities/xinclude.dtd
EXTRA_DIST = $(ALL_MAN_PAGES) $(MAN_XML) $(EXTRA_XML)
-@HAVE_XSLTPROC_TRUE@GEN_XML = $(ALL_MAN_PAGES:%=xml-source/%.proc.xml)
-@HAVE_XSLTPROC_TRUE@MOSTLYCLEANFILES = $(GEN_XML)
-@HAVE_XSLTPROC_TRUE@MAINTAINERCLEANFILES = $(ALL_MAN_PAGES)
+GEN_XML = $(ALL_MAN_PAGES:%=xml-source/%.proc.xml)
+MOSTLYCLEANFILES = $(GEN_XML)
+MAINTAINERCLEANFILES = $(ALL_MAN_PAGES)
all: all-am
.SUFFIXES:
for dir in "$(DESTDIR)$(man5dir)" "$(DESTDIR)$(man8dir)"; do \
test -z "$$dir" || $(mkdir_p) "$$dir"; \
done
-install: install-am
+@BUILD_MAN_PAGES_TRUE@install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
-test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+@BUILD_MAN_PAGES_FALSE@install-data-hook:
clean: clean-am
clean-am: clean-generic clean-libtool mostlyclean-am
uninstall-info-am uninstall-man uninstall-man5 uninstall-man8
-@HAVE_XSLTPROC_TRUE@xml-source/%.proc.xml: $(SRCMANPAGEDIR)/%.xml $(srcdir)/xslt/expand-sambadoc.xsl
-@HAVE_XSLTPROC_TRUE@ $(XSLTPROC) --path $(srcdir)/xslt/ --xinclude --stringparam latex.imagebasedir "$*/" --stringparam noreference 1 --output $@ $(srcdir)/xslt/expand-sambadoc.xsl $<
-
-@HAVE_XSLTPROC_TRUE@%: xml-source/%.proc.xml $(srcdir)/xslt/man.xsl
-@HAVE_XSLTPROC_TRUE@ $(XSLTPROC) --path $(srcdir)/xslt/ --output $@ man.xsl $<
-
-# ^- HAVE_XSLTPROC
-
-install-data-hook:
- @list="$(man8_MANS)"; \
- for p in $$list; do \
- pa=$(DESTDIR)$(man8dir)/`echo $$p|sed '$(transform)'`; \
- echo chown $(BINARY_OWNER) $$pa; \
- chown $(BINARY_OWNER) $$pa; \
- echo chgrp $(SETUID_GROUP) $$pa; \
- chgrp $(SETUID_GROUP) $$pa; \
- done
- @list="$(man5_MANS)"; \
- for p in $$list; do \
- pa=$(DESTDIR)$(man5dir)/`echo $$p|sed '$(transform)'`; \
- echo chown $(BINARY_OWNER) $$pa; \
- chown $(BINARY_OWNER) $$pa; \
- echo chgrp $(SETUID_GROUP) $$pa; \
- chgrp $(SETUID_GROUP) $$pa; \
- done
+@BUILD_MAN_PAGES_TRUE@@HAVE_XSLTPROC_TRUE@xml-source/%.proc.xml: $(SRCMANPAGEDIR)/%.xml $(srcdir)/xslt/expand-sambadoc.xsl
+@BUILD_MAN_PAGES_TRUE@@HAVE_XSLTPROC_TRUE@ $(XSLTPROC) --path $(srcdir)/xslt/ --xinclude --stringparam latex.imagebasedir "$*/" --stringparam noreference 1 --output $@ $(srcdir)/xslt/expand-sambadoc.xsl $<
+
+@BUILD_MAN_PAGES_TRUE@@HAVE_XSLTPROC_TRUE@%: xml-source/%.proc.xml $(srcdir)/xslt/man.xsl
+@BUILD_MAN_PAGES_TRUE@@HAVE_XSLTPROC_TRUE@ $(XSLTPROC) --path $(srcdir)/xslt/ --output $@ man.xsl $<
+
+@BUILD_MAN_PAGES_TRUE@@HAVE_XSLTPROC_FALSE@xml-source/%.proc.xml: $(SRCMANPAGEDIR)/%.xml $(srcdir)/xslt/expand-sambadoc.xsl
+@BUILD_MAN_PAGES_TRUE@@HAVE_XSLTPROC_FALSE@ @echo WARNING: $@ can not be generated: xsltproc is not available.
+
+@BUILD_MAN_PAGES_TRUE@@HAVE_XSLTPROC_FALSE@%: xml-source/%.proc.xml $(srcdir)/xslt/man.xsl
+@BUILD_MAN_PAGES_TRUE@@HAVE_XSLTPROC_FALSE@ @echo WARNING: $@ can not be generated: xsltproc is not available.
+
+@BUILD_MAN_PAGES_FALSE@xml-source/%.proc.xml: $(SRCMANPAGEDIR)/%.xml $(srcdir)/xslt/expand-sambadoc.xsl
+@BUILD_MAN_PAGES_FALSE@ @echo Build of $@ skipped.
+
+@BUILD_MAN_PAGES_FALSE@%: xml-source/%.proc.xml $(srcdir)/xslt/man.xsl
+@BUILD_MAN_PAGES_FALSE@ @echo Build of $@ skipped.
+
+@BUILD_MAN_PAGES_TRUE@install-data-hook:
+@BUILD_MAN_PAGES_TRUE@ @list="$(man8_MANS)"; \
+@BUILD_MAN_PAGES_TRUE@ for p in $$list; do \
+@BUILD_MAN_PAGES_TRUE@ pa=$(DESTDIR)$(man8dir)/`echo $$p|sed '$(transform)'`; \
+@BUILD_MAN_PAGES_TRUE@ echo chown $(BINARY_OWNER) $$pa; \
+@BUILD_MAN_PAGES_TRUE@ chown $(BINARY_OWNER) $$pa; \
+@BUILD_MAN_PAGES_TRUE@ echo chgrp $(SETUID_GROUP) $$pa; \
+@BUILD_MAN_PAGES_TRUE@ chgrp $(SETUID_GROUP) $$pa; \
+@BUILD_MAN_PAGES_TRUE@ done
+@BUILD_MAN_PAGES_TRUE@ @list="$(man5_MANS)"; \
+@BUILD_MAN_PAGES_TRUE@ for p in $$list; do \
+@BUILD_MAN_PAGES_TRUE@ pa=$(DESTDIR)$(man5dir)/`echo $$p|sed '$(transform)'`; \
+@BUILD_MAN_PAGES_TRUE@ echo chown $(BINARY_OWNER) $$pa; \
+@BUILD_MAN_PAGES_TRUE@ chown $(BINARY_OWNER) $$pa; \
+@BUILD_MAN_PAGES_TRUE@ echo chgrp $(SETUID_GROUP) $$pa; \
+@BUILD_MAN_PAGES_TRUE@ chgrp $(SETUID_GROUP) $$pa; \
+@BUILD_MAN_PAGES_TRUE@ done
+
+@BUILD_MAN_PAGES_FALSE@install:
+@BUILD_MAN_PAGES_FALSE@ @echo Skipping man page installation.
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
amadmin - administrative interface to control Amanda backups
.SH "SYNOPSIS"
.HP 8
-\fBamadmin\fR \fIconfig\fR \fIcommand\fR [\fIcommand\fRÂ \fIoptions\fR]
+\fBamadmin\fR \fIconfig\fR \fIcommand\fR [\fIcommand\fR\fIoptions\fR] [-o \fIconfigoption\fR]*
+
.SH "DESCRIPTION"
.PP
\fBAmadmin\fR
on
\fBhostname\fR
(or all hosts). Mostly used for debugging.
+.TP
+\fB-o\fR \fIconfigoption\fR
+See the "\fBCONFIGURATION OVERWRITE\fR" section in
+\fBamanda\fR(8).
.SH "EXAMPLES"
.PP
Request three specific file systems on
.PP
\fBamaespipe\fR
requires
-\fBaespipe\fR
+\fBaespipe\fR,
+\fBuuencode\fR
and
\fBgpg\fR
to work. Aespipe is available from
--- /dev/null
+.\"Generated by db2man.xsl. Don't modify this, modify the source.
+.de Sh \" Subsection
+.br
+.if t .Sp
+.ne 5
+.PP
+\fB\\$1\fR
+.PP
+..
+.de Sp \" Vertical space (when we can't use .PP)
+.if t .sp .5v
+.if n .sp
+..
+.de Ip \" List item
+.br
+.ie \\n(.$>=3 .ne \\$3
+.el .ne 3
+.IP "\\$1" \\$2
+..
+.TH "AMANDA-CLIENT.CONF" 5 "" "" ""
+.SH "NAME"
+amanda-client.conf - Client configuration file for Amanda, the Advanced Maryland Automatic Network Disk Archiver
+.SH "DESCRIPTION"
+.PP
+\fIamanda-client.conf\fR
+is the client configuration file for
+\fBAmanda\fR. This manpage lists the relevant sections and parameters of this file for quick reference.
+.PP
+The files
+\fB<CONFIG_DIR>/amanda-client.conf\fR
+and
+\fB<CONFIG_DIR>/<config>/amanda-client.conf\fR
+are loaded.
+.SH "PARAMETERS"
+.PP
+There are a number of configuration parameters that control the behavior of the
+\fBAmanda\fR
+programs. All have default values, so you need not specify the parameter in
+\fBamanda-client.conf\fR
+if the default is suitable.
+.PP
+Lines starting with # are ignored, as are blank lines. Comments may be placed on a line with a directive by starting the comment with a #. The remainder of the line is ignored.
+.PP
+Keywords are case insensitive, i.e.
+\fBauth\fR
+and
+\fBAuth\fR
+are treated the same.
+.PP
+Integer arguments may have one of the following (case insensitive) suffixes, some of which have a multiplier effect:
+.SS "POSSIBLE SUFFIXES"
+.TP
+\fBb byte bytes\fR
+Some number of bytes.
+.TP
+\fBbps\fR
+Some number of bytes per second.
+.TP
+\fBk kb kbyte kbytes kilobyte kilobytes\fR
+Some number of kilobytes (bytes*1024).
+.TP
+\fBkps kbps\fR
+Some number of kilobytes per second (bytes*1024).
+.TP
+\fBm mb meg mbyte mbytes megabyte megabytes\fR
+Some number of megabytes (bytes*1024*1024).
+.TP
+\fBmps mbps\fR
+Some number of megabytes per second (bytes*1024*1024).
+.TP
+\fBg gb gbyte gbytes gigabyte gigabytes\fR
+Some number of gigabytes (bytes*1024*1024*1024).
+.TP
+\fBtape tapes\fR
+Some number of tapes.
+.TP
+\fBday days\fR
+Some number of days.
+.TP
+\fBweek weeks\fR
+Some number of weeks (days*7).
+.sp
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+\fBNote\fR
+The value
+\fBinf\fR
+may be used in most places where an integer is expected
+to mean an infinite amount.
+
+Boolean arguments may have any of the values
+\fBy\fR,
+\fByes\fR,
+\fBt\fR,
+\fBtrue\fR
+or
+\fBon\fR
+to indicate a true state, or
+\fBn\fR,
+\fBno\fR,
+\fBf\fR,
+\fBfalse\fR
+or
+\fBoff\fR
+to indicate a false state. If no argument is given,
+\fBtrue\fR
+is assumed.
+.SS "PARAMETERS"
+.TP
+\fBconf\fR \fB string\fR
+Default:
+\fBSet by configure\fR. The conf use by amrecover.
+.TP
+\fBindex_server\fR \fB string\fR
+Default:
+\fBSet by configure\fR. The amindexd server amrecover will connect to.
+.TP
+\fBtape_server\fR \fB string\fR
+Default:
+\fBSet by configure\fR. The amidxtaped server amrecover will connect to.
+.TP
+\fBtapedev\fR \fB string\fR
+Default:
+\fBSet by configure\fR. The tapedev amrecover will use.
+.TP
+\fBauth\fR \fB string\fR
+Default:
+\fBbsd\fR. Type of authorization to perform between tape server and backup client hosts.
+.sp
+\fBbsd\fR, bsd authorization with udp initial connection and one tcp connection by data stream.
+.sp
+\fBbsdtcp\fR, bsd authorization but use only one tcp connection.
+.sp
+\fBbsdudp\fR, like bsd, but will use only one tcp connection for all data stream.
+.sp
+\fBkrb4\fR
+to use Kerberos-IV authorization.
+.sp
+\fBkrb5\fR
+to use Kerberos-V authorization.
+.sp
+\fBrsh\fR
+to use rsh authorization.
+.sp
+\fBssh\fR
+to use OpenSSH authorization.
+.TP
+\fBssh_keys\fR \fB string\fR
+Default:
+\fBNo default\fR. The key file the ssh auth will use, it must be the private key. If this parameter is not specified, then the deafult ssh key will be used.
+.TP
+\fBgnutar_list_dir\fR \fB string\fR
+Default from configure
+\fB--with-gnutar-listdir=DIR\fR. The directory where gnutar keep its state file.
+.TP
+\fBamandates\fR \fB string\fR
+Default:
+\fB/etc/amandates\fR. The file where amanda keep the last date of each dumplevel.
+.SH "AUTHOR"
+.PP
+James da Silva,
+<jds@amanda.org>: Original text
+.PP
+Stefan G. Weichinger,
+<sgw@amanda.org>, maintainer of the
+\fBAmanda\fR-documentation: XML-conversion, major update, splitting
+.SH "SEE ALSO"
+.PP
+\fBamanda\fR(8),
+\fBamanda.conf\fR(5),
+\fBamcrypt\fR(8),
+\fBaespipe\fR(1),
+
\fBhostname diskname\fR [ \fBdiskdevice\fR ] {
normal
- holdingdisk no
+ holdingdisk never
} [ \fBspindle\fR [ \fBinterface\fR ] ]
.fi
.SH "TAPE MANAGEMENT"
\fBhostname\fR
[
\fBusername\fR
-]
+[
+\fBservice\fR
+]*]
.sp
If
\fBusername\fR
or
\fBxinetd\fR
configuration file.
+.sp
+The
+\fBservice\fR
+is a list of the service the client is authorized to execute:
+\fBamdump\fR,
+\fBnoop\fR,
+\fBselfcheck\fR,
+\fBsendsize\fR,
+\fBsendbackup\fR,
+\fBamindexd\fR,
+\fBamidxtaped\fR.
+\fBamdump\fR
+is a shortcut for "noop selfcheck sendsize sendbackup"
.TP
Kerberos
\fBAmanda\fR
.nf
//some-pc/home normalpw
- //another-pc/disk otheruser%otherpw.fi
-With clear text passwords, this file should obviously be tightly protected. It only needs to be readable by the
-\fBAmanda\fR-user on the Samba server.
-.sp
+ //another-pc/disk otheruser%otherpw
+.fi
+
+
+With clear text passwords, this file should obviously be tightly protected.
+It only needs to be readable by the \fBAmanda\fR-user on the Samba server.
+
You can find further information in the
\fBdocs/SAMBA\fRfile that comes with an
\fBAmanda\fR
expression is a range expression where we only match the prefix. Leading ^ is removed. Trailing $ forces an exact match.
20001212-14match all dates beginning with 20001212, 20001213 or 2000121420001212-4same as previous20001212-24match all dates between 20001212 and 200012242000121match all dates that start with 2000121 (20001210-20001219)2match all dates that start with 2 (20000101-29991231)2000-10match all dates between 20000101-20101231200010$match only 200010.PP
+.SH "CONFIGURATION OVERWRITE"
+.PP
+Most command allow to overwrite any configuration parameter on the command line with the -o option.
+.PP
+-o NAME=value
+.PP
+eg. -o runtapes=2
+.PP
+eg. -o DUMPTYPE:no-compress:compress="server fast"
+.PP
+eg. -o TAPETYPE:HP-DAT:length=2000m
+.PP
+eg. -o INTERFACE:local:use="2000 kbps"
.SH "AUTHOR"
.PP
James da Silva,
.PP
\fBamadmin\fR(8),
\fBamanda.conf\fR(5),
+\fBamanda-client.conf\fR(5),
\fBamcheck\fR(8),
\fBamcheckdb\fR(8),
\fBamcleanup\fR(8),
\fIamanda.conf\fR
is the main configuration file for
\fBAmanda\fR. This manpage lists the relevant sections and parameters of this file for quick reference.
+.PP
+The file
+\fB<CONFIG_DIR>/<config>/amanda.conf\fR
+is loaded.
.SH "PARAMETERS"
.PP
There are a number of configuration parameters that control the behavior of the
\fBtapecycle\fR
parameter slightly lower than the actual number of tapes in rotation. This allows the administrator to more easily cope with damaged or misplaced tapes or schedule adjustments that call for slight adjustments in the rotation order.
.TP
+\fBusetimestamps\fR \fB bool\fR
+Default:
+\fBNo\fR. By default, Amanda can only track at most one run per calendar day. When this option is enabled, however, Amanda can track as many runs as you care to make.
+.sp
+\fBWARNING\fR: This option is not backward-compatible. Do not enable it if you intend to downgrade your server installation to Amanda community edition 2.5.0
+.TP
\fBlabel_new_tapes\fR \fB string\fR
Default: not set. When set, this directive will cause
\fBAmanda\fR
When using this directive, specify the template for new tape labels. The template should contain some number of contiguous '%' characters, which will be replaced with a generated number. Be sure to specify enough '%' characters that you do not run out of tape labels. Example:
label_new_tapes "DailySet1-%%%"
.TP
-\fBlabel_new_tapes\fR \fB string\fR
-
-=======
- Default: not set. When set, this directive will cause
-\fBAmanda\fR
-to automatically write an Amanda tape label to any black tape she encounters. This option is DANGEROUS because when set,
-\fBAmanda\fR
-will ERASE any non-\fBAmanda\fR
-tapes you may have, and may also ERASE any near-failing tapes. Use with caution.
-.sp
-When using this directive, specify the template for new tape labels. The template should contain some number of contiguous '%' characters, which will be replaced with a generated number. Be sure to specify enough '%' characters that you do not run out of tape labels. Example:
-label_new_tapes "DailySet1-%%%"
-.TP
\fBdumpuser\fR \fB string\fR
Default:
\fBamanda\fR. The login name
.TP
\fBamrecover_do_fsf\fR \fB bool\fR
Default:
-\fBoff\fR. Amrecover will call amrestore with the -f flag for faster positioning of the tape.
+\fBon\fR. Amrecover will call amrestore with the -f flag for faster positioning of the tape.
.TP
\fBamrecover_check_label\fR \fB bool\fR
Default:
-\fBoff\fR. Amrecover will call amrestore with the -l flag to check the label.
+\fBon\fR. Amrecover will call amrestore with the -l flag to check the label.
.TP
\fBamrecover_changer\fR \fB string\fR
Default: ''. Amrecover will use the changer if you use 'settape <string>' and that string is the same as the amrecover_changer setting.
holdingdisk \fBname\fR {
\fBholdingdisk-option\fR \fBholdingdisk-value\fR
...
-}.fi
+}
+.fi
.PP
\fBName\fR
is a logical name for this holding disk.
Default:
\fBbsd\fR. Type of authorization to perform between tape server and backup client hosts.
.sp
+\fBbsd\fR, bsd authorization with udp initial connection and one tcp connection by data stream.
+.sp
+\fBbsdtcp\fR, bsd authorization but use only one tcp connection.
+.sp
+\fBbsdudp\fR, like bsd, but will use only one tcp connection for all data stream.
+.sp
\fBkrb4\fR
to use Kerberos-IV authorization.
.sp
\fBkrb5\fR
to use Kerberos-V authorization.
.sp
+\fBrsh\fR
+to use rsh authorization.
+.sp
\fBssh\fR
to use OpenSSH authorization.
.TP
+\fBamandad_path\fR \fB string\fR
+Default:
+\fB$libexec/amandad\fR. Specify the amandad path of the client, only use with rsh/ssh authentification.
+.TP
+\fBclient_username\fR \fB string\fR
+Default:
+\fBCLIENT_LOGIN\fR. Specify the username to connect on the client, only use with rsh/ssh authentification.
+.TP
\fBbumpsize\fR int
Default:
\fB10 Mbytes\fR. The minimum savings required to trigger an automatic bump from one incremental level to the next, expressed as size. If
.sp
decryption-parameter must not contain white space.
.sp
-(See dumptype encrypt-fast in example/amanda.conf for reference)
+(See dumptype server-encrypt-fast in example/amanda.conf for reference)
.TP
•
encrypt server
Specify server_decrypt_option "decryption-parameter" Default: "-d"
.sp
decryption-parameter must not contain white space.
+.sp
+(See dumptype client-encrypt-nocomp in example/amanda.conf for reference)
.RE
.PP
Note that current logic assumes compression then encryption during backup(thus decrypt then uncompress during restore). So specifying client-encryption AND server-compression is not supported.
\fBamcrypt\fR
which is a wrapper of
\fBaespipe\fR
-is provided as a reference encryption program.
+is provided as a reference symmetric encryption program.
.TP
\fBestimate\fR \fBclient|calcsize|server\fR
Default:
for a backup of
\fI/usr/local\fR, and so on.
.TP
-\fBholdingdisk\fR \fB boolean\fR
+\fBholdingdisk\fR [ \fBnever|auto|required]\fR ]
Default:
-\fByes\fR. Whether a holding disk should be used for these backups or whether they should go directly to tape. If the holding disk is a portion of another file system that
+\fBauto\fR. Whether a holding disk should be used for these backups or whether they should go directly to tape. If the holding disk is a portion of another file system that
\fBAmanda\fR
is backing up, that file system should refer to a dumptype with
\fBholdingdisk\fR
set to
-\fBno\fR
+\fBnever\fR
to avoid backing up the holding disk into itself.
+.RS
+.TP
+\fBnever\fR|no|false|off
+Never use a holdingdisk, the dump will always go directly to tape. There will be no dump if you have a tape error.
+.TP
+\fBauto\fR|yes|true|on
+Use the holding disk, unless there is a problem with the holding disk, the dump won't fit there or the medium doesn't require spooling (e.g., VFS device)
+.TP
+\fBrequired\fR
+Always dump to holdingdisk, never directly to tape. There will be no dump if it doesn't fit on holdingdisk
+.RE
.TP
\fBignore\fR \fB boolean\fR
Default:
.SH "SEE ALSO"
.PP
\fBamanda\fR(8),
+\fBamanda-client.conf\fR(5),
\fBamcrypt\fR(8),
\fBaespipe\fR(1),
amcheck - run Amanda self-checks
.SH "SYNOPSIS"
.HP 8
-\fBamcheck\fR [-mwsclt] [-Maddress] \fIconfig\fR [\fIhost\fRÂ [\fIdisk\fR...]...]
+\fBamcheck\fR [-am] [-w] [-sclt] [-M \fIaddress\fR]*
+ \fIconfig\fR [\fIhost\fR [\fIdisk\fR]*]*
+ [-o \fIconfigoption\fR]*
+
.SH "DESCRIPTION"
.PP
\fBAmcheck\fR
\fB-lt\fR).
.TP
\fB-c\fR
-Run the client host checks.
+Run the client host checks.Multiple specific clients can be checked by specifying the client name.
.TP
\fB-l\fR
Run the local tests (e.g. permissions) on the server host.
\fB-w\fR
Enables a DESTRUCTIVE check for write-protection on the tape (which would otherwise cause the subsequent
\fBamdump\fR
-to fail). If the tape is writable, this check causes all data after the tape label to be erased. If the label_new_tapes option is enabled, this check may ERASE any non-Amanda tape in the drive or changer. The check implies
-\fB-t\fR
-and is only made if the tape is otherwise correct.
+to fail). If the tape is writable, this check causes all data after the tape label to be erased. If the label_new_tapes option is enabled, this check may ERASE any non-Amanda tape in the drive or changer. The check enable the tape tests on the server host and is only made if the tape is otherwise correct.
.TP
\fB-m\fR
Nothing is printed, but mail is sent if any errors are detected. The mail goes to the
\fB-m\fR
but the mail is always sent.
.TP
-\fB-M\fR\fIaddress\fR
+\fB-M\fR \fIaddress\fR
Mail the report to
\fBaddress\fR
instead of the
value from
\fBamanda.conf\fR. Implies
\fB-m\fR.
+.TP
+\fIhost\fR [\fIdisk\fR]*
+Specify the host and disk on which the command will work.
+.TP
+\fB-o\fR \fIconfigoption\fR
+See the "\fBCONFIGURATION OVERWRITE\fR" section in
+\fBamanda\fR(8).
.PP
The default is
\fB-cs\fR.
\fBamanda\fR(8)
man page for more details about
\fBAmanda\fR.
+.SH "OPTIONS"
+.TP
+\fB-k\fR
+Kill all Amanda processes.
.SH "EXAMPLES"
.PP
This example runs the
--- /dev/null
+.\"Generated by db2man.xsl. Don't modify this, modify the source.
+.de Sh \" Subsection
+.br
+.if t .Sp
+.ne 5
+.PP
+\fB\\$1\fR
+.PP
+..
+.de Sp \" Vertical space (when we can't use .PP)
+.if t .sp .5v
+.if n .sp
+..
+.de Ip \" List item
+.br
+.ie \\n(.$>=3 .ne \\$3
+.el .ne 3
+.IP "\\$1" \\$2
+..
+.TH "AMCRYPT-OSSL-ASYM" 8 "" "" ""
+.SH "NAME"
+amcrypt-ossl-asym - crypt program for Amanda asymmetric data encryption using OpenSSL
+.SH "SYNOPSIS"
+.HP 18
+\fBamcrypt-ossl-asym\fR [-d]
+.SH "DESCRIPTION"
+.PP
+\fBamcrypt-ossl-asym\fR
+uses
+\fBOpenSSL\fR
+to encrypt and decrypt data. OpenSSL is available from
+www.openssl.org. OpenSSL offers a wide variety of cipher choices (
+\fBamcrypt-ossl-asym\fR
+defaults to 256-bit AES) and can use hardware cryptographic accelerators on several platforms.
+.PP
+\fBamcrypt-ossl-asym\fR
+will search for the OpenSSL program in the following directories: /bin:/usr/bin:/usr/local/bin:/usr/ssl/bin:/usr/local/ssl/bin.
+.SH "GENERATING PUBLIC AND PRIVATE KEYS"
+.PP
+RSA keys can be generated with the standard OpenSSL commands, e.g.:
+.nf
+
+$ cd /var/lib/amanda
+$ openssl genrsa -aes128 -out backup-privkey.pem 1024
+Generating RSA private key, 1024 bit long modulus
+[...]
+Enter pass phrase for backup-privkey.pem: \fBENTER YOUR PASS PHRASE\fR
+Verifying - Enter pass phrase for backup-key.pem: \fBENTER YOUR PASS PHRASE\fR
+
+$ openssl rsa -in backup-privkey.pem -pubout -out backup-pubkey.pem
+Enter pass phrase for backup-privkey.pem: \fBENTER YOUR PASS PHRASE\fR
+Writing RSA key
+
+.fi
+.PP
+To generate a private key without a passphrase, omit the
+\fB-aes128\fR
+option. See
+\fBopenssl_genrsa\fR(1)
+for more key generation options.
+.PP
+Note that it is always possible to generate the public key from the private key.
+.SH "KEY AND PASSPHRASE MANAGEMENT"
+.PP
+\fBamcrypt-ossl-asym\fR
+uses the
+\fBpublic key\fR
+to encrypt data. The security of the data does not depend on the confidentiality of the public key. The
+\fBprivate key\fR
+is used to decrypt data, and must be protected. Encrypted backup data cannot be recovered without the private key. The private key may optionally be encrypted with a passphrase.
+.PP
+While the public key must be online at all times to perorm backups, the private key and optional passphrase are only needed to restore data. It is recommended that the latter be stored offline all other times. For example, you could keep the private key on removable media, and copy it into place for a restore; or you could keep the private key online, encrypted with a passphrase that is present only for a restore.
+.PP
+OpenSSL's key derivation routines use a salt to guard against dictionary attacks on the pass phrase; still it is important to pick a pass phrase that is hard to guess. The Diceware method (see
+www.diceware.com) can be used to create passphrases that are difficult to guess and easy to remember.
+.SH "FILES"
+.TP
+/var/lib/amanda/backup-privkey.pem
+File containing the RSA private key. It should not be readable by any user other than the
+\fBAmanda\fR
+user.
+.TP
+/var/lib/amanda/backup-pubkey.pem
+File containing the RSA public key.
+.TP
+/var/lib/amanda/.am_passphrase
+File containing the passphrase. It should not be readable by any user other than the
+\fBAmanda\fR
+user.
+.SH "SEE ALSO"
+.PP
+\fBamanda\fR(8),
+\fBamanda.conf\fR(5),
+\fBopenssl\fR(1),
+\fBamcrypt-ossl\fR(8)
+
--- /dev/null
+.\"Generated by db2man.xsl. Don't modify this, modify the source.
+.de Sh \" Subsection
+.br
+.if t .Sp
+.ne 5
+.PP
+\fB\\$1\fR
+.PP
+..
+.de Sp \" Vertical space (when we can't use .PP)
+.if t .sp .5v
+.if n .sp
+..
+.de Ip \" List item
+.br
+.ie \\n(.$>=3 .ne \\$3
+.el .ne 3
+.IP "\\$1" \\$2
+..
+.TH "AMCRYPT-OSSL" 8 "" "" ""
+.SH "NAME"
+amcrypt-ossl - crypt program for Amanda symmetric data encryption using OpenSSL
+.SH "SYNOPSIS"
+.HP 13
+\fBamcrypt-ossl\fR [-d]
+.SH "DESCRIPTION"
+.PP
+\fBamcrypt-ossl\fR
+uses
+\fBOpenSSL\fR
+to encrypt and decrypt data. OpenSSL is available from
+www.openssl.org. OpenSSL offers a wide variety of cipher choices (
+\fBamcrypt-ossl\fR
+defaults to 256-bit AES) and can use hardware cryptographic accelerators on several platforms.
+.PP
+\fBamcrypt-ossl\fR
+will search for the OpenSSL program in the following directories: /bin:/usr/bin:/usr/local/bin:/usr/ssl/bin:/usr/local/ssl/bin.
+.SH "PASSPHRASE MANAGEMENT"
+.PP
+\fBamcrypt-ossl\fR
+uses the same pass phrase to encrypt and decrypt data. It is very important to store and protect the pass phrase properly. Encrypted backup data can
+\fBonly\fR
+be recovered with the correct passphrase.
+.PP
+OpenSSL's key derivation routines use a salt to guard against dictionary attacks on the pass phrase; still it is important to pick a pass phrase that is hard to guess. The Diceware method (see
+www.diceware.com) can be used to create passphrases that are difficult to guess and easy to remember.
+.SH "FILES"
+.TP
+/var/lib/amanda/.am_passphrase
+File containing the pass phrase. It should not be readable by any user other than the
+\fBAmanda\fR
+user.
+.SH "SEE ALSO"
+.PP
+\fBamanda\fR(8),
+\fBamanda.conf\fR(5),
+\fBopenssl\fR(1),
+\fBamcrypt-ossl-asym\fR(8)
+
.PP
\fBamcrypt\fR
requires
-\fBaespipe\fR
+\fBaespipe\fR,
+\fBuuencode\fR
and
\fBgpg\fR
to work. Aespipe is available from
amdump - back up all disks in an Amanda configuration
.SH "SYNOPSIS"
.HP 7
-\fBamdump\fR \fIconfig\fR [\fIhost\fRÂ [\fIdisk\fR...]...]
+\fBamdump\fR \fIconfig\fR [\fIhost\fR [\fIdisk\fR]*]*
+ [-o \fIconfigoption\fR]*
+
.SH "DESCRIPTION"
.PP
\fBAmdump\fR
\fBamanda\fR(8)
man page for more details about
\fBAmanda\fR.
+.SH "OPTIONS"
+.TP
+\fIhost\fR [\fIdisk\fR]*
+Specify the host and disk on which the command will work.
+.TP
+\fB-o\fR \fIconfigoption\fR
+See the "\fBCONFIGURATION OVERWRITE\fR" section in
+\fBamanda\fR(8).
.SH "EXAMPLE"
.PP
Here is a typical crontab entry. It runs
amfetchdump - extract backup images from multiple Amanda tapes.
.SH "SYNOPSIS"
.HP 12
-\fBamfetchdump\fR [-pcClawns] [-d \fIdevice\fR] [-o \fIdirectory\fR] [-i \fIlogfile\fR] [-b \fIblocksize\fR] \fIconfig\fR \fIhostname\fR [\fIdisk\fR [ \fIdate\fR [ \fIlevel\fR [ \fIhostname\fR [...] ] ] ]]
+\fBamfetchdump\fR [-pcClawns] [-d \fIdevice\fR] [-O \fIdirectory\fR] [-i \fIlogfile\fR] [-b \fIblocksize\fR] \fIconfig\fR \fIhostname\fR [\fIdisk\fR [ \fIdate\fR [ \fIlevel\fR [ \fIhostname\fR [...] ] ] ]] [-o \fIconfigoption\fR]*
+
.SH "DESCRIPTION"
.PP
\fBAmfetchdump\fR
\fB-d\fR \fIdevice\fR
Restore from this tape device instead of the default.
.TP
-\fB-o\fR \fIdirectory\fR
+\fB-O\fR \fIdirectory\fR
Output restored files to this directory, instead of to the current working directory.
.TP
\fB-c\fR
.TP
\fB-b\fR \fIblocksize\fR
Force a particular block size when reading from tapes. This value will usually be autodetected, and should not normally need to be set.
+.TP
+\fB-o\fR \fIconfigoption\fR
+See the "\fBCONFIGURATION OVERWRITE\fR" section in
+\fBamanda\fR(8).
.SH "EXAMPLES"
.PP
All the examples here assume your configuration is called
amflush - flush Amanda backup files from holding disk to tape
.SH "SYNOPSIS"
.HP 8
-\fBamflush\fR [-b] [-f] [-s] [-DÂ \fIdatestamp\fR...] \fIconfig\fR [\fIhost\fRÂ [\fIdisk\fR...]...]
+\fBamflush\fR [-b] [-f] [-s] [-D \fIdatestamp\fR]*
+ \fIconfig\fR [\fIhost\fR [\fIdisk\fR]*]*
+ [-o \fIconfigoption\fR]*
+
.SH "DESCRIPTION"
.PP
\fBAmflush\fR
for a description.
\fB-D 20001225-7\fR
will flush all dumps from 25 december 2000 to 27 december 2000.
+.TP
+\fIhost\fR [\fIdisk\fR]*
+Specify the host and disk on which the command will work.
+.TP
+\fB-o\fR \fIconfigoption\fR
+See the "\fBCONFIGURATION OVERWRITE\fR" section in
+\fBamanda\fR(8).
.PP
You can specify many host/disk expressions, only disks that match an expression will be flushed. All disks are flushed if no expressions are given. see the "HOST & DISK EXPRESSION" section of
\fBamanda\fR(8)
amgetconf - look up amanda.conf variables
.SH "SYNOPSIS"
.HP 10
-\fBamgetconf\fR [\fIconfig\fR] \fIparameter\fR
+\fBamgetconf\fR [\fIconfig\fR] \fIparameter\fR [-o \fIconfigoption\fR]*
+
.SH "DESCRIPTION"
.PP
\fBAmgetconf\fR
\fBamanda\fR(8)
man page for more details about
\fBAmanda\fR.
+.SH "OPTIONS"
+.TP
+\fB-o\fR \fIconfigoption\fR
+See the "\fBCONFIGURATION OVERWRITE\fR" section in
+\fBamanda\fR(8).
.SH "EXAMPLE"
.PP
Find out the path to the log file directory:
\fBparam\fR
is not a known keyword (e.g. not a valid
\fBamanda.conf\fR
-keyword). In this case,
-\fBamgetconf\fR
-will write "\fBBUGGY\fR" to stdout as the value.
+keyword).
.SH "SEE ALSO"
.PP
\fBamanda\fR(8)
amlabel - label an Amanda tape
.SH "SYNOPSIS"
.HP 8
-\fBamlabel\fR [-f] \fIconfig\fR \fIlabel\fR [\fIslot\fRÂ \fIslot\fR]
+\fBamlabel\fR [-f] \fIconfig\fR \fIlabel\fR [slot \fIslot\fR] [-o \fIconfigoption\fR]*
+
.SH "DESCRIPTION"
.PP
All
\fBamanda\fR(8)
man page for more details about
\fBAmanda\fR.
+.SH "OPTIONS"
+.TP
+\fB-o\fR \fIconfigoption\fR
+See the "\fBCONFIGURATION OVERWRITE\fR" section in
+\fBamanda\fR(8).
.SH "EXAMPLE"
.PP
Write an
amrecover - Amanda index database browser
.SH "SYNOPSIS"
.HP 10
-\fBamrecover\fR [[-C ] \fIconfig\fR] [-s \fIindex-server\fR] [-t \fItape-server\fR] [-d \fItape-device\fR]
+\fBamrecover\fR [[-C] \fIconfig\fR] [-s \fIindex-server\fR] [-t \fItape-server\fR] [-d \fItape-device\fR] [-o \fIclientconfigoption\fR]*
+
.SH "DESCRIPTION"
.PP
\fBAmrecover\fR
\fBlcd\fR
to move into that directory, otherwise a directory tree that resembles the backed up filesystem will be created in the current directory. See the examples below for details.
.PP
+Amrecover will read the
+\fBamanda-client.conf\fR
+file and the
+\fIconfig\fR\fB/amanda-client.conf\fR
+file.
+.PP
See the
\fBamanda\fR(8)
man page for more details about
.TP
\fB-d tape-device\fR
Tape device to use on the tape server host.
+.TP
+\fB-o\fR \fIclientconfigoption\fR
+See the "\fBCONFIGURATION OVERWRITE\fR" section in
+\fBamanda\fR(8).
.SH "COMMANDS"
.PP
\fBAmrecover\fR
\fBsethost hostname\fR
Specifies which host to look at backup files for (default: the local host).
.TP
-\fBsetdate YYYY-MM-DD\fR
-Set the date (default: today). File listing commands only return information on backup images for this day, for the day before with the next lower dump level, and so on, until the most recent level 0 backup on or before the specified date is encountered.
+\fBsetdate YYYY-MM-DD-HH-MM[-SS] | YYYY-MM-DD\fR
+Set the restore time (default: now). File listing commands only return information on backup images for this day, for the day before with the next lower dump level, and so on, until the most recent level 0 backup on or before the specified date is encountered.
.sp
For example, if:
.sp
.fi
.sp
-then if 1997-07-08 is the requested date, files from the following days would be used:
+then the command
+\fBsetdate 1997-07-08-00\fR
+would yield files from the following days:
.sp
.nf
\fBmountpoint\fR
is not specified, all pathnames will be relative to the (unknown) mount point instead of full pathnames.
.TP
+\fBlisthost [diskdevice]\fR
+List all
+\fBhost\fR
+.TP
\fBlistdisk [diskdevice]\fR
List all
\fBdiskname\fR
commands will use $PAGER to display the file lists. Defaults to
\fBmore\fR
if PAGER is not set.
+.PP
+\fBAMANDA_SERVER\fR
+If set, $AMANDA_SERVER will be used as index-server. The value will take precedence over the compiled default, but will be overridden by the -s switch.
+.PP
+\fBAMANDA_TAPE_SERVER\fR
+If set, $AMANDA_TAPE_SERVER will be used as tape-server. The value will take precedence over the compiled default, but will be overridden by the -t switch.
.SH "AUTHOR"
.PP
Alan M. McIvor
.SH "SEE ALSO"
.PP
\fBamanda\fR(8),
+\fBamanda-client.conf\fR(5),
\fBamrestore\fR(8),
\fBamfetchdump\fR(8),
\fBreadline\fR(3)
amreport - generate a formatted output of statistics for an Amanda run
.SH "SYNOPSIS"
.HP 9
-\fBamreport\fR [\fIconfig\fR] [-l \fIlogfile\fR] [-f \fIoutputfile\fR] [-p \fIpostscriptfile\fR]
+\fBamreport\fR [\fIconfig\fR] [-i] [-M \fIaddress\fR] [-l \fIlogfile\fR] [-f \fIoutputfile\fR] [-p \fIpostscriptfile\fR] [-o \fIconfigoption\fR]*
+
.SH "DESCRIPTION"
.PP
\fBAmreport\fR
\fBconfig\fR
Name of the configuration to process.
.TP
+\fB-i\fR
+Don't email the report.
+.TP
+\fB-M\fR \fIaddress\fR
+Mail the report to
+\fBaddress\fR
+instead of the
+\fBmailto\fR
+value from
+\fBamanda.conf\fR.
+.TP
\fB-l\fR \fIlogfile\fR
Name of the log file to parse to generate the report. If a log file is not specified, it defaults to the file:
.PP
command. This option has an effect only if the
\fBlbl-templ\fR
directive is specified in amanda.conf.
+.TP
+\fB-o\fR \fIconfigoption\fR
+See the "\fBCONFIGURATION OVERWRITE\fR" section in
+\fBamanda\fR(8).
.SH "LABEL PRINTING"
.PP
\fBAmanda\fR
amrestore - extract backup images from an Amanda tape
.SH "SYNOPSIS"
.HP 10
-\fBamrestore\fR [-r -c -C] [-b \fIblocksize\fR] [-f \fIfileno\fR] [-l \fIlabel\fR] [-p] [-h] \fItapedevice\fR \fIholdingfile\fR [\fIhostname\fR [\fIdiskname\fR [\fIdatestamp\fR [\fIhostname\fR [\fIdiskname\fR [\fIdatestamp\fR...]]]]]]
+\fBamrestore\fR [-r -c -C] [-b \fIblocksize\fR] [-f \fIfileno\fR] [-l \fIlabel\fR] [-p] [-h] \fItapedevice\fR|Â \fIholdingfile\fR [\fIhostname\fR [\fIdiskname\fR [\fIdatestamp\fR [\fIhostname\fR [\fIdiskname\fR [\fIdatestamp\fR ...]]]]]]
.SH "DESCRIPTION"
.PP
\fBAmrestore\fR
uses the header to determine the restore program to use.
.PP
If a header is written (-r or -h), only 32 KBytes are output regardless of the tape blocksize. This makes the resulting image usable as a holding file.
+.TP
+\fB-o\fR \fIconfigoption\fR
+See the "\fBCONFIGURATION OVERWRITE\fR" section in
+\fBamanda\fR(8).
.SH "EXAMPLES"
.PP
The following does an interactive restore of disk
amtapetype - generate a tapetype definition.
.SH "SYNOPSIS"
.HP 11
-\fBamtapetype\fR [-h] [-c] [-o] [-b \fIblocksize\fR] [-e \fIestsize\fR] [-f \fItapedev\fR] [-t \fItypename\fR]
+\fBamtapetype\fR [-h] [-c] [-o] [-b \fIblocksize\fR] -e \fIestsize\fR [-f \fItapedev\fR] [-t \fItypename\fR]
.SH "DESCRIPTION"
.PP
\fBamtapetype\fR
record block size (default: 32k)
.TP
\fB-e\fR\fI estsize\fR
-estimated tape size (default: 1g == 1024m)
+estimated tape size (No default!)
.TP
\fB-f\fR\fI tapedev\fR
tape device name (default: $TAPE) The device to perform the test.
.sp
.nf
-% amtapetype -f /dev/nst0
+% amtapetype -f /dev/nst0 -e 150G
.fi
.SH "NOTES"
<!-- IDs for AMANDA files-->
<!ENTITY amandaddebug ' <filename>amandad.debug</filename>'>
<!ENTITY amconf '<filename>amanda.conf</filename>'>
+<!ENTITY amclientconf '<filename>amanda-client.conf</filename>'>
<!ENTITY amandahosts '<filename>.amandahosts</filename>'>
<!ENTITY disklist '<filename>disklist</filename>'>
<!ENTITY amandapass '<filename>/etc/amandapass</filename>'>
<!ENTITY amcheckdb ' <command>amcheckdb</command>'>
<!ENTITY amcleanup ' <command>amcleanup</command>'>
<!ENTITY amcrypt ' <command>amcrypt</command>'>
+<!ENTITY amcryptsimple ' <command>amcryptsimple</command>'>
+<!ENTITY amcryptossl ' <command>amcrypt-ossl</command>'>
+<!ENTITY amcryptosslasym ' <command>amcrypt-ossl-asym</command>'>
+<!ENTITY amgpgcrypt ' <command>amgpgcrypt</command>'>
<!ENTITY amdd ' <command>amdd</command>'>
+<!ENTITY amaddclient ' <command>amaddclient</command>'>
<!ENTITY amdump ' <command>amdump</command>'>
<!ENTITY amflush ' <command>amflush</command>'>
<!ENTITY amgetconf ' <command>amgetconf</command>'>
<!ENTITY amreport ' <command>amreport</command>'>
<!ENTITY amrestore ' <command>amrestore</command>'>
<!ENTITY amrmtape ' <command>amrmtape</command>'>
+<!ENTITY amserverconfig ' <command>amserverconfig</command>'>
<!ENTITY amstatus ' <command>amstatus</command>'>
<!ENTITY amtape ' <command>amtape</command>'>
<!ENTITY amtapetype ' <command>amtapetype</command>'>
<!--
- $Id: xinclude.dtd,v 1.1 2005/11/19 00:51:20 paddy_s Exp $
+ $Id: xinclude.dtd,v 1.2 2006/05/25 01:47:13 johnfranks Exp $
The XInclude DTD is from
<command>amadmin</command>
<arg choice='plain'><replaceable>config</replaceable></arg>
<arg choice='plain'><replaceable>command</replaceable></arg>
- <arg choice='opt'><arg choice='plain'><replaceable>command</replaceable></arg><arg choice='plain'><replaceable>options</replaceable></arg></arg>
+ <group><replaceable><arg choice='plain'>command</arg><arg choice='plain'>options</arg></replaceable></group>
+ <group><arg choice='plain'>-o</arg><arg choice='plain'><replaceable>configoption</replaceable></arg></group>*
</cmdsynopsis>
</refsynopsisdiv>
Mostly used for debugging.</para>
</listitem>
</varlistentry>
+
+ <varlistentry>
+ <term><emphasis remap='B'>-o</emphasis> <replaceable>configoption</replaceable></term>
+ <listitem>
+<para>See the "<emphasis remap='B'>CONFIGURATION OVERWRITE</emphasis>"
+ section in <citerefentry><refentrytitle>amanda</refentrytitle><manvolnum>8</manvolnum></citerefentry>.</para>
+ </listitem>
+ </varlistentry>
+
</variablelist>
</refsect1>
<refsect1><title>DESCRIPTION</title>
<para>&amaespipe;
-requires <emphasis remap='B'>aespipe</emphasis> and <emphasis remap='B'>gpg</emphasis> to work.
+requires <emphasis remap='B'>aespipe</emphasis>, <emphasis remap='B'>uuencode</emphasis> and <emphasis remap='B'>gpg</emphasis> to work.
Aespipe is available from <ulink url="http://loop-aes.sourceforge.net"/></para>
<para>&amaespipe; will search for the aespipe program in the following directories:
/usr/bin:/usr/local/bin:/sbin:/usr/sbin. </para>
--- /dev/null
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
+ "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd"
+[
+ <!-- entities files to use -->
+ <!ENTITY % global_entities SYSTEM '../entities/global.entities'>
+ %global_entities;
+]>
+
+<refentry id='amanda-client.conf.5'>
+
+<refmeta>
+<refentrytitle>amanda-client.conf</refentrytitle>
+<manvolnum>5</manvolnum>
+</refmeta>
+<refnamediv>
+<refname>amanda-client.conf</refname>
+<refpurpose>Client configuration file for &A;, the Advanced Maryland Automatic Network Disk Archiver</refpurpose>
+</refnamediv>
+<!-- body begins here -->
+
+<refsect1><title>DESCRIPTION</title>
+<para>&amclientconf; is the client configuration file for &A;. This manpage lists the
+relevant sections and parameters of this file for quick reference.</para>
+<para> The files <emphasis remap='B'><CONFIG_DIR>/amanda-client.conf</emphasis> and <emphasis remap='B'><CONFIG_DIR>/<config>/amanda-client.conf</emphasis> are loaded.</para>
+</refsect1>
+
+<refsect1><title>PARAMETERS</title>
+
+<para>There are a number of configuration parameters that control the
+behavior of the &A; programs.
+All have default values,
+so you need not specify the parameter in
+<emphasis remap='B'>amanda-client.conf</emphasis>
+if the default is suitable.</para>
+
+<para>Lines starting with # are ignored, as are blank lines.
+Comments may be placed on a line with a directive by starting
+the comment with a #.
+The remainder of the line is ignored.</para>
+
+<para>Keywords are case insensitive, i.e.
+<emphasis remap='B'>auth</emphasis>
+and
+<emphasis remap='B'>Auth</emphasis>
+are treated the same.</para>
+
+<para>Integer arguments may have one of the following (case insensitive) suffixes,
+some of which have a multiplier effect:</para>
+
+<refsect2><title>POSSIBLE SUFFIXES</title>
+
+<variablelist remap='TP'>
+ <varlistentry>
+ <term><emphasis remap='B'>b byte bytes</emphasis></term>
+ <listitem>
+<para>Some number of bytes.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><emphasis remap='B'>bps</emphasis></term>
+ <listitem>
+<para>Some number of bytes per second.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><emphasis remap='B'>k kb kbyte kbytes kilobyte kilobytes</emphasis></term>
+ <listitem>
+<para>Some number of kilobytes (bytes*1024).</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><emphasis remap='B'>kps kbps</emphasis></term>
+ <listitem>
+<para>Some number of kilobytes per second (bytes*1024).</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><emphasis remap='B'>m mb meg mbyte mbytes megabyte megabytes</emphasis></term>
+ <listitem>
+<para>Some number of megabytes (bytes*1024*1024).</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><emphasis remap='B'>mps mbps</emphasis></term>
+ <listitem>
+<para>Some number of megabytes per second (bytes*1024*1024).</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><emphasis remap='B'>g gb gbyte gbytes gigabyte gigabytes</emphasis></term>
+ <listitem>
+<para>Some number of gigabytes (bytes*1024*1024*1024).</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><emphasis remap='B'>tape tapes</emphasis></term>
+ <listitem>
+<para>Some number of tapes.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><emphasis remap='B'>day days</emphasis></term>
+ <listitem>
+<para>Some number of days.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><emphasis remap='B'>week weeks</emphasis></term>
+ <listitem>
+<para>Some number of weeks (days*7).</para>
+
+<note>The value
+<emphasis remap='B'>inf</emphasis>
+may be used in most places where an integer is expected
+to mean an infinite amount.
+
+<para>Boolean arguments may have any of the values
+<emphasis remap='B'>y</emphasis>,
+<emphasis remap='B'>yes</emphasis>,
+<emphasis remap='B'>t</emphasis>,
+<emphasis remap='B'>true</emphasis>
+or
+<emphasis remap='B'>on</emphasis>
+to indicate a true state, or
+<emphasis remap='B'>n</emphasis>,
+<emphasis remap='B'>no</emphasis>,
+<emphasis remap='B'>f</emphasis>,
+<emphasis remap='B'>false</emphasis>
+or
+<emphasis remap='B'>off</emphasis>
+to indicate a false state.
+If no argument is given,
+<emphasis remap='B'>true</emphasis>
+is assumed.
+</para>
+</note>
+ </listitem>
+ </varlistentry>
+</variablelist>
+</refsect2>
+
+<refsect2>
+<title>PARAMETERS</title>
+
+<variablelist remap='TP'>
+ <varlistentry>
+ <term><emphasis remap='B'>conf</emphasis> <emphasis remap='I'> string</emphasis></term>
+ <listitem>
+<para>Default:
+<emphasis remap='I'>Set by configure</emphasis>.
+The conf use by amrecover.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><emphasis remap='B'>index_server</emphasis> <emphasis remap='I'> string</emphasis></term>
+ <listitem>
+<para>Default:
+<emphasis remap='I'>Set by configure</emphasis>.
+The amindexd server amrecover will connect to.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><emphasis remap='B'>tape_server</emphasis> <emphasis remap='I'> string</emphasis></term>
+ <listitem>
+<para>Default:
+<emphasis remap='I'>Set by configure</emphasis>.
+The amidxtaped server amrecover will connect to.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><emphasis remap='B'>tapedev</emphasis> <emphasis remap='I'> string</emphasis></term>
+ <listitem>
+<para>Default:
+<emphasis remap='I'>Set by configure</emphasis>.
+The tapedev amrecover will use.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><emphasis remap='B'>auth</emphasis> <emphasis remap='I'> string</emphasis></term>
+ <listitem>
+<para>Default:
+<emphasis remap='I'>bsd</emphasis>.
+Type of authorization to perform between tape server and backup client hosts.</para>
+<para><emphasis remap='B'>bsd</emphasis>, bsd authorization with udp initial
+connection and one tcp connection by data stream.</para>
+<para><emphasis remap='B'>bsdtcp</emphasis>, bsd authorization but use only
+one tcp connection.</para>
+<para><emphasis remap='B'>bsdudp</emphasis>, like bsd, but will use only one
+tcp connection for all data stream.</para>
+<para><emphasis remap='B'>krb4</emphasis> to use Kerberos-IV
+authorization.</para>
+<para><emphasis remap='B'>krb5</emphasis> to use Kerberos-V
+authorization.</para>
+<para><emphasis remap='B'>rsh</emphasis> to use rsh
+authorization.</para>
+<para><emphasis remap='B'>ssh</emphasis> to use OpenSSH
+authorization.</para>
+
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><emphasis remap='B'>ssh_keys</emphasis> <emphasis remap='I'> string</emphasis></term>
+ <listitem>
+<para>Default:
+<emphasis remap='I'>No default</emphasis>.
+The key file the ssh auth will use, it must be the private key. If this parameter is not specified, then the deafult ssh key will be used.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><emphasis remap='B'>gnutar_list_dir</emphasis> <emphasis remap='I'> string</emphasis></term>
+ <listitem>
+<para>Default from configure
+<emphasis remap='I'>--with-gnutar-listdir=DIR</emphasis>.
+The directory where gnutar keep its state file.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><emphasis remap='B'>amandates</emphasis> <emphasis remap='I'> string</emphasis></term>
+ <listitem>
+<para>Default:
+<emphasis remap='I'>/etc/amandates</emphasis>.
+The file where amanda keep the last date of each dumplevel.</para>
+ </listitem>
+ </varlistentry>
+
+</variablelist>
+</refsect2>
+</refsect1>
+
+<refsect1><title>AUTHOR</title>
+<para>James da Silva, &email.jds;: Original text</para>
+<para>&maintainer.sgw;: XML-conversion, major update, splitting</para>
+</refsect1>
+
+<refsect1><title>SEE ALSO</title>
+<para>
+<citerefentry><refentrytitle>amanda</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+<citerefentry><refentrytitle>amanda.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+<citerefentry><refentrytitle>amcrypt</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+<citerefentry><refentrytitle>aespipe</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+</para>
+</refsect1>
+</refentry>
+
<programlisting>
<emphasis remap='I'>hostname diskname</emphasis> [ <emphasis remap='I'>diskdevice</emphasis> ] {
normal
- holdingdisk no
+ holdingdisk never
} [ <emphasis remap='I'>spindle</emphasis> [ <emphasis remap='I'>interface</emphasis> ] ]
</programlisting>
<para><emphasis remap='I'>hostname</emphasis>
[
<emphasis remap='I'>username</emphasis>
-]</para>
+[
+<emphasis remap='I'>service</emphasis>
+]*]</para>
<para>If
<emphasis remap='I'>username</emphasis>
or
<emphasis remap='B'>xinetd</emphasis>
configuration file.</para>
+<para>The <emphasis remap='I'>service</emphasis> is a list of the service the client is authorized to execute:
+<emphasis remap='B'>amdump</emphasis>,
+<emphasis remap='B'>noop</emphasis>,
+<emphasis remap='B'>selfcheck</emphasis>,
+<emphasis remap='B'>sendsize</emphasis>,
+<emphasis remap='B'>sendbackup</emphasis>,
+<emphasis remap='B'>amindexd</emphasis>,
+<emphasis remap='B'>amidxtaped</emphasis>.
+<emphasis remap='B'>amdump</emphasis> is a shortcut for "noop selfcheck sendsize sendbackup"</para>
</listitem>
</varlistentry>
<varlistentry>
<programlisting>
//some-pc/home normalpw
- //another-pc/disk otheruser%otherpw</programlisting>
+ //another-pc/disk otheruser%otherpw
+</programlisting>
-<para>With clear text passwords, this file should obviously be tightly protected.
-It only needs to be readable by the &A;-user on the Samba server.</para>
+With clear text passwords, this file should obviously be tightly protected.
+It only needs to be readable by the &A;-user on the Samba server.
<para>You can find further information in the
<emphasis remap='B'>docs/SAMBA</emphasis>
</informaltable>
<para/>
+</refsect1>
+
+<refsect1><title>CONFIGURATION OVERWRITE</title>
+<para>Most command allow to overwrite any configuration parameter on
+the command line with the -o option.</para>
+<para>-o NAME=value</para>
+<para>eg. -o runtapes=2</para>
+<para>eg. -o DUMPTYPE:no-compress:compress="server fast"</para>
+<para>eg. -o TAPETYPE:HP-DAT:length=2000m</para>
+<para>eg. -o INTERFACE:local:use="2000 kbps"</para>
+
+
</refsect1>
<refsect1><title>AUTHOR</title>
<para>
<citerefentry><refentrytitle>amadmin</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
<citerefentry><refentrytitle>amanda.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+<citerefentry><refentrytitle>amanda-client.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
<citerefentry><refentrytitle>amcheck</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
<citerefentry><refentrytitle>amcheckdb</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
<citerefentry><refentrytitle>amcleanup</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
<refsect1><title>DESCRIPTION</title>
<para>&amconf; is the main configuration file for &A;. This manpage lists the
relevant sections and parameters of this file for quick reference.</para>
+<para> The file <emphasis remap='B'><CONFIG_DIR>/<config>/amanda.conf</emphasis> is loaded.</para>
</refsect1>
<refsect1><title>PARAMETERS</title>
</varlistentry>
<varlistentry>
- <term><emphasis remap='B'>label_new_tapes</emphasis>
- <emphasis remap='I'> string</emphasis></term>
-<listitem>
- <para>Default: not set.
-When set, this directive will cause &A; to automatically write an &A;
-tape label to any blank tape she encounters. This option is DANGEROUS
-because when set, &A; will ERASE any non-&A; tapes you may have, and may
-also ERASE any near-failing tapes. Use with caution.</para>
-<para>When using this directive, specify the template for new tape
-labels. The template should contain some number of contiguous '%'
-characters, which will be replaced with a generated number. Be sure to
-specify enough '%' characters that you do not run out of tape labels.
-Example:
-<markup>label_new_tapes "DailySet1-%%%"</markup>
-</para>
-</listitem>
-</varlistentry>
+ <term><emphasis remap='B'>usetimestamps</emphasis>
+ <emphasis remap='I'> bool</emphasis></term>
+ <listitem>
+ <para>Default: <emphasis remap='B'>No</emphasis>.
+By default, Amanda can only track at most one run per calendar day. When
+this option is enabled, however, Amanda can track as many runs as you care
+to make.
+ </para>
+ <para>
+<emphasis remap='B'>WARNING</emphasis>: This option is not backward-compatible.
+Do not enable it if you intend to downgrade your server installation to
+Amanda community edition 2.5.0
+ </para>
+ </listitem>
+ </varlistentry>
<varlistentry>
-=======
<term><emphasis remap='B'>label_new_tapes</emphasis>
<emphasis remap='I'> string</emphasis></term>
<listitem>
<para>Default: not set.
-When set, this directive will cause &A; to automatically write an Amanda
-tape label to any black tape she encounters. This option is DANGEROUS
+When set, this directive will cause &A; to automatically write an &A;
+tape label to any blank tape she encounters. This option is DANGEROUS
because when set, &A; will ERASE any non-&A; tapes you may have, and may
also ERASE any near-failing tapes. Use with caution.</para>
<para>When using this directive, specify the template for new tape
<term><emphasis remap='B'>amrecover_do_fsf</emphasis> <emphasis remap='I'> bool</emphasis></term>
<listitem>
<para>Default:
-<emphasis remap='I'>off</emphasis>.
+<emphasis remap='I'>on</emphasis>.
Amrecover will call amrestore with the -f flag for faster positioning of the tape.</para>
</listitem>
</varlistentry>
<term><emphasis remap='B'>amrecover_check_label</emphasis> <emphasis remap='I'> bool</emphasis></term>
<listitem>
<para>Default:
-<emphasis remap='I'>off</emphasis>.
+<emphasis remap='I'>on</emphasis>.
Amrecover will call amrestore with the -l flag to check the label.</para>
</listitem>
</varlistentry>
holdingdisk <emphasis remap='I'>name</emphasis> {
<emphasis remap='I'>holdingdisk-option</emphasis> <emphasis remap='I'>holdingdisk-value</emphasis>
<literal>...</literal>
-}</programlisting>
+}
+</programlisting>
<para><emphasis remap='I'>Name</emphasis>
is a logical name for this holding disk.</para>
<para>Default:
<emphasis remap='I'>bsd</emphasis>.
Type of authorization to perform between tape server and backup client hosts.</para>
+<para><emphasis remap='B'>bsd</emphasis>, bsd authorization with udp initial
+connection and one tcp connection by data stream.</para>
+<para><emphasis remap='B'>bsdtcp</emphasis>, bsd authorization but use only
+one tcp connection.</para>
+<para><emphasis remap='B'>bsdudp</emphasis>, like bsd, but will use only one
+tcp connection for all data stream.</para>
<para><emphasis remap='B'>krb4</emphasis> to use Kerberos-IV
authorization.</para>
<para><emphasis remap='B'>krb5</emphasis> to use Kerberos-V
authorization.</para>
+<para><emphasis remap='B'>rsh</emphasis> to use rsh
+authorization.</para>
<para><emphasis remap='B'>ssh</emphasis> to use OpenSSH
authorization.</para>
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><emphasis remap='B'>amandad_path</emphasis> <emphasis remap='I'> string</emphasis></term>
+ <listitem>
+<para>Default:
+<emphasis remap='I'>$libexec/amandad</emphasis>.
+Specify the amandad path of the client, only use with rsh/ssh authentification.
+</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><emphasis remap='B'>client_username</emphasis> <emphasis remap='I'> string</emphasis></term>
+ <listitem>
+<para>Default:
+<emphasis remap='I'>CLIENT_LOGIN</emphasis>.
+Specify the username to connect on the client, only use with rsh/ssh authentification.
+</para>
+ </listitem>
+ </varlistentry>
+
<!-- bumping parameters yanked from the global section above -->
<varlistentry>
<para>PROG must not contain white space.</para>
<para>Specify client_decrypt_option "decryption-parameter" Default: "-d"</para>
<para>decryption-parameter must not contain white space.</para>
-<para>(See dumptype encrypt-fast in example/amanda.conf for reference)</para>
+<para>(See dumptype server-encrypt-fast in example/amanda.conf for reference)</para>
</listitem>
<listitem><para>encrypt server</para>
<para>Specify server_encrypt "PROG"</para>
<para>PROG must not contain white space.</para>
<para>Specify server_decrypt_option "decryption-parameter" Default: "-d"</para>
<para>decryption-parameter must not contain white space.</para>
+<para>(See dumptype client-encrypt-nocomp in example/amanda.conf for reference)</para>
</listitem>
</itemizedlist>
</listitem>
client-encryption AND server-compression is not supported.
<emphasis remap='I'>amcrypt</emphasis> which is a wrapper of
<emphasis remap='I'>aespipe</emphasis> is provided as a reference
- encryption program.</para>
+ symmetric encryption program.</para>
</varlistentry>
</varlistentry>
<varlistentry>
- <term><emphasis remap='B'>holdingdisk</emphasis> <emphasis remap='I'> boolean</emphasis></term>
+ <term><emphasis remap='B'>holdingdisk</emphasis> [ <emphasis remap='I'>never|auto|required]</emphasis> ]</term>
<listitem>
<para>Default:
-<emphasis remap='I'>yes</emphasis>.
+<emphasis remap='I'>auto</emphasis>.
Whether a holding disk should be used for these backups or whether they should go directly to tape.
If the holding disk is a portion of another file system that &A;
is backing up, that file system should refer to a dumptype with
<emphasis remap='B'>holdingdisk</emphasis>
set to
-<emphasis remap='I'>no</emphasis>
+<emphasis remap='I'>never</emphasis>
to avoid backing up the holding disk into itself.</para>
+
+ <variablelist remap='TP'>
+ <varlistentry>
+ <term><emphasis remap='B'>never</emphasis>|no|false|off</term>
+ <listitem>
+ <para>Never use a holdingdisk, the dump will always go directly to tape. There will be no dump if you have a tape error.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><emphasis remap='B'>auto</emphasis>|yes|true|on</term>
+ <listitem>
+ <para>Use the holding disk, unless there is a problem with the holding disk, the dump won't fit there or the medium doesn't require spooling (e.g., VFS device)</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><emphasis remap='B'>required</emphasis></term>
+ <listitem>
+ <para>Always dump to holdingdisk, never directly to tape. There will be no dump if it doesn't fit on holdingdisk</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
</listitem>
</varlistentry>
<refsect1><title>SEE ALSO</title>
<para>
<citerefentry><refentrytitle>amanda</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+<citerefentry><refentrytitle>amanda-client.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
<citerefentry><refentrytitle>amcrypt</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
<citerefentry><refentrytitle>aespipe</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
</para>
<refsynopsisdiv>
<cmdsynopsis>
<command>amcheck</command>
- <arg choice='opt'>-mwsclt </arg>
- <arg choice='opt'>-Maddress </arg>
+ <arg choice='opt'>-am</arg>
+ <arg choice='opt'>-w</arg>
+ <arg choice='opt'>-sclt</arg>
+ <group><arg choice='plain'>-M</arg><arg choice='plain'><replaceable>address</replaceable></arg></group>*
<arg choice='plain'><replaceable>config</replaceable></arg>
- <arg choice='opt' rep='repeat'><arg choice='plain'><replaceable>host</replaceable></arg><arg choice='opt' rep='repeat'><replaceable>disk</replaceable></arg></arg>
-
+ <group><arg choice='plain'><replaceable>host</replaceable></arg><arg choice='opt'><replaceable>disk</replaceable></arg>*</group>*
+ <group><arg choice='plain'>-o</arg><arg choice='plain'><replaceable>configoption</replaceable></arg></group>*
</cmdsynopsis>
</refsynopsisdiv>
<varlistentry>
<term><option>-c</option></term>
<listitem>
-<para>Run the client host checks.</para>
+<para>Run the client host checks.Multiple specific clients can be
+checked by specifying the client name.</para>
</listitem>
</varlistentry>
<varlistentry>
is writable, this check causes all data after the tape label to be
erased. If the label_new_tapes option is enabled, this check may ERASE
any non-Amanda tape in the drive or changer.
-The check implies
-<option>-t</option>
+The check enable the tape tests on the server host
and is only made if the tape is otherwise correct.</para>
</listitem>
</varlistentry>
but the mail is always sent.</para>
</listitem>
</varlistentry>
+
<varlistentry>
- <term><option>-M</option><replaceable>address</replaceable></term>
+ <term><option>-M</option> <replaceable>address</replaceable></term>
<listitem>
<para>Mail the report to
<emphasis remap='I'>address</emphasis>
<option>-m</option>.</para>
</listitem>
</varlistentry>
+
+ <varlistentry>
+ <term><replaceable>host</replaceable> [<replaceable>disk</replaceable>]*</term>
+ <listitem>
+<para>Specify the host and disk on which the command will work.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><emphasis remap='B'>-o</emphasis> <replaceable>configoption</replaceable></term>
+ <listitem>
+<para>See the "<emphasis remap='B'>CONFIGURATION OVERWRITE</emphasis>" section in <citerefentry><refentrytitle>amanda</refentrytitle><manvolnum>8</manvolnum></citerefentry>.</para>
+ </listitem>
+ </varlistentry>
</variablelist>
<para>The default is
man page for more details about &A;.</para>
</refsect1>
+<refsect1><title>OPTIONS</title>
+<variablelist remap='TP'>
+ <varlistentry>
+ <term><option>-k</option></term>
+ <listitem>
+ <para>Kill all Amanda processes.</para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+</refsect1>
+
<refsect1><title>EXAMPLES</title>
<para>This example runs the &A; cleanup process by hand after
a failure.</para>
--- /dev/null
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
+ "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd"
+[
+ <!-- entities files to use -->
+ <!ENTITY % global_entities SYSTEM '../entities/global.entities'>
+ %global_entities;
+]>
+
+<refentry id='amcrypt-asym-ossl.8'>
+
+<refmeta>
+ <refentrytitle>amcrypt-ossl-asym</refentrytitle>
+ <manvolnum>8</manvolnum>
+</refmeta>
+<refnamediv>
+ <refname>amcrypt-ossl-asym</refname>
+ <refpurpose>crypt program for &A; asymmetric data encryption using OpenSSL</refpurpose>
+</refnamediv>
+<!-- body begins here -->
+<refsynopsisdiv>
+ <cmdsynopsis>
+ <command>amcrypt-ossl-asym</command>
+ <arg choice="opt">-d</arg>
+ </cmdsynopsis>
+</refsynopsisdiv>
+<refsect1>
+ <title>DESCRIPTION</title>
+ <para>
+ &amcryptosslasym; uses <emphasis remap='B'>OpenSSL</emphasis> to
+ encrypt and decrypt data. OpenSSL is available from <ulink
+ url="http://www.openssl.org/">www.openssl.org</ulink>. OpenSSL
+ offers a wide variety of cipher choices (&amcryptosslasym; defaults
+ to 256-bit AES) and can use hardware cryptographic accelerators on
+ several platforms.
+ </para>
+ <para>
+ &amcryptosslasym; will search for the OpenSSL program in the following
+ directories: /bin:/usr/bin:/usr/local/bin:/usr/ssl/bin:/usr/local/ssl/bin.
+ </para>
+</refsect1>
+<refsect1>
+ <title>GENERATING PUBLIC AND PRIVATE KEYS</title>
+ <para>
+ RSA keys can be generated with the standard OpenSSL commands, e.g.:
+ </para>
+ <programlisting>
+$ cd /var/lib/amanda
+$ openssl genrsa -aes128 -out backup-privkey.pem 1024
+Generating RSA private key, 1024 bit long modulus
+[...]
+Enter pass phrase for backup-privkey.pem: <emphasis remap='I'>ENTER YOUR PASS PHRASE</emphasis>
+Verifying - Enter pass phrase for backup-key.pem: <emphasis remap='I'>ENTER YOUR PASS PHRASE</emphasis>
+
+$ openssl rsa -in backup-privkey.pem -pubout -out backup-pubkey.pem
+Enter pass phrase for backup-privkey.pem: <emphasis remap='I'>ENTER YOUR PASS PHRASE</emphasis>
+Writing RSA key
+
+</programlisting>
+ <para>
+ To generate a private key without a passphrase, omit the
+ <option>-aes128</option> option. See
+ <citerefentry><refentrytitle>openssl_genrsa</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+ for more key generation options.
+ </para>
+ <para>
+ Note that it is always possible to generate the public key from the
+ private key.
+ </para>
+</refsect1>
+<refsect1>
+ <title>KEY AND PASSPHRASE MANAGEMENT</title>
+ <para>
+ &amcryptosslasym; uses the <emphasis remap='I'>public key</emphasis>
+ to encrypt data. The security of the data does not depend on the
+ confidentiality of the public key. The <emphasis remap='I'>private
+ key</emphasis> is used to decrypt data, and must be protected.
+ Encrypted backup data cannot be recovered without the private key.
+ The private key may optionally be encrypted with a passphrase.
+ </para>
+ <para>
+ While the public key must be online at all times to perorm backups,
+ the private key and optional passphrase are only needed to restore
+ data. It is recommended that the latter be stored offline all other
+ times. For example, you could keep the private key on removable media,
+ and copy it into place for a restore; or you could keep the private
+ key online, encrypted with a passphrase that is present only for a
+ restore.
+ </para>
+ <para>
+ OpenSSL's key derivation routines use a salt to guard against
+ dictionary attacks on the pass phrase; still it is important to pick
+ a pass phrase that is hard to guess. The Diceware method (see <ulink
+ url="http://www.diceware.com/">www.diceware.com</ulink>) can
+ be used to create passphrases that are difficult to guess and easy to
+ remember.
+ </para>
+</refsect1>
+<refsect1>
+ <title>FILES</title>
+ <variablelist remap='TP'>
+ <varlistentry>
+ <term>/var/lib/amanda/backup-privkey.pem</term>
+ <listitem>
+ <para>
+ File containing the RSA private key. It should not be readable
+ by any user other than the &A; user.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>/var/lib/amanda/backup-pubkey.pem</term>
+ <listitem>
+ <para>
+ File containing the RSA public key.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>/var/lib/amanda/.am_passphrase</term>
+ <listitem>
+ <para>
+ File containing the passphrase. It should not be readable by
+ any user other than the &A; user.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+</refsect1>
+<refsect1>
+ <title>SEE ALSO</title>
+ <para>
+ <citerefentry>
+ <refentrytitle>amanda</refentrytitle>
+ <manvolnum>8</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>amanda.conf</refentrytitle>
+ <manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>openssl</refentrytitle>
+ <manvolnum>1</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>amcrypt-ossl</refentrytitle>
+ <manvolnum>8</manvolnum>
+ </citerefentry>
+ </para>
+</refsect1>
+
+</refentry>
--- /dev/null
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
+ "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd"
+[
+ <!-- entities files to use -->
+ <!ENTITY % global_entities SYSTEM '../entities/global.entities'>
+ %global_entities;
+]>
+
+<refentry id='amcrypt-ossl.8'>
+
+<refmeta>
+ <refentrytitle>amcrypt-ossl</refentrytitle>
+ <manvolnum>8</manvolnum>
+</refmeta>
+<refnamediv>
+ <refname>amcrypt-ossl</refname>
+ <refpurpose>crypt program for &A; symmetric data encryption using OpenSSL</refpurpose>
+</refnamediv>
+<!-- body begins here -->
+<refsynopsisdiv>
+ <cmdsynopsis>
+ <command>amcrypt-ossl</command>
+ <arg choice="opt">-d</arg>
+ </cmdsynopsis>
+</refsynopsisdiv>
+<refsect1>
+ <title>DESCRIPTION</title>
+ <para>
+ &amcryptossl; uses <emphasis remap='B'>OpenSSL</emphasis> to encrypt
+ and decrypt data. OpenSSL is available from <ulink
+ url="http://www.openssl.org/">www.openssl.org</ulink>. OpenSSL
+ offers a wide variety of cipher choices (&amcryptossl; defaults to
+ 256-bit AES) and can use hardware cryptographic accelerators on several
+ platforms.
+ </para>
+ <para>
+ &amcryptossl; will search for the OpenSSL program in the following
+ directories: /bin:/usr/bin:/usr/local/bin:/usr/ssl/bin:/usr/local/ssl/bin.
+ </para>
+</refsect1>
+<refsect1>
+ <title>PASSPHRASE MANAGEMENT</title>
+ <para>
+ &amcryptossl; uses the same pass phrase to encrypt and decrypt data.
+ It is very important to store and protect the pass phrase properly.
+ Encrypted backup data can <emphasis remap='B'>only</emphasis> be
+ recovered with the correct passphrase.
+ </para>
+ <para>
+ OpenSSL's key derivation routines use a salt to guard against
+ dictionary attacks on the pass phrase; still it is important to pick
+ a pass phrase that is hard to guess. The Diceware method (see <ulink
+ url="http://www.diceware.com/">www.diceware.com</ulink>) can be used to create passphrases
+ that are difficult to guess and easy to remember.
+ </para>
+</refsect1>
+<refsect1>
+ <title>FILES</title>
+ <variablelist remap='TP'>
+ <varlistentry>
+ <term>/var/lib/amanda/.am_passphrase</term>
+ <listitem>
+ <para>
+ File containing the pass phrase. It should not be readable by any user other than the &A; user.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+</refsect1>
+<refsect1>
+ <title>SEE ALSO</title>
+ <para>
+ <citerefentry>
+ <refentrytitle>amanda</refentrytitle>
+ <manvolnum>8</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>amanda.conf</refentrytitle>
+ <manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>openssl</refentrytitle>
+ <manvolnum>1</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>amcrypt-ossl-asym</refentrytitle>
+ <manvolnum>8</manvolnum>
+ </citerefentry>
+ </para>
+</refsect1>
+
+</refentry>
<refsect1><title>DESCRIPTION</title>
<para>&amcrypt;
-requires <emphasis remap='B'>aespipe</emphasis> and <emphasis
+requires <emphasis remap='B'>aespipe</emphasis>, <emphasis
+remap='B'>uuencode</emphasis> and <emphasis
remap='B'>gpg</emphasis> to work. Aespipe is available from <ulink
url="http://loop-aes.sourceforge.net"/></para>
<para>&amcrypt; will search for the aespipe program in the following directories:
<cmdsynopsis>
<command>amdump</command>
<arg choice='plain'><replaceable>config</replaceable></arg>
- <arg choice='opt' rep='repeat'><arg choice='plain'><replaceable>host</replaceable></arg><arg choice='opt' rep='repeat'><replaceable>disk</replaceable></arg></arg>
-
+ <group><arg choice='plain'><replaceable>host</replaceable></arg><arg choice='opt'><replaceable>disk</replaceable></arg>*</group>*
+ <group><arg choice='plain'>-o</arg><arg choice='plain'><replaceable>configoption</replaceable></arg></group>*
</cmdsynopsis>
</refsynopsisdiv>
man page for more details about &A;.</para>
</refsect1>
+<refsect1><title>OPTIONS</title>
+<variablelist remap='TP'>
+
+ <varlistentry>
+ <term><replaceable>host</replaceable> [<replaceable>disk</replaceable>]*</term>
+ <listitem>
+<para>Specify the host and disk on which the command will work.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><emphasis remap='B'>-o</emphasis> <replaceable>configoption</replaceable></term>
+ <listitem>
+<para>See the "<emphasis remap='B'>CONFIGURATION OVERWRITE</emphasis>" section in <citerefentry><refentrytitle>amanda</refentrytitle><manvolnum>8</manvolnum></citerefentry>.</para>
+ </listitem>
+ </varlistentry>
+
+</variablelist>
+</refsect1>
+
<refsect1><title>EXAMPLE</title>
<para>Here is a typical crontab entry. It runs
<command>amdump</command>
<command>amfetchdump</command>
<arg choice='opt'>-pcClawns</arg>
<arg choice='opt'>-d <replaceable>device</replaceable></arg>
- <arg choice='opt'>-o <replaceable>directory</replaceable></arg>
+ <arg choice='opt'>-O <replaceable>directory</replaceable></arg>
<arg choice='opt'>-i <replaceable>logfile</replaceable></arg>
<arg choice='opt'>-b <replaceable>blocksize</replaceable></arg>
<arg choice='plain'><replaceable>config</replaceable></arg>
</arg>
</arg>
</arg>
+ <group><arg choice='plain'>-o</arg><arg choice='plain'><replaceable>configoption</replaceable></arg></group>*
</cmdsynopsis>
</refsynopsisdiv>
<listitem><para> Restore from this tape device instead of the default.</para></listitem>
</varlistentry>
<varlistentry>
- <term><option>-o</option>
+ <term><option>-O</option>
<replaceable>directory</replaceable></term>
<listitem><para>Output restored files to this directory, instead of to the
current working directory.</para></listitem>
value will usually be autodetected, and should not normally need
to be set.</para></listitem>
</varlistentry>
+
+ <varlistentry>
+ <term><emphasis remap='B'>-o</emphasis> <replaceable>configoption</replaceable></term>
+ <listitem>
+<para>See the "<emphasis remap='B'>CONFIGURATION OVERWRITE</emphasis>"
+ section in <citerefentry><refentrytitle>amanda</refentrytitle><manvolnum>8</manvolnum></citerefentry>.</para>
+ </listitem>
+ </varlistentry>
+
</variablelist>
</refsect1>
<refsynopsisdiv>
<cmdsynopsis>
<command>amflush</command>
- <arg choice='opt'>-b </arg>
- <arg choice='opt'>-f </arg>
- <arg choice='opt'>-s </arg>
- <arg choice='opt' rep='repeat'><arg choice='plain'>-D </arg><arg choice='plain'><replaceable>datestamp</replaceable></arg></arg>
-
+ <arg choice='opt'>-b</arg>
+ <arg choice='opt'>-f</arg>
+ <arg choice='opt'>-s</arg>
+ <group><arg choice='plain'>-D</arg><arg choice='plain'><replaceable>datestamp</replaceable></arg></group>*
<arg choice='plain'><replaceable>config</replaceable></arg>
- <arg choice='opt' rep='repeat'><arg choice='plain'><replaceable>host</replaceable></arg><arg choice='opt' rep='repeat'><replaceable>disk</replaceable></arg></arg>
-
+ <group><arg choice='plain'><replaceable>host</replaceable></arg><arg choice='opt'><replaceable>disk</replaceable></arg>*</group>*
+ <group><arg choice='plain'>-o</arg><arg choice='plain'><replaceable>configoption</replaceable></arg></group>*
</cmdsynopsis>
</refsynopsisdiv>
dumps from 25 december 2000 to 27 december 2000.</para>
</listitem>
</varlistentry>
+
+ <varlistentry>
+ <term><replaceable>host</replaceable> [<replaceable>disk</replaceable>]*</term>
+ <listitem>
+<para>Specify the host and disk on which the command will work.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><emphasis remap='B'>-o</emphasis> <replaceable>configoption</replaceable></term>
+ <listitem>
+<para>See the "<emphasis remap='B'>CONFIGURATION OVERWRITE</emphasis>" section in <citerefentry><refentrytitle>amanda</refentrytitle><manvolnum>8</manvolnum></citerefentry>.</para>
+ </listitem>
+ </varlistentry>
+
</variablelist>
<para>You can specify many host/disk expressions, only disks that
<command>amgetconf</command>
<arg choice='opt'><replaceable>config</replaceable></arg>
<arg choice='plain'><replaceable>parameter</replaceable></arg>
+ <group><arg choice='plain'>-o</arg><arg choice='plain'><replaceable>configoption</replaceable></arg></group>*
</cmdsynopsis>
</refsynopsisdiv>
man page for more details about &A;.</para>
</refsect1>
+<refsect1><title>OPTIONS</title>
+<variablelist remap='TP'>
+
+ <varlistentry>
+ <term><emphasis remap='B'>-o</emphasis> <replaceable>configoption</replaceable></term>
+ <listitem>
+<para>See the "<emphasis remap='B'>CONFIGURATION OVERWRITE</emphasis>" section in <citerefentry><refentrytitle>amanda</refentrytitle><manvolnum>8</manvolnum></citerefentry>.</para>
+ </listitem>
+ </varlistentry>
+
+
+</variablelist>
+</refsect1>
+
<refsect1><title>EXAMPLE</title>
<para>Find out the path to the log file directory:</para>
(e.g. not a valid
<emphasis remap='I'>amanda.conf</emphasis>
keyword).
-In this case,
-<command>amgetconf</command>
-will write "<emphasis remap='B'>BUGGY</emphasis>" to stdout as the value.</para>
+</para>
</listitem>
</varlistentry>
</variablelist>
<arg choice='opt'>-f </arg>
<arg choice='plain'><replaceable>config</replaceable></arg>
<arg choice='plain'><replaceable>label</replaceable></arg>
- <arg choice='opt'><arg choice='plain'><replaceable>slot</replaceable></arg><arg choice='plain'><replaceable>slot</replaceable></arg></arg>
+ <group><arg choice='plain'>slot</arg><arg choice='plain'><replaceable>slot</replaceable></arg></group>
+ <group><arg choice='plain'>-o</arg><arg choice='plain'><replaceable>configoption</replaceable></arg></group>*
</cmdsynopsis>
</refsynopsisdiv>
man page for more details about &A;.</para>
</refsect1>
+<refsect1><title>OPTIONS</title>
+<variablelist remap='TP'>
+
+ <varlistentry>
+ <term><emphasis remap='B'>-o</emphasis> <replaceable>configoption</replaceable></term>
+ <listitem>
+<para>See the "<emphasis remap='B'>CONFIGURATION OVERWRITE</emphasis>" section in <citerefentry><refentrytitle>amanda</refentrytitle><manvolnum>8</manvolnum></citerefentry>.</para>
+ </listitem>
+ </varlistentry>
+
+
+</variablelist>
+</refsect1>
+
<refsect1><title>EXAMPLE</title>
<para>Write an &A; label with the string "DMP000" on
the tape loaded in the device named in the
<refsynopsisdiv>
<cmdsynopsis>
<command>amrecover</command>
- <arg choice='opt'><arg choice='opt'>-C </arg><arg choice='plain'><replaceable>config</replaceable></arg></arg>
- <arg choice='opt'><arg choice='plain'>-s </arg><arg choice='plain'><replaceable>index-server</replaceable></arg></arg>
- <arg choice='opt'><arg choice='plain'>-t </arg><arg choice='plain'><replaceable>tape-server</replaceable></arg></arg>
- <arg choice='opt'><arg choice='plain'>-d </arg><arg choice='plain'><replaceable>tape-device</replaceable></arg></arg>
+ <group><arg choice='opt'>-C </arg><arg choice='plain'><replaceable>config</replaceable></arg></group>
+ <group><arg choice='plain'>-s </arg><arg choice='plain'><replaceable>index-server</replaceable></arg></group>
+ <group><arg choice='plain'>-t </arg><arg choice='plain'><replaceable>tape-server</replaceable></arg></group>
+ <group><arg choice='plain'>-d </arg><arg choice='plain'><replaceable>tape-device</replaceable></arg></group>
+ <group><arg choice='plain'>-o </arg><arg choice='plain'><replaceable>clientconfigoption</replaceable></arg></group>*
</cmdsynopsis>
</refsynopsisdiv>
the backed up filesystem will be created in the current directory.
See the examples below for details.</para>
+<para>Amrecover will read the <emphasis remap='B'>amanda-client.conf</emphasis> file and the <replaceable>config</replaceable><emphasis remap='B'>/amanda-client.conf</emphasis> file.</para>
+
<para>See the
<citerefentry><refentrytitle>amanda</refentrytitle><manvolnum>8</manvolnum></citerefentry>
man page for more details about &A;.</para>
<para>Tape device to use on the tape server host.</para>
</listitem>
</varlistentry>
+
+ <varlistentry>
+ <term><emphasis remap='B'>-o</emphasis> <replaceable>clientconfigoption</replaceable></term>
+ <listitem>
+<para>See the "<emphasis remap='B'>CONFIGURATION OVERWRITE</emphasis>"
+ section in <citerefentry><refentrytitle>amanda</refentrytitle><manvolnum>8</manvolnum></citerefentry>.</para>
+ </listitem>
+ </varlistentry>
+
</variablelist>
</refsect1>
</listitem>
</varlistentry>
<varlistentry>
- <term><emphasis remap='B'>setdate YYYY-MM-DD</emphasis></term>
+ <term><emphasis remap='B'>setdate YYYY-MM-DD-HH-MM[-SS] | YYYY-MM-DD</emphasis></term>
<listitem>
-<para>Set the date (default: today).
+<para>Set the restore time (default: now).
File listing commands only return information on
backup images for this day,
for the day before with the next lower dump level,
1996-07-06 through 1997-07-08 were level 2 backups
</literallayout> <!-- .fi -->
-<para>then if 1997-07-08 is the requested date,
-files from the following days would be used:</para>
+<para>then the command <emphasis remap='B'>setdate 1997-07-08-00</emphasis>
+would yield files from the following days:</para>
<!-- .RS -->
<literallayout remap='.nf'>
<emphasis remap='I'>mountpoint</emphasis>
is not specified, all pathnames will be relative to the (unknown)
mount point instead of full pathnames.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><emphasis remap='B'>listhost [diskdevice]</emphasis></term>
+ <listitem>
+<para>List all
+<emphasis remap='B'>host</emphasis></para>
</listitem>
</varlistentry>
<varlistentry>
Defaults to
<emphasis remap='I'>more</emphasis>
if PAGER is not set.</para>
+<para><envar>AMANDA_SERVER</envar>
+If set, $AMANDA_SERVER will be used as index-server.
+The value will take precedence over the compiled default,
+but will be overridden by the -s switch.
+</para>
+<para><envar>AMANDA_TAPE_SERVER</envar>
+If set, $AMANDA_TAPE_SERVER will be used as tape-server.
+The value will take precedence over the compiled default,
+but will be overridden by the -t switch.
+</para>
<!-- .RE -->
</refsect1>
<refsect1><title>SEE ALSO</title>
<para><citerefentry><refentrytitle>amanda</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+<citerefentry><refentrytitle>amanda-client.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
<citerefentry><refentrytitle>amrestore</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
<citerefentry><refentrytitle>amfetchdump</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
<citerefentry><refentrytitle>readline</refentrytitle><manvolnum>3</manvolnum></citerefentry></para>
<cmdsynopsis>
<command>amreport</command>
<arg choice='opt'><replaceable>config</replaceable></arg>
- <arg choice='opt'><arg choice='plain'>-l </arg><arg choice='plain'><replaceable>logfile</replaceable></arg></arg>
- <arg choice='opt'><arg choice='plain'>-f </arg><arg choice='plain'><replaceable>outputfile</replaceable></arg></arg>
- <arg choice='opt'><arg choice='plain'>-p </arg><arg choice='plain'><replaceable>postscriptfile</replaceable></arg></arg>
+ <arg choice='opt'>-i</arg>
+ <group><arg choice='plain'>-M</arg><arg choice='plain'><replaceable>address</replaceable></arg></group>
+ <group><arg choice='plain'>-l</arg><arg choice='plain'><replaceable>logfile</replaceable></arg></group>
+ <group><arg choice='plain'>-f</arg><arg choice='plain'><replaceable>outputfile</replaceable></arg></group>
+ <group><arg choice='plain'>-p</arg><arg choice='plain'><replaceable>postscriptfile</replaceable></arg></group>
+ <group><arg choice='plain'>-o</arg><arg choice='plain'><replaceable>configoption</replaceable></arg></group>*
</cmdsynopsis>
</refsynopsisdiv>
<term><emphasis remap='I'>config</emphasis></term>
<listitem>
<para>Name of the configuration to process.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><option>-i</option></term>
+ <listitem>
+<para>Don't email the report.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><option>-M</option> <replaceable>address</replaceable></term>
+ <listitem>
+<para>Mail the report to
+<emphasis remap='I'>address</emphasis>
+instead of the
+<emphasis remap='B'>mailto</emphasis>
+value from
+<emphasis remap='I'>amanda.conf</emphasis>.
+</para>
</listitem>
</varlistentry>
<varlistentry>
directive is specified in amanda.conf.</para>
</listitem>
</varlistentry>
+
+ <varlistentry>
+ <term><emphasis remap='B'>-o</emphasis> <replaceable>configoption</replaceable></term>
+ <listitem>
+<para>See the "<emphasis remap='B'>CONFIGURATION OVERWRITE</emphasis>" section in <citerefentry><refentrytitle>amanda</refentrytitle><manvolnum>8</manvolnum></citerefentry>.</para>
+ </listitem>
+ </varlistentry>
+
</variablelist>
</refsect1>
<cmdsynopsis>
<command>amrestore</command>
<group choice='opt'><arg choice='plain'>-r </arg><arg choice='plain'>-c </arg><arg choice='plain'>-C </arg></group>
- <arg choice='opt'><arg choice='plain'>-b </arg><arg choice='plain'><replaceable>blocksize</replaceable></arg></arg>
- <arg choice='opt'><arg choice='plain'>-f </arg><arg choice='plain'><replaceable>fileno</replaceable></arg></arg>
- <arg choice='opt'><arg choice='plain'>-l </arg><arg choice='plain'><replaceable>label</replaceable></arg></arg>
- <arg choice='opt'>-p </arg>
- <arg choice='opt'>-h </arg>
- <group choice='plain'><arg choice='plain'><replaceable>tapedevice</replaceable></arg><arg choice='plain'><replaceable>holdingfile</replaceable></arg><arg choice='opt'><arg choice='plain'><replaceable>hostname</replaceable></arg><arg choice='opt'><arg choice='plain'><replaceable>diskname</replaceable></arg><arg choice='opt'><arg choice='plain'><replaceable>datestamp</replaceable></arg><arg choice='opt'><arg choice='plain'><replaceable>hostname</replaceable></arg><arg choice='opt'><arg choice='plain'><replaceable>diskname</replaceable></arg><arg choice='opt' rep='repeat'><replaceable>datestamp</replaceable></arg></arg></arg></arg></arg></arg></group>
+ <group><arg choice='plain'>-b</arg><arg choice='plain'><replaceable>blocksize</replaceable></arg></group>
+ <group><arg choice='plain'>-f</arg><arg choice='plain'><replaceable>fileno</replaceable></arg></group>
+ <group><arg choice='plain'>-l </arg><arg choice='plain'><replaceable>label</replaceable></arg></group>
+ <arg choice='opt'>-p</arg>
+ <arg choice='opt'>-h</arg>
+ <arg choice='plain'><arg choice='plain'><replaceable>tapedevice</replaceable></arg>|<arg choice='plain'><replaceable>holdingfile</replaceable></arg></arg>
+ <group><arg choice='plain'><replaceable>hostname</replaceable></arg><group><arg choice='plain'><replaceable>diskname</replaceable></arg><group><arg choice='plain'><replaceable>datestamp</replaceable></arg><group><arg choice='plain'><replaceable>hostname</replaceable></arg><group><arg choice='plain'><replaceable>diskname</replaceable></arg><group><arg choice='plain'><replaceable>datestamp</replaceable></arg><arg choice='plain'>...</arg></group></group></group></group></group></group>
</cmdsynopsis>
</refsynopsisdiv>
<para>If a header is written (-r or -h),
only 32 KBytes are output regardless of the tape blocksize.
This makes the resulting image usable as a holding file.</para>
+
+<variablelist remap='TP'>
+ <varlistentry>
+ <term><emphasis remap='B'>-o</emphasis> <replaceable>configoption</replaceable></term>
+ <listitem>
+<para>See the "<emphasis remap='B'>CONFIGURATION OVERWRITE</emphasis>" section in <citerefentry><refentrytitle>amanda</refentrytitle><manvolnum>8</manvolnum></citerefentry>.</para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
</refsect1>
<refsect1><title>EXAMPLES</title>
<arg choice='opt'>-c </arg>
<arg choice='opt'>-o </arg>
<arg choice='opt'>-b <replaceable>blocksize</replaceable></arg>
- <arg choice='opt'>-e <replaceable>estsize</replaceable></arg>
+ <arg choice='plain'>-e <replaceable>estsize</replaceable></arg>
<arg choice='opt'>-f <replaceable>tapedev</replaceable></arg>
<arg choice='opt'>-t <replaceable>typename</replaceable></arg>
</cmdsynopsis>
<varlistentry>
<term><option>-e</option><replaceable> estsize</replaceable></term>
<listitem>
-<para>estimated tape size (default: 1g == 1024m)</para>
+<para>estimated tape size (No default!)</para>
</listitem>
</varlistentry>
<varlistentry>
<!-- .RS -->
<literallayout remap='.nf'>
-% amtapetype -f /dev/nst0
+% amtapetype -f /dev/nst0 -e 150G
</literallayout></refsect1>
<refsect1><title>NOTES</title>
--- /dev/null
+# Makefile for Amanda file recovery programs.
+
+INCLUDES = -I$(top_builddir)/common-src \
+ -I$(top_srcdir)/common-src \
+ -I$(top_srcdir)/client-src
+
+LINT=@AMLINT@
+LINTFLAGS=@AMLINTFLAGS@
+
+LIB_EXTENSION = la
+
+sbin_PROGRAMS = amoldrecover
+
+if WANT_RUNTIME_PSEUDO_RELOC
+AM_LDFLAGS = -Wl,-enable-runtime-pseudo-reloc
+endif
+
+###
+# Because libamanda includes routines (e.g. regex) provided by some system
+# libraries, and because of the way libtool sets up the command line, we
+# need to list libamanda twice here, first to override the system library
+# routines, and second to pick up any references in the other libraries.
+###
+
+LDADD = ../common-src/libamanda.$(LIB_EXTENSION) \
+ @LEXLIB@ \
+ ../client-src/libamclient.$(LIB_EXTENSION) \
+ $(READLINE_LIBS) \
+ ../common-src/libamanda.$(LIB_EXTENSION)
+
+amoldrecover_CSRC = amrecover.c \
+ display_commands.c extract_list.c \
+ help.c set_commands.c
+
+amoldrecover_SOURCES = $(amoldrecover_CSRC) uparse.y uscan.l
+
+noinst_HEADERS = amrecover.h uparse.h
+
+AM_YFLAGS = -d
+
+# so that uscan.c is never generated before uparse.h
+# otherwise we might have makedepend problems
+$(srcdir)/uscan.c: $(srcdir)/uparse.h
+
+uscan.$(OBJEXT): $(srcdir)/uscan.c
+ $(CC) $(CFLAGS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CPPFLAGS) -c $<
+
+uparse.$(OBJEXT): $(srcdir)/uparse.c
+ $(CC) $(CFLAGS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CPPFLAGS) -c $<
+
+
+install-exec-hook:
+ @list="$(sbin_PROGRAMS)"; \
+ for p in $$list; do \
+ pa=$(DESTDIR)$(sbindir)/`echo $$p|sed '$(transform)'`; \
+ echo chown $(BINARY_OWNER) $$pa; \
+ chown $(BINARY_OWNER) $$pa; \
+ echo chgrp $(SETUID_GROUP) $$pa; \
+ chgrp $(SETUID_GROUP) $$pa; \
+ echo chmod o-rwx $$pa; \
+ chmod o-rwx $$pa; \
+ done
+
+
+lint:
+ @ f="$(amoldrecover_CSRC)"; \
+ (cd ../common-src; make listlibsrc); \
+ f="$$f "`cat ../common-src/listlibsrc.output`; \
+ (cd ../server-src; make listlibsrc); \
+ f="$$f "`cat ../server-src/listlibsrc.output`; \
+ echo $(LINT) $$f; \
+ $(LINT) $(LINTFLAGS) $(CPPFLAGS) $(DEFS) -I. -I../config $(INCLUDES) $$f;\
+ if [ $$? -ne 0 ]; then \
+ exit 1; \
+ fi; \
+ exit 0
--- /dev/null
+# Makefile.in generated by automake 1.9.6 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+# Makefile for Amanda file recovery programs.
+
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+top_builddir = ..
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+INSTALL = @INSTALL@
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+sbin_PROGRAMS = amoldrecover$(EXEEXT)
+subdir = oldrecover-src
+DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \
+ $(srcdir)/Makefile.in uparse.c uparse.h uscan.c
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
+ $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config/config.h
+CONFIG_CLEAN_FILES =
+am__installdirs = "$(DESTDIR)$(sbindir)"
+sbinPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
+PROGRAMS = $(sbin_PROGRAMS)
+am__objects_1 = amrecover.$(OBJEXT) display_commands.$(OBJEXT) \
+ extract_list.$(OBJEXT) help.$(OBJEXT) set_commands.$(OBJEXT)
+am_amoldrecover_OBJECTS = $(am__objects_1) uparse.$(OBJEXT) \
+ uscan.$(OBJEXT)
+amoldrecover_OBJECTS = $(am_amoldrecover_OBJECTS)
+amoldrecover_LDADD = $(LDADD)
+am__DEPENDENCIES_1 =
+amoldrecover_DEPENDENCIES = ../common-src/libamanda.$(LIB_EXTENSION) \
+ ../client-src/libamclient.$(LIB_EXTENSION) \
+ $(am__DEPENDENCIES_1) ../common-src/libamanda.$(LIB_EXTENSION)
+DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)/config
+depcomp = $(SHELL) $(top_srcdir)/config/depcomp
+am__depfiles_maybe = depfiles
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+LEXCOMPILE = $(LEX) $(LFLAGS) $(AM_LFLAGS)
+LTLEXCOMPILE = $(LIBTOOL) --mode=compile $(LEX) $(LFLAGS) $(AM_LFLAGS)
+YACCCOMPILE = $(YACC) $(YFLAGS) $(AM_YFLAGS)
+LTYACCCOMPILE = $(LIBTOOL) --mode=compile $(YACC) $(YFLAGS) \
+ $(AM_YFLAGS)
+SOURCES = $(amoldrecover_SOURCES)
+DIST_SOURCES = $(amoldrecover_SOURCES)
+HEADERS = $(noinst_HEADERS)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+AMANDA_DBGDIR = @AMANDA_DBGDIR@
+AMANDA_DEBUG_DAYS = @AMANDA_DEBUG_DAYS@
+AMANDA_TMPDIR = @AMANDA_TMPDIR@
+AMDEP_FALSE = @AMDEP_FALSE@
+AMDEP_TRUE = @AMDEP_TRUE@
+AMLINT = @AMLINT@
+AMLINTFLAGS = @AMLINTFLAGS@
+AMPLOT_CAT_COMPRESS = @AMPLOT_CAT_COMPRESS@
+AMPLOT_CAT_GZIP = @AMPLOT_CAT_GZIP@
+AMPLOT_CAT_PACK = @AMPLOT_CAT_PACK@
+AMPLOT_COMPRESS = @AMPLOT_COMPRESS@
+AMTAR = @AMTAR@
+AM_CFLAGS = @AM_CFLAGS@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+AWK_VAR_ASSIGNMENT_OPT = @AWK_VAR_ASSIGNMENT_OPT@
+BINARY_OWNER = @BINARY_OWNER@
+BUILD_MAN_PAGES_FALSE = @BUILD_MAN_PAGES_FALSE@
+BUILD_MAN_PAGES_TRUE = @BUILD_MAN_PAGES_TRUE@
+CAT = @CAT@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CHIO = @CHIO@
+CHS = @CHS@
+CLIENT_LOGIN = @CLIENT_LOGIN@
+CLIENT_SCRIPTS_OPT = @CLIENT_SCRIPTS_OPT@
+COMPRESS = @COMPRESS@
+CONFIGURE_COMMAND = @CONFIGURE_COMMAND@
+CONFIG_DIR = @CONFIG_DIR@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DB_EXT = @DB_EXT@
+DD = @DD@
+DEFAULT_CHANGER_DEVICE = @DEFAULT_CHANGER_DEVICE@
+DEFAULT_CONFIG = @DEFAULT_CONFIG@
+DEFAULT_RAW_TAPE_DEVICE = @DEFAULT_RAW_TAPE_DEVICE@
+DEFAULT_SERVER = @DEFAULT_SERVER@
+DEFAULT_TAPE_DEVICE = @DEFAULT_TAPE_DEVICE@
+DEFAULT_TAPE_SERVER = @DEFAULT_TAPE_SERVER@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DOC_BUILD_DATE = @DOC_BUILD_DATE@
+DUMP = @DUMP@
+DUMPER_DIR = @DUMPER_DIR@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+GETCONF = @GETCONF@
+GNUPLOT = @GNUPLOT@
+GNUTAR = @GNUTAR@
+GNUTAR_LISTED_INCREMENTAL_DIR = @GNUTAR_LISTED_INCREMENTAL_DIR@
+GNUTAR_LISTED_INCREMENTAL_DIRX = @GNUTAR_LISTED_INCREMENTAL_DIRX@
+GREP = @GREP@
+GZIP = @GZIP@
+HAVE_XSLTPROC_FALSE = @HAVE_XSLTPROC_FALSE@
+HAVE_XSLTPROC_TRUE = @HAVE_XSLTPROC_TRUE@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIBTOOL_DEPS = @LIBTOOL_DEPS@
+LL_FMT = @LL_FMT@
+LN_S = @LN_S@
+LTALLOCA = @LTALLOCA@
+LTLIBOBJS = @LTLIBOBJS@
+MAILER = @MAILER@
+MAKEINFO = @MAKEINFO@
+MAXTAPEBLOCKSIZE = @MAXTAPEBLOCKSIZE@
+MCUTIL = @MCUTIL@
+MT = @MT@
+MTX = @MTX@
+MT_FILE_FLAG = @MT_FILE_FLAG@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PCAT = @PCAT@
+PERL = @PERL@
+PRINT = @PRINT@
+RANLIB = @RANLIB@
+READLINE_LIBS = @READLINE_LIBS@
+RESTORE = @RESTORE@
+SAMBA_CLIENT = @SAMBA_CLIENT@
+SERVICE_SUFFIX = @SERVICE_SUFFIX@
+SETUID_GROUP = @SETUID_GROUP@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SNAPSHOT_STAMP = @SNAPSHOT_STAMP@
+STRIP = @STRIP@
+USE_VERSION_SUFFIXES = @USE_VERSION_SUFFIXES@
+VDUMP = @VDUMP@
+VERSION = @VERSION@
+VERSION_COMMENT = @VERSION_COMMENT@
+VERSION_MAJOR = @VERSION_MAJOR@
+VERSION_MINOR = @VERSION_MINOR@
+VERSION_PATCH = @VERSION_PATCH@
+VERSION_SUFFIX = @VERSION_SUFFIX@
+VRESTORE = @VRESTORE@
+VXDUMP = @VXDUMP@
+VXRESTORE = @VXRESTORE@
+WANT_AMPLOT_FALSE = @WANT_AMPLOT_FALSE@
+WANT_AMPLOT_TRUE = @WANT_AMPLOT_TRUE@
+WANT_CHG_SCSI_FALSE = @WANT_CHG_SCSI_FALSE@
+WANT_CHG_SCSI_TRUE = @WANT_CHG_SCSI_TRUE@
+WANT_CHIO_SCSI_FALSE = @WANT_CHIO_SCSI_FALSE@
+WANT_CHIO_SCSI_TRUE = @WANT_CHIO_SCSI_TRUE@
+WANT_CLIENT_FALSE = @WANT_CLIENT_FALSE@
+WANT_CLIENT_TRUE = @WANT_CLIENT_TRUE@
+WANT_RECOVER_FALSE = @WANT_RECOVER_FALSE@
+WANT_RECOVER_TRUE = @WANT_RECOVER_TRUE@
+WANT_RESTORE_FALSE = @WANT_RESTORE_FALSE@
+WANT_RESTORE_TRUE = @WANT_RESTORE_TRUE@
+WANT_RUNTIME_PSEUDO_RELOC_FALSE = @WANT_RUNTIME_PSEUDO_RELOC_FALSE@
+WANT_RUNTIME_PSEUDO_RELOC_TRUE = @WANT_RUNTIME_PSEUDO_RELOC_TRUE@
+WANT_SAMBA_FALSE = @WANT_SAMBA_FALSE@
+WANT_SAMBA_TRUE = @WANT_SAMBA_TRUE@
+WANT_SERVER_FALSE = @WANT_SERVER_FALSE@
+WANT_SERVER_TRUE = @WANT_SERVER_TRUE@
+WANT_SETUID_CLIENT_FALSE = @WANT_SETUID_CLIENT_FALSE@
+WANT_SETUID_CLIENT_TRUE = @WANT_SETUID_CLIENT_TRUE@
+WANT_SSH_SECURITY_FALSE = @WANT_SSH_SECURITY_FALSE@
+WANT_SSH_SECURITY_TRUE = @WANT_SSH_SECURITY_TRUE@
+WANT_TAPE_FALSE = @WANT_TAPE_FALSE@
+WANT_TAPE_TRUE = @WANT_TAPE_TRUE@
+XFSDUMP = @XFSDUMP@
+XFSRESTORE = @XFSRESTORE@
+XSLTPROC = @XSLTPROC@
+YACC = @YACC@
+ac_c = @ac_c@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
+ac_ct_RANLIB = @ac_ct_RANLIB@
+ac_ct_STRIP = @ac_ct_STRIP@
+ac_n = @ac_n@
+am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
+am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
+am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
+am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+datadir = @datadir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+INCLUDES = -I$(top_builddir)/common-src \
+ -I$(top_srcdir)/common-src \
+ -I$(top_srcdir)/client-src
+
+LINT = @AMLINT@
+LINTFLAGS = @AMLINTFLAGS@
+LIB_EXTENSION = la
+@WANT_RUNTIME_PSEUDO_RELOC_TRUE@AM_LDFLAGS = -Wl,-enable-runtime-pseudo-reloc
+
+###
+# Because libamanda includes routines (e.g. regex) provided by some system
+# libraries, and because of the way libtool sets up the command line, we
+# need to list libamanda twice here, first to override the system library
+# routines, and second to pick up any references in the other libraries.
+###
+LDADD = ../common-src/libamanda.$(LIB_EXTENSION) \
+ @LEXLIB@ \
+ ../client-src/libamclient.$(LIB_EXTENSION) \
+ $(READLINE_LIBS) \
+ ../common-src/libamanda.$(LIB_EXTENSION)
+
+amoldrecover_CSRC = amrecover.c \
+ display_commands.c extract_list.c \
+ help.c set_commands.c
+
+amoldrecover_SOURCES = $(amoldrecover_CSRC) uparse.y uscan.l
+noinst_HEADERS = amrecover.h uparse.h
+AM_YFLAGS = -d
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .l .lo .o .obj .y
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu oldrecover-src/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu oldrecover-src/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+install-sbinPROGRAMS: $(sbin_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ test -z "$(sbindir)" || $(mkdir_p) "$(DESTDIR)$(sbindir)"
+ @list='$(sbin_PROGRAMS)'; for p in $$list; do \
+ p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
+ if test -f $$p \
+ || test -f $$p1 \
+ ; then \
+ f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \
+ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(sbinPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(sbindir)/$$f'"; \
+ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(sbinPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(sbindir)/$$f" || exit 1; \
+ else :; fi; \
+ done
+
+uninstall-sbinPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(sbin_PROGRAMS)'; for p in $$list; do \
+ f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \
+ echo " rm -f '$(DESTDIR)$(sbindir)/$$f'"; \
+ rm -f "$(DESTDIR)$(sbindir)/$$f"; \
+ done
+
+clean-sbinPROGRAMS:
+ @list='$(sbin_PROGRAMS)'; for p in $$list; do \
+ f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f $$p $$f"; \
+ rm -f $$p $$f ; \
+ done
+uparse.h: uparse.c
+ @if test ! -f $@; then \
+ rm -f uparse.c; \
+ $(MAKE) uparse.c; \
+ else :; fi
+amoldrecover$(EXEEXT): $(amoldrecover_OBJECTS) $(amoldrecover_DEPENDENCIES)
+ @rm -f amoldrecover$(EXEEXT)
+ $(LINK) $(amoldrecover_LDFLAGS) $(amoldrecover_OBJECTS) $(amoldrecover_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/amrecover.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/display_commands.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/extract_list.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/help.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/set_commands.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uparse.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uscan.Po@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ if $(LTCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+.l.c:
+ $(LEXCOMPILE) $<
+ sed '/^#/ s|$(LEX_OUTPUT_ROOT)\.c|$@|' $(LEX_OUTPUT_ROOT).c >$@
+ rm -f $(LEX_OUTPUT_ROOT).c
+
+.y.c:
+ $(YACCCOMPILE) $<
+ if test -f y.tab.h; then \
+ to=`echo "$*_H" | sed \
+ -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/' \
+ -e 's/[^ABCDEFGHIJKLMNOPQRSTUVWXYZ]/_/g'`; \
+ sed -e "/^#/!b" -e "s/Y_TAB_H/$$to/g" -e "s|y\.tab\.h|$*.h|" \
+ y.tab.h >$*.ht; \
+ rm -f y.tab.h; \
+ if cmp -s $*.ht $*.h; then \
+ rm -f $*.ht ;\
+ else \
+ mv $*.ht $*.h; \
+ fi; \
+ fi
+ if test -f y.output; then \
+ mv y.output $*.output; \
+ fi
+ sed '/^#/ s|y\.tab\.c|$@|' y.tab.c >$@t && mv $@t $@
+ rm -f y.tab.c
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+distclean-libtool:
+ -rm -f libtool
+uninstall-info-am:
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
+ list='$(DISTFILES)'; for file in $$list; do \
+ case $$file in \
+ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
+ esac; \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+ dir="/$$dir"; \
+ $(mkdir_p) "$(distdir)$$dir"; \
+ else \
+ dir=''; \
+ fi; \
+ if test -d $$d/$$file; then \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(PROGRAMS) $(HEADERS)
+installdirs:
+ for dir in "$(DESTDIR)$(sbindir)"; do \
+ test -z "$$dir" || $(mkdir_p) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -rm -f uparse.c
+ -rm -f uparse.h
+ -rm -f uscan.c
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-sbinPROGRAMS \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-libtool distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-exec-am: install-sbinPROGRAMS
+ @$(NORMAL_INSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) install-exec-hook
+
+install-info: install-info-am
+
+install-man:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-info-am uninstall-sbinPROGRAMS
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-sbinPROGRAMS ctags distclean \
+ distclean-compile distclean-generic distclean-libtool \
+ distclean-tags distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-exec \
+ install-exec-am install-exec-hook install-info install-info-am \
+ install-man install-sbinPROGRAMS install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags uninstall uninstall-am uninstall-info-am \
+ uninstall-sbinPROGRAMS
+
+
+# so that uscan.c is never generated before uparse.h
+# otherwise we might have makedepend problems
+$(srcdir)/uscan.c: $(srcdir)/uparse.h
+
+uscan.$(OBJEXT): $(srcdir)/uscan.c
+ $(CC) $(CFLAGS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CPPFLAGS) -c $<
+
+uparse.$(OBJEXT): $(srcdir)/uparse.c
+ $(CC) $(CFLAGS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CPPFLAGS) -c $<
+
+install-exec-hook:
+ @list="$(sbin_PROGRAMS)"; \
+ for p in $$list; do \
+ pa=$(DESTDIR)$(sbindir)/`echo $$p|sed '$(transform)'`; \
+ echo chown $(BINARY_OWNER) $$pa; \
+ chown $(BINARY_OWNER) $$pa; \
+ echo chgrp $(SETUID_GROUP) $$pa; \
+ chgrp $(SETUID_GROUP) $$pa; \
+ echo chmod o-rwx $$pa; \
+ chmod o-rwx $$pa; \
+ done
+
+lint:
+ @ f="$(amoldrecover_CSRC)"; \
+ (cd ../common-src; make listlibsrc); \
+ f="$$f "`cat ../common-src/listlibsrc.output`; \
+ (cd ../server-src; make listlibsrc); \
+ f="$$f "`cat ../server-src/listlibsrc.output`; \
+ echo $(LINT) $$f; \
+ $(LINT) $(LINTFLAGS) $(CPPFLAGS) $(DEFS) -I. -I../config $(INCLUDES) $$f;\
+ if [ $$? -ne 0 ]; then \
+ exit 1; \
+ fi; \
+ exit 0
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
--- /dev/null
+/*
+ * Amanda, The Advanced Maryland Automatic Network Disk Archiver
+ * Copyright (c) 1991-1998, 2000 University of Maryland at College Park
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of U.M. not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. U.M. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: the Amanda Development Team. Its members are listed in a
+ * file named AUTHORS, in the root directory of this distribution.
+ */
+/*
+ * $Id: amrecover.c,v 1.7 2006/07/25 18:27:57 martinea Exp $
+ *
+ * an interactive program for recovering backed-up files
+ */
+
+#include "amanda.h"
+#include "version.h"
+//#ifdef HAVE_NETINET_IN_SYSTM_H
+//#include <netinet/in_systm.h>
+//#endif
+//#include <netinet/in.h>
+//#ifdef HAVE_NETINET_IP_H
+//#include <netinet/ip.h>
+//#endif
+#include "stream.h"
+#include "amfeatures.h"
+#include "amrecover.h"
+#include "getfsent.h"
+#include "dgram.h"
+#include "util.h"
+
+extern int process_line(char *line);
+int guess_disk(char *cwd, size_t cwd_len, char **dn_guess, char **mpt_guess);
+int get_line(void);
+int grab_reply(int show);
+void sigint_handler(int signum);
+int main(int argc, char **argv);
+
+#define USAGE "Usage: amoldrecover [[-C] <config>] [-s <index-server>] [-t <tape-server>] [-d <tape-device>]\n"
+
+char *config = NULL;
+char *server_name = NULL;
+int server_socket;
+char *server_line = NULL;
+char *dump_datestamp = NULL; /* date we are restoring */
+char *dump_hostname; /* which machine we are restoring */
+char *disk_name = NULL; /* disk we are restoring */
+char *mount_point = NULL; /* where disk was mounted */
+char *disk_path = NULL; /* path relative to mount point */
+char dump_date[STR_SIZE]; /* date on which we are restoring */
+int quit_prog; /* set when time to exit parser */
+char *tape_server_name = NULL;
+int tape_server_socket;
+char *tape_device_name = NULL;
+am_feature_t *our_features = NULL;
+am_feature_t *indexsrv_features = NULL;
+am_feature_t *tapesrv_features = NULL;
+
+/* gets a "line" from server and put in server_line */
+/* server_line is terminated with \0, \r\n is striped */
+/* returns -1 if error */
+
+int
+get_line(void)
+{
+ char *line = NULL;
+ char *part = NULL;
+ size_t len;
+
+ while(1) {
+ if((part = areads(server_socket)) == NULL) {
+ int save_errno = errno;
+
+ if(server_line) {
+ fputs(server_line, stderr); /* show the last line read */
+ fputc('\n', stderr);
+ }
+ if(save_errno != 0) {
+ fprintf(stderr, "%s: Error reading line from server: %s\n",
+ get_pname(),
+ strerror(save_errno));
+ } else {
+ fprintf(stderr, "%s: Unexpected end of file, check amindexd*debug on server %s\n",
+ get_pname(),
+ server_name);
+ }
+ errno = save_errno;
+ break; /* exit while loop */
+ }
+ if(line) {
+ strappend(line, part);
+ amfree(part);
+ } else {
+ line = part;
+ part = NULL;
+ }
+ if((len = strlen(line)) > 0 && line[len-1] == '\r') {
+ line[len-1] = '\0';
+ server_line = newstralloc(server_line, line);
+ amfree(line);
+ return 0;
+ }
+ /*
+ * Hmmm. We got a "line" from areads(), which means it saw
+ * a '\n' (or EOF, etc), but there was not a '\r' before it.
+ * Put a '\n' back in the buffer and loop for more.
+ */
+ strappend(line, "\n");
+ }
+ amfree(line);
+ amfree(server_line);
+ return -1;
+}
+
+
+/* get reply from server and print to screen */
+/* handle multi-line reply */
+/* return -1 if error */
+/* return code returned by server always occupies first 3 bytes of global
+ variable server_line */
+int
+grab_reply(
+ int show)
+{
+ do {
+ if (get_line() == -1) {
+ return -1;
+ }
+ if(show) puts(server_line);
+ } while (server_line[3] == '-');
+ if(show) fflush(stdout);
+
+ return 0;
+}
+
+
+/* get 1 line of reply */
+/* returns -1 if error, 0 if last (or only) line, 1 if more to follow */
+int
+get_reply_line(void)
+{
+ if (get_line() == -1)
+ return -1;
+ return server_line[3] == '-';
+}
+
+
+/* returns pointer to returned line */
+char *
+reply_line(void)
+{
+ return server_line;
+}
+
+
+
+/* returns 0 if server returned an error code (ie code starting with 5)
+ and non-zero otherwise */
+int
+server_happy(void)
+{
+ return server_line[0] != '5';
+}
+
+
+int
+send_command(
+ char * cmd)
+{
+ /*
+ * NOTE: this routine is called from sigint_handler, so we must be
+ * **very** careful about what we do since there is no way to know
+ * our state at the time the interrupt happened. For instance,
+ * do not use any stdio or malloc routines here.
+ */
+ struct iovec msg[2];
+ ssize_t bytes;
+
+ memset(msg, 0, sizeof(msg));
+ msg[0].iov_base = cmd;
+ msg[0].iov_len = strlen(msg[0].iov_base);
+ msg[1].iov_base = "\r\n";
+ msg[1].iov_len = strlen(msg[1].iov_base);
+ bytes = (ssize_t)(msg[0].iov_len + msg[1].iov_len);
+
+ if (writev(server_socket, msg, 2) < bytes) {
+ return -1;
+ }
+ return (0);
+}
+
+
+/* send a command to the server, get reply and print to screen */
+int
+converse(
+ char * cmd)
+{
+ if (send_command(cmd) == -1) return -1;
+ if (grab_reply(1) == -1) return -1;
+ return 0;
+}
+
+
+/* same as converse() but reply not echoed to stdout */
+int
+exchange(
+ char * cmd)
+{
+ if (send_command(cmd) == -1) return -1;
+ if (grab_reply(0) == -1) return -1;
+ return 0;
+}
+
+
+/* basic interrupt handler for when user presses ^C */
+/* Bale out, letting server know before doing so */
+void
+sigint_handler(
+ int signum)
+{
+ /*
+ * NOTE: we must be **very** careful about what we do here since there
+ * is no way to know our state at the time the interrupt happened.
+ * For instance, do not use any stdio routines here or in any called
+ * routines. Also, use _exit() instead of exit() to make sure stdio
+ * buffer flushing is not attempted.
+ */
+ (void)signum; /* Quiet unused parameter warning */
+
+ if (extract_restore_child_pid != -1)
+ (void)kill(extract_restore_child_pid, SIGKILL);
+ extract_restore_child_pid = -1;
+
+ (void)send_command("QUIT");
+ _exit(1);
+}
+
+
+void
+clean_pathname(
+ char * s)
+{
+ size_t length;
+ length = strlen(s);
+
+ /* remove "/" at end of path */
+ if(length>1 && s[length-1]=='/')
+ s[length-1]='\0';
+
+ /* change "/." to "/" */
+ if(strcmp(s,"/.")==0)
+ s[1]='\0';
+
+ /* remove "/." at end of path */
+ if(strcmp(&(s[length-2]),"/.")==0)
+ s[length-2]='\0';
+}
+
+
+/* try and guess the disk the user is currently on.
+ Return -1 if error, 0 if disk not local, 1 if disk local,
+ 2 if disk local but can't guess name */
+/* do this by looking for the longest mount point which matches the
+ current directory */
+int
+guess_disk (
+ char * cwd,
+ size_t cwd_len,
+ char ** dn_guess,
+ char ** mpt_guess)
+{
+ size_t longest_match = 0;
+ size_t current_length;
+ size_t cwd_length;
+ int local_disk = 0;
+ generic_fsent_t fsent;
+ char *fsname = NULL;
+ char *disk_try = NULL;
+
+ *dn_guess = NULL;
+ *mpt_guess = NULL;
+
+ if (getcwd(cwd, cwd_len) == NULL) {
+ return -1;
+ /*NOTREACHED*/
+ }
+ cwd_length = strlen(cwd);
+ dbprintf(("guess_disk: %d: \"%s\"\n", cwd_length, cwd));
+
+ if (open_fstab() == 0) {
+ return -1;
+ /*NOTREACHED*/
+ }
+
+ while (get_fstab_nextentry(&fsent))
+ {
+ current_length = fsent.mntdir ? strlen(fsent.mntdir) : (size_t)0;
+ dbprintf(("guess_disk: %d: %d: \"%s\": \"%s\"\n",
+ longest_match,
+ current_length,
+ fsent.mntdir ? fsent.mntdir : "(mntdir null)",
+ fsent.fsname ? fsent.fsname : "(fsname null)"));
+ if ((current_length > longest_match)
+ && (current_length <= cwd_length)
+ && (strncmp(fsent.mntdir, cwd, current_length) == 0))
+ {
+ longest_match = current_length;
+ *mpt_guess = newstralloc(*mpt_guess, fsent.mntdir);
+ if(strncmp(fsent.fsname,DEV_PREFIX,(strlen(DEV_PREFIX))))
+ {
+ fsname = newstralloc(fsname, fsent.fsname);
+ }
+ else
+ {
+ fsname = newstralloc(fsname,fsent.fsname+strlen(DEV_PREFIX));
+ }
+ local_disk = is_local_fstype(&fsent);
+ dbprintf(("guess_disk: local_disk = %d, fsname = \"%s\"\n",
+ local_disk,
+ fsname));
+ }
+ }
+ close_fstab();
+
+ if (longest_match == 0) {
+ amfree(*mpt_guess);
+ amfree(fsname);
+ return -1; /* ? at least / should match */
+ }
+
+ if (!local_disk) {
+ amfree(*mpt_guess);
+ amfree(fsname);
+ return 0;
+ }
+
+ /* have mount point now */
+ /* disk name may be specified by mount point (logical name) or
+ device name, have to determine */
+ printf("Trying disk %s ...\n", *mpt_guess);
+ disk_try = stralloc2("DISK ", *mpt_guess); /* try logical name */
+ if (exchange(disk_try) == -1)
+ exit(1);
+ amfree(disk_try);
+ if (server_happy())
+ {
+ *dn_guess = stralloc(*mpt_guess); /* logical is okay */
+ amfree(fsname);
+ return 1;
+ }
+ printf("Trying disk %s ...\n", fsname);
+ disk_try = stralloc2("DISK ", fsname); /* try device name */
+ if (exchange(disk_try) == -1)
+ exit(1);
+ amfree(disk_try);
+ if (server_happy())
+ {
+ *dn_guess = stralloc(fsname); /* dev name is okay */
+ amfree(fsname);
+ return 1;
+ }
+
+ /* neither is okay */
+ amfree(*mpt_guess);
+ amfree(fsname);
+ return 2;
+}
+
+
+void
+quit(void)
+{
+ quit_prog = 1;
+ (void)converse("QUIT");
+}
+
+char *localhost = NULL;
+
+#ifdef DEFAULT_TAPE_SERVER
+# define DEFAULT_TAPE_SERVER_FAILOVER (DEFAULT_TAPE_SERVER)
+#else
+# define DEFAULT_TAPE_SERVER_FAILOVER (NULL)
+#endif
+
+int
+main(
+ int argc,
+ char ** argv)
+{
+ in_port_t my_port;
+ struct servent *sp;
+ int i;
+ time_t timer;
+ char *lineread = NULL;
+ struct sigaction act, oact;
+ extern char *optarg;
+ extern int optind;
+ char cwd[STR_SIZE], *dn_guess = NULL, *mpt_guess = NULL;
+ char *service_name;
+ char *line = NULL;
+ struct tm *tm;
+
+ safe_fd(-1, 0);
+
+ set_pname("amoldrecover");
+
+ /* Don't die when child closes pipe */
+ signal(SIGPIPE, SIG_IGN);
+
+ dbopen(DBG_SUBDIR_CLIENT);
+
+#ifndef IGNORE_UID_CHECK
+ if (geteuid() != 0) {
+ erroutput_type |= ERR_SYSLOG;
+ error("amrecover must be run by root");
+ /*NOTREACHED*/
+ }
+#endif
+
+ localhost = alloc(MAX_HOSTNAME_LENGTH+1);
+ if (gethostname(localhost, MAX_HOSTNAME_LENGTH) != 0) {
+ error("cannot determine local host name\n");
+ /*NOTREACHED*/
+ }
+ localhost[MAX_HOSTNAME_LENGTH] = '\0';
+
+ config = newstralloc(config, DEFAULT_CONFIG);
+
+ dbrename(config, DBG_SUBDIR_CLIENT);
+
+ amfree(server_name);
+ server_name = getenv("AMANDA_SERVER");
+ if(!server_name) server_name = DEFAULT_SERVER;
+ server_name = stralloc(server_name);
+
+ amfree(tape_server_name);
+ tape_server_name = getenv("AMANDA_TAPESERVER");
+ if(!tape_server_name) tape_server_name = DEFAULT_TAPE_SERVER;
+ tape_server_name = stralloc(tape_server_name);
+
+ if (argc > 1 && argv[1][0] != '-')
+ {
+ /*
+ * If the first argument is not an option flag, then we assume
+ * it is a configuration name to match the syntax of the other
+ * Amanda utilities.
+ */
+ char **new_argv;
+
+ new_argv = (char **) alloc((size_t)((argc + 1 + 1) * sizeof(*new_argv)));
+ new_argv[0] = argv[0];
+ new_argv[1] = "-C";
+ for (i = 1; i < argc; i++)
+ {
+ new_argv[i + 1] = argv[i];
+ }
+ new_argv[i + 1] = NULL;
+ argc++;
+ argv = new_argv;
+ }
+ while ((i = getopt(argc, argv, "C:s:t:d:U")) != EOF)
+ {
+ switch (i)
+ {
+ case 'C':
+ config = newstralloc(config, optarg);
+ break;
+
+ case 's':
+ server_name = newstralloc(server_name, optarg);
+ break;
+
+ case 't':
+ tape_server_name = newstralloc(tape_server_name, optarg);
+ break;
+
+ case 'd':
+ tape_device_name = newstralloc(tape_device_name, optarg);
+ break;
+
+ case 'U':
+ case '?':
+ (void)printf(USAGE);
+ return 0;
+ }
+ }
+ if (optind != argc)
+ {
+ (void)fprintf(stderr, USAGE);
+ exit(1);
+ }
+
+ amfree(disk_name);
+ amfree(mount_point);
+ amfree(disk_path);
+ dump_date[0] = '\0';
+
+ /* Don't die when child closes pipe */
+ signal(SIGPIPE, SIG_IGN);
+
+ /* set up signal handler */
+ act.sa_handler = sigint_handler;
+ sigemptyset(&act.sa_mask);
+ act.sa_flags = 0;
+ if (sigaction(SIGINT, &act, &oact) != 0) {
+ error("error setting signal handler: %s", strerror(errno));
+ /*NOTREACHED*/
+ }
+
+ service_name = stralloc2("amandaidx", SERVICE_SUFFIX);
+
+ printf("AMRECOVER Version %s. Contacting server on %s ...\n",
+ version(), server_name);
+ if ((sp = getservbyname(service_name, "tcp")) == NULL) {
+ error("%s/tcp unknown protocol", service_name);
+ /*NOTREACHED*/
+ }
+ amfree(service_name);
+ server_socket = stream_client_privileged(server_name,
+ (in_port_t)ntohs((in_port_t)sp->s_port),
+ 0,
+ 0,
+ &my_port,
+ 0);
+ if (server_socket < 0) {
+ error("cannot connect to %s: %s", server_name, strerror(errno));
+ /*NOTREACHED*/
+ }
+ if (my_port >= IPPORT_RESERVED) {
+ aclose(server_socket);
+ error("did not get a reserved port: %d", my_port);
+ /*NOTREACHED*/
+ }
+
+#if 0
+ /*
+ * We may need root privilege again later for a reserved port to
+ * the tape server, so we will drop down now but might have to
+ * come back later.
+ */
+ setegid(getgid());
+ seteuid(getuid());
+#endif
+
+ /* get server's banner */
+ if (grab_reply(1) == -1) {
+ aclose(server_socket);
+ exit(1);
+ }
+ if (!server_happy())
+ {
+ dbclose();
+ aclose(server_socket);
+ exit(1);
+ }
+
+ /* do the security thing */
+ line = get_security();
+ if (converse(line) == -1) {
+ aclose(server_socket);
+ exit(1);
+ }
+ if (!server_happy()) {
+ aclose(server_socket);
+ exit(1);
+ }
+ memset(line, '\0', strlen(line));
+ amfree(line);
+
+ /* try to get the features from the server */
+ {
+ char *our_feature_string = NULL;
+ char *their_feature_string = NULL;
+
+ our_features = am_init_feature_set();
+ our_feature_string = am_feature_to_string(our_features);
+ line = stralloc2("FEATURES ", our_feature_string);
+ if(exchange(line) == 0) {
+ their_feature_string = stralloc(server_line+13);
+ indexsrv_features = am_string_to_feature(their_feature_string);
+ }
+ else {
+ indexsrv_features = am_set_default_feature_set();
+ }
+ amfree(our_feature_string);
+ amfree(their_feature_string);
+ amfree(line);
+ }
+
+ /* set the date of extraction to be today */
+ (void)time(&timer);
+ tm = localtime(&timer);
+ if (tm)
+ strftime(dump_date, sizeof(dump_date), "%Y-%m-%d", tm);
+ else
+ error("BAD DATE");
+
+ printf("Setting restore date to today (%s)\n", dump_date);
+ line = stralloc2("DATE ", dump_date);
+ if (converse(line) == -1) {
+ aclose(server_socket);
+ exit(1);
+ }
+ amfree(line);
+
+ line = stralloc2("SCNF ", config);
+ if (converse(line) == -1) {
+ aclose(server_socket);
+ exit(1);
+ }
+ amfree(line);
+
+ if (server_happy())
+ {
+ /* set host we are restoring to this host by default */
+ amfree(dump_hostname);
+ set_host(localhost);
+ if (dump_hostname)
+ {
+ /* get a starting disk and directory based on where
+ we currently are */
+ switch (guess_disk(cwd, sizeof(cwd), &dn_guess, &mpt_guess))
+ {
+ case 1:
+ /* okay, got a guess. Set disk accordingly */
+ printf("$CWD '%s' is on disk '%s' mounted at '%s'.\n",
+ cwd, dn_guess, mpt_guess);
+ set_disk(dn_guess, mpt_guess);
+ set_directory(cwd);
+ if (server_happy() && strcmp(cwd, mpt_guess) != 0)
+ printf("WARNING: not on root of selected filesystem, check man-page!\n");
+ amfree(dn_guess);
+ amfree(mpt_guess);
+ break;
+
+ case 0:
+ printf("$CWD '%s' is on a network mounted disk\n",
+ cwd);
+ printf("so you must 'sethost' to the server\n");
+ /* fake an unhappy server */
+ server_line[0] = '5';
+ break;
+
+ case 2:
+ case -1:
+ default:
+ printf("Use the setdisk command to choose dump disk to recover\n");
+ /* fake an unhappy server */
+ server_line[0] = '5';
+ break;
+ }
+ }
+ }
+
+ quit_prog = 0;
+ do
+ {
+ if ((lineread = readline("amrecover> ")) == NULL) {
+ clearerr(stdin);
+ putchar('\n');
+ break;
+ }
+ if (lineread[0] != '\0')
+ {
+ add_history(lineread);
+ process_line(lineread); /* act on line's content */
+ }
+ amfree(lineread);
+ } while (!quit_prog);
+
+ dbclose();
+
+ aclose(server_socket);
+ return 0;
+}
+
+char *
+get_security(void)
+{
+ struct passwd *pwptr;
+
+ if((pwptr = getpwuid(getuid())) == NULL) {
+ error("can't get login name for my uid %ld", (long)getuid());
+ /*NOTREACHED*/
+ }
+ return stralloc2("SECURITY USER ", pwptr->pw_name);
+}
--- /dev/null
+/*
+ * Amanda, The Advanced Maryland Automatic Network Disk Archiver
+ * Copyright (c) 1991-1998, 2000 University of Maryland at College Park
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of U.M. not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. U.M. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: the Amanda Development Team. Its members are listed in a
+ * file named AUTHORS, in the root directory of this distribution.
+ */
+/*
+ * $Id: amrecover.h,v 1.2 2006/05/25 01:47:13 johnfranks Exp $
+ *
+ * data structures and declarations for amrecover
+ */
+
+#include "amanda.h"
+#include "amfeatures.h"
+
+typedef struct DIR_ITEM
+{
+ char *date;
+ int level;
+ char *tape;
+ char *path;
+ off_t fileno;
+
+ struct DIR_ITEM *next;
+}
+DIR_ITEM;
+
+extern char *server_name;
+extern char *config;
+extern char *dump_datestamp; /* date we are restoring */
+extern char *dump_hostname; /* which machine we are restoring */
+extern char *disk_name; /* disk we are restoring */
+extern char *mount_point; /* where disk was mounted */
+extern char *disk_path; /* path relative to mount point */
+extern char dump_date[STR_SIZE]; /* date on which we are restoring */
+extern int quit_prog; /* set when time to exit parser */
+extern char *tape_server_name;
+extern char *tape_device_name;
+extern am_feature_t *our_features;
+extern am_feature_t *indexsrv_features;
+extern am_feature_t *tapesrv_features;
+extern pid_t extract_restore_child_pid;
+
+extern void free_dir_item(DIR_ITEM *item);
+
+extern int converse(char *cmd);
+extern int exchange(char *cmd);
+extern int server_happy(void);
+extern int send_command(char *cmd);
+extern int get_reply_line(void);
+extern char *reply_line(void);
+
+extern void quit(void);
+
+extern void help_list(void); /* list commands */
+
+extern void set_disk(char *dsk, char *mtpt);
+extern void list_disk(char *amdevice);
+extern void list_host(void);
+extern void set_host(const char *host);
+extern int set_date(char *date);
+extern void set_directory(char *dir);
+extern void cd_glob(char *dir);
+extern void cd_regex(char *dir);
+extern void cd_dir(char *dir, char *default_dir);
+extern void set_tape(char *tape);
+extern void show_directory(void);
+extern void set_mode(int mode);
+extern void show_mode(void);
+
+extern void list_disk_history(void);
+extern void list_directory(void);
+extern DIR_ITEM *get_dir_list(void);
+extern DIR_ITEM *get_next_dir_item(DIR_ITEM *this);
+extern void suck_dir_list_from_server(void);
+extern void clear_dir_list(void);
+extern void clean_pathname(char *s);
+extern void display_extract_list(char *file);
+extern void clear_extract_list(void);
+extern int is_extract_list_nonempty(void);
+extern void add_glob(char *glob);
+extern void add_regex(char *regex);
+extern void add_file(char *path, char *regex);
+extern void delete_glob(char *glob);
+extern void delete_regex(char *regex);
+extern void delete_file(char *path, char *regex);
+
+extern void extract_files(void);
+
+#ifdef SAMBA_CLIENT
+#define SAMBA_SMBCLIENT 0
+#define SAMBA_TAR 1
+#endif
+
+extern char *get_security(void);
--- /dev/null
+/*
+ * Amanda, The Advanced Maryland Automatic Network Disk Archiver
+ * Copyright (c) 1991-1998 University of Maryland at College Park
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of U.M. not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. U.M. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: the Amanda Development Team. Its members are listed in a
+ * file named AUTHORS, in the root directory of this distribution.
+ */
+/*
+ * $Id: display_commands.c,v 1.3 2006/07/05 19:42:17 martinea Exp $
+ *
+ * implements the directory-display related commands in amrecover
+ */
+
+#include "amanda.h"
+#include "amrecover.h"
+#include "util.h"
+
+DIR_ITEM *get_dir_list(void);
+DIR_ITEM *get_next_dir_item(DIR_ITEM *this);
+
+void clear_dir_list(void);
+void free_dir_item(DIR_ITEM *item);
+static int add_dir_list_item(char *date,
+ int level,
+ char *tape,
+ off_t fileno,
+ char *path);
+void list_disk_history(void);
+void suck_dir_list_from_server(void);
+void list_directory(void);
+
+static DIR_ITEM *dir_list = NULL;
+
+DIR_ITEM *
+get_dir_list(void)
+{
+ return dir_list;
+}
+
+DIR_ITEM *
+get_next_dir_item(
+ /*@keep@*/ DIR_ITEM * this)
+{
+ return this->next;
+}
+
+
+void
+clear_dir_list(void)
+{
+ free_dir_item(dir_list); /* Frees all items from dir_list to end of list */
+ dir_list = NULL;
+}
+
+void
+free_dir_item(
+ DIR_ITEM * item)
+{
+ DIR_ITEM *next;
+
+ while (item != NULL) {
+ next = item->next;
+ amfree(item->date);
+ amfree(item->tape);
+ amfree(item->path);
+ amfree(item);
+ item = next;
+ }
+}
+
+/* add item to list if path not already on list */
+static int
+add_dir_list_item(
+ char * date,
+ int level,
+ char * tape,
+ off_t fileno,
+ char * path)
+{
+ DIR_ITEM *next;
+
+ dbprintf(("add_dir_list_item: Adding \"%s\" \"%d\" \"%s\" \""
+ OFF_T_FMT "\" \"%s\"\n",
+ date, level, tape, (OFF_T_FMT_TYPE)fileno, path));
+
+ next = (DIR_ITEM *)alloc(sizeof(DIR_ITEM));
+ memset(next, 0, sizeof(DIR_ITEM));
+
+ next->date = stralloc(date);
+ next->level = level;
+ next->tape = stralloc(tape);
+ next->fileno = fileno;
+ next->path = stralloc(path);
+
+ next->next = dir_list;
+ dir_list = next;
+
+ return 0;
+}
+
+
+void
+list_disk_history(void)
+{
+ if (converse("DHST") == -1)
+ exit(1);
+}
+
+
+void
+suck_dir_list_from_server(void)
+{
+ char *cmd = NULL;
+ char *err = NULL;
+ int i;
+ char *l = NULL;
+ char *date;
+ int level = 0;
+ off_t fileno = (off_t)-1;
+ char *tape, *tape_undo, tape_undo_ch = '\0';
+ char *dir, *qdir;
+ char *disk_path_slash = NULL;
+ char *disk_path_slash_dot = NULL;
+ char *s;
+ int ch;
+
+ if (disk_path == NULL) {
+ printf("Directory must be set before getting listing\n");
+ return;
+ } else if(strcmp(disk_path, "/") == 0) {
+ disk_path_slash = stralloc(disk_path);
+ } else {
+ disk_path_slash = stralloc2(disk_path, "/");
+ }
+
+ clear_dir_list();
+
+ cmd = stralloc2("OLSD ", disk_path);
+ if (send_command(cmd) == -1) {
+ amfree(cmd);
+ amfree(disk_path_slash);
+ exit(1);
+ }
+ amfree(cmd);
+ /* skip preamble */
+ if ((i = get_reply_line()) == -1) {
+ amfree(disk_path_slash);
+ exit(1);
+ }
+ if (i == 0) /* assume something wrong! */
+ {
+ amfree(disk_path_slash);
+ l = reply_line();
+ printf("%s\n", l);
+ return;
+ }
+ disk_path_slash_dot = stralloc2(disk_path_slash, ".");
+ amfree(cmd);
+ amfree(err);
+ tape_undo = NULL;
+ /* skip the last line -- duplicate of the preamble */
+ while ((i = get_reply_line()) != 0)
+ {
+ if (i == -1) {
+ amfree(disk_path_slash_dot);
+ amfree(disk_path_slash);
+ exit(1);
+ }
+ if(err) {
+ if(cmd == NULL) {
+ if(tape_undo) *tape_undo = tape_undo_ch;
+ tape_undo = NULL;
+ cmd = stralloc(l); /* save for the error report */
+ }
+ continue; /* throw the rest of the lines away */
+ }
+ l = reply_line();
+ if (!server_happy())
+ {
+ printf("%s\n", l);
+ continue;
+ }
+#define sc "201-"
+ if (strncmp(l, sc, sizeof(sc)-1) != 0) {
+ err = "bad reply: not 201-";
+ continue;
+ }
+ s = l + sizeof(sc)-1;
+ ch = *s++;
+#undef sc
+ skip_whitespace(s, ch);
+ if(ch == '\0') {
+ err = "bad reply: missing date field";
+ continue;
+ }
+ date = s - 1;
+ skip_non_whitespace(s, ch);
+ *(s - 1) = '\0';
+
+ skip_whitespace(s, ch);
+ if(ch == '\0' || sscanf(s - 1, "%d", &level) != 1) {
+ err = "bad reply: cannot parse level field";
+ continue;
+ }
+ skip_integer(s, ch);
+
+ skip_whitespace(s, ch);
+ if(ch == '\0') {
+ err = "bad reply: missing tape field";
+ continue;
+ }
+ tape = s - 1;
+ skip_non_whitespace(s, ch);
+ tape_undo = s - 1;
+ tape_undo_ch = *tape_undo;
+ *tape_undo = '\0';
+
+ if(am_has_feature(indexsrv_features, fe_amindexd_fileno_in_OLSD)) {
+ skip_whitespace(s, ch);
+ if(ch == '\0' || sscanf(s - 1, OFF_T_FMT,
+ (OFF_T_FMT_TYPE *)&fileno) != 1) {
+ err = "bad reply: cannot parse fileno field";
+ continue;
+ }
+ skip_integer(s, ch);
+ }
+ else {
+ fileno = (off_t)-1;
+ }
+
+ skip_whitespace(s, ch);
+ if(ch == '\0') {
+ err = "bad reply: missing directory field";
+ continue;
+ }
+ qdir = s - 1;
+ dir = unquote_string(qdir);
+
+ /* add a '.' if it a the entry for the current directory */
+ if((strcmp(disk_path,dir)==0) || (strcmp(disk_path_slash,dir)==0)) {
+ amfree(dir);
+ dir = stralloc(disk_path_slash_dot);
+ }
+ add_dir_list_item(date, level, tape, fileno, dir);
+ amfree(dir);
+ }
+ amfree(disk_path_slash_dot);
+ amfree(disk_path_slash);
+ if(!server_happy()) {
+ puts(reply_line());
+ } else if(err) {
+ if(*err) {
+ puts(err);
+ }
+ if (cmd)
+ puts(cmd);
+ clear_dir_list();
+ }
+ amfree(cmd);
+}
+
+
+void
+list_directory(void)
+{
+ size_t i;
+ DIR_ITEM *item;
+ FILE *fp;
+ char *pager;
+ char *pager_command;
+ char *quoted;
+
+ if (disk_path == NULL) {
+ printf("Must select a disk before listing files; use the setdisk command.\n");
+ return;
+ }
+
+ if ((pager = getenv("PAGER")) == NULL)
+ {
+ pager = "more";
+ }
+ /*
+ * Set up the pager command so if the pager is terminated, we do
+ * not get a SIGPIPE back.
+ */
+ pager_command = stralloc2(pager, " ; /bin/cat > /dev/null");
+ if ((fp = popen(pager_command, "w")) == NULL)
+ {
+ printf("Warning - can't pipe through %s\n", pager);
+ fp = stdout;
+ }
+ amfree(pager_command);
+ i = strlen(disk_path);
+ if (i != 1)
+ i++; /* so disk_path != "/" */
+ for (item = get_dir_list(); item != NULL; item=get_next_dir_item(item)) {
+ quoted = quote_string(item->path + i);
+ fprintf(fp, "%s %s\n", item->date, quoted);
+ amfree(quoted);
+ }
+ apclose(fp);
+}
--- /dev/null
+/*
+ * Amanda, The Advanced Maryland Automatic Network Disk Archiver
+ * Copyright (c) 1991-1998, 2000 University of Maryland at College Park
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of U.M. not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. U.M. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: the Amanda Development Team. Its members are listed in a
+ * file named AUTHORS, in the root directory of this distribution.
+ */
+/*
+ * $Id: extract_list.c,v 1.6 2006/08/24 01:57:15 paddy_s Exp $
+ *
+ * implements the "extract" command in amrecover
+ */
+
+#include "amanda.h"
+#include "version.h"
+#include "amrecover.h"
+#include "fileheader.h"
+#include "dgram.h"
+#include "stream.h"
+#include "tapelist.h"
+#ifdef SAMBA_CLIENT
+#include "findpass.h"
+#endif
+#include "util.h"
+
+typedef struct EXTRACT_LIST_ITEM {
+ char *path;
+
+ struct EXTRACT_LIST_ITEM *next;
+}
+EXTRACT_LIST_ITEM;
+
+typedef struct EXTRACT_LIST {
+ char *date; /* date tape created */
+ int level; /* level of dump */
+ char *tape; /* tape label */
+ off_t fileno; /* fileno on tape */
+ EXTRACT_LIST_ITEM *files; /* files to get off tape */
+
+ struct EXTRACT_LIST *next;
+}
+EXTRACT_LIST;
+
+#define SKIP_TAPE 2
+#define RETRY_TAPE 3
+
+char *dump_device_name = NULL;
+
+extern char *localhost;
+
+/* global pid storage for interrupt handler */
+pid_t extract_restore_child_pid = -1;
+
+static EXTRACT_LIST *extract_list = NULL;
+static int tape_control_sock = -1;
+static int tape_data_sock = -1;
+
+#ifdef SAMBA_CLIENT
+unsigned short samba_extract_method = SAMBA_TAR;
+#endif /* SAMBA_CLIENT */
+
+#define READ_TIMEOUT 240*60
+
+EXTRACT_LIST *first_tape_list(void);
+EXTRACT_LIST *next_tape_list(EXTRACT_LIST *list);
+int is_extract_list_nonempty(void);
+int length_of_tape_list(EXTRACT_LIST *tape_list);
+void add_file(char *path, char *regex);
+void add_glob(char *glob);
+void add_regex(char *regex);
+void clear_extract_list(void);
+void clean_tape_list(EXTRACT_LIST *tape_list);
+void clean_extract_list(void);
+void delete_file(char *path, char *regex);
+void delete_glob(char *glob);
+void delete_regex(char *regex);
+void delete_tape_list(EXTRACT_LIST *tape_list);
+void display_extract_list(char *file);
+void extract_files(void);
+void read_file_header(char *buffer,
+ dumpfile_t *file,
+ size_t buflen,
+ int tapedev);
+void writer_intermediary(int ctl_fd, int data_fd, EXTRACT_LIST *elist);
+void writer_intermediary(int ctl_fd, int data_fd, EXTRACT_LIST *elist);
+
+static int add_extract_item(DIR_ITEM *ditem);
+static int delete_extract_item(DIR_ITEM *ditem);
+static int extract_files_setup(char *label, off_t fsf);
+static int okay_to_continue(int allow_tape,
+ int allow_skip,
+ int allow_retry);
+static int okay_to_continue(int, int, int);
+static ssize_t read_buffer(int datafd,
+ char *buffer,
+ size_t buflen,
+ long timeout_s);
+static void clear_tape_list(EXTRACT_LIST *tape_list);
+static void extract_files_child(int in_fd, EXTRACT_LIST *elist);
+static void send_to_tape_server(int tss, char *cmd);
+
+
+/*
+ * Function: ssize_t read_buffer(datafd, buffer, buflen, timeout_s)
+ *
+ * Description:
+ * read data from input file desciptor waiting up to timeout_s
+ * seconds before returning data.
+ *
+ * Inputs:
+ * datafd - File descriptor to read from.
+ * buffer - Buffer to read into.
+ * buflen - Maximum number of bytes to read into buffer.
+ * timeout_s - Seconds to wait before returning what was already read.
+ *
+ * Returns:
+ * >0 - Number of data bytes in buffer.
+ * 0 - EOF
+ * -1 - errno == ETIMEDOUT if no data available in specified time.
+ * errno == ENFILE if datafd is invalid.
+ * otherwise errno is set by select or read..
+ */
+
+static ssize_t
+read_buffer(
+ int datafd,
+ char * buffer,
+ size_t buflen,
+ long timeout_s)
+{
+ ssize_t size = 0;
+ fd_set readset;
+ struct timeval timeout;
+ char *dataptr;
+ ssize_t spaceleft;
+ int nfound;
+
+ if(datafd < 0 || datafd >= (int)FD_SETSIZE) {
+ errno = EMFILE; /* out of range */
+ return -1;
+ }
+
+ dataptr = buffer;
+ spaceleft = (ssize_t)buflen;
+
+ do {
+ FD_ZERO(&readset);
+ FD_SET(datafd, &readset);
+ timeout.tv_sec = timeout_s;
+ timeout.tv_usec = 0;
+ nfound = select(datafd+1, &readset, NULL, NULL, &timeout);
+ if(nfound < 0 ) {
+ /* Select returned an error. */
+ fprintf(stderr,"select error: %s\n", strerror(errno));
+ size = -1;
+ break;
+ }
+
+ if (nfound == 0) {
+ /* Select timed out. */
+ if (timeout_s != 0) {
+ /* Not polling: a real read timeout */
+ fprintf(stderr,"timeout waiting for restore\n");
+ fprintf(stderr,"increase READ_TIMEOUT in recover-src/extract_list.c if your tape is slow\n");
+ }
+ errno = ETIMEDOUT;
+ size = -1;
+ break;
+ }
+
+ if(!FD_ISSET(datafd, &readset))
+ continue;
+
+ /* Select says data is available, so read it. */
+ size = read(datafd, dataptr, (size_t)spaceleft);
+ if (size < 0) {
+ if ((errno == EINTR) || (errno == EAGAIN)) {
+ continue;
+ }
+ if (errno != EPIPE) {
+ fprintf(stderr, "read_buffer: read error - %s",
+ strerror(errno));
+ break;
+ }
+ size = 0;
+ }
+ spaceleft -= size;
+ dataptr += size;
+ } while ((size > 0) && (spaceleft > 0));
+
+ return ((((ssize_t)buflen-spaceleft) > 0) ? ((ssize_t)buflen-spaceleft) : size);
+}
+
+
+EXTRACT_LIST *
+first_tape_list(void)
+{
+ return extract_list;
+}
+
+EXTRACT_LIST *
+next_tape_list(
+ /*@keep@*/ EXTRACT_LIST *list)
+{
+ if (list == NULL)
+ return NULL;
+ return list->next;
+}
+
+static void
+clear_tape_list(
+ EXTRACT_LIST * tape_list)
+{
+ EXTRACT_LIST_ITEM *this, *next;
+
+
+ this = tape_list->files;
+ while (this != NULL)
+ {
+ next = this->next;
+ amfree(this->path);
+ amfree(this);
+ this = next;
+ }
+ tape_list->files = NULL;
+}
+
+
+/* remove a tape list from the extract list, clearing the tape list
+ beforehand if necessary */
+void
+delete_tape_list(
+ EXTRACT_LIST * tape_list)
+{
+ EXTRACT_LIST *this, *prev;
+
+ if (tape_list == NULL)
+ return;
+
+ /* is it first on the list? */
+ if (tape_list == extract_list)
+ {
+ extract_list = tape_list->next;
+ clear_tape_list(tape_list);
+ amfree(tape_list->date);
+ amfree(tape_list->tape);
+ amfree(tape_list);
+ return;
+ }
+
+ /* so not first on list - find it and delete */
+ prev = extract_list;
+ this = extract_list->next;
+ while (this != NULL)
+ {
+ if (this == tape_list)
+ {
+ prev->next = tape_list->next;
+ clear_tape_list(tape_list);
+ amfree(tape_list->date);
+ amfree(tape_list->tape);
+ amfree(tape_list);
+ return;
+ }
+ prev = this;
+ this = this->next;
+ }
+ /*NOTREACHED*/
+}
+
+
+/* return the number of files on a tape's list */
+int
+length_of_tape_list(
+ EXTRACT_LIST * tape_list)
+{
+ EXTRACT_LIST_ITEM *fn;
+ int n;
+
+ n = 0;
+ for (fn = tape_list->files; fn != NULL; fn = fn->next)
+ n++;
+
+ return n;
+}
+
+
+void
+clear_extract_list(void)
+{
+ while (extract_list != NULL)
+ delete_tape_list(extract_list);
+}
+
+
+void
+clean_tape_list(
+ EXTRACT_LIST *tape_list)
+{
+ EXTRACT_LIST_ITEM *fn1, *pfn1, *ofn1;
+ EXTRACT_LIST_ITEM *fn2, *pfn2, *ofn2;
+ int remove_fn1;
+ int remove_fn2;
+
+ pfn1 = NULL;
+ fn1 = tape_list->files;
+ while (fn1 != NULL) {
+ remove_fn1 = 0;
+
+ pfn2 = fn1;
+ fn2 = fn1->next;
+ while (fn2 != NULL && remove_fn1 == 0) {
+ remove_fn2 = 0;
+ if(strcmp(fn1->path, fn2->path) == 0) {
+ remove_fn2 = 1;
+ } else if (strncmp(fn1->path, fn2->path, strlen(fn1->path)) == 0 &&
+ ((strlen(fn2->path) > strlen(fn1->path) &&
+ fn2->path[strlen(fn1->path)] == '/') ||
+ (fn1->path[strlen(fn1->path)-1] == '/'))) {
+ remove_fn2 = 1;
+ } else if (strncmp(fn2->path, fn1->path, strlen(fn2->path)) == 0 &&
+ ((strlen(fn1->path) > strlen(fn2->path) &&
+ fn1->path[strlen(fn2->path)] == '/') ||
+ (fn2->path[strlen(fn2->path)-1] == '/'))) {
+ remove_fn1 = 1;
+ break;
+ }
+
+ if (remove_fn2) {
+ dbprintf(("removing path %s, it is included in %s\n",
+ fn2->path, fn1->path));
+ ofn2 = fn2;
+ fn2 = fn2->next;
+ amfree(ofn2->path);
+ amfree(ofn2);
+ pfn2->next = fn2;
+ } else if (remove_fn1 == 0) {
+ pfn2 = fn2;
+ fn2 = fn2->next;
+ }
+ }
+
+ if(remove_fn1 != 0) {
+ /* fn2->path is always valid */
+ /*@i@*/ dbprintf(("removing path %s, it is included in %s\n",
+ /*@i@*/ fn1->path, fn2->path));
+ ofn1 = fn1;
+ fn1 = fn1->next;
+ amfree(ofn1->path);
+ if(pfn1 == NULL) {
+ amfree(tape_list->files);
+ tape_list->files = fn1;
+ } else {
+ amfree(pfn1->next);
+ pfn1->next = fn1;
+ }
+ } else {
+ pfn1 = fn1;
+ fn1 = fn1->next;
+ }
+ }
+}
+
+
+void
+clean_extract_list(void)
+{
+ EXTRACT_LIST *this;
+
+ for (this = extract_list; this != NULL; this = this->next)
+ clean_tape_list(this);
+}
+
+
+/* returns -1 if error */
+/* returns 0 on succes */
+/* returns 1 if already added */
+static int
+add_extract_item(
+ DIR_ITEM * ditem)
+{
+ EXTRACT_LIST *this, *this1;
+ EXTRACT_LIST_ITEM *that, *curr;
+ char *ditem_path = NULL;
+
+ ditem_path = stralloc(ditem->path);
+ clean_pathname(ditem_path);
+
+ for (this = extract_list; this != NULL; this = this->next)
+ {
+ /* see if this is the list for the tape */
+ if (this->level == ditem->level && strcmp(this->tape, ditem->tape) == 0)
+ {
+ /* yes, so add to list */
+ curr=this->files;
+ while(curr!=NULL)
+ {
+ if (strcmp(curr->path, ditem_path) == 0) {
+ amfree(ditem_path);
+ return 1;
+ }
+ curr=curr->next;
+ }
+ that = (EXTRACT_LIST_ITEM *)alloc(sizeof(EXTRACT_LIST_ITEM));
+ that->path = stralloc(ditem_path);
+ that->next = this->files;
+ this->files = that; /* add at front since easiest */
+ amfree(ditem_path);
+ return 0;
+ }
+ }
+
+ /* so this is the first time we have seen this tape */
+ this = (EXTRACT_LIST *)alloc(sizeof(EXTRACT_LIST));
+ this->tape = stralloc(ditem->tape);
+ this->level = ditem->level;
+ this->fileno = ditem->fileno;
+ this->date = stralloc(ditem->date);
+ that = (EXTRACT_LIST_ITEM *)alloc(sizeof(EXTRACT_LIST_ITEM));
+ that->path = stralloc(ditem_path);
+ that->next = NULL;
+ this->files = that;
+
+ /* add this in date increasing order */
+ /* because restore must be done in this order */
+ /* add at begining */
+ if(extract_list==NULL || strcmp(this->date,extract_list->date) < 0)
+ {
+ this->next = extract_list;
+ extract_list = this;
+ amfree(ditem_path);
+ return 0;
+ }
+ for (this1 = extract_list; this1->next != NULL; this1 = this1->next)
+ {
+ /* add in the middle */
+ if(strcmp(this->date,this1->next->date) < 0)
+ {
+ this->next = this1->next;
+ this1->next = this;
+ amfree(ditem_path);
+ return 0;
+ }
+ }
+ /* add at end */
+ this->next = NULL;
+ this1->next = this;
+ amfree(ditem_path);
+ return 0;
+}
+
+
+/* returns -1 if error */
+/* returns 0 on deletion */
+/* returns 1 if not there */
+static int
+delete_extract_item(
+ DIR_ITEM * ditem)
+{
+ EXTRACT_LIST *this;
+ EXTRACT_LIST_ITEM *that, *prev;
+ char *ditem_path = NULL;
+
+ ditem_path = stralloc(ditem->path);
+ clean_pathname(ditem_path);
+
+ for (this = extract_list; this != NULL; this = this->next)
+ {
+ /* see if this is the list for the tape */
+ if (this->level == ditem->level && strcmp(this->tape, ditem->tape) == 0)
+ {
+ /* yes, so find file on list */
+ that = this->files;
+ if (strcmp(that->path, ditem_path) == 0)
+ {
+ /* first on list */
+ this->files = that->next;
+ amfree(that->path);
+ amfree(that);
+ /* if list empty delete it */
+ if (this->files == NULL)
+ delete_tape_list(this);
+ amfree(ditem_path);
+ return 0;
+ }
+ prev = that;
+ that = that->next;
+ while (that != NULL)
+ {
+ if (strcmp(that->path, ditem_path) == 0)
+ {
+ prev->next = that->next;
+ amfree(that->path);
+ amfree(that);
+ amfree(ditem_path);
+ return 0;
+ }
+ prev = that;
+ that = that->next;
+ }
+ amfree(ditem_path);
+ return 1;
+ }
+ }
+
+ amfree(ditem_path);
+ return 1;
+}
+
+void
+add_glob(
+ char * glob)
+{
+ char *regex;
+ char *regex_path;
+ char *s;
+ char *uqglob = unquote_string(glob);
+
+ regex = glob_to_regex(uqglob);
+ dbprintf(("add_glob (%s) -> %s\n", uqglob, regex));
+ if ((s = validate_regexp(regex)) != NULL) {
+ printf("%s is not a valid shell wildcard pattern: ", glob);
+ puts(s);
+ } else {
+ /*
+ * glob_to_regex() anchors the beginning of the pattern with ^,
+ * but we will be tacking it onto the end of the current directory
+ * in add_file, so strip that off. Also, it anchors the end with
+ * $, but we need to match an optional trailing /, so tack that on
+ * the end.
+ */
+ regex_path = stralloc(regex + 1);
+ regex_path[strlen(regex_path) - 1] = '\0';
+ strappend(regex_path, "[/]*$");
+ add_file(uqglob, regex_path);
+ amfree(regex_path);
+ }
+ amfree(regex);
+ amfree(uqglob);
+}
+
+void
+add_regex(
+ char * regex)
+{
+ char *s;
+ char *uqregex = unquote_string(regex);
+
+ if ((s = validate_regexp(uqregex)) != NULL) {
+ printf("%s is not a valid regular expression: ", regex);
+ puts(s);
+ } else {
+ add_file(uqregex, regex);
+ }
+ amfree(uqregex);
+}
+
+void add_file(
+ char * path,
+ char * regex)
+{
+ DIR_ITEM *ditem, lditem;
+ char *path_on_disk = NULL;
+ char *path_on_disk_slash = NULL;
+ char *cmd = NULL;
+ char *err = NULL;
+ int i;
+ ssize_t j;
+ char *dir, *dir_undo, dir_undo_ch = '\0';
+ char *ditem_path = NULL;
+ char *l = NULL;
+ int added;
+ char *s, *fp, *quoted;
+ int ch;
+ int found_one;
+ int dir_entries;
+
+ if (disk_path == NULL) {
+ printf("Must select directory before adding files\n");
+ return;
+ }
+ memset(&lditem, 0, sizeof(lditem)); /* Prevent use of bogus data... */
+
+ dbprintf(("add_file: Looking for \"%s\"\n", regex));
+
+ if(strcmp(regex, "/[/]*$") == 0) { /* "/" behave like "." */
+ regex = "\\.[/]*$";
+ }
+ else if(strcmp(regex, "[^/]*[/]*$") == 0) { /* "*" */
+ //regex =
+ regex = "([^/.]|\\.[^/]+|[^/.][^/]*)[/]*$";
+ } else {
+ /* remove "/" at end of path */
+ j = (ssize_t)(strlen(regex) - 1);
+ while(j >= 0 && regex[j] == '/')
+ regex[j--] = '\0';
+ }
+
+ /* convert path (assumed in cwd) to one on disk */
+ if (strcmp(disk_path, "/") == 0) {
+ if (*regex == '/') {
+ /* No mods needed if already starts with '/' */
+ path_on_disk = stralloc(regex);
+ } else {
+ /* Prepend '/' */
+ path_on_disk = stralloc2("/", regex);
+ }
+ } else {
+ char *clean_disk_path = clean_regex(disk_path);
+ path_on_disk = vstralloc(clean_disk_path, "/", regex, NULL);
+ amfree(clean_disk_path);
+ }
+
+ path_on_disk_slash = stralloc2(path_on_disk, "/");
+
+ dbprintf(("add_file: Converted path=\"%s\" to path_on_disk=\"%s\"\n",
+ regex, path_on_disk));
+
+ found_one = 0;
+ dir_entries = 0;
+ for (ditem=get_dir_list(); ditem!=NULL; ditem=get_next_dir_item(ditem))
+ {
+ dir_entries++;
+ quoted = quote_string(ditem->path);
+ dbprintf(("add_file: Pondering ditem->path=%s\n", quoted));
+ amfree(quoted);
+ if (match(path_on_disk, ditem->path)
+ || match(path_on_disk_slash, ditem->path))
+ {
+ found_one = 1;
+ j = (ssize_t)strlen(ditem->path);
+ if((j > 0 && ditem->path[j-1] == '/')
+ || (j > 1 && ditem->path[j-2] == '/' && ditem->path[j-1] == '.'))
+ { /* It is a directory */
+ ditem_path = newstralloc(ditem_path, ditem->path);
+ clean_pathname(ditem_path);
+
+ cmd = stralloc2("ORLD ", ditem_path);
+ if(send_command(cmd) == -1) {
+ amfree(cmd);
+ amfree(ditem_path);
+ amfree(path_on_disk);
+ amfree(path_on_disk_slash);
+ exit(1);
+ }
+ amfree(cmd);
+ cmd = NULL;
+ /* skip preamble */
+ if ((i = get_reply_line()) == -1) {
+ amfree(ditem_path);
+ amfree(path_on_disk);
+ amfree(path_on_disk_slash);
+ exit(1);
+ }
+ if(i==0) { /* assume something wrong */
+ amfree(ditem_path);
+ amfree(path_on_disk);
+ amfree(path_on_disk_slash);
+ l = reply_line();
+ printf("%s\n", l);
+ return;
+ }
+ dir_undo = NULL;
+ added=0;
+ lditem.path = newstralloc(lditem.path, ditem->path);
+ /* skip the last line -- duplicate of the preamble */
+
+ while ((i = get_reply_line()) != 0) {
+ if (i == -1) {
+ amfree(ditem_path);
+ amfree(path_on_disk);
+ amfree(path_on_disk_slash);
+ exit(1);
+ }
+ if(err) {
+ if(cmd == NULL) {
+ if(dir_undo) *dir_undo = dir_undo_ch;
+ dir_undo = NULL;
+ cmd = stralloc(l); /* save for error report */
+ }
+ continue; /* throw the rest of the lines away */
+ }
+ l=reply_line();
+ if (!server_happy()) {
+ puts(l);
+ continue;
+ }
+#define sc "201-"
+ if(strncmp(l, sc, sizeof(sc)-1) != 0) {
+ err = "bad reply: not 201-";
+ continue;
+ }
+
+ s = l + sizeof(sc)-1;
+ ch = *s++;
+#undef sc
+ skip_whitespace(s, ch);
+ if(ch == '\0') {
+ err = "bad reply: missing date field";
+ continue;
+ }
+ fp = s-1;
+ skip_non_whitespace(s, ch);
+ s[-1] = '\0';
+ lditem.date = newstralloc(lditem.date, fp);
+ s[-1] = (char)ch;
+
+ skip_whitespace(s, ch);
+ if(ch == '\0' || sscanf(s - 1, "%d", &lditem.level) != 1) {
+ err = "bad reply: cannot parse level field";
+ continue;
+ }
+ skip_integer(s, ch);
+
+ skip_whitespace(s, ch);
+ if(ch == '\0') {
+ err = "bad reply: missing tape field";
+ continue;
+ }
+ fp = s-1;
+ skip_non_whitespace(s, ch);
+ s[-1] = '\0';
+ lditem.tape = newstralloc(lditem.tape, fp);
+ s[-1] = (char)ch;
+
+ if(am_has_feature(indexsrv_features, fe_amindexd_fileno_in_ORLD)) {
+ skip_whitespace(s, ch);
+ if(ch == '\0' || sscanf(s - 1, OFF_T_FMT,
+ (OFF_T_FMT_TYPE *)&lditem.fileno) != 1) {
+ err = "bad reply: cannot parse fileno field";
+ continue;
+ }
+ skip_integer(s, ch);
+ }
+
+ skip_whitespace(s, ch);
+ if(ch == '\0') {
+ err = "bad reply: missing directory field";
+ continue;
+ }
+ dir = s - 1;
+ skip_quoted_string(s, ch);
+ dir_undo = s - 1;
+ dir_undo_ch = *dir_undo;
+ *dir_undo = '\0';
+
+ switch(add_extract_item(&lditem)) {
+ case -1:
+ printf("System error\n");
+ dbprintf(("add_file: (Failed) System error\n"));
+ break;
+
+ case 0:
+ quoted = quote_string(lditem.path);
+ printf("Added dir %s at date %s\n",
+ quoted, lditem.date);
+ dbprintf(("add_file: (Successful) Added dir %s at date %s\n",
+ quoted, lditem.date));
+ amfree(quoted);
+ added=1;
+ break;
+
+ case 1:
+ break;
+ }
+ }
+ if(!server_happy()) {
+ puts(reply_line());
+ } else if(err) {
+ if (*err)
+ puts(err);
+ if (cmd)
+ puts(cmd);
+ } else if(added == 0) {
+ quoted = quote_string(ditem_path);
+ printf("dir %s already added\n", quoted);
+ dbprintf(("add_file: dir %s already added\n", quoted));
+ amfree(quoted);
+ }
+ }
+ else /* It is a file */
+ {
+ switch(add_extract_item(ditem)) {
+ case -1:
+ printf("System error\n");
+ dbprintf(("add_file: (Failed) System error\n"));
+ break;
+
+ case 0:
+ quoted = quote_string(ditem->path);
+ printf("Added file %s\n", quoted);
+ dbprintf(("add_file: (Successful) Added %s\n", quoted));
+ amfree(quoted);
+ break;
+
+ case 1:
+ quoted = quote_string(ditem->path);
+ printf("File %s already added\n", quoted);
+ dbprintf(("add_file: file %s already added\n", quoted));
+ amfree(quoted);
+ break;
+ }
+ }
+ }
+ }
+ if (cmd != NULL)
+ amfree(cmd);
+ amfree(ditem_path);
+ amfree(path_on_disk);
+ amfree(path_on_disk_slash);
+
+ if(! found_one) {
+ quoted = quote_string(path);
+ printf("File %s doesn't exist in directory\n", quoted);
+ dbprintf(("add_file: (Failed) File %s doesn't exist in directory\n",
+ quoted));
+ amfree(quoted);
+ }
+}
+
+
+void
+delete_glob(
+ char * glob)
+{
+ char *regex;
+ char *regex_path;
+ char *s;
+ char *uqglob = unquote_string(glob);
+
+ regex = glob_to_regex(uqglob);
+ dbprintf(("delete_glob (%s) -> %s\n", uqglob, regex));
+ if ((s = validate_regexp(regex)) != NULL) {
+ printf("\"%s\" is not a valid shell wildcard pattern: ", glob);
+ puts(s);
+ } else {
+ /*
+ * glob_to_regex() anchors the beginning of the pattern with ^,
+ * but we will be tacking it onto the end of the current directory
+ * in add_file, so strip that off. Also, it anchors the end with
+ * $, but we need to match an optional trailing /, so tack that on
+ * the end.
+ */
+ regex_path = stralloc(regex + 1);
+ regex_path[strlen(regex_path) - 1] = '\0';
+ strappend(regex_path, "[/]*$");
+ delete_file(uqglob, regex_path);
+ amfree(regex_path);
+ }
+ amfree(regex);
+ amfree(uqglob);
+}
+
+void
+delete_regex(
+ char * regex)
+{
+ char *s;
+ char *uqregex = unquote_string(regex);
+
+ if ((s = validate_regexp(regex)) != NULL) {
+ printf("\"%s\" is not a valid regular expression: ", regex);
+ puts(s);
+ } else {
+ delete_file(uqregex, uqregex);
+ }
+ amfree(uqregex);
+}
+
+void
+delete_file(
+ char * path,
+ char * regex)
+{
+ DIR_ITEM *ditem, lditem;
+ char *path_on_disk = NULL;
+ char *path_on_disk_slash = NULL;
+ char *cmd = NULL;
+ char *err = NULL;
+ int i;
+ ssize_t j;
+ char *date;
+ char *tape, *tape_undo, tape_undo_ch = '\0';
+ char *dir_undo, dir_undo_ch = '\0';
+ int level = 0;
+ off_t fileno;
+ char *ditem_path = NULL;
+ char *l = NULL;
+ int deleted;
+ char *s;
+ int ch;
+ int found_one;
+ char *quoted;
+
+ if (disk_path == NULL) {
+ printf("Must select directory before deleting files\n");
+ return;
+ }
+ memset(&lditem, 0, sizeof(lditem)); /* Prevent use of bogus data... */
+
+ dbprintf(("delete_file: Looking for \"%s\"\n", path));
+
+ if (strcmp(regex, "[^/]*[/]*$") == 0) {
+ /* Looking for * find everything but single . */
+ regex = "([^/.]|\\.[^/]+|[^/.][^/]*)[/]*$";
+ } else {
+ /* remove "/" at end of path */
+ j = (ssize_t)(strlen(regex) - 1);
+ while(j >= 0 && regex[j] == '/') regex[j--] = '\0';
+ }
+
+ /* convert path (assumed in cwd) to one on disk */
+ if (strcmp(disk_path, "/") == 0) {
+ if (*regex == '/') {
+ if (strcmp(regex, "/[/]*$") == 0) {
+ /* We want "/" to match the directory itself: "/." */
+ path_on_disk = stralloc("/\\.[/]*$");
+ } else {
+ /* No mods needed if already starts with '/' */
+ path_on_disk = stralloc(regex);
+ }
+ } else {
+ /* Prepend '/' */
+ path_on_disk = stralloc2("/", regex);
+ }
+ } else {
+ char *clean_disk_path = clean_regex(disk_path);
+ path_on_disk = vstralloc(clean_disk_path, "/", regex, NULL);
+ amfree(clean_disk_path);
+ }
+
+ path_on_disk_slash = stralloc2(path_on_disk, "/");
+
+ dbprintf(("delete_file: Converted path=\"%s\" to path_on_disk=\"%s\"\n",
+ regex, path_on_disk));
+ found_one = 0;
+ for (ditem=get_dir_list(); ditem!=NULL; ditem=get_next_dir_item(ditem))
+ {
+ quoted = quote_string(ditem->path);
+ dbprintf(("delete_file: Pondering ditem->path=%s\n", quoted));
+ amfree(quoted);
+ if (match(path_on_disk, ditem->path)
+ || match(path_on_disk_slash, ditem->path))
+ {
+ found_one = 1;
+ j = (ssize_t)strlen(ditem->path);
+ if((j > 0 && ditem->path[j-1] == '/')
+ || (j > 1 && ditem->path[j-2] == '/' && ditem->path[j-1] == '.'))
+ { /* It is a directory */
+ ditem_path = newstralloc(ditem_path, ditem->path);
+ clean_pathname(ditem_path);
+
+ cmd = stralloc2("ORLD ", ditem_path);
+ if(send_command(cmd) == -1) {
+ amfree(cmd);
+ amfree(ditem_path);
+ amfree(path_on_disk);
+ amfree(path_on_disk_slash);
+ exit(1);
+ }
+ amfree(cmd);
+ /* skip preamble */
+ if ((i = get_reply_line()) == -1) {
+ amfree(ditem_path);
+ amfree(path_on_disk);
+ amfree(path_on_disk_slash);
+ exit(1);
+ }
+ if(i==0) /* assume something wrong */
+ {
+ amfree(ditem_path);
+ amfree(path_on_disk);
+ amfree(path_on_disk_slash);
+ l = reply_line();
+ printf("%s\n", l);
+ return;
+ }
+ deleted=0;
+ lditem.path = newstralloc(lditem.path, ditem->path);
+ amfree(cmd);
+ tape_undo = dir_undo = NULL;
+ /* skip the last line -- duplicate of the preamble */
+ while ((i = get_reply_line()) != 0)
+ {
+ if (i == -1) {
+ amfree(ditem_path);
+ amfree(path_on_disk);
+ amfree(path_on_disk_slash);
+ exit(1);
+ }
+ if(err) {
+ if(cmd == NULL) {
+ if(tape_undo) *tape_undo = tape_undo_ch;
+ if(dir_undo) *dir_undo = dir_undo_ch;
+ tape_undo = dir_undo = NULL;
+ cmd = stralloc(l); /* save for the error report */
+ }
+ continue; /* throw the rest of the lines away */
+ }
+ l=reply_line();
+ if (!server_happy()) {
+ puts(l);
+ continue;
+ }
+#define sc "201-"
+ if(strncmp(l, sc, sizeof(sc)-1) != 0) {
+ err = "bad reply: not 201-";
+ continue;
+ }
+ s = l + sizeof(sc)-1;
+ ch = *s++;
+#undef sc
+ skip_whitespace(s, ch);
+ if(ch == '\0') {
+ err = "bad reply: missing date field";
+ continue;
+ }
+ date = s - 1;
+ skip_non_whitespace(s, ch);
+ *(s - 1) = '\0';
+
+ skip_whitespace(s, ch);
+ if(ch == '\0' || sscanf(s - 1, "%d", &level) != 1) {
+ err = "bad reply: cannot parse level field";
+ continue;
+ }
+ skip_integer(s, ch);
+
+ skip_whitespace(s, ch);
+ if(ch == '\0') {
+ err = "bad reply: missing tape field";
+ continue;
+ }
+ tape = s - 1;
+ skip_non_whitespace(s, ch);
+ tape_undo = s - 1;
+ tape_undo_ch = *tape_undo;
+ *tape_undo = '\0';
+
+ if(am_has_feature(indexsrv_features, fe_amindexd_fileno_in_ORLD)) {
+ skip_whitespace(s, ch);
+ if(ch == '\0' || sscanf(s - 1, OFF_T_FMT,
+ (OFF_T_FMT_TYPE *)&fileno) != 1) {
+ err = "bad reply: cannot parse fileno field";
+ continue;
+ }
+ skip_integer(s, ch);
+ }
+
+ skip_whitespace(s, ch);
+ if(ch == '\0') {
+ err = "bad reply: missing directory field";
+ continue;
+ }
+ skip_non_whitespace(s, ch);
+ dir_undo = s - 1;
+ dir_undo_ch = *dir_undo;
+ *dir_undo = '\0';
+
+ lditem.date = newstralloc(lditem.date, date);
+ lditem.level=level;
+ lditem.tape = newstralloc(lditem.tape, tape);
+ switch(delete_extract_item(&lditem)) {
+ case -1:
+ printf("System error\n");
+ dbprintf(("delete_file: (Failed) System error\n"));
+ break;
+ case 0:
+ printf("Deleted dir %s at date %s\n", ditem_path, date);
+ dbprintf(("delete_file: (Successful) Deleted dir %s at date %s\n",
+ ditem_path, date));
+ deleted=1;
+ break;
+ case 1:
+ break;
+ }
+ }
+ if(!server_happy()) {
+ puts(reply_line());
+ } else if(err) {
+ if (*err)
+ puts(err);
+ if (cmd)
+ puts(cmd);
+ } else if(deleted == 0) {
+ printf("Warning - dir '%s' not on tape list\n",
+ ditem_path);
+ dbprintf(("delete_file: dir '%s' not on tape list\n",
+ ditem_path));
+ }
+ }
+ else
+ {
+ switch(delete_extract_item(ditem)) {
+ case -1:
+ printf("System error\n");
+ dbprintf(("delete_file: (Failed) System error\n"));
+ break;
+ case 0:
+ printf("Deleted %s\n", ditem->path);
+ dbprintf(("delete_file: (Successful) Deleted %s\n",
+ ditem->path));
+ break;
+ case 1:
+ printf("Warning - file '%s' not on tape list\n",
+ ditem->path);
+ dbprintf(("delete_file: file '%s' not on tape list\n",
+ ditem->path));
+ break;
+ }
+ }
+ }
+ }
+ amfree(cmd);
+ amfree(ditem_path);
+ amfree(path_on_disk);
+ amfree(path_on_disk_slash);
+
+ if(! found_one) {
+ printf("File %s doesn't exist in directory\n", path);
+ dbprintf(("delete_file: (Failed) File %s doesn't exist in directory\n",
+ path));
+ }
+}
+
+
+/* print extract list into file. If NULL ptr passed print to screen */
+void
+display_extract_list(
+ char * file)
+{
+ EXTRACT_LIST *this;
+ EXTRACT_LIST_ITEM *that;
+ FILE *fp;
+ char *pager;
+ char *pager_command;
+ char *uqfile;
+
+ if (file == NULL)
+ {
+ if ((pager = getenv("PAGER")) == NULL)
+ {
+ pager = "more";
+ }
+ /*
+ * Set up the pager command so if the pager is terminated, we do
+ * not get a SIGPIPE back.
+ */
+ pager_command = stralloc2(pager, " ; /bin/cat > /dev/null");
+ if ((fp = popen(pager_command, "w")) == NULL)
+ {
+ printf("Warning - can't pipe through %s\n", pager);
+ fp = stdout;
+ }
+ amfree(pager_command);
+ }
+ else
+ {
+ uqfile = unquote_string(file);
+ if ((fp = fopen(uqfile, "w")) == NULL)
+ {
+ printf("Can't open file %s to print extract list into\n", file);
+ amfree(uqfile);
+ return;
+ }
+ amfree(uqfile);
+ }
+
+ for (this = extract_list; this != NULL; this = this->next)
+ {
+ fprintf(fp, "TAPE %s LEVEL %d DATE %s\n",
+ this->tape, this->level, this->date);
+ for (that = this->files; that != NULL; that = that->next)
+ fprintf(fp, "\t%s\n", that->path);
+ }
+
+ if (file == NULL) {
+ apclose(fp);
+ } else {
+ printf("Extract list written to file %s\n", file);
+ afclose(fp);
+ }
+}
+
+
+/* returns 0 if extract list empty and 1 if it isn't */
+int
+is_extract_list_nonempty(void)
+{
+ return (extract_list != NULL);
+}
+
+
+/* prints continue prompt and waits for response,
+ returns 0 if don't, non-0 if do */
+static int
+okay_to_continue(
+ int allow_tape,
+ int allow_skip,
+ int allow_retry)
+{
+ int ch;
+ int ret = -1;
+ char *line = NULL;
+ char *s;
+ char *prompt;
+ int get_tape;
+
+ get_tape = 0;
+ while (ret < 0) {
+ if (get_tape) {
+ prompt = "New tape device [?]: ";
+ } else if (allow_tape && allow_skip) {
+ prompt = "Continue [?/Y/n/s/t]? ";
+ } else if (allow_tape && !allow_skip) {
+ prompt = "Continue [?/Y/n/t]? ";
+ } else if (allow_retry) {
+ prompt = "Continue [?/Y/n/r]? ";
+ } else {
+ prompt = "Continue [?/Y/n]? ";
+ }
+ fputs(prompt, stdout);
+ fflush(stdout); fflush(stderr);
+ amfree(line);
+ if ((line = agets(stdin)) == NULL) {
+ putchar('\n');
+ clearerr(stdin);
+ if (get_tape) {
+ get_tape = 0;
+ continue;
+ }
+ ret = 0;
+ break;
+ }
+ s = line;
+ while ((ch = *s++) != '\0' && isspace(ch)) {
+ (void)ch; /* Quiet empty loop body warning */
+ }
+ if (ch == '?') {
+ if (get_tape) {
+ printf("Enter a new device ([host:]device) or \"default\"\n");
+ } else {
+ printf("Enter \"y\"es to continue, \"n\"o to stop");
+ if(allow_skip) {
+ printf(", \"s\"kip this tape");
+ }
+ if(allow_retry) {
+ printf(" or \"r\"etry this tape");
+ }
+ if (allow_tape) {
+ printf(" or \"t\"ape to change tape drives");
+ }
+ putchar('\n');
+ }
+ } else if (get_tape) {
+ set_tape(s - 1);
+ get_tape = 0;
+ } else if (ch == '\0' || ch == 'Y' || ch == 'y') {
+ ret = 1;
+ } else if (allow_tape && (ch == 'T' || ch == 't')) {
+ get_tape = 1;
+ } else if (ch == 'N' || ch == 'n') {
+ ret = 0;
+ } else if (allow_retry && (ch == 'R' || ch == 'r')) {
+ ret = RETRY_TAPE;
+ } else if (allow_skip && (ch == 'S' || ch == 's')) {
+ ret = SKIP_TAPE;
+ }
+ }
+ /*@ignore@*/
+ amfree(line);
+ /*@end@*/
+ return ret;
+}
+
+static void
+send_to_tape_server(
+ int tss,
+ char * cmd)
+{
+ char *msg = stralloc2(cmd, "\r\n");
+
+ if (fullwrite(tss, msg, strlen(msg)) < 0)
+ {
+ error("Error writing to tape server");
+ /*NOTREACHED*/
+ }
+ amfree(msg);
+}
+
+
+/* start up connection to tape server and set commands to initiate
+ transfer of dump image.
+ Return tape server socket on success, -1 on error. */
+static int
+extract_files_setup(
+ char * label,
+ off_t fsf)
+{
+ struct servent *sp;
+ in_port_t my_port, my_data_port;
+ char *disk_regex = NULL;
+ char *host_regex = NULL;
+ char *service_name = NULL;
+ char *line = NULL;
+ char *clean_datestamp, *ch, *ch1;
+ char *our_feature_string = NULL;
+ char *tt = NULL;
+
+ service_name = stralloc2("amidxtape", SERVICE_SUFFIX);
+
+ /* get tape server details */
+ if ((sp = getservbyname(service_name, "tcp")) == NULL)
+ {
+ printf("%s/tcp unknown protocol - config error?\n", service_name);
+ amfree(service_name);
+ return -1;
+ }
+ amfree(service_name);
+ seteuid(0); /* it either works ... */
+ setegid(0);
+ tape_control_sock = stream_client_privileged(tape_server_name,
+ (in_port_t)ntohs((in_port_t)sp->s_port),
+ 0,
+ STREAM_BUFSIZE,
+ &my_port,
+ 0);
+ if (tape_control_sock < 0)
+ {
+ printf("cannot connect to %s: %s\n", tape_server_name, strerror(errno));
+ return -1;
+ }
+ if (my_port >= IPPORT_RESERVED) {
+ aclose(tape_control_sock);
+ printf("did not get a reserved port: %u\n", (unsigned)my_port);
+ return -1;
+ }
+
+ setegid(getgid());
+ seteuid(getuid()); /* put it back */
+
+ /* do the security thing */
+ line = get_security();
+ send_to_tape_server(tape_control_sock, line);
+ memset(line, '\0', strlen(line));
+ amfree(line);
+
+ disk_regex = alloc(strlen(disk_name) * 2 + 3);
+
+ ch = disk_name;
+ ch1 = disk_regex;
+
+ /* we want to force amrestore to only match disk_name exactly */
+ *(ch1++) = '^';
+
+ /* We need to escape some characters first... NT compatibilty crap */
+ for (; *ch != 0; ch++, ch1++) {
+ switch (*ch) { /* done this way in case there are more */
+ case '$':
+ *(ch1++) = '\\';
+ /* no break; we do want to fall through... */
+ default:
+ *ch1 = *ch;
+ }
+ }
+
+ /* we want to force amrestore to only match disk_name exactly */
+ *(ch1++) = '$';
+
+ *ch1 = '\0';
+
+ host_regex = alloc(strlen(dump_hostname) * 2 + 3);
+
+ ch = dump_hostname;
+ ch1 = host_regex;
+
+ /* we want to force amrestore to only match dump_hostname exactly */
+ *(ch1++) = '^';
+
+ /* We need to escape some characters first... NT compatibilty crap */
+ for (; *ch != 0; ch++, ch1++) {
+ switch (*ch) { /* done this way in case there are more */
+ case '$':
+ *(ch1++) = '\\';
+ /* no break; we do want to fall through... */
+ default:
+ *ch1 = *ch;
+ }
+ }
+
+ /* we want to force amrestore to only match dump_hostname exactly */
+ *(ch1++) = '$';
+
+ *ch1 = '\0';
+
+ clean_datestamp = stralloc(dump_datestamp);
+ for(ch=ch1=clean_datestamp;*ch1 != '\0';ch1++) {
+ if(*ch1 != '-') {
+ *ch = *ch1;
+ ch++;
+ }
+ }
+ *ch = '\0';
+
+ /* push our feature list off to the tape server */
+ /* XXX assumes that index server and tape server are equivalent, ew */
+ if(am_has_feature(indexsrv_features, fe_amidxtaped_exchange_features)){
+ char buffer[32768] = "\0";
+
+ our_feature_string = am_feature_to_string(our_features);
+ tt = newstralloc2(tt, "FEATURES=", our_feature_string);
+ send_to_tape_server(tape_control_sock, tt);
+ if (read(tape_control_sock, buffer, sizeof(buffer)) <= 0) {
+ error("Could not read features from control socket\n");
+ /*NOTREACHED*/
+ }
+ tapesrv_features = am_string_to_feature(buffer);
+ amfree(our_feature_string);
+ }
+
+
+ if(am_has_feature(indexsrv_features, fe_amidxtaped_header) &&
+ am_has_feature(indexsrv_features, fe_amidxtaped_device) &&
+ am_has_feature(indexsrv_features, fe_amidxtaped_host) &&
+ am_has_feature(indexsrv_features, fe_amidxtaped_disk) &&
+ am_has_feature(indexsrv_features, fe_amidxtaped_datestamp)) {
+
+ if(am_has_feature(indexsrv_features, fe_amidxtaped_config)) {
+ tt = newstralloc2(tt, "CONFIG=", config);
+ send_to_tape_server(tape_control_sock, tt);
+ }
+ if(am_has_feature(indexsrv_features, fe_amidxtaped_label) &&
+ label && label[0] != '/') {
+ tt = newstralloc2(tt,"LABEL=",label);
+ send_to_tape_server(tape_control_sock, tt);
+ }
+ if(am_has_feature(indexsrv_features, fe_amidxtaped_fsf)) {
+ char v_fsf[100];
+ snprintf(v_fsf, 99, OFF_T_FMT, (OFF_T_FMT_TYPE)fsf);
+ tt = newstralloc2(tt, "FSF=",v_fsf);
+ send_to_tape_server(tape_control_sock, tt);
+ }
+ send_to_tape_server(tape_control_sock, "HEADER");
+ tt = newstralloc2(tt, "DEVICE=", dump_device_name);
+ send_to_tape_server(tape_control_sock, tt);
+ tt = newstralloc2(tt, "HOST=", host_regex);
+ send_to_tape_server(tape_control_sock, tt);
+ tt = newstralloc2(tt, "DISK=", disk_regex);
+ send_to_tape_server(tape_control_sock, tt);
+ tt = newstralloc2(tt, "DATESTAMP=", clean_datestamp);
+ send_to_tape_server(tape_control_sock, tt);
+ send_to_tape_server(tape_control_sock, "END");
+ amfree(tt);
+ }
+ else if(am_has_feature(indexsrv_features, fe_amidxtaped_nargs)) {
+ /* send to the tape server what tape file we want */
+ /* 6 args:
+ * "-h"
+ * "-p"
+ * "tape device"
+ * "hostname"
+ * "diskname"
+ * "datestamp"
+ */
+ send_to_tape_server(tape_control_sock, "6");
+ send_to_tape_server(tape_control_sock, "-h");
+ send_to_tape_server(tape_control_sock, "-p");
+ send_to_tape_server(tape_control_sock, dump_device_name);
+ send_to_tape_server(tape_control_sock, host_regex);
+ send_to_tape_server(tape_control_sock, disk_regex);
+ send_to_tape_server(tape_control_sock, clean_datestamp);
+
+ dbprintf(("Started amidxtaped with arguments \"6 -h -p %s %s %s %s\"\n",
+ dump_device_name, host_regex, disk_regex, clean_datestamp));
+ }
+
+ /*
+ * split-restoring amidxtaped versions will expect to set up a data
+ * connection for dumpfile data, distinct from the socket we're already
+ * using for control data
+ */
+
+ if(am_has_feature(tapesrv_features, fe_recover_splits)){
+ char buffer[32768];
+ in_port_t data_port = (in_port_t)-1;
+ ssize_t nread;
+
+ nread = read(tape_control_sock, buffer, sizeof(buffer));
+
+ if (nread <= 0) {
+ error("Could not read from control socket: %s\n",
+ strerror(errno));
+ /*NOTREACHED*/
+ }
+
+ buffer[nread] = '\0';
+ if (sscanf(buffer, "CONNECT %hu\n",
+ (unsigned short *)&data_port) != 1) {
+ error("Recieved invalid port number message from control socket: %s\n",
+ buffer);
+ /*NOTREACHED*/
+ }
+
+ tape_data_sock = stream_client_privileged(server_name,
+ data_port,
+ 0,
+ STREAM_BUFSIZE,
+ &my_data_port,
+ 0);
+ if(tape_data_sock == -1){
+ error("Unable to make data connection to server: %s\n",
+ strerror(errno));
+ /*NOTREACHED*/
+ }
+
+ amfree(our_feature_string);
+
+ line = get_security();
+
+ send_to_tape_server(tape_data_sock, line);
+ memset(line, '\0', strlen(line));
+ amfree(line);
+ }
+
+ amfree(disk_regex);
+ amfree(host_regex);
+ amfree(clean_datestamp);
+
+ return tape_control_sock;
+}
+
+
+/*
+ * Reads the first block of a tape file.
+ */
+
+void
+read_file_header(
+ char * buffer,
+ dumpfile_t *file,
+ size_t buflen,
+ int tapedev)
+{
+ ssize_t bytes_read;
+
+ bytes_read = read_buffer(tapedev, buffer, buflen, READ_TIMEOUT);
+ if(bytes_read < 0) {
+ error("error reading header (%s), check amidxtaped.*.debug on server",
+ strerror(errno));
+ /*NOTREACHED*/
+ }
+
+ if((size_t)bytes_read < buflen) {
+ fprintf(stderr, "%s: short block %d byte%s\n",
+ get_pname(), (int)bytes_read, (bytes_read == 1) ? "" : "s");
+ print_header(stdout, file);
+ error("Can't read file header");
+ /*NOTREACHED*/
+ }
+
+ /* bytes_read == buflen */
+ parse_file_header(buffer, file, (size_t)bytes_read);
+}
+
+enum dumptypes {
+ IS_UNKNOWN,
+ IS_DUMP,
+ IS_GNUTAR,
+ IS_TAR,
+ IS_SAMBA,
+ IS_SAMBA_TAR
+};
+
+static void
+extract_files_child(
+ int in_fd,
+ EXTRACT_LIST * elist)
+{
+ int save_errno;
+ int extra_params = 0;
+ int i,j=0;
+ char **restore_args = NULL;
+ int files_off_tape;
+ EXTRACT_LIST_ITEM *fn;
+ enum dumptypes dumptype = IS_UNKNOWN;
+ char buffer[DISK_BLOCK_BYTES];
+ dumpfile_t file;
+ size_t len_program;
+ char *cmd = NULL;
+ int passwd_field = -1;
+#ifdef SAMBA_CLIENT
+ char *domain = NULL, *smbpass = NULL;
+#endif
+
+ /* code executed by child to do extraction */
+ /* never returns */
+
+ /* make in_fd be our stdin */
+ if (dup2(in_fd, STDIN_FILENO) == -1)
+ {
+ error("dup2 failed in extract_files_child: %s", strerror(errno));
+ /*NOTREACHED*/
+ }
+
+ /* read the file header */
+ fh_init(&file);
+ read_file_header(buffer, &file, sizeof(buffer), STDIN_FILENO);
+
+ if(file.type != F_DUMPFILE) {
+ print_header(stdout, &file);
+ error("bad header");
+ /*NOTREACHED*/
+ }
+
+ if (file.program != NULL) {
+#ifdef GNUTAR
+ if (strcmp(file.program, GNUTAR) == 0)
+ dumptype = IS_GNUTAR;
+#endif
+
+ if (dumptype == IS_UNKNOWN) {
+ len_program = strlen(file.program);
+ if(len_program >= 3 &&
+ strcmp(&file.program[len_program-3],"tar") == 0)
+ dumptype = IS_TAR;
+ }
+
+#ifdef SAMBA_CLIENT
+ if (dumptype == IS_UNKNOWN && strcmp(file.program, SAMBA_CLIENT) ==0) {
+ if (samba_extract_method == SAMBA_TAR)
+ dumptype = IS_SAMBA_TAR;
+ else
+ dumptype = IS_SAMBA;
+ }
+#endif
+ }
+
+ /* form the arguments to restore */
+ files_off_tape = length_of_tape_list(elist);
+ switch (dumptype) {
+ case IS_SAMBA:
+#ifdef SAMBA_CLIENT
+ extra_params = 10;
+ break;
+#endif
+ case IS_TAR:
+ case IS_GNUTAR:
+ extra_params = 4;
+ break;
+ case IS_SAMBA_TAR:
+ extra_params = 3;
+ break;
+ case IS_UNKNOWN:
+ case IS_DUMP:
+#ifdef AIX_BACKUP
+ extra_params = 2;
+#else
+#if defined(XFSDUMP)
+ if (strcmp(file.program, XFSDUMP) == 0) {
+ extra_params = 4 + files_off_tape;
+ } else
+#endif
+ {
+ extra_params = 4;
+ }
+#endif
+ break;
+ }
+
+ restore_args = (char **)alloc((size_t)((extra_params + files_off_tape + 1)
+ * sizeof(char *)));
+ switch(dumptype) {
+ case IS_SAMBA:
+#ifdef SAMBA_CLIENT
+ restore_args[j++] = stralloc("smbclient");
+ smbpass = findpass(file.disk, &domain);
+ if (smbpass) {
+ restore_args[j++] = stralloc(file.disk);
+ passwd_field=j;
+ restore_args[j++] = stralloc("-U");
+ restore_args[j++] = smbpass;
+ if (domain) {
+ restore_args[j++] = stralloc("-W");
+ restore_args[j++] = stralloc(domain);
+ } else
+ extra_params -= 2;
+ } else
+ extra_params -= 6;
+ restore_args[j++] = stralloc("-d0");
+ restore_args[j++] = stralloc("-Tx");
+ restore_args[j++] = stralloc("-"); /* data on stdin */
+ break;
+#endif
+ case IS_TAR:
+ case IS_GNUTAR:
+ restore_args[j++] = stralloc("tar");
+ restore_args[j++] = stralloc("--numeric-owner");
+ restore_args[j++] = stralloc("-xpGvf");
+ restore_args[j++] = stralloc("-"); /* data on stdin */
+ break;
+ case IS_SAMBA_TAR:
+ restore_args[j++] = stralloc("tar");
+ restore_args[j++] = stralloc("-xpvf");
+ restore_args[j++] = stralloc("-"); /* data on stdin */
+ break;
+ case IS_UNKNOWN:
+ case IS_DUMP:
+ restore_args[j++] = stralloc("restore");
+#ifdef AIX_BACKUP
+ restore_args[j++] = stralloc("-xB");
+#else
+#if defined(XFSDUMP)
+ if (strcmp(file.program, XFSDUMP) == 0) {
+ restore_args[j++] = stralloc("-v");
+ restore_args[j++] = stralloc("silent");
+ } else
+#endif
+#if defined(VDUMP)
+ if (strcmp(file.program, VDUMP) == 0) {
+ restore_args[j++] = stralloc("xf");
+ restore_args[j++] = stralloc("-"); /* data on stdin */
+ } else
+#endif
+ {
+ restore_args[j++] = stralloc("xbf");
+ restore_args[j++] = stralloc("2"); /* read in units of 1K */
+ restore_args[j++] = stralloc("-"); /* data on stdin */
+ }
+#endif
+ }
+
+ for (i = 0, fn = elist->files; i < files_off_tape; i++, fn = fn->next)
+ {
+ switch (dumptype) {
+ case IS_TAR:
+ case IS_GNUTAR:
+ case IS_SAMBA_TAR:
+ case IS_SAMBA:
+ if (strcmp(fn->path, "/") == 0)
+ restore_args[j++] = stralloc(".");
+ else
+ restore_args[j++] = stralloc2(".", fn->path);
+ break;
+ case IS_UNKNOWN:
+ case IS_DUMP:
+#if defined(XFSDUMP)
+ if (strcmp(file.program, XFSDUMP) == 0) {
+ /*
+ * xfsrestore needs a -s option before each file to be
+ * restored, and also wants them to be relative paths.
+ */
+ restore_args[j++] = stralloc("-s");
+ restore_args[j++] = stralloc(fn->path + 1);
+ } else
+#endif
+ {
+ restore_args[j++] = stralloc(fn->path);
+ }
+ }
+ }
+#if defined(XFSDUMP)
+ if (strcmp(file.program, XFSDUMP) == 0) {
+ restore_args[j++] = stralloc("-");
+ restore_args[j++] = stralloc(".");
+ }
+#endif
+ restore_args[j] = NULL;
+
+ switch (dumptype) {
+ case IS_SAMBA:
+#ifdef SAMBA_CLIENT
+ cmd = stralloc(SAMBA_CLIENT);
+ break;
+#else
+ /* fall through to ... */
+#endif
+ case IS_TAR:
+ case IS_GNUTAR:
+ case IS_SAMBA_TAR:
+#ifndef GNUTAR
+ fprintf(stderr, "warning: GNUTAR program not available.\n");
+ cmd = stralloc("tar");
+#else
+ cmd = stralloc(GNUTAR);
+#endif
+ break;
+ case IS_UNKNOWN:
+ case IS_DUMP:
+ cmd = NULL;
+#if defined(DUMP)
+ if (strcmp(file.program, DUMP) == 0) {
+ cmd = stralloc(RESTORE);
+ }
+#endif
+#if defined(VDUMP)
+ if (strcmp(file.program, VDUMP) == 0) {
+ cmd = stralloc(VRESTORE);
+ }
+#endif
+#if defined(VXDUMP)
+ if (strcmp(file.program, VXDUMP) == 0) {
+ cmd = stralloc(VXRESTORE);
+ }
+#endif
+#if defined(XFSDUMP)
+ if (strcmp(file.program, XFSDUMP) == 0) {
+ cmd = stralloc(XFSRESTORE);
+ }
+#endif
+ if (cmd == NULL) {
+ fprintf(stderr, "warning: restore program for %s not available.\n",
+ file.program);
+ cmd = stralloc("restore");
+ }
+ }
+ if (cmd) {
+ dbprintf(("Exec'ing %s with arguments:\n", cmd));
+ for (i = 0; i < j; i++) {
+ if( i == passwd_field)
+ dbprintf(("\tXXXXX\n"));
+ else
+ dbprintf(("\t%s\n", restore_args[i]));
+ }
+ (void)execv(cmd, restore_args);
+ /* only get here if exec failed */
+ save_errno = errno;
+ for (i = 0; i < j; i++) {
+ amfree(restore_args[i]);
+ }
+ amfree(restore_args);
+ errno = save_errno;
+ perror("amrecover couldn't exec");
+ fprintf(stderr, " problem executing %s\n", cmd);
+ amfree(cmd);
+ }
+ exit(1);
+ /*NOT REACHED */
+}
+
+/*
+ * Interpose something between the process writing out the dump (writing it to
+ * some extraction program, really) and the socket from which we're reading, so
+ * that we can do things like prompt for human interaction for multiple tapes.
+ */
+void
+writer_intermediary(
+ int ctl_fd,
+ int data_fd,
+ EXTRACT_LIST * elist)
+{
+ int child_pipe[2];
+ pid_t pid;
+ char buffer[DISK_BLOCK_BYTES];
+ ssize_t bytes_read;
+ amwait_t extractor_status;
+ int max_fd, nfound;
+ SELECT_ARG_TYPE readset, selectset;
+ struct timeval timeout;
+
+ /*
+ * If there's no distinct data channel (such as if we're talking to an
+ * older server), don't bother doing anything complicated. Just run the
+ * extraction.
+ */
+ if(data_fd == -1){
+ extract_files_child(ctl_fd, elist);
+ /*NOTREACHED*/
+ }
+
+ if(pipe(child_pipe) == -1) {
+ error("extract_list - error setting up pipe to extractor: %s\n",
+ strerror(errno));
+ /*NOTREACHED*/
+ }
+
+ /* okay, ready to extract. fork a child to do the actual work */
+ if ((pid = fork()) == 0) {
+ /* this is the child process */
+ /* never gets out of this clause */
+ aclose(child_pipe[1]);
+ extract_files_child(child_pipe[0], elist);
+ /*NOTREACHED*/
+ }
+
+ /* This is the parent */
+ if (pid == -1) {
+ error("writer_intermediary - error forking child");
+ /*NOTREACHED*/
+ }
+
+ aclose(child_pipe[0]);
+
+ if(data_fd > ctl_fd) max_fd = data_fd+1;
+ else max_fd = ctl_fd+1;
+ FD_ZERO(&readset);
+ FD_SET(data_fd, &readset);
+ FD_SET(ctl_fd, &readset);
+
+ do {
+ timeout.tv_sec = READ_TIMEOUT;
+ timeout.tv_usec = 0;
+ FD_COPY(&readset, &selectset);
+
+ nfound = select(max_fd, &selectset, NULL, NULL,
+ &timeout);
+ if(nfound < 0) {
+ fprintf(stderr,"select error: %s\n", strerror(errno));
+ break;
+ }
+
+ if (nfound == 0) { /* timeout */
+ fprintf(stderr, "timeout waiting %d seconds for restore\n",
+ READ_TIMEOUT);
+ fprintf(stderr, "increase READ_TIMEOUT in recover-src/extract_list.c if your tape is slow\n");
+ break;
+ }
+
+ if(FD_ISSET(ctl_fd, &selectset)) {
+ bytes_read = read(ctl_fd, buffer, sizeof(buffer)-1);
+ switch(bytes_read) {
+ case -1:
+ if ((errno != EINTR) && (errno != EAGAIN)) {
+ if (errno != EPIPE) {
+ fprintf(stderr,"writer ctl fd read error: %s",
+ strerror(errno));
+ }
+ FD_CLR(ctl_fd, &readset);
+ }
+ break;
+
+ case 0:
+ FD_CLR(ctl_fd, &readset);
+ break;
+
+ default: {
+ char desired_tape[MAX_TAPE_LABEL_BUF];
+
+ buffer[bytes_read] = '\0';
+ /* if prompted for a tape, relay said prompt to the user */
+ if(sscanf(buffer, "FEEDME %132s\n", desired_tape) == 1) {
+ int done = 0;
+ while (!done) {
+ char *input = NULL;
+ printf("Please insert tape %s. Continue? [Y|n]: ",
+ desired_tape);
+ fflush(stdout);
+
+ input = agets(stdin); /* strips \n */
+ if (strcasecmp("", input) == 0||
+ strcasecmp("y", input) == 0||
+ strcasecmp("yes", input) == 0) {
+ send_to_tape_server(tape_control_sock, "OK");
+ done = 1;
+ } else if (strcasecmp("n", input) == 0||
+ strcasecmp("no", input) == 0) {
+ send_to_tape_server(tape_control_sock, "ERROR");
+ /* Abort!
+ We are the middle process, so just die. */
+ exit(EXIT_FAILURE);
+ }
+ amfree(input);
+ }
+ } else {
+ fprintf(stderr, "Strange message from tape server: %s", buffer);
+ break;
+ }
+ }
+ }
+ }
+
+ /* now read some dump data */
+ if(FD_ISSET(data_fd, &selectset)) {
+ bytes_read = read(data_fd, buffer, sizeof(buffer)-1);
+ switch(bytes_read) {
+ case -1:
+ if ((errno != EINTR) && (errno != EAGAIN)) {
+ if (errno != EPIPE) {
+ fprintf(stderr,"writer data fd read error: %s",
+ strerror(errno));
+ }
+ FD_CLR(data_fd, &readset);
+ }
+ break;
+
+ case 0:
+ FD_CLR(data_fd, &readset);
+ break;
+
+ default:
+ /*
+ * spit what we got from the server to the child
+ * process handling actual dumpfile extraction
+ */
+ if(fullwrite(child_pipe[1], buffer, (size_t)bytes_read) < 0) {
+ if(errno == EPIPE) {
+ error("%s: pipe data reader has quit: %s\n",
+ get_pname(), strerror(errno));
+ /* NOTREACHED */
+ }
+ error("Write error to extract child: %s\n",
+ strerror(errno));
+ /* NOTREACHED */
+ }
+ break;
+ }
+ }
+ } while(FD_ISSET(ctl_fd, &readset) || FD_ISSET(data_fd, &readset));
+
+ aclose(child_pipe[1]);
+
+ waitpid(pid, &extractor_status, 0);
+ if(WEXITSTATUS(extractor_status) != 0){
+ int ret = WEXITSTATUS(extractor_status);
+ if(ret == 255) ret = -1;
+ error("Extractor child exited with status %d\n", ret);
+ /*NOTREACHED*/
+ }
+
+ exit(0);
+}
+
+/* exec restore to do the actual restoration */
+
+/* does the actual extraction of files */
+/*
+ * The original design had the dump image being returned exactly as it
+ * appears on the tape, and this routine getting from the index server
+ * whether or not it is compressed, on the assumption that the tape
+ * server may not know how to uncompress it. But
+ * - Amrestore can't do that. It returns either compressed or uncompressed
+ * (always). Amrestore assumes it can uncompress files. It is thus a good
+ * idea to run the tape server on a machine with gzip.
+ * - The information about compression in the disklist is really only
+ * for future dumps. It is possible to change compression on a drive
+ * so the information in the disklist may not necessarily relate to
+ * the dump image on the tape.
+ * Consequently the design was changed to assuming that amrestore can
+ * uncompress any dump image and have it return an uncompressed file
+ * always.
+ */
+void
+extract_files(void)
+{
+ EXTRACT_LIST *elist;
+ pid_t pid;
+ amwait_t child_stat;
+ char buf[STR_SIZE];
+ char *l;
+ int first;
+ int otc;
+ tapelist_t *tlist = NULL;
+
+ if (!is_extract_list_nonempty())
+ {
+ printf("Extract list empty - No files to extract!\n");
+ return;
+ }
+
+ clean_extract_list();
+
+ /* get tape device name from index server if none specified */
+ if (tape_server_name == NULL) {
+ tape_server_name = newstralloc(tape_server_name, server_name);
+ }
+ if (tape_device_name == NULL) {
+ if (send_command("TAPE") == -1)
+ exit(1);
+ if (get_reply_line() == -1)
+ exit(1);
+ l = reply_line();
+ if (!server_happy())
+ {
+ printf("%s\n", l);
+ exit(1);
+ }
+ /* skip reply number */
+ tape_device_name = newstralloc(tape_device_name, l+4);
+ }
+
+ if (strcmp(tape_device_name, "/dev/null") == 0)
+ {
+ printf("amrecover: warning: using %s as the tape device will not work\n",
+ tape_device_name);
+ }
+
+ first=1;
+ for (elist = first_tape_list(); elist != NULL; elist = next_tape_list(elist))
+ if(elist->tape[0]!='/') {
+ if(first) {
+ printf("\nExtracting files using tape drive %s on host %s.\n",
+ tape_device_name, tape_server_name);
+ printf("The following tapes are needed:");
+ first=0;
+ }
+ else
+ printf(" ");
+ tlist = unmarshal_tapelist_str(elist->tape);
+ for( ; tlist != NULL; tlist = tlist->next)
+ printf(" %s", tlist->label);
+ printf("\n");
+ amfree(tlist);
+ }
+ first=1;
+ for (elist = first_tape_list(); elist != NULL; elist = next_tape_list(elist))
+ {
+ if(elist->tape[0]=='/') {
+ if(first) {
+ printf("\nExtracting files from holding disk on host %s.\n",
+ tape_server_name);
+ printf("The following files are needed:");
+ first=0;
+ }
+ else
+ printf(" ");
+ tlist = unmarshal_tapelist_str(elist->tape);
+ for( ; tlist != NULL; tlist = tlist->next)
+ printf(" %s", tlist->label);
+ printf("\n");
+ amfree(tlist);
+ }
+ }
+ printf("\n");
+
+ if (getcwd(buf, sizeof(buf)) == NULL) {
+ perror("extract_list: Current working directory unavailable");
+ exit(1);
+ }
+
+ printf("Restoring files into directory %s\n", buf);
+#ifdef SAMBA_CLIENT
+ if (samba_extract_method == SAMBA_SMBCLIENT)
+ printf("(unless it is a Samba backup, that will go through to the SMB server)\n");
+#endif
+ if (!okay_to_continue(0,0,0))
+ return;
+ printf("\n");
+
+ while ((elist = first_tape_list()) != NULL)
+ {
+ if(elist->tape[0]=='/') {
+ dump_device_name = newstralloc(dump_device_name, elist->tape);
+ printf("Extracting from file ");
+ tlist = unmarshal_tapelist_str(dump_device_name);
+ for( ; tlist != NULL; tlist = tlist->next)
+ printf(" %s", tlist->label);
+ printf("\n");
+ amfree(tlist);
+ }
+ else {
+ printf("Extracting files using tape drive %s on host %s.\n",
+ tape_device_name, tape_server_name);
+ tlist = unmarshal_tapelist_str(elist->tape);
+ printf("Load tape %s now\n", tlist->label);
+ amfree(tlist);
+ otc = okay_to_continue(1,1,0);
+ if (otc == 0)
+ return;
+ else if (otc == SKIP_TAPE) {
+ delete_tape_list(elist); /* skip this tape */
+ continue;
+ }
+ dump_device_name = newstralloc(dump_device_name, tape_device_name);
+ }
+ dump_datestamp = newstralloc(dump_datestamp, elist->date);
+
+ /* connect to the tape handler daemon on the tape drive server */
+ if ((tape_control_sock = extract_files_setup(elist->tape, elist->fileno)) == -1)
+ {
+ fprintf(stderr, "amrecover - can't talk to tape server\n");
+ return;
+ }
+
+ /* okay, ready to extract. fork a child to do the actual work */
+ if ((pid = fork()) == 0)
+ {
+ /* this is the child process */
+ /* never gets out of this clause */
+ writer_intermediary(tape_control_sock, tape_data_sock, elist);
+ /*NOT REACHED*/
+ }
+ /* this is the parent */
+ if (pid == -1)
+ {
+ perror("extract_list - error forking child");
+ aclose(tape_control_sock);
+ exit(1);
+ }
+
+ /* store the child pid globally so that it can be killed on intr */
+ extract_restore_child_pid = pid;
+
+ /* wait for the child process to finish */
+ if ((pid = waitpid(-1, &child_stat, 0)) == (pid_t)-1)
+ {
+ perror("extract_list - error waiting for child");
+ exit(1);
+ }
+
+ if(tape_data_sock != -1) {
+ aclose(tape_data_sock);
+ }
+
+ if (pid == extract_restore_child_pid)
+ {
+ extract_restore_child_pid = -1;
+ }
+ else
+ {
+ fprintf(stderr, "extract list - unknown child terminated?\n");
+ exit(1);
+ }
+ if ((WIFEXITED(child_stat) != 0) && (WEXITSTATUS(child_stat) != 0))
+ {
+ fprintf(stderr,
+ "extract_list - child returned non-zero status: %d\n",
+ WEXITSTATUS(child_stat));
+ otc = okay_to_continue(0,0,1);
+ if(otc == 0)
+ return;
+
+ if(otc == 1) {
+ delete_tape_list(elist); /* tape failed so delete from list */
+ }
+ }
+ else {
+ delete_tape_list(elist); /* tape done so delete from list */
+ }
+ }
+}
--- /dev/null
+/*
+ * Amanda, The Advanced Maryland Automatic Network Disk Archiver
+ * Copyright (c) 1991-1998, 2000 University of Maryland at College Park
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of U.M. not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. U.M. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: the Amanda Development Team. Its members are listed in a
+ * file named AUTHORS, in the root directory of this distribution.
+ */
+/*
+ * $Id: help.c,v 1.2 2006/05/25 01:47:13 johnfranks Exp $
+ *
+ * implements the "help" command in amrecover
+ */
+
+#include "amanda.h"
+#include "amrecover.h"
+
+/* print a list of valid commands */
+void
+help_list(void)
+{
+ printf("valid commands are:\n\n");
+
+ printf("add path1 ... - add to extraction list (shell wildcards)\n");
+ printf("addx path1 ... - add to extraction list (regular expressions)\n");
+ printf("cd directory - change cwd on virtual file system (shell wildcards)\n");
+ printf("cdx directory - change cwd on virtual file system (regular expressions)\n");
+ printf("clear - clear extraction list\n");
+ printf("delete path1 ... - delete from extraction list (shell wildcards)\n");
+ printf("deletex path1 ... - delete from extraction list (regular expressions)\n");
+ printf("extract - extract selected files from tapes\n");
+ printf("exit\n");
+ printf("help\n");
+ printf("history - show dump history of disk\n");
+ printf("list [filename] - show extraction list, optionally writing to file\n");
+ printf("lcd directory - change cwd on local file system\n");
+ printf("ls - list directory on virtual file system\n");
+ printf("lpwd - show cwd on local file system\n");
+ printf("mode - show the method used to extract SMB shares\n");
+ printf("pwd - show cwd on virtual file system\n");
+ printf("quit\n");
+ printf("listhost - list hosts\n");
+ printf("listdisk [diskdevice] - list disks\n");
+ printf("setdate {YYYY-MM-DD|--MM-DD|---DD} - set date of look\n");
+ printf(" {YYYY-MM-DD-HH-MM-SS} - set date of look\n");
+ printf("setdisk diskname [mountpoint] - select disk on dump host\n");
+ printf("sethost host - select dump host\n");
+ printf("settape [host:][device|default] - select tape server and/or device\n");
+ printf("setmode smb|tar - select the method used to extract SMB shares\n");
+ printf("\n");
+}
--- /dev/null
+/*
+ * Amanda, The Advanced Maryland Automatic Network Disk Archiver
+ * Copyright (c) 1991-1998, 2000 University of Maryland at College Park
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of U.M. not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. U.M. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: the Amanda Development Team. Its members are listed in a
+ * file named AUTHORS, in the root directory of this distribution.
+ */
+/*
+ * $Id: set_commands.c,v 1.3 2006/07/05 13:14:58 martinea Exp $
+ *
+ * implements the "set" commands in amrecover
+ */
+
+#include "amanda.h"
+#include "amrecover.h"
+
+#ifdef SAMBA_CLIENT
+extern unsigned short samba_extract_method;
+#endif /* SAMBA_CLIENT */
+
+/* sets a date, mapping given date into standard form if needed */
+int
+set_date(
+ char * date)
+{
+ char *cmd = NULL;
+
+ clear_dir_list();
+
+ cmd = stralloc2("DATE ", date);
+ if (converse(cmd) == -1)
+ exit(1);
+
+ /* if a host/disk/directory is set, then check if that directory
+ is still valid at the new date, and if not set directory to
+ mount_point */
+ if (disk_path != NULL) {
+ cmd = newstralloc2(cmd, "OISD ", disk_path);
+ if (exchange(cmd) == -1)
+ exit(1);
+ if (server_happy())
+ {
+ suck_dir_list_from_server();
+ }
+ else
+ {
+ printf("No index records for cwd on new date\n");
+ printf("Setting cwd to mount point\n");
+ disk_path = newstralloc(disk_path, "/"); /* fake it */
+ clear_dir_list();
+ }
+ }
+ amfree(cmd);
+ return 0;
+}
+
+
+void
+set_host(
+ const char * host)
+{
+ char *cmd = NULL;
+ struct hostent *hp;
+ char **hostp;
+ int found_host = 0;
+
+ if (is_extract_list_nonempty())
+ {
+ printf("Must clear extract list before changing host\n");
+ return;
+ }
+
+ cmd = stralloc2("HOST ", host);
+ if (converse(cmd) == -1)
+ exit(1);
+ if (server_happy())
+ {
+ found_host = 1;
+ }
+ else
+ {
+ /*
+ * Try converting the given host to a fully qualified name
+ * and then try each of the aliases.
+ */
+ if ((hp = gethostbyname(host)) != NULL) {
+ host = hp->h_name;
+ printf("Trying host %s ...\n", host);
+ cmd = newstralloc2(cmd, "HOST ", host);
+ if (converse(cmd) == -1)
+ exit(1);
+ if(server_happy())
+ {
+ found_host = 1;
+ }
+ else
+ {
+ for (hostp = hp->h_aliases; (host = *hostp) != NULL; hostp++)
+ {
+ printf("Trying host %s ...\n", host);
+ cmd = newstralloc2(cmd, "HOST ", host);
+ if (converse(cmd) == -1)
+ exit(1);
+ if(server_happy())
+ {
+ found_host = 1;
+ break;
+ }
+ }
+ }
+ }
+ }
+ if(found_host)
+ {
+ dump_hostname = newstralloc(dump_hostname, host);
+ amfree(disk_name);
+ amfree(mount_point);
+ amfree(disk_path);
+ clear_dir_list();
+ }
+ amfree(cmd);
+}
+
+
+void
+list_host(void)
+{
+ char *cmd = NULL;
+
+ cmd = stralloc("LISTHOST");
+ if (converse(cmd) == -1)
+ exit(1);
+ amfree(cmd);
+}
+
+void
+set_disk(
+ char * dsk,
+ char * mtpt)
+{
+ char *cmd = NULL;
+
+ if (is_extract_list_nonempty())
+ {
+ printf("Must clear extract list before changing disk\n");
+ return;
+ }
+
+ /* if mount point specified, check it is valid */
+ if ((mtpt != NULL) && (*mtpt != '/'))
+ {
+ printf("Mount point \"%s\" invalid - must start with /\n", mtpt);
+ return;
+ }
+
+ clear_dir_list();
+ cmd = stralloc2("DISK ", dsk);
+ if (converse(cmd) == -1)
+ exit(1);
+ amfree(cmd);
+
+ if (!server_happy())
+ return;
+
+ disk_name = newstralloc(disk_name, dsk);
+ if (mtpt == NULL)
+ {
+ /* mount point not specified */
+ if (*dsk == '/')
+ {
+ /* disk specified by mount point, hence use it */
+ mount_point = newstralloc(mount_point, dsk);
+ }
+ else
+ {
+ /* device name given, use '/' because nothing better */
+ mount_point = newstralloc(mount_point, "/");
+ }
+ }
+ else
+ {
+ /* mount point specified */
+ mount_point = newstralloc(mount_point, mtpt);
+ }
+
+ /* set the working directory to the mount point */
+ /* there is the possibility that there are no index records for the
+ disk for the given date, hence setting the directory to the
+ mount point will fail. Preempt this by checking first so we can write
+ a more informative message. */
+ if (exchange("OISD /") == -1)
+ exit(1);
+ if (server_happy())
+ {
+ disk_path = newstralloc(disk_path, "/");
+ suck_dir_list_from_server(); /* get list of directory contents */
+ }
+ else
+ {
+ printf("No index records for disk for specified date\n");
+ printf("If date correct, notify system administrator\n");
+ disk_path = newstralloc(disk_path, "/"); /* fake it */
+ clear_dir_list();
+ }
+}
+
+void
+list_disk(
+ char * amdevice)
+{
+ char *cmd = NULL;
+
+ if(amdevice) {
+ cmd = stralloc2("LISTDISK ", amdevice);
+ if (converse(cmd) == -1)
+ exit(1);
+ amfree(cmd);
+ }
+ else {
+ cmd = stralloc("LISTDISK");
+ if (converse(cmd) == -1)
+ exit(1);
+ amfree(cmd);
+ }
+}
+
+void
+cd_glob(
+ char * glob)
+{
+ char *regex;
+ char *regex_path;
+ char *s;
+
+ char *path_on_disk = NULL;
+
+ if (disk_name == NULL) {
+ printf("Must select disk before changing directory\n");
+ return;
+ }
+
+ regex = glob_to_regex(glob);
+ dbprintf(("cd_glob (%s) -> %s\n", glob, regex));
+ if ((s = validate_regexp(regex)) != NULL) {
+ printf("\"%s\" is not a valid shell wildcard pattern: ", glob);
+ puts(s);
+ amfree(regex);
+ return;
+ }
+ /*
+ * glob_to_regex() anchors the beginning of the pattern with ^,
+ * but we will be tacking it onto the end of the current directory
+ * in add_file, so strip that off. Also, it anchors the end with
+ * $, but we need to match a trailing /, add it if it is not there
+ */
+ regex_path = stralloc(regex + 1);
+ amfree(regex);
+ if(regex_path[strlen(regex_path) - 2] != '/' ) {
+ regex_path[strlen(regex_path) - 1] = '\0';
+ strappend(regex_path, "/$");
+ }
+
+ /* convert path (assumed in cwd) to one on disk */
+ if (strcmp(disk_path, "/") == 0)
+ path_on_disk = stralloc2("/", regex_path);
+ else {
+ char *clean_disk_path = clean_regex(disk_path);
+ path_on_disk = vstralloc(clean_disk_path, "/", regex_path, NULL);
+ amfree(clean_disk_path);
+ }
+
+ cd_dir(path_on_disk, glob);
+
+ amfree(regex_path);
+ amfree(path_on_disk);
+}
+
+void
+cd_regex(
+ char * regex)
+{
+ char *s;
+
+ char *path_on_disk = NULL;
+
+ if (disk_name == NULL) {
+ printf("Must select disk before changing directory\n");
+ return;
+ }
+
+ if ((s = validate_regexp(regex)) != NULL) {
+ printf("\"%s\" is not a valid regular expression: ", regex);
+ puts(s);
+ return;
+ }
+
+ /* convert path (assumed in cwd) to one on disk */
+ if (strcmp(disk_path, "/") == 0)
+ path_on_disk = stralloc2("/", regex);
+ else {
+ char *clean_disk_path = clean_regex(disk_path);
+ path_on_disk = vstralloc(clean_disk_path, "/", regex, NULL);
+ amfree(clean_disk_path);
+ }
+
+ cd_dir(path_on_disk, regex);
+
+ amfree(path_on_disk);
+}
+
+void
+cd_dir(
+ char * path_on_disk,
+ char * default_dir)
+{
+ char *path_on_disk_slash = NULL;
+ char *dir = NULL;
+
+ int nb_found;
+ size_t i;
+
+ DIR_ITEM *ditem;
+
+ path_on_disk_slash = stralloc2(path_on_disk, "/");
+
+ nb_found = 0;
+
+ for (ditem=get_dir_list(); ditem!=NULL && nb_found <= 1;
+ ditem=get_next_dir_item(ditem))
+ {
+ if (match(path_on_disk, ditem->path)
+ || match(path_on_disk_slash, ditem->path))
+ {
+ i = strlen(ditem->path);
+ if((i > 0 && ditem->path[i-1] == '/')
+ || (i > 1 && ditem->path[i-2] == '/' && ditem->path[i-1] == '.'))
+ { /* It is a directory */
+ char *dir1, *dir2;
+ nb_found++;
+ dir = newstralloc(dir,ditem->path);
+ if(dir[strlen(dir)-1] == '/')
+ dir[strlen(dir)-1] = '\0'; /* remove last / */
+ /* remove everything before the last / */
+ dir1 = rindex(dir,'/');
+ if (dir1) {
+ dir1++;
+ dir2 = stralloc(dir1);
+ amfree(dir);
+ dir = dir2;
+ }
+ }
+ }
+ }
+ amfree(path_on_disk_slash);
+
+ if(nb_found==0) {
+ set_directory(default_dir);
+ }
+ else if(nb_found==1) {
+ set_directory(dir);
+ }
+ else {
+ printf("Too many directory\n");
+ }
+ amfree(dir);
+}
+
+void
+set_directory(
+ char * dir)
+{
+ char *cmd = NULL;
+ char *new_dir = NULL;
+ char *dp, *de;
+ char *ldir = NULL;
+
+ /* do nothing if "." */
+ if(strcmp(dir,".")==0) {
+ show_directory(); /* say where we are */
+ return;
+ /*NOTREACHED*/
+ }
+
+ if (disk_name == NULL) {
+ printf("Must select disk before setting directory\n");
+ return;
+ /*NOTREACHED*/
+ }
+
+ ldir = stralloc(dir);
+ clean_pathname(ldir);
+
+ /* convert directory into absolute path relative to disk mount point */
+ if (ldir[0] == '/')
+ {
+ /* absolute path specified, must start with mount point */
+ if (strcmp(mount_point, "/") == 0)
+ {
+ new_dir = stralloc(ldir);
+ }
+ else
+ {
+ if (strncmp(mount_point, ldir, strlen(mount_point)) != 0)
+ {
+ printf("Invalid directory - Can't cd outside mount point \"%s\"\n",
+ mount_point);
+ amfree(ldir);
+ return;
+ /*NOTREACHED*/
+ }
+ new_dir = stralloc(ldir+strlen(mount_point));
+ if (strlen(new_dir) == 0) {
+ new_dir = newstralloc(new_dir, "/");
+ /* i.e. ldir == mount_point */
+ }
+ }
+ }
+ else
+ {
+ new_dir = stralloc(disk_path);
+ dp = ldir;
+ /* strip any leading ..s */
+ while (strncmp(dp, "../", 3) == 0)
+ {
+ de = strrchr(new_dir, '/'); /* always at least 1 */
+ if (de == new_dir)
+ {
+ /* at top of disk */
+ *(de + 1) = '\0';
+ dp = dp + 3;
+ }
+ else
+ {
+ *de = '\0';
+ dp = dp + 3;
+ }
+ }
+ if (strcmp(dp, "..") == 0) {
+ if (strcmp(new_dir, "/") == 0) {
+ /* at top of disk */
+ printf("Invalid directory - Can't cd outside mount point \"%s\"\n",
+ mount_point);
+ /*@ignore@*/
+ amfree(new_dir);
+ /*@end@*/
+ amfree(ldir);
+ return;
+ /*NOTREACHED*/
+ }
+ de = strrchr(new_dir, '/'); /* always at least 1 */
+ if (de == new_dir)
+ {
+ /* at top of disk */
+ *(de+1) = '\0';
+ }
+ else
+ {
+ *de = '\0';
+ }
+ } else {
+ /*@ignore@*/
+ if (strcmp(new_dir, "/") != 0) {
+ strappend(new_dir, "/");
+ }
+ strappend(new_dir, ldir);
+ /*@end@*/
+ }
+ }
+
+ cmd = stralloc2("OISD ", new_dir);
+ if (exchange(cmd) == -1) {
+ exit(1);
+ /*NOTREACHED*/
+ }
+ amfree(cmd);
+
+ if (server_happy())
+ {
+ disk_path = newstralloc(disk_path, new_dir);
+ suck_dir_list_from_server(); /* get list of directory contents */
+ show_directory(); /* say where we moved to */
+ }
+ else
+ {
+ printf("Invalid directory - %s\n", dir);
+ }
+
+ /*@ignore@*/
+ amfree(new_dir);
+ amfree(ldir);
+ /*@end@*/
+}
+
+
+/* prints the current working directory */
+void
+show_directory(void)
+{
+ if (mount_point == NULL || disk_path == NULL)
+ printf("Must select disk first\n");
+ else if (strcmp(mount_point, "/") == 0)
+ printf("%s\n", disk_path);
+ else if (strcmp(disk_path, "/") == 0)
+ printf("%s\n", mount_point);
+ else
+ printf("%s%s\n", mount_point, disk_path);
+}
+
+
+/* set the tape server and device */
+void
+set_tape(
+ char * tape)
+{
+ char *tapedev = strchr(tape, ':');
+
+ if (tapedev)
+ {
+ if (tapedev != tape) {
+ if((strchr(tapedev+1, ':') == NULL) &&
+ (strncmp(tape, "null:", 5) == 0 ||
+ strncmp(tape, "rait:", 5) == 0 ||
+ strncmp(tape, "file:", 5) == 0 ||
+ strncmp(tape, "tape:", 5) == 0)) {
+ tapedev = tape;
+ }
+ else {
+ *tapedev = '\0';
+ tape_server_name = newstralloc(tape_server_name, tape);
+ ++tapedev;
+ }
+ } else { /* reset server_name if start with : */
+ amfree(tape_server_name);
+ ++tapedev;
+ }
+ } else
+ tapedev = tape;
+
+ if (tapedev[0])
+ {
+ if (strcmp(tapedev, "default") == 0)
+ amfree(tape_device_name);
+ else
+ tape_device_name = newstralloc(tape_device_name, tapedev);
+ }
+
+ if (tape_device_name)
+ printf ("Using tape \"%s\"", tape_device_name);
+ else
+ printf ("Using default tape");
+
+ if (tape_server_name)
+ printf (" from server %s.\n", tape_server_name);
+ else
+ printf (".\nTape server unspecified, assumed to be %s.\n",
+ server_name);
+}
+
+void
+set_mode(
+ int mode)
+{
+#ifdef SAMBA_CLIENT
+ if (mode == SAMBA_SMBCLIENT) {
+ printf ("SAMBA dumps will be extracted using smbclient\n");
+ samba_extract_method = SAMBA_SMBCLIENT;
+ } else {
+ if (mode == SAMBA_TAR) {
+ printf ("SAMBA dumps will be extracted as TAR dumps\n");
+ samba_extract_method = SAMBA_TAR;
+ }
+ }
+#else
+ (void)mode; /* Quiet unused parameter warning */
+#endif /* SAMBA_CLIENT */
+}
+
+void
+show_mode(void)
+{
+#ifdef SAMBA_CLIENT
+ printf ("SAMBA dumps are extracted ");
+
+ if (samba_extract_method == SAMBA_TAR) {
+ printf (" as TAR dumps\n");
+ } else {
+ printf ("using smbclient\n");
+ }
+#endif /* SAMBA_CLIENT */
+}
--- /dev/null
+/* A Bison parser, made by GNU Bison 2.1. */
+
+/* Skeleton parser for Yacc-like parsing with Bison,
+ Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ 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., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA. */
+
+/* As a special exception, when this file is copied by Bison into a
+ Bison output file, you may use that output file without restriction.
+ This special exception was added by the Free Software Foundation
+ in version 1.24 of Bison. */
+
+/* Written by Richard Stallman by simplifying the original so called
+ ``semantic'' parser. */
+
+/* All symbols defined below should begin with yy or YY, to avoid
+ infringing on user name space. This should be done even for local
+ variables, as they might otherwise be expanded by user macros.
+ There are some unavoidable exceptions within include files to
+ define necessary library symbols; they are noted "INFRINGES ON
+ USER NAME SPACE" below. */
+
+/* Identify Bison output. */
+#define YYBISON 1
+
+/* Bison version. */
+#define YYBISON_VERSION "2.1"
+
+/* Skeleton name. */
+#define YYSKELETON_NAME "yacc.c"
+
+/* Pure parsers. */
+#define YYPURE 0
+
+/* Using locations. */
+#define YYLSP_NEEDED 0
+
+
+
+/* Tokens. */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+ /* Put the tokens into the symbol table, so that GDB and other debuggers
+ know about them. */
+ enum yytokentype {
+ LISTHOST = 258,
+ LISTDISK = 259,
+ SETHOST = 260,
+ SETDISK = 261,
+ SETDATE = 262,
+ SETTAPE = 263,
+ SETMODE = 264,
+ CD = 265,
+ CDX = 266,
+ QUIT = 267,
+ DHIST = 268,
+ LS = 269,
+ ADD = 270,
+ ADDX = 271,
+ EXTRACT = 272,
+ LIST = 273,
+ DELETE = 274,
+ DELETEX = 275,
+ PWD = 276,
+ CLEAR = 277,
+ HELP = 278,
+ LCD = 279,
+ LPWD = 280,
+ MODE = 281,
+ SMB = 282,
+ TAR = 283,
+ PATH = 284,
+ DATE = 285
+ };
+#endif
+/* Tokens. */
+#define LISTHOST 258
+#define LISTDISK 259
+#define SETHOST 260
+#define SETDISK 261
+#define SETDATE 262
+#define SETTAPE 263
+#define SETMODE 264
+#define CD 265
+#define CDX 266
+#define QUIT 267
+#define DHIST 268
+#define LS 269
+#define ADD 270
+#define ADDX 271
+#define EXTRACT 272
+#define LIST 273
+#define DELETE 274
+#define DELETEX 275
+#define PWD 276
+#define CLEAR 277
+#define HELP 278
+#define LCD 279
+#define LPWD 280
+#define MODE 281
+#define SMB 282
+#define TAR 283
+#define PATH 284
+#define DATE 285
+
+
+
+
+/* Copy the first part of user declarations. */
+#line 31 "uparse.y"
+
+#include "amanda.h"
+#include "amrecover.h"
+
+void yyerror(char *s);
+extern int yylex(void);
+extern char * yytext;
+
+
+
+/* Enabling traces. */
+#ifndef YYDEBUG
+# define YYDEBUG 0
+#endif
+
+/* Enabling verbose error messages. */
+#ifdef YYERROR_VERBOSE
+# undef YYERROR_VERBOSE
+# define YYERROR_VERBOSE 1
+#else
+# define YYERROR_VERBOSE 0
+#endif
+
+/* Enabling the token table. */
+#ifndef YYTOKEN_TABLE
+# define YYTOKEN_TABLE 0
+#endif
+
+#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
+#line 42 "uparse.y"
+typedef union YYSTYPE {
+ int intval;
+ double floatval;
+ char * strval;
+ int subtok;
+} YYSTYPE;
+/* Line 196 of yacc.c. */
+#line 162 "uparse.c"
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
+# define YYSTYPE_IS_TRIVIAL 1
+#endif
+
+
+
+/* Copy the second part of user declarations. */
+
+
+/* Line 219 of yacc.c. */
+#line 174 "uparse.c"
+
+#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__)
+# define YYSIZE_T __SIZE_TYPE__
+#endif
+#if ! defined (YYSIZE_T) && defined (size_t)
+# define YYSIZE_T size_t
+#endif
+#if ! defined (YYSIZE_T) && (defined (__STDC__) || defined (__cplusplus))
+# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
+# define YYSIZE_T size_t
+#endif
+#if ! defined (YYSIZE_T)
+# define YYSIZE_T unsigned int
+#endif
+
+#ifndef YY_
+# if YYENABLE_NLS
+# if ENABLE_NLS
+# include <libintl.h> /* INFRINGES ON USER NAME SPACE */
+# define YY_(msgid) dgettext ("bison-runtime", msgid)
+# endif
+# endif
+# ifndef YY_
+# define YY_(msgid) msgid
+# endif
+#endif
+
+#if ! defined (yyoverflow) || YYERROR_VERBOSE
+
+/* The parser invokes alloca or malloc; define the necessary symbols. */
+
+# ifdef YYSTACK_USE_ALLOCA
+# if YYSTACK_USE_ALLOCA
+# ifdef __GNUC__
+# define YYSTACK_ALLOC __builtin_alloca
+# else
+# define YYSTACK_ALLOC alloca
+# if defined (__STDC__) || defined (__cplusplus)
+# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+# define YYINCLUDED_STDLIB_H
+# endif
+# endif
+# endif
+# endif
+
+# ifdef YYSTACK_ALLOC
+ /* Pacify GCC's `empty if-body' warning. */
+# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
+# ifndef YYSTACK_ALLOC_MAXIMUM
+ /* The OS might guarantee only one guard page at the bottom of the stack,
+ and a page size can be as small as 4096 bytes. So we cannot safely
+ invoke alloca (N) if N exceeds 4096. Use a slightly smaller number
+ to allow for a few compiler-allocated temporary stack slots. */
+# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2005 */
+# endif
+# else
+# define YYSTACK_ALLOC YYMALLOC
+# define YYSTACK_FREE YYFREE
+# ifndef YYSTACK_ALLOC_MAXIMUM
+# define YYSTACK_ALLOC_MAXIMUM ((YYSIZE_T) -1)
+# endif
+# ifdef __cplusplus
+extern "C" {
+# endif
+# ifndef YYMALLOC
+# define YYMALLOC malloc
+# if (! defined (malloc) && ! defined (YYINCLUDED_STDLIB_H) \
+ && (defined (__STDC__) || defined (__cplusplus)))
+void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
+# endif
+# endif
+# ifndef YYFREE
+# define YYFREE free
+# if (! defined (free) && ! defined (YYINCLUDED_STDLIB_H) \
+ && (defined (__STDC__) || defined (__cplusplus)))
+void free (void *); /* INFRINGES ON USER NAME SPACE */
+# endif
+# endif
+# ifdef __cplusplus
+}
+# endif
+# endif
+#endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */
+
+
+#if (! defined (yyoverflow) \
+ && (! defined (__cplusplus) \
+ || (defined (YYSTYPE_IS_TRIVIAL) && YYSTYPE_IS_TRIVIAL)))
+
+/* A type that is properly aligned for any stack member. */
+union yyalloc
+{
+ short int yyss;
+ YYSTYPE yyvs;
+ };
+
+/* The size of the maximum gap between one aligned stack and the next. */
+# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
+
+/* The size of an array large to enough to hold all stacks, each with
+ N elements. */
+# define YYSTACK_BYTES(N) \
+ ((N) * (sizeof (short int) + sizeof (YYSTYPE)) \
+ + YYSTACK_GAP_MAXIMUM)
+
+/* Copy COUNT objects from FROM to TO. The source and destination do
+ not overlap. */
+# ifndef YYCOPY
+# if defined (__GNUC__) && 1 < __GNUC__
+# define YYCOPY(To, From, Count) \
+ __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
+# else
+# define YYCOPY(To, From, Count) \
+ do \
+ { \
+ YYSIZE_T yyi; \
+ for (yyi = 0; yyi < (Count); yyi++) \
+ (To)[yyi] = (From)[yyi]; \
+ } \
+ while (0)
+# endif
+# endif
+
+/* Relocate STACK from its old location to the new one. The
+ local variables YYSIZE and YYSTACKSIZE give the old and new number of
+ elements in the stack, and YYPTR gives the new location of the
+ stack. Advance YYPTR to a properly aligned location for the next
+ stack. */
+# define YYSTACK_RELOCATE(Stack) \
+ do \
+ { \
+ YYSIZE_T yynewbytes; \
+ YYCOPY (&yyptr->Stack, Stack, yysize); \
+ Stack = &yyptr->Stack; \
+ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
+ yyptr += yynewbytes / sizeof (*yyptr); \
+ } \
+ while (0)
+
+#endif
+
+#if defined (__STDC__) || defined (__cplusplus)
+ typedef signed char yysigned_char;
+#else
+ typedef short int yysigned_char;
+#endif
+
+/* YYFINAL -- State number of the termination state. */
+#define YYFINAL 55
+/* YYLAST -- Last index in YYTABLE. */
+#define YYLAST 45
+
+/* YYNTOKENS -- Number of terminals. */
+#define YYNTOKENS 31
+/* YYNNTS -- Number of nonterminals. */
+#define YYNNTS 16
+/* YYNRULES -- Number of rules. */
+#define YYNRULES 49
+/* YYNRULES -- Number of states. */
+#define YYNSTATES 61
+
+/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
+#define YYUNDEFTOK 2
+#define YYMAXUTOK 285
+
+#define YYTRANSLATE(YYX) \
+ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
+
+/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */
+static const unsigned char yytranslate[] =
+{
+ 0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
+ 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
+ 25, 26, 27, 28, 29, 30
+};
+
+#if YYDEBUG
+/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
+ YYRHS. */
+static const unsigned char yyprhs[] =
+{
+ 0, 0, 3, 5, 7, 9, 11, 13, 15, 17,
+ 19, 21, 23, 24, 26, 29, 31, 34, 37, 41,
+ 44, 47, 49, 52, 55, 58, 61, 63, 65, 68,
+ 70, 72, 74, 76, 78, 81, 84, 86, 89, 92,
+ 94, 97, 100, 102, 105, 108, 110, 112, 115, 117
+};
+
+/* YYRHS -- A `-1'-separated list of the rules' RHS. */
+static const yysigned_char yyrhs[] =
+{
+ 32, 0, -1, 33, -1, 34, -1, 35, -1, 36,
+ -1, 38, -1, 40, -1, 42, -1, 44, -1, 45,
+ -1, 46, -1, -1, 3, -1, 4, 29, -1, 4,
+ -1, 7, 30, -1, 5, 29, -1, 6, 29, 29,
+ -1, 6, 29, -1, 8, 29, -1, 8, -1, 10,
+ 29, -1, 11, 29, -1, 9, 27, -1, 9, 28,
+ -1, 13, -1, 14, -1, 18, 29, -1, 18, -1,
+ 21, -1, 22, -1, 26, -1, 12, -1, 15, 37,
+ -1, 37, 29, -1, 29, -1, 16, 39, -1, 39,
+ 29, -1, 29, -1, 19, 41, -1, 41, 29, -1,
+ 29, -1, 20, 43, -1, 43, 29, -1, 29, -1,
+ 25, -1, 24, 29, -1, 23, -1, 17, -1
+};
+
+/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
+static const unsigned char yyrline[] =
+{
+ 0, 65, 65, 66, 67, 68, 69, 70, 71, 72,
+ 73, 74, 75, 84, 85, 86, 87, 88, 89, 90,
+ 91, 92, 93, 94, 95, 100, 108, 109, 110, 111,
+ 112, 113, 114, 118, 122, 126, 127, 131, 135, 136,
+ 140, 144, 145, 149, 153, 154, 158, 159, 168, 172
+};
+#endif
+
+#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE
+/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
+ First, the terminals, then, starting at YYNTOKENS, nonterminals. */
+static const char *const yytname[] =
+{
+ "$end", "error", "$undefined", "LISTHOST", "LISTDISK", "SETHOST",
+ "SETDISK", "SETDATE", "SETTAPE", "SETMODE", "CD", "CDX", "QUIT", "DHIST",
+ "LS", "ADD", "ADDX", "EXTRACT", "LIST", "DELETE", "DELETEX", "PWD",
+ "CLEAR", "HELP", "LCD", "LPWD", "MODE", "SMB", "TAR", "PATH", "DATE",
+ "$accept", "ucommand", "set_command", "display_command", "quit_command",
+ "add_command", "add_path", "addx_command", "addx_path", "delete_command",
+ "delete_path", "deletex_command", "deletex_path", "local_command",
+ "help_command", "extract_command", 0
+};
+#endif
+
+# ifdef YYPRINT
+/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
+ token YYLEX-NUM. */
+static const unsigned short int yytoknum[] =
+{
+ 0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
+ 265, 266, 267, 268, 269, 270, 271, 272, 273, 274,
+ 275, 276, 277, 278, 279, 280, 281, 282, 283, 284,
+ 285
+};
+# endif
+
+/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
+static const unsigned char yyr1[] =
+{
+ 0, 31, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 33, 33, 33, 33, 33, 33, 33,
+ 33, 33, 33, 33, 33, 33, 34, 34, 34, 34,
+ 34, 34, 34, 35, 36, 37, 37, 38, 39, 39,
+ 40, 41, 41, 42, 43, 43, 44, 44, 45, 46
+};
+
+/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
+static const unsigned char yyr2[] =
+{
+ 0, 2, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 0, 1, 2, 1, 2, 2, 3, 2,
+ 2, 1, 2, 2, 2, 2, 1, 1, 2, 1,
+ 1, 1, 1, 1, 2, 2, 1, 2, 2, 1,
+ 2, 2, 1, 2, 2, 1, 1, 2, 1, 1
+};
+
+/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
+ STATE-NUM when YYTABLE doesn't specify something else to do. Zero
+ means the default is an error. */
+static const unsigned char yydefact[] =
+{
+ 12, 13, 15, 0, 0, 0, 21, 0, 0, 0,
+ 33, 26, 27, 0, 0, 49, 29, 0, 0, 30,
+ 31, 48, 0, 46, 32, 0, 2, 3, 4, 5,
+ 6, 7, 8, 9, 10, 11, 14, 17, 19, 16,
+ 20, 24, 25, 22, 23, 36, 34, 39, 37, 28,
+ 42, 40, 45, 43, 47, 1, 18, 35, 38, 41,
+ 44
+};
+
+/* YYDEFGOTO[NTERM-NUM]. */
+static const yysigned_char yydefgoto[] =
+{
+ -1, 25, 26, 27, 28, 29, 46, 30, 48, 31,
+ 51, 32, 53, 33, 34, 35
+};
+
+/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
+ STATE-NUM. */
+#define YYPACT_NINF -6
+static const yysigned_char yypact[] =
+{
+ -3, -6, -5, -1, 0, 1, 3, -2, 4, 5,
+ -6, -6, -6, 6, 7, -6, 8, 9, 10, -6,
+ -6, -6, 11, -6, -6, 27, -6, -6, -6, -6,
+ -6, -6, -6, -6, -6, -6, -6, -6, 12, -6,
+ -6, -6, -6, -6, -6, -6, 13, -6, 14, -6,
+ -6, 15, -6, 16, -6, -6, -6, -6, -6, -6,
+ -6
+};
+
+/* YYPGOTO[NTERM-NUM]. */
+static const yysigned_char yypgoto[] =
+{
+ -6, -6, -6, -6, -6, -6, -6, -6, -6, -6,
+ -6, -6, -6, -6, -6, -6
+};
+
+/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
+ positive, shift that token. If negative, reduce the rule which
+ number is the opposite. If zero, do what YYDEFACT says.
+ If YYTABLE_NINF, syntax error. */
+#define YYTABLE_NINF -1
+static const unsigned char yytable[] =
+{
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
+ 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
+ 21, 22, 23, 24, 36, 41, 42, 55, 37, 38,
+ 0, 39, 40, 43, 44, 45, 47, 49, 50, 52,
+ 54, 56, 57, 58, 59, 60
+};
+
+static const yysigned_char yycheck[] =
+{
+ 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
+ 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
+ 23, 24, 25, 26, 29, 27, 28, 0, 29, 29,
+ -1, 30, 29, 29, 29, 29, 29, 29, 29, 29,
+ 29, 29, 29, 29, 29, 29
+};
+
+/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
+ symbol of state STATE-NUM. */
+static const unsigned char yystos[] =
+{
+ 0, 3, 4, 5, 6, 7, 8, 9, 10, 11,
+ 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
+ 22, 23, 24, 25, 26, 32, 33, 34, 35, 36,
+ 38, 40, 42, 44, 45, 46, 29, 29, 29, 30,
+ 29, 27, 28, 29, 29, 29, 37, 29, 39, 29,
+ 29, 41, 29, 43, 29, 0, 29, 29, 29, 29,
+ 29
+};
+
+#define yyerrok (yyerrstatus = 0)
+#define yyclearin (yychar = YYEMPTY)
+#define YYEMPTY (-2)
+#define YYEOF 0
+
+#define YYACCEPT goto yyacceptlab
+#define YYABORT goto yyabortlab
+#define YYERROR goto yyerrorlab
+
+
+/* Like YYERROR except do call yyerror. This remains here temporarily
+ to ease the transition to the new meaning of YYERROR, for GCC.
+ Once GCC version 2 has supplanted version 1, this can go. */
+
+#define YYFAIL goto yyerrlab
+
+#define YYRECOVERING() (!!yyerrstatus)
+
+#define YYBACKUP(Token, Value) \
+do \
+ if (yychar == YYEMPTY && yylen == 1) \
+ { \
+ yychar = (Token); \
+ yylval = (Value); \
+ yytoken = YYTRANSLATE (yychar); \
+ YYPOPSTACK; \
+ goto yybackup; \
+ } \
+ else \
+ { \
+ yyerror (YY_("syntax error: cannot back up")); \
+ YYERROR; \
+ } \
+while (0)
+
+
+#define YYTERROR 1
+#define YYERRCODE 256
+
+
+/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
+ If N is 0, then set CURRENT to the empty location which ends
+ the previous symbol: RHS[0] (always defined). */
+
+#define YYRHSLOC(Rhs, K) ((Rhs)[K])
+#ifndef YYLLOC_DEFAULT
+# define YYLLOC_DEFAULT(Current, Rhs, N) \
+ do \
+ if (N) \
+ { \
+ (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \
+ (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \
+ (Current).last_line = YYRHSLOC (Rhs, N).last_line; \
+ (Current).last_column = YYRHSLOC (Rhs, N).last_column; \
+ } \
+ else \
+ { \
+ (Current).first_line = (Current).last_line = \
+ YYRHSLOC (Rhs, 0).last_line; \
+ (Current).first_column = (Current).last_column = \
+ YYRHSLOC (Rhs, 0).last_column; \
+ } \
+ while (0)
+#endif
+
+
+/* YY_LOCATION_PRINT -- Print the location on the stream.
+ This macro was not mandated originally: define only if we know
+ we won't break user code: when these are the locations we know. */
+
+#ifndef YY_LOCATION_PRINT
+# if YYLTYPE_IS_TRIVIAL
+# define YY_LOCATION_PRINT(File, Loc) \
+ fprintf (File, "%d.%d-%d.%d", \
+ (Loc).first_line, (Loc).first_column, \
+ (Loc).last_line, (Loc).last_column)
+# else
+# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
+# endif
+#endif
+
+
+/* YYLEX -- calling `yylex' with the right arguments. */
+
+#ifdef YYLEX_PARAM
+# define YYLEX yylex (YYLEX_PARAM)
+#else
+# define YYLEX yylex ()
+#endif
+
+/* Enable debugging if requested. */
+#if YYDEBUG
+
+# ifndef YYFPRINTF
+# include <stdio.h> /* INFRINGES ON USER NAME SPACE */
+# define YYFPRINTF fprintf
+# endif
+
+# define YYDPRINTF(Args) \
+do { \
+ if (yydebug) \
+ YYFPRINTF Args; \
+} while (0)
+
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \
+do { \
+ if (yydebug) \
+ { \
+ YYFPRINTF (stderr, "%s ", Title); \
+ yysymprint (stderr, \
+ Type, Value); \
+ YYFPRINTF (stderr, "\n"); \
+ } \
+} while (0)
+
+/*------------------------------------------------------------------.
+| yy_stack_print -- Print the state stack from its BOTTOM up to its |
+| TOP (included). |
+`------------------------------------------------------------------*/
+
+#if defined (__STDC__) || defined (__cplusplus)
+static void
+yy_stack_print (short int *bottom, short int *top)
+#else
+static void
+yy_stack_print (bottom, top)
+ short int *bottom;
+ short int *top;
+#endif
+{
+ YYFPRINTF (stderr, "Stack now");
+ for (/* Nothing. */; bottom <= top; ++bottom)
+ YYFPRINTF (stderr, " %d", *bottom);
+ YYFPRINTF (stderr, "\n");
+}
+
+# define YY_STACK_PRINT(Bottom, Top) \
+do { \
+ if (yydebug) \
+ yy_stack_print ((Bottom), (Top)); \
+} while (0)
+
+
+/*------------------------------------------------.
+| Report that the YYRULE is going to be reduced. |
+`------------------------------------------------*/
+
+#if defined (__STDC__) || defined (__cplusplus)
+static void
+yy_reduce_print (int yyrule)
+#else
+static void
+yy_reduce_print (yyrule)
+ int yyrule;
+#endif
+{
+ int yyi;
+ unsigned long int yylno = yyrline[yyrule];
+ YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu), ",
+ yyrule - 1, yylno);
+ /* Print the symbols being reduced, and their result. */
+ for (yyi = yyprhs[yyrule]; 0 <= yyrhs[yyi]; yyi++)
+ YYFPRINTF (stderr, "%s ", yytname[yyrhs[yyi]]);
+ YYFPRINTF (stderr, "-> %s\n", yytname[yyr1[yyrule]]);
+}
+
+# define YY_REDUCE_PRINT(Rule) \
+do { \
+ if (yydebug) \
+ yy_reduce_print (Rule); \
+} while (0)
+
+/* Nonzero means print parse trace. It is left uninitialized so that
+ multiple parsers can coexist. */
+int yydebug;
+#else /* !YYDEBUG */
+# define YYDPRINTF(Args)
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location)
+# define YY_STACK_PRINT(Bottom, Top)
+# define YY_REDUCE_PRINT(Rule)
+#endif /* !YYDEBUG */
+
+
+/* YYINITDEPTH -- initial size of the parser's stacks. */
+#ifndef YYINITDEPTH
+# define YYINITDEPTH 200
+#endif
+
+/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
+ if the built-in stack extension method is used).
+
+ Do not make this value too large; the results are undefined if
+ YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)
+ evaluated with infinite-precision integer arithmetic. */
+
+#ifndef YYMAXDEPTH
+# define YYMAXDEPTH 10000
+#endif
+
+\f
+
+#if YYERROR_VERBOSE
+
+# ifndef yystrlen
+# if defined (__GLIBC__) && defined (_STRING_H)
+# define yystrlen strlen
+# else
+/* Return the length of YYSTR. */
+static YYSIZE_T
+# if defined (__STDC__) || defined (__cplusplus)
+yystrlen (const char *yystr)
+# else
+yystrlen (yystr)
+ const char *yystr;
+# endif
+{
+ const char *yys = yystr;
+
+ while (*yys++ != '\0')
+ continue;
+
+ return yys - yystr - 1;
+}
+# endif
+# endif
+
+# ifndef yystpcpy
+# if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE)
+# define yystpcpy stpcpy
+# else
+/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
+ YYDEST. */
+static char *
+# if defined (__STDC__) || defined (__cplusplus)
+yystpcpy (char *yydest, const char *yysrc)
+# else
+yystpcpy (yydest, yysrc)
+ char *yydest;
+ const char *yysrc;
+# endif
+{
+ char *yyd = yydest;
+ const char *yys = yysrc;
+
+ while ((*yyd++ = *yys++) != '\0')
+ continue;
+
+ return yyd - 1;
+}
+# endif
+# endif
+
+# ifndef yytnamerr
+/* Copy to YYRES the contents of YYSTR after stripping away unnecessary
+ quotes and backslashes, so that it's suitable for yyerror. The
+ heuristic is that double-quoting is unnecessary unless the string
+ contains an apostrophe, a comma, or backslash (other than
+ backslash-backslash). YYSTR is taken from yytname. If YYRES is
+ null, do not copy; instead, return the length of what the result
+ would have been. */
+static YYSIZE_T
+yytnamerr (char *yyres, const char *yystr)
+{
+ if (*yystr == '"')
+ {
+ size_t yyn = 0;
+ char const *yyp = yystr;
+
+ for (;;)
+ switch (*++yyp)
+ {
+ case '\'':
+ case ',':
+ goto do_not_strip_quotes;
+
+ case '\\':
+ if (*++yyp != '\\')
+ goto do_not_strip_quotes;
+ /* Fall through. */
+ default:
+ if (yyres)
+ yyres[yyn] = *yyp;
+ yyn++;
+ break;
+
+ case '"':
+ if (yyres)
+ yyres[yyn] = '\0';
+ return yyn;
+ }
+ do_not_strip_quotes: ;
+ }
+
+ if (! yyres)
+ return yystrlen (yystr);
+
+ return yystpcpy (yyres, yystr) - yyres;
+}
+# endif
+
+#endif /* YYERROR_VERBOSE */
+
+\f
+
+#if YYDEBUG
+/*--------------------------------.
+| Print this symbol on YYOUTPUT. |
+`--------------------------------*/
+
+#if defined (__STDC__) || defined (__cplusplus)
+static void
+yysymprint (FILE *yyoutput, int yytype, YYSTYPE *yyvaluep)
+#else
+static void
+yysymprint (yyoutput, yytype, yyvaluep)
+ FILE *yyoutput;
+ int yytype;
+ YYSTYPE *yyvaluep;
+#endif
+{
+ /* Pacify ``unused variable'' warnings. */
+ (void) yyvaluep;
+
+ if (yytype < YYNTOKENS)
+ YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
+ else
+ YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
+
+
+# ifdef YYPRINT
+ if (yytype < YYNTOKENS)
+ YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
+# endif
+ switch (yytype)
+ {
+ default:
+ break;
+ }
+ YYFPRINTF (yyoutput, ")");
+}
+
+#endif /* ! YYDEBUG */
+/*-----------------------------------------------.
+| Release the memory associated to this symbol. |
+`-----------------------------------------------*/
+
+#if defined (__STDC__) || defined (__cplusplus)
+static void
+yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep)
+#else
+static void
+yydestruct (yymsg, yytype, yyvaluep)
+ const char *yymsg;
+ int yytype;
+ YYSTYPE *yyvaluep;
+#endif
+{
+ /* Pacify ``unused variable'' warnings. */
+ (void) yyvaluep;
+
+ if (!yymsg)
+ yymsg = "Deleting";
+ YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
+
+ switch (yytype)
+ {
+
+ default:
+ break;
+ }
+}
+\f
+
+/* Prevent warnings from -Wmissing-prototypes. */
+
+#ifdef YYPARSE_PARAM
+# if defined (__STDC__) || defined (__cplusplus)
+int yyparse (void *YYPARSE_PARAM);
+# else
+int yyparse ();
+# endif
+#else /* ! YYPARSE_PARAM */
+#if defined (__STDC__) || defined (__cplusplus)
+int yyparse (void);
+#else
+int yyparse ();
+#endif
+#endif /* ! YYPARSE_PARAM */
+
+
+
+/* The look-ahead symbol. */
+int yychar;
+
+/* The semantic value of the look-ahead symbol. */
+YYSTYPE yylval;
+
+/* Number of syntax errors so far. */
+int yynerrs;
+
+
+
+/*----------.
+| yyparse. |
+`----------*/
+
+#ifdef YYPARSE_PARAM
+# if defined (__STDC__) || defined (__cplusplus)
+int yyparse (void *YYPARSE_PARAM)
+# else
+int yyparse (YYPARSE_PARAM)
+ void *YYPARSE_PARAM;
+# endif
+#else /* ! YYPARSE_PARAM */
+#if defined (__STDC__) || defined (__cplusplus)
+int
+yyparse (void)
+#else
+int
+yyparse ()
+
+#endif
+#endif
+{
+
+ int yystate;
+ int yyn;
+ int yyresult;
+ /* Number of tokens to shift before error messages enabled. */
+ int yyerrstatus;
+ /* Look-ahead token as an internal (translated) token number. */
+ int yytoken = 0;
+
+ /* Three stacks and their tools:
+ `yyss': related to states,
+ `yyvs': related to semantic values,
+ `yyls': related to locations.
+
+ Refer to the stacks thru separate pointers, to allow yyoverflow
+ to reallocate them elsewhere. */
+
+ /* The state stack. */
+ short int yyssa[YYINITDEPTH];
+ short int *yyss = yyssa;
+ short int *yyssp;
+
+ /* The semantic value stack. */
+ YYSTYPE yyvsa[YYINITDEPTH];
+ YYSTYPE *yyvs = yyvsa;
+ YYSTYPE *yyvsp;
+
+
+
+#define YYPOPSTACK (yyvsp--, yyssp--)
+
+ YYSIZE_T yystacksize = YYINITDEPTH;
+
+ /* The variables used to return semantic value and location from the
+ action routines. */
+ YYSTYPE yyval;
+
+
+ /* When reducing, the number of symbols on the RHS of the reduced
+ rule. */
+ int yylen;
+
+ YYDPRINTF ((stderr, "Starting parse\n"));
+
+ yystate = 0;
+ yyerrstatus = 0;
+ yynerrs = 0;
+ yychar = YYEMPTY; /* Cause a token to be read. */
+
+ /* Initialize stack pointers.
+ Waste one element of value and location stack
+ so that they stay on the same level as the state stack.
+ The wasted elements are never initialized. */
+
+ yyssp = yyss;
+ yyvsp = yyvs;
+
+ goto yysetstate;
+
+/*------------------------------------------------------------.
+| yynewstate -- Push a new state, which is found in yystate. |
+`------------------------------------------------------------*/
+ yynewstate:
+ /* In all cases, when you get here, the value and location stacks
+ have just been pushed. so pushing a state here evens the stacks.
+ */
+ yyssp++;
+
+ yysetstate:
+ *yyssp = yystate;
+
+ if (yyss + yystacksize - 1 <= yyssp)
+ {
+ /* Get the current used size of the three stacks, in elements. */
+ YYSIZE_T yysize = yyssp - yyss + 1;
+
+#ifdef yyoverflow
+ {
+ /* Give user a chance to reallocate the stack. Use copies of
+ these so that the &'s don't force the real ones into
+ memory. */
+ YYSTYPE *yyvs1 = yyvs;
+ short int *yyss1 = yyss;
+
+
+ /* Each stack pointer address is followed by the size of the
+ data in use in that stack, in bytes. This used to be a
+ conditional around just the two extra args, but that might
+ be undefined if yyoverflow is a macro. */
+ yyoverflow (YY_("memory exhausted"),
+ &yyss1, yysize * sizeof (*yyssp),
+ &yyvs1, yysize * sizeof (*yyvsp),
+
+ &yystacksize);
+
+ yyss = yyss1;
+ yyvs = yyvs1;
+ }
+#else /* no yyoverflow */
+# ifndef YYSTACK_RELOCATE
+ goto yyexhaustedlab;
+# else
+ /* Extend the stack our own way. */
+ if (YYMAXDEPTH <= yystacksize)
+ goto yyexhaustedlab;
+ yystacksize *= 2;
+ if (YYMAXDEPTH < yystacksize)
+ yystacksize = YYMAXDEPTH;
+
+ {
+ short int *yyss1 = yyss;
+ union yyalloc *yyptr =
+ (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
+ if (! yyptr)
+ goto yyexhaustedlab;
+ YYSTACK_RELOCATE (yyss);
+ YYSTACK_RELOCATE (yyvs);
+
+# undef YYSTACK_RELOCATE
+ if (yyss1 != yyssa)
+ YYSTACK_FREE (yyss1);
+ }
+# endif
+#endif /* no yyoverflow */
+
+ yyssp = yyss + yysize - 1;
+ yyvsp = yyvs + yysize - 1;
+
+
+ YYDPRINTF ((stderr, "Stack size increased to %lu\n",
+ (unsigned long int) yystacksize));
+
+ if (yyss + yystacksize - 1 <= yyssp)
+ YYABORT;
+ }
+
+ YYDPRINTF ((stderr, "Entering state %d\n", yystate));
+
+ goto yybackup;
+
+/*-----------.
+| yybackup. |
+`-----------*/
+yybackup:
+
+/* Do appropriate processing given the current state. */
+/* Read a look-ahead token if we need one and don't already have one. */
+/* yyresume: */
+
+ /* First try to decide what to do without reference to look-ahead token. */
+
+ yyn = yypact[yystate];
+ if (yyn == YYPACT_NINF)
+ goto yydefault;
+
+ /* Not known => get a look-ahead token if don't already have one. */
+
+ /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */
+ if (yychar == YYEMPTY)
+ {
+ YYDPRINTF ((stderr, "Reading a token: "));
+ yychar = YYLEX;
+ }
+
+ if (yychar <= YYEOF)
+ {
+ yychar = yytoken = YYEOF;
+ YYDPRINTF ((stderr, "Now at end of input.\n"));
+ }
+ else
+ {
+ yytoken = YYTRANSLATE (yychar);
+ YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
+ }
+
+ /* If the proper action on seeing token YYTOKEN is to reduce or to
+ detect an error, take that action. */
+ yyn += yytoken;
+ if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
+ goto yydefault;
+ yyn = yytable[yyn];
+ if (yyn <= 0)
+ {
+ if (yyn == 0 || yyn == YYTABLE_NINF)
+ goto yyerrlab;
+ yyn = -yyn;
+ goto yyreduce;
+ }
+
+ if (yyn == YYFINAL)
+ YYACCEPT;
+
+ /* Shift the look-ahead token. */
+ YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
+
+ /* Discard the token being shifted unless it is eof. */
+ if (yychar != YYEOF)
+ yychar = YYEMPTY;
+
+ *++yyvsp = yylval;
+
+
+ /* Count tokens shifted since error; after three, turn off error
+ status. */
+ if (yyerrstatus)
+ yyerrstatus--;
+
+ yystate = yyn;
+ goto yynewstate;
+
+
+/*-----------------------------------------------------------.
+| yydefault -- do the default action for the current state. |
+`-----------------------------------------------------------*/
+yydefault:
+ yyn = yydefact[yystate];
+ if (yyn == 0)
+ goto yyerrlab;
+ goto yyreduce;
+
+
+/*-----------------------------.
+| yyreduce -- Do a reduction. |
+`-----------------------------*/
+yyreduce:
+ /* yyn is the number of a rule to reduce with. */
+ yylen = yyr2[yyn];
+
+ /* If YYLEN is nonzero, implement the default value of the action:
+ `$$ = $1'.
+
+ Otherwise, the following line sets YYVAL to garbage.
+ This behavior is undocumented and Bison
+ users should not rely upon it. Assigning to YYVAL
+ unconditionally makes the parser a bit smaller, and it avoids a
+ GCC warning that YYVAL may be used uninitialized. */
+ yyval = yyvsp[1-yylen];
+
+
+ YY_REDUCE_PRINT (yyn);
+ switch (yyn)
+ {
+ case 12:
+#line 75 "uparse.y"
+ {
+ char * errstr = vstralloc("Invalid command: ", yytext, NULL);
+ yyerror(errstr);
+ amfree(errstr);
+ YYERROR;
+ }
+ break;
+
+ case 13:
+#line 84 "uparse.y"
+ { list_host(); }
+ break;
+
+ case 14:
+#line 85 "uparse.y"
+ { list_disk((yyvsp[0].strval)); amfree((yyvsp[0].strval)); }
+ break;
+
+ case 15:
+#line 86 "uparse.y"
+ { list_disk(NULL); }
+ break;
+
+ case 16:
+#line 87 "uparse.y"
+ { set_date((yyvsp[0].strval)); amfree((yyvsp[0].strval)); }
+ break;
+
+ case 17:
+#line 88 "uparse.y"
+ { set_host((yyvsp[0].strval)); amfree((yyvsp[0].strval)); }
+ break;
+
+ case 18:
+#line 89 "uparse.y"
+ { set_disk((yyvsp[-1].strval), (yyvsp[0].strval)); amfree((yyvsp[-1].strval)); amfree((yyvsp[0].strval)); }
+ break;
+
+ case 19:
+#line 90 "uparse.y"
+ { set_disk((yyvsp[0].strval), NULL); amfree((yyvsp[0].strval)); }
+ break;
+
+ case 20:
+#line 91 "uparse.y"
+ { set_tape((yyvsp[0].strval)); amfree((yyvsp[0].strval)); }
+ break;
+
+ case 21:
+#line 92 "uparse.y"
+ { set_tape(""); }
+ break;
+
+ case 22:
+#line 93 "uparse.y"
+ { cd_glob((yyvsp[0].strval)); amfree((yyvsp[0].strval)); }
+ break;
+
+ case 23:
+#line 94 "uparse.y"
+ { cd_regex((yyvsp[0].strval)); amfree((yyvsp[0].strval)); }
+ break;
+
+ case 24:
+#line 95 "uparse.y"
+ {
+#ifdef SAMBA_CLIENT
+ set_mode(SAMBA_SMBCLIENT);
+#endif /* SAMBA_CLIENT */
+ }
+ break;
+
+ case 25:
+#line 100 "uparse.y"
+ {
+#ifdef SAMBA_CLIENT
+ set_mode(SAMBA_TAR);
+#endif /* SAMBA_CLIENT */
+ }
+ break;
+
+ case 26:
+#line 108 "uparse.y"
+ { list_disk_history(); }
+ break;
+
+ case 27:
+#line 109 "uparse.y"
+ { list_directory(); }
+ break;
+
+ case 28:
+#line 110 "uparse.y"
+ { display_extract_list((yyvsp[0].strval)); amfree((yyvsp[0].strval)); }
+ break;
+
+ case 29:
+#line 111 "uparse.y"
+ { display_extract_list(NULL); }
+ break;
+
+ case 30:
+#line 112 "uparse.y"
+ { show_directory(); }
+ break;
+
+ case 31:
+#line 113 "uparse.y"
+ { clear_extract_list(); }
+ break;
+
+ case 32:
+#line 114 "uparse.y"
+ { show_mode (); }
+ break;
+
+ case 33:
+#line 118 "uparse.y"
+ { quit(); }
+ break;
+
+ case 35:
+#line 126 "uparse.y"
+ { add_glob((yyvsp[0].strval)); amfree((yyvsp[0].strval)); }
+ break;
+
+ case 36:
+#line 127 "uparse.y"
+ { add_glob((yyvsp[0].strval)); amfree((yyvsp[0].strval)); }
+ break;
+
+ case 38:
+#line 135 "uparse.y"
+ { add_regex((yyvsp[0].strval)); amfree((yyvsp[0].strval)); }
+ break;
+
+ case 39:
+#line 136 "uparse.y"
+ { add_regex((yyvsp[0].strval)); amfree((yyvsp[0].strval)); }
+ break;
+
+ case 41:
+#line 144 "uparse.y"
+ { delete_glob((yyvsp[0].strval)); amfree((yyvsp[0].strval)); }
+ break;
+
+ case 42:
+#line 145 "uparse.y"
+ { delete_glob((yyvsp[0].strval)); amfree((yyvsp[0].strval)); }
+ break;
+
+ case 44:
+#line 153 "uparse.y"
+ { delete_regex((yyvsp[0].strval)); amfree((yyvsp[0].strval)); }
+ break;
+
+ case 45:
+#line 154 "uparse.y"
+ { delete_regex((yyvsp[0].strval)); amfree((yyvsp[0].strval)); }
+ break;
+
+ case 46:
+#line 158 "uparse.y"
+ { char buf[STR_SIZE]; puts(getcwd(buf, sizeof(buf))); }
+ break;
+
+ case 47:
+#line 159 "uparse.y"
+ {
+ if (chdir((yyvsp[0].strval)) == -1) {
+ perror((yyvsp[0].strval));
+ }
+ amfree((yyvsp[0].strval));
+ }
+ break;
+
+ case 48:
+#line 168 "uparse.y"
+ { help_list(); }
+ break;
+
+ case 49:
+#line 172 "uparse.y"
+ { extract_files(); }
+ break;
+
+
+ default: break;
+ }
+
+/* Line 1126 of yacc.c. */
+#line 1402 "uparse.c"
+\f
+ yyvsp -= yylen;
+ yyssp -= yylen;
+
+
+ YY_STACK_PRINT (yyss, yyssp);
+
+ *++yyvsp = yyval;
+
+
+ /* Now `shift' the result of the reduction. Determine what state
+ that goes to, based on the state we popped back to and the rule
+ number reduced by. */
+
+ yyn = yyr1[yyn];
+
+ yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
+ if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
+ yystate = yytable[yystate];
+ else
+ yystate = yydefgoto[yyn - YYNTOKENS];
+
+ goto yynewstate;
+
+
+/*------------------------------------.
+| yyerrlab -- here on detecting error |
+`------------------------------------*/
+yyerrlab:
+ /* If not already recovering from an error, report this error. */
+ if (!yyerrstatus)
+ {
+ ++yynerrs;
+#if YYERROR_VERBOSE
+ yyn = yypact[yystate];
+
+ if (YYPACT_NINF < yyn && yyn < YYLAST)
+ {
+ int yytype = YYTRANSLATE (yychar);
+ YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]);
+ YYSIZE_T yysize = yysize0;
+ YYSIZE_T yysize1;
+ int yysize_overflow = 0;
+ char *yymsg = 0;
+# define YYERROR_VERBOSE_ARGS_MAXIMUM 5
+ char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
+ int yyx;
+
+#if 0
+ /* This is so xgettext sees the translatable formats that are
+ constructed on the fly. */
+ YY_("syntax error, unexpected %s");
+ YY_("syntax error, unexpected %s, expecting %s");
+ YY_("syntax error, unexpected %s, expecting %s or %s");
+ YY_("syntax error, unexpected %s, expecting %s or %s or %s");
+ YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s");
+#endif
+ char *yyfmt;
+ char const *yyf;
+ static char const yyunexpected[] = "syntax error, unexpected %s";
+ static char const yyexpecting[] = ", expecting %s";
+ static char const yyor[] = " or %s";
+ char yyformat[sizeof yyunexpected
+ + sizeof yyexpecting - 1
+ + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2)
+ * (sizeof yyor - 1))];
+ char const *yyprefix = yyexpecting;
+
+ /* Start YYX at -YYN if negative to avoid negative indexes in
+ YYCHECK. */
+ int yyxbegin = yyn < 0 ? -yyn : 0;
+
+ /* Stay within bounds of both yycheck and yytname. */
+ int yychecklim = YYLAST - yyn;
+ int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
+ int yycount = 1;
+
+ yyarg[0] = yytname[yytype];
+ yyfmt = yystpcpy (yyformat, yyunexpected);
+
+ for (yyx = yyxbegin; yyx < yyxend; ++yyx)
+ if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
+ {
+ if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
+ {
+ yycount = 1;
+ yysize = yysize0;
+ yyformat[sizeof yyunexpected - 1] = '\0';
+ break;
+ }
+ yyarg[yycount++] = yytname[yyx];
+ yysize1 = yysize + yytnamerr (0, yytname[yyx]);
+ yysize_overflow |= yysize1 < yysize;
+ yysize = yysize1;
+ yyfmt = yystpcpy (yyfmt, yyprefix);
+ yyprefix = yyor;
+ }
+
+ yyf = YY_(yyformat);
+ yysize1 = yysize + yystrlen (yyf);
+ yysize_overflow |= yysize1 < yysize;
+ yysize = yysize1;
+
+ if (!yysize_overflow && yysize <= YYSTACK_ALLOC_MAXIMUM)
+ yymsg = (char *) YYSTACK_ALLOC (yysize);
+ if (yymsg)
+ {
+ /* Avoid sprintf, as that infringes on the user's name space.
+ Don't have undefined behavior even if the translation
+ produced a string with the wrong number of "%s"s. */
+ char *yyp = yymsg;
+ int yyi = 0;
+ while ((*yyp = *yyf))
+ {
+ if (*yyp == '%' && yyf[1] == 's' && yyi < yycount)
+ {
+ yyp += yytnamerr (yyp, yyarg[yyi++]);
+ yyf += 2;
+ }
+ else
+ {
+ yyp++;
+ yyf++;
+ }
+ }
+ yyerror (yymsg);
+ YYSTACK_FREE (yymsg);
+ }
+ else
+ {
+ yyerror (YY_("syntax error"));
+ goto yyexhaustedlab;
+ }
+ }
+ else
+#endif /* YYERROR_VERBOSE */
+ yyerror (YY_("syntax error"));
+ }
+
+
+
+ if (yyerrstatus == 3)
+ {
+ /* If just tried and failed to reuse look-ahead token after an
+ error, discard it. */
+
+ if (yychar <= YYEOF)
+ {
+ /* Return failure if at end of input. */
+ if (yychar == YYEOF)
+ YYABORT;
+ }
+ else
+ {
+ yydestruct ("Error: discarding", yytoken, &yylval);
+ yychar = YYEMPTY;
+ }
+ }
+
+ /* Else will try to reuse look-ahead token after shifting the error
+ token. */
+ goto yyerrlab1;
+
+
+/*---------------------------------------------------.
+| yyerrorlab -- error raised explicitly by YYERROR. |
+`---------------------------------------------------*/
+yyerrorlab:
+
+ /* Pacify compilers like GCC when the user code never invokes
+ YYERROR and the label yyerrorlab therefore never appears in user
+ code. */
+ if (0)
+ goto yyerrorlab;
+
+yyvsp -= yylen;
+ yyssp -= yylen;
+ yystate = *yyssp;
+ goto yyerrlab1;
+
+
+/*-------------------------------------------------------------.
+| yyerrlab1 -- common code for both syntax error and YYERROR. |
+`-------------------------------------------------------------*/
+yyerrlab1:
+ yyerrstatus = 3; /* Each real token shifted decrements this. */
+
+ for (;;)
+ {
+ yyn = yypact[yystate];
+ if (yyn != YYPACT_NINF)
+ {
+ yyn += YYTERROR;
+ if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
+ {
+ yyn = yytable[yyn];
+ if (0 < yyn)
+ break;
+ }
+ }
+
+ /* Pop the current state because it cannot handle the error token. */
+ if (yyssp == yyss)
+ YYABORT;
+
+
+ yydestruct ("Error: popping", yystos[yystate], yyvsp);
+ YYPOPSTACK;
+ yystate = *yyssp;
+ YY_STACK_PRINT (yyss, yyssp);
+ }
+
+ if (yyn == YYFINAL)
+ YYACCEPT;
+
+ *++yyvsp = yylval;
+
+
+ /* Shift the error token. */
+ YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
+
+ yystate = yyn;
+ goto yynewstate;
+
+
+/*-------------------------------------.
+| yyacceptlab -- YYACCEPT comes here. |
+`-------------------------------------*/
+yyacceptlab:
+ yyresult = 0;
+ goto yyreturn;
+
+/*-----------------------------------.
+| yyabortlab -- YYABORT comes here. |
+`-----------------------------------*/
+yyabortlab:
+ yyresult = 1;
+ goto yyreturn;
+
+#ifndef yyoverflow
+/*-------------------------------------------------.
+| yyexhaustedlab -- memory exhaustion comes here. |
+`-------------------------------------------------*/
+yyexhaustedlab:
+ yyerror (YY_("memory exhausted"));
+ yyresult = 2;
+ /* Fall through. */
+#endif
+
+yyreturn:
+ if (yychar != YYEOF && yychar != YYEMPTY)
+ yydestruct ("Cleanup: discarding lookahead",
+ yytoken, &yylval);
+ while (yyssp != yyss)
+ {
+ yydestruct ("Cleanup: popping",
+ yystos[*yyssp], yyvsp);
+ YYPOPSTACK;
+ }
+#ifndef yyoverflow
+ if (yyss != yyssa)
+ YYSTACK_FREE (yyss);
+#endif
+ return yyresult;
+}
+
+
+#line 176 "uparse.y"
+
+
+void
+yyerror(
+ char * s)
+{
+ printf("%s\n", s);
+}
+
--- /dev/null
+/* A Bison parser, made by GNU Bison 2.1. */
+
+/* Skeleton parser for Yacc-like parsing with Bison,
+ Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ 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., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA. */
+
+/* As a special exception, when this file is copied by Bison into a
+ Bison output file, you may use that output file without restriction.
+ This special exception was added by the Free Software Foundation
+ in version 1.24 of Bison. */
+
+/* Tokens. */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+ /* Put the tokens into the symbol table, so that GDB and other debuggers
+ know about them. */
+ enum yytokentype {
+ LISTHOST = 258,
+ LISTDISK = 259,
+ SETHOST = 260,
+ SETDISK = 261,
+ SETDATE = 262,
+ SETTAPE = 263,
+ SETMODE = 264,
+ CD = 265,
+ CDX = 266,
+ QUIT = 267,
+ DHIST = 268,
+ LS = 269,
+ ADD = 270,
+ ADDX = 271,
+ EXTRACT = 272,
+ LIST = 273,
+ DELETE = 274,
+ DELETEX = 275,
+ PWD = 276,
+ CLEAR = 277,
+ HELP = 278,
+ LCD = 279,
+ LPWD = 280,
+ MODE = 281,
+ SMB = 282,
+ TAR = 283,
+ PATH = 284,
+ DATE = 285
+ };
+#endif
+/* Tokens. */
+#define LISTHOST 258
+#define LISTDISK 259
+#define SETHOST 260
+#define SETDISK 261
+#define SETDATE 262
+#define SETTAPE 263
+#define SETMODE 264
+#define CD 265
+#define CDX 266
+#define QUIT 267
+#define DHIST 268
+#define LS 269
+#define ADD 270
+#define ADDX 271
+#define EXTRACT 272
+#define LIST 273
+#define DELETE 274
+#define DELETEX 275
+#define PWD 276
+#define CLEAR 277
+#define HELP 278
+#define LCD 279
+#define LPWD 280
+#define MODE 281
+#define SMB 282
+#define TAR 283
+#define PATH 284
+#define DATE 285
+
+
+
+
+#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
+#line 42 "uparse.y"
+typedef union YYSTYPE {
+ int intval;
+ double floatval;
+ char * strval;
+ int subtok;
+} YYSTYPE;
+/* Line 1447 of yacc.c. */
+#line 105 "uparse.h"
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
+# define YYSTYPE_IS_TRIVIAL 1
+#endif
+
+extern YYSTYPE yylval;
+
+
+
--- /dev/null
+/*
+ * Amanda, The Advanced Maryland Automatic Network Disk Archiver
+ * Copyright (c) 1991-1998, 2000 University of Maryland at College Park
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of U.M. not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. U.M. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: the Amanda Development Team. Its members are listed in a
+ * file named AUTHORS, in the root directory of this distribution.
+ */
+/*
+ * $Id: uparse.y,v 1.2 2006/05/25 01:47:13 johnfranks Exp $
+ *
+ * parser for amrecover interactive language
+ */
+%{
+#include "amanda.h"
+#include "amrecover.h"
+
+void yyerror(char *s);
+extern int yylex(void);
+extern char * yytext;
+
+%}
+
+/* DECLARATIONS */
+%union {
+ int intval;
+ double floatval;
+ char * strval;
+ int subtok;
+}
+
+ /* literal keyword tokens */
+
+%token LISTHOST LISTDISK SETHOST SETDISK SETDATE SETTAPE SETMODE
+%token CD CDX QUIT DHIST LS ADD ADDX EXTRACT
+%token LIST DELETE DELETEX PWD CLEAR HELP LCD LPWD MODE SMB TAR
+
+ /* typed tokens */
+
+%token <strval> PATH
+%token <strval> DATE
+
+
+/* GRAMMAR */
+%%
+
+ucommand:
+ set_command
+ | display_command
+ | quit_command
+ | add_command
+ | addx_command
+ | delete_command
+ | deletex_command
+ | local_command
+ | help_command
+ | extract_command
+ | {
+ char * errstr = vstralloc("Invalid command: ", yytext, NULL);
+ yyerror(errstr);
+ amfree(errstr);
+ YYERROR;
+ } /* Quiets compiler warnings about unused label */
+ ;
+
+set_command:
+ LISTHOST { list_host(); }
+ | LISTDISK PATH { list_disk($2); amfree($2); }
+ | LISTDISK { list_disk(NULL); }
+ | SETDATE DATE { set_date($2); amfree($2); }
+ | SETHOST PATH { set_host($2); amfree($2); }
+ | SETDISK PATH PATH { set_disk($2, $3); amfree($2); amfree($3); }
+ | SETDISK PATH { set_disk($2, NULL); amfree($2); }
+ | SETTAPE PATH { set_tape($2); amfree($2); }
+ | SETTAPE { set_tape(""); }
+ | CD PATH { cd_glob($2); amfree($2); }
+ | CDX PATH { cd_regex($2); amfree($2); }
+ | SETMODE SMB {
+#ifdef SAMBA_CLIENT
+ set_mode(SAMBA_SMBCLIENT);
+#endif /* SAMBA_CLIENT */
+ }
+ | SETMODE TAR {
+#ifdef SAMBA_CLIENT
+ set_mode(SAMBA_TAR);
+#endif /* SAMBA_CLIENT */
+ }
+ ;
+
+display_command:
+ DHIST { list_disk_history(); }
+ | LS { list_directory(); }
+ | LIST PATH { display_extract_list($2); amfree($2); }
+ | LIST { display_extract_list(NULL); }
+ | PWD { show_directory(); }
+ | CLEAR { clear_extract_list(); }
+ | MODE { show_mode (); }
+ ;
+
+quit_command:
+ QUIT { quit(); }
+ ;
+
+add_command:
+ ADD add_path
+ ;
+
+add_path:
+ add_path PATH { add_glob($2); amfree($2); }
+ | PATH { add_glob($1); amfree($1); }
+ ;
+
+addx_command:
+ ADDX addx_path
+ ;
+
+addx_path:
+ addx_path PATH { add_regex($2); amfree($2); }
+ | PATH { add_regex($1); amfree($1); }
+ ;
+
+delete_command:
+ DELETE delete_path
+ ;
+
+delete_path:
+ delete_path PATH { delete_glob($2); amfree($2); }
+ | PATH { delete_glob($1); amfree($1); }
+ ;
+
+deletex_command:
+ DELETEX deletex_path
+ ;
+
+deletex_path:
+ deletex_path PATH { delete_regex($2); amfree($2); }
+ | PATH { delete_regex($1); amfree($1); }
+ ;
+
+local_command:
+ LPWD { char buf[STR_SIZE]; puts(getcwd(buf, sizeof(buf))); }
+ | LCD PATH {
+ if (chdir($2) == -1) {
+ perror($2);
+ }
+ amfree($2);
+ }
+ ;
+
+help_command:
+ HELP { help_list(); }
+ ;
+
+extract_command:
+ EXTRACT { extract_files(); }
+ ;
+
+/* ADDITIONAL C CODE */
+%%
+
+void
+yyerror(
+ char * s)
+{
+ printf("%s\n", s);
+}
--- /dev/null
+/* A lexical scanner generated by flex*/
+
+/* Scanner skeleton version:
+ * $Header: /home/daffy/u0/vern/flex/RCS/flex.skl,v 2.91 96/09/10 16:58:48 vern Exp $
+ */
+
+#define FLEX_SCANNER
+#define YY_FLEX_MAJOR_VERSION 2
+#define YY_FLEX_MINOR_VERSION 5
+
+#include <stdio.h>
+#include <unistd.h>
+
+
+/* cfront 1.2 defines "c_plusplus" instead of "__cplusplus" */
+#ifdef c_plusplus
+#ifndef __cplusplus
+#define __cplusplus
+#endif
+#endif
+
+
+#ifdef __cplusplus
+
+#include <stdlib.h>
+
+/* Use prototypes in function declarations. */
+#define YY_USE_PROTOS
+
+/* The "const" storage-class-modifier is valid. */
+#define YY_USE_CONST
+
+#else /* ! __cplusplus */
+
+#if __STDC__
+
+#define YY_USE_PROTOS
+#define YY_USE_CONST
+
+#endif /* __STDC__ */
+#endif /* ! __cplusplus */
+
+#ifdef __TURBOC__
+ #pragma warn -rch
+ #pragma warn -use
+#include <io.h>
+#include <stdlib.h>
+#define YY_USE_CONST
+#define YY_USE_PROTOS
+#endif
+
+#ifdef YY_USE_CONST
+#define yyconst const
+#else
+#define yyconst
+#endif
+
+
+#ifdef YY_USE_PROTOS
+#define YY_PROTO(proto) proto
+#else
+#define YY_PROTO(proto) ()
+#endif
+
+/* Returned upon end-of-file. */
+#define YY_NULL 0
+
+/* Promotes a possibly negative, possibly signed char to an unsigned
+ * integer for use as an array index. If the signed char is negative,
+ * we want to instead treat it as an 8-bit unsigned char, hence the
+ * double cast.
+ */
+#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
+
+/* Enter a start condition. This macro really ought to take a parameter,
+ * but we do it the disgusting crufty way forced on us by the ()-less
+ * definition of BEGIN.
+ */
+#define BEGIN yy_start = 1 + 2 *
+
+/* Translate the current start state into a value that can be later handed
+ * to BEGIN to return to the state. The YYSTATE alias is for lex
+ * compatibility.
+ */
+#define YY_START ((yy_start - 1) / 2)
+#define YYSTATE YY_START
+
+/* Action number for EOF rule of a given start state. */
+#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
+
+/* Special action meaning "start processing a new file". */
+#define YY_NEW_FILE yyrestart( yyin )
+
+#define YY_END_OF_BUFFER_CHAR 0
+
+/* Size of default input buffer. */
+#define YY_BUF_SIZE 16384
+
+typedef struct yy_buffer_state *YY_BUFFER_STATE;
+
+extern int yyleng;
+extern FILE *yyin, *yyout;
+
+#define EOB_ACT_CONTINUE_SCAN 0
+#define EOB_ACT_END_OF_FILE 1
+#define EOB_ACT_LAST_MATCH 2
+
+/* The funky do-while in the following #define is used to turn the definition
+ * int a single C statement (which needs a semi-colon terminator). This
+ * avoids problems with code like:
+ *
+ * if ( condition_holds )
+ * yyless( 5 );
+ * else
+ * do_something_else();
+ *
+ * Prior to using the do-while the compiler would get upset at the
+ * "else" because it interpreted the "if" statement as being all
+ * done when it reached the ';' after the yyless() call.
+ */
+
+/* Return all but the first 'n' matched characters back to the input stream. */
+
+#define yyless(n) \
+ do \
+ { \
+ /* Undo effects of setting up yytext. */ \
+ *yy_cp = yy_hold_char; \
+ YY_RESTORE_YY_MORE_OFFSET \
+ yy_c_buf_p = yy_cp = yy_bp + n - YY_MORE_ADJ; \
+ YY_DO_BEFORE_ACTION; /* set up yytext again */ \
+ } \
+ while ( 0 )
+
+#define unput(c) yyunput( c, yytext_ptr )
+
+/* Some routines like yy_flex_realloc() are emitted as static but are
+ not called by all lexers. This generates warnings in some compilers,
+ notably GCC. Arrange to suppress these. */
+#ifdef __GNUC__
+#define YY_MAY_BE_UNUSED __attribute__((unused))
+#else
+#define YY_MAY_BE_UNUSED
+#endif
+
+/* The following is because we cannot portably get our hands on size_t
+ * (without autoconf's help, which isn't available because we want
+ * flex-generated scanners to compile on their own).
+ */
+typedef unsigned int yy_size_t;
+
+
+struct yy_buffer_state
+ {
+ FILE *yy_input_file;
+
+ char *yy_ch_buf; /* input buffer */
+ char *yy_buf_pos; /* current position in input buffer */
+
+ /* Size of input buffer in bytes, not including room for EOB
+ * characters.
+ */
+ yy_size_t yy_buf_size;
+
+ /* Number of characters read into yy_ch_buf, not including EOB
+ * characters.
+ */
+ int yy_n_chars;
+
+ /* Whether we "own" the buffer - i.e., we know we created it,
+ * and can realloc() it to grow it, and should free() it to
+ * delete it.
+ */
+ int yy_is_our_buffer;
+
+ /* Whether this is an "interactive" input source; if so, and
+ * if we're using stdio for input, then we want to use getc()
+ * instead of fread(), to make sure we stop fetching input after
+ * each newline.
+ */
+ int yy_is_interactive;
+
+ /* Whether we're considered to be at the beginning of a line.
+ * If so, '^' rules will be active on the next match, otherwise
+ * not.
+ */
+ int yy_at_bol;
+
+ /* Whether to try to fill the input buffer when we reach the
+ * end of it.
+ */
+ int yy_fill_buffer;
+
+ int yy_buffer_status;
+#define YY_BUFFER_NEW 0
+#define YY_BUFFER_NORMAL 1
+ /* When an EOF's been seen but there's still some text to process
+ * then we mark the buffer as YY_EOF_PENDING, to indicate that we
+ * shouldn't try reading from the input source any more. We might
+ * still have a bunch of tokens to match, though, because of
+ * possible backing-up.
+ *
+ * When we actually see the EOF, we change the status to "new"
+ * (via yyrestart()), so that the user can continue scanning by
+ * just pointing yyin at a new input file.
+ */
+#define YY_BUFFER_EOF_PENDING 2
+ };
+
+static YY_BUFFER_STATE yy_current_buffer = 0;
+
+/* We provide macros for accessing buffer states in case in the
+ * future we want to put the buffer states in a more general
+ * "scanner state".
+ */
+#define YY_CURRENT_BUFFER yy_current_buffer
+
+
+/* yy_hold_char holds the character lost when yytext is formed. */
+static char yy_hold_char;
+
+static int yy_n_chars; /* number of characters read into yy_ch_buf */
+
+
+int yyleng;
+
+/* Points to current character in buffer. */
+static char *yy_c_buf_p = (char *) 0;
+static int yy_init = 1; /* whether we need to initialize */
+static int yy_start = 0; /* start state number */
+
+/* Flag which is used to allow yywrap()'s to do buffer switches
+ * instead of setting up a fresh yyin. A bit of a hack ...
+ */
+static int yy_did_buffer_switch_on_eof;
+
+void yyrestart YY_PROTO(( FILE *input_file ));
+
+void yy_switch_to_buffer YY_PROTO(( YY_BUFFER_STATE new_buffer ));
+void yy_load_buffer_state YY_PROTO(( void ));
+YY_BUFFER_STATE yy_create_buffer YY_PROTO(( FILE *file, int size ));
+void yy_delete_buffer YY_PROTO(( YY_BUFFER_STATE b ));
+void yy_init_buffer YY_PROTO(( YY_BUFFER_STATE b, FILE *file ));
+void yy_flush_buffer YY_PROTO(( YY_BUFFER_STATE b ));
+#define YY_FLUSH_BUFFER yy_flush_buffer( yy_current_buffer )
+
+YY_BUFFER_STATE yy_scan_buffer YY_PROTO(( char *base, yy_size_t size ));
+YY_BUFFER_STATE yy_scan_string YY_PROTO(( yyconst char *yy_str ));
+YY_BUFFER_STATE yy_scan_bytes YY_PROTO(( yyconst char *bytes, int len ));
+
+static void *yy_flex_alloc YY_PROTO(( yy_size_t ));
+static void *yy_flex_realloc YY_PROTO(( void *, yy_size_t )) YY_MAY_BE_UNUSED;
+static void yy_flex_free YY_PROTO(( void * ));
+
+#define yy_new_buffer yy_create_buffer
+
+#define yy_set_interactive(is_interactive) \
+ { \
+ if ( ! yy_current_buffer ) \
+ yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \
+ yy_current_buffer->yy_is_interactive = is_interactive; \
+ }
+
+#define yy_set_bol(at_bol) \
+ { \
+ if ( ! yy_current_buffer ) \
+ yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \
+ yy_current_buffer->yy_at_bol = at_bol; \
+ }
+
+#define YY_AT_BOL() (yy_current_buffer->yy_at_bol)
+
+typedef unsigned char YY_CHAR;
+FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0;
+typedef int yy_state_type;
+extern char *yytext;
+#define yytext_ptr yytext
+
+static yy_state_type yy_get_previous_state YY_PROTO(( void ));
+static yy_state_type yy_try_NUL_trans YY_PROTO(( yy_state_type current_state ));
+static int yy_get_next_buffer YY_PROTO(( void ));
+static void yy_fatal_error YY_PROTO(( yyconst char msg[] ));
+
+/* Done after the current pattern has been matched and before the
+ * corresponding action - sets up yytext.
+ */
+#define YY_DO_BEFORE_ACTION \
+ yytext_ptr = yy_bp; \
+ yyleng = (int) (yy_cp - yy_bp); \
+ yy_hold_char = *yy_cp; \
+ *yy_cp = '\0'; \
+ yy_c_buf_p = yy_cp;
+
+#define YY_NUM_RULES 40
+#define YY_END_OF_BUFFER 41
+static yyconst short int yy_accept[131] =
+ { 0,
+ 0, 0, 0, 0, 41, 40, 39, 38, 34, 38,
+ 38, 22, 38, 38, 38, 38, 38, 38, 38, 38,
+ 38, 38, 38, 35, 37, 40, 39, 38, 38, 38,
+ 38, 38, 8, 38, 38, 38, 38, 38, 38, 38,
+ 38, 13, 38, 38, 38, 38, 38, 38, 35, 36,
+ 38, 38, 38, 14, 9, 38, 38, 38, 38, 38,
+ 38, 23, 38, 38, 38, 19, 38, 38, 26, 27,
+ 29, 38, 38, 15, 38, 38, 11, 38, 21, 38,
+ 16, 24, 28, 10, 38, 38, 38, 38, 30, 31,
+ 20, 38, 38, 38, 38, 38, 38, 38, 38, 38,
+
+ 38, 38, 17, 38, 38, 38, 38, 38, 38, 38,
+ 38, 38, 38, 18, 25, 12, 38, 38, 5, 4,
+ 3, 6, 7, 38, 2, 1, 33, 38, 32, 0
+ } ;
+
+static yyconst int yy_ec[256] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 2, 3,
+ 2, 2, 2, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 4, 5, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 6, 4, 4, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 4, 4, 4,
+ 4, 4, 8, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 9, 4, 4, 4, 4, 10, 11, 12, 13,
+
+ 14, 4, 4, 15, 16, 4, 17, 18, 19, 4,
+ 20, 21, 22, 23, 24, 25, 26, 4, 27, 28,
+ 29, 4, 4, 4, 4, 4, 1, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4
+ } ;
+
+static yyconst int yy_meta[30] =
+ { 0,
+ 1, 1, 2, 3, 4, 3, 3, 3, 5, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3
+ } ;
+
+static yyconst short int yy_base[135] =
+ { 0,
+ 0, 0, 25, 26, 161, 162, 30, 0, 162, 154,
+ 30, 0, 146, 25, 144, 129, 25, 28, 136, 128,
+ 128, 28, 143, 0, 162, 0, 43, 0, 44, 145,
+ 47, 138, 122, 135, 130, 32, 129, 122, 132, 120,
+ 116, 0, 129, 128, 124, 114, 127, 114, 0, 162,
+ 129, 49, 52, 107, 0, 124, 119, 107, 108, 109,
+ 104, 0, 103, 114, 112, 0, 100, 47, 0, 0,
+ 117, 116, 115, 0, 98, 95, 0, 109, 0, 98,
+ 48, 0, 0, 0, 54, 97, 96, 105, 107, 61,
+ 0, 99, 100, 88, 94, 89, 83, 83, 82, 92,
+
+ 83, 96, 74, 76, 71, 75, 74, 83, 79, 70,
+ 80, 79, 67, 0, 0, 0, 72, 58, 0, 0,
+ 0, 0, 0, 64, 0, 0, 69, 62, 58, 162,
+ 76, 79, 84, 87
+ } ;
+
+static yyconst short int yy_def[135] =
+ { 0,
+ 130, 1, 131, 131, 130, 130, 130, 132, 130, 132,
+ 132, 132, 132, 132, 132, 132, 132, 132, 132, 132,
+ 132, 132, 132, 133, 130, 134, 130, 132, 132, 132,
+ 132, 132, 132, 132, 132, 132, 132, 132, 132, 132,
+ 132, 132, 132, 132, 132, 132, 132, 132, 133, 130,
+ 132, 132, 132, 132, 132, 132, 132, 132, 132, 132,
+ 132, 132, 132, 132, 132, 132, 132, 132, 132, 132,
+ 132, 132, 132, 132, 132, 132, 132, 132, 132, 132,
+ 132, 132, 132, 132, 132, 132, 132, 132, 132, 132,
+ 132, 132, 132, 132, 132, 132, 132, 132, 132, 132,
+
+ 132, 132, 132, 132, 132, 132, 132, 132, 132, 132,
+ 132, 132, 132, 132, 132, 132, 132, 132, 132, 132,
+ 132, 132, 132, 132, 132, 132, 132, 132, 132, 0,
+ 130, 130, 130, 130
+ } ;
+
+static yyconst short int yy_nxt[192] =
+ { 0,
+ 6, 7, 7, 8, 9, 10, 11, 12, 8, 13,
+ 8, 14, 15, 16, 17, 8, 8, 18, 19, 8,
+ 20, 21, 8, 22, 23, 8, 8, 8, 8, 25,
+ 25, 27, 27, 26, 26, 30, 31, 33, 37, 39,
+ 38, 46, 34, 40, 27, 27, 47, 58, 41, 51,
+ 52, 42, 30, 31, 72, 52, 59, 73, 53, 85,
+ 95, 86, 96, 97, 129, 87, 102, 90, 129, 98,
+ 127, 88, 124, 113, 128, 127, 24, 24, 24, 24,
+ 24, 28, 126, 28, 49, 49, 49, 50, 125, 50,
+ 50, 50, 123, 122, 121, 120, 119, 118, 117, 116,
+
+ 115, 114, 113, 112, 111, 110, 109, 108, 107, 106,
+ 105, 104, 103, 89, 101, 100, 99, 94, 93, 92,
+ 91, 90, 89, 71, 84, 83, 82, 81, 80, 79,
+ 78, 77, 76, 75, 74, 71, 70, 69, 68, 67,
+ 66, 65, 64, 63, 62, 61, 60, 57, 56, 55,
+ 54, 53, 48, 45, 44, 43, 36, 35, 32, 29,
+ 130, 5, 130, 130, 130, 130, 130, 130, 130, 130,
+ 130, 130, 130, 130, 130, 130, 130, 130, 130, 130,
+ 130, 130, 130, 130, 130, 130, 130, 130, 130, 130,
+ 130
+
+ } ;
+
+static yyconst short int yy_chk[192] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 3,
+ 4, 7, 7, 3, 4, 11, 11, 14, 17, 18,
+ 17, 22, 14, 18, 27, 27, 22, 36, 18, 29,
+ 29, 18, 31, 31, 52, 52, 36, 53, 53, 68,
+ 81, 68, 81, 85, 129, 68, 90, 90, 128, 85,
+ 124, 68, 113, 113, 127, 127, 131, 131, 131, 131,
+ 131, 132, 118, 132, 133, 133, 133, 134, 117, 134,
+ 134, 134, 112, 111, 110, 109, 108, 107, 106, 105,
+
+ 104, 103, 102, 101, 100, 99, 98, 97, 96, 95,
+ 94, 93, 92, 89, 88, 87, 86, 80, 78, 76,
+ 75, 73, 72, 71, 67, 65, 64, 63, 61, 60,
+ 59, 58, 57, 56, 54, 51, 48, 47, 46, 45,
+ 44, 43, 41, 40, 39, 38, 37, 35, 34, 33,
+ 32, 30, 23, 21, 20, 19, 16, 15, 13, 10,
+ 5, 130, 130, 130, 130, 130, 130, 130, 130, 130,
+ 130, 130, 130, 130, 130, 130, 130, 130, 130, 130,
+ 130, 130, 130, 130, 130, 130, 130, 130, 130, 130,
+ 130
+
+ } ;
+
+static yy_state_type yy_last_accepting_state;
+static char *yy_last_accepting_cpos;
+
+/* The intent behind this definition is that it'll catch
+ * any uses of REJECT which flex missed.
+ */
+#define REJECT reject_used_but_not_detected
+#define yymore() yymore_used_but_not_detected
+#define YY_MORE_ADJ 0
+#define YY_RESTORE_YY_MORE_OFFSET
+char *yytext;
+#line 1 "uscan.l"
+#define INITIAL 0
+/*
+ * amanda, the advanced maryland automatic network disk archiver
+ * Copyright (c) 1991-2000 University of Maryland at College Park
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of U.M. not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. U.M. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: the Amanda Development Team. Its members are listed in a
+ * file named AUTHORS, in the root directory of this distribution.
+ */
+/*
+ * $Id: uscan.l,v 1.3 2006/07/05 11:15:56 martinea Exp $
+ *
+ * lexer for amrecover interactive language
+ */
+#line 32 "uscan.l"
+#include "amanda.h"
+#include "uparse.h"
+
+/*
+ * We redefine this here to prevent compiler warning about ignoring fwrite
+ * return value...
+ */
+#undef ECHO
+#define ECHO do { \
+ if (fwrite(yytext, (size_t)yyleng, 1, yyout) <= 0) { \
+ yyerror("ECHO failure"); \
+ } \
+ } while (0)
+
+#define YY_NO_UNPUT
+
+#define DATE_ALLOC_SIZE sizeof("YYYY-MM-DD-HH-MM-SS") /* includes null */
+
+#define YY_DECL int yylex()
+extern int yylex(void);
+
+extern void yyerror(char *s);
+extern int yyparse(void);
+static int ll_parse_date(int type, char *text);
+int process_line(char *line);
+#define quotedpath 1
+
+#line 62 "uscan.l"
+static char *string_buf = NULL;
+#line 517 "uscan.c"
+
+/* Macros after this point can all be overridden by user definitions in
+ * section 1.
+ */
+
+#ifndef YY_SKIP_YYWRAP
+#ifdef __cplusplus
+extern "C" int yywrap YY_PROTO(( void ));
+#else
+extern int yywrap YY_PROTO(( void ));
+#endif
+#endif
+
+#ifndef YY_NO_UNPUT
+static void yyunput YY_PROTO(( int c, char *buf_ptr ));
+#endif
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy YY_PROTO(( char *, yyconst char *, int ));
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen YY_PROTO(( yyconst char * ));
+#endif
+
+#ifndef YY_NO_INPUT
+#ifdef __cplusplus
+static int yyinput YY_PROTO(( void ));
+#else
+static int input YY_PROTO(( void ));
+#endif
+#endif
+
+#if YY_STACK_USED
+static int yy_start_stack_ptr = 0;
+static int yy_start_stack_depth = 0;
+static int *yy_start_stack = 0;
+#ifndef YY_NO_PUSH_STATE
+static void yy_push_state YY_PROTO(( int new_state ));
+#endif
+#ifndef YY_NO_POP_STATE
+static void yy_pop_state YY_PROTO(( void ));
+#endif
+#ifndef YY_NO_TOP_STATE
+static int yy_top_state YY_PROTO(( void ));
+#endif
+
+#else
+#define YY_NO_PUSH_STATE 1
+#define YY_NO_POP_STATE 1
+#define YY_NO_TOP_STATE 1
+#endif
+
+#ifdef YY_MALLOC_DECL
+YY_MALLOC_DECL
+#else
+#if __STDC__
+#ifndef __cplusplus
+#include <stdlib.h>
+#endif
+#else
+/* Just try to get by without declaring the routines. This will fail
+ * miserably on non-ANSI systems for which sizeof(size_t) != sizeof(int)
+ * or sizeof(void*) != sizeof(int).
+ */
+#endif
+#endif
+
+/* Amount of stuff to slurp up with each read. */
+#ifndef YY_READ_BUF_SIZE
+#define YY_READ_BUF_SIZE 8192
+#endif
+
+/* Copy whatever the last rule matched to the standard output. */
+
+#ifndef ECHO
+/* This used to be an fputs(), but since the string might contain NUL's,
+ * we now use fwrite().
+ */
+#define ECHO (void) fwrite( yytext, yyleng, 1, yyout )
+#endif
+
+/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL,
+ * is returned in "result".
+ */
+#ifndef YY_INPUT
+#define YY_INPUT(buf,result,max_size) \
+ if ( yy_current_buffer->yy_is_interactive ) \
+ { \
+ int c = '*', n; \
+ for ( n = 0; n < max_size && \
+ (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
+ buf[n] = (char) c; \
+ if ( c == '\n' ) \
+ buf[n++] = (char) c; \
+ if ( c == EOF && ferror( yyin ) ) \
+ YY_FATAL_ERROR( "input in flex scanner failed" ); \
+ result = n; \
+ } \
+ else if ( ((result = fread( buf, 1, max_size, yyin )) == 0) \
+ && ferror( yyin ) ) \
+ YY_FATAL_ERROR( "input in flex scanner failed" );
+#endif
+
+/* No semi-colon after return; correct usage is to write "yyterminate();" -
+ * we don't want an extra ';' after the "return" because that will cause
+ * some compilers to complain about unreachable statements.
+ */
+#ifndef yyterminate
+#define yyterminate() return YY_NULL
+#endif
+
+/* Number of entries by which start-condition stack grows. */
+#ifndef YY_START_STACK_INCR
+#define YY_START_STACK_INCR 25
+#endif
+
+/* Report a fatal error. */
+#ifndef YY_FATAL_ERROR
+#define YY_FATAL_ERROR(msg) yy_fatal_error( msg )
+#endif
+
+/* Default declaration of generated scanner - a define so the user can
+ * easily add parameters.
+ */
+#ifndef YY_DECL
+#define YY_DECL int yylex YY_PROTO(( void ))
+#endif
+
+/* Code executed at the beginning of each rule, after yytext and yyleng
+ * have been set up.
+ */
+#ifndef YY_USER_ACTION
+#define YY_USER_ACTION
+#endif
+
+/* Code executed at the end of each rule. */
+#ifndef YY_BREAK
+#define YY_BREAK break;
+#endif
+
+#define YY_RULE_SETUP \
+ YY_USER_ACTION
+
+YY_DECL
+ {
+ register yy_state_type yy_current_state;
+ register char *yy_cp = NULL, *yy_bp = NULL;
+ register int yy_act;
+
+#line 65 "uscan.l"
+
+
+
+ /* literal keyword tokens */
+
+
+#line 675 "uscan.c"
+
+ if ( yy_init )
+ {
+ yy_init = 0;
+
+#ifdef YY_USER_INIT
+ YY_USER_INIT;
+#endif
+
+ if ( ! yy_start )
+ yy_start = 1; /* first start state */
+
+ if ( ! yyin )
+ yyin = stdin;
+
+ if ( ! yyout )
+ yyout = stdout;
+
+ if ( ! yy_current_buffer )
+ yy_current_buffer =
+ yy_create_buffer( yyin, YY_BUF_SIZE );
+
+ yy_load_buffer_state();
+ }
+
+ while ( 1 ) /* loops until end-of-file is reached */
+ {
+ yy_cp = yy_c_buf_p;
+
+ /* Support of yytext. */
+ *yy_cp = yy_hold_char;
+
+ /* yy_bp points to the position in yy_ch_buf of the start of
+ * the current run.
+ */
+ yy_bp = yy_cp;
+
+ yy_current_state = yy_start;
+yy_match:
+ do
+ {
+ register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)];
+ if ( yy_accept[yy_current_state] )
+ {
+ yy_last_accepting_state = yy_current_state;
+ yy_last_accepting_cpos = yy_cp;
+ }
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 131 )
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ ++yy_cp;
+ }
+ while ( yy_base[yy_current_state] != 162 );
+
+yy_find_action:
+ yy_act = yy_accept[yy_current_state];
+ if ( yy_act == 0 )
+ { /* have to back up */
+ yy_cp = yy_last_accepting_cpos;
+ yy_current_state = yy_last_accepting_state;
+ yy_act = yy_accept[yy_current_state];
+ }
+
+ YY_DO_BEFORE_ACTION;
+
+
+do_action: /* This label is used only to access EOF actions. */
+
+
+ switch ( yy_act )
+ { /* beginning of action switch */
+ case 0: /* must back up */
+ /* undo the effects of YY_DO_BEFORE_ACTION */
+ *yy_cp = yy_hold_char;
+ yy_cp = yy_last_accepting_cpos;
+ yy_current_state = yy_last_accepting_state;
+ goto yy_find_action;
+
+case 1:
+YY_RULE_SETUP
+#line 71 "uscan.l"
+{ return LISTHOST; }
+ YY_BREAK
+case 2:
+YY_RULE_SETUP
+#line 72 "uscan.l"
+{ return LISTDISK; }
+ YY_BREAK
+case 3:
+YY_RULE_SETUP
+#line 73 "uscan.l"
+{ return SETHOST; }
+ YY_BREAK
+case 4:
+YY_RULE_SETUP
+#line 74 "uscan.l"
+{ return SETDISK; }
+ YY_BREAK
+case 5:
+YY_RULE_SETUP
+#line 75 "uscan.l"
+{ return SETDATE; }
+ YY_BREAK
+case 6:
+YY_RULE_SETUP
+#line 76 "uscan.l"
+{ return SETMODE; }
+ YY_BREAK
+case 7:
+YY_RULE_SETUP
+#line 77 "uscan.l"
+{ return SETTAPE; }
+ YY_BREAK
+case 8:
+YY_RULE_SETUP
+#line 78 "uscan.l"
+{ return CD; }
+ YY_BREAK
+case 9:
+YY_RULE_SETUP
+#line 79 "uscan.l"
+{ return CDX; }
+ YY_BREAK
+case 10:
+YY_RULE_SETUP
+#line 80 "uscan.l"
+{ return QUIT; }
+ YY_BREAK
+case 11:
+YY_RULE_SETUP
+#line 81 "uscan.l"
+{ return QUIT; }
+ YY_BREAK
+case 12:
+YY_RULE_SETUP
+#line 82 "uscan.l"
+{ return DHIST; }
+ YY_BREAK
+case 13:
+YY_RULE_SETUP
+#line 83 "uscan.l"
+{ return LS; }
+ YY_BREAK
+case 14:
+YY_RULE_SETUP
+#line 84 "uscan.l"
+{ return ADD; }
+ YY_BREAK
+case 15:
+YY_RULE_SETUP
+#line 85 "uscan.l"
+{ return ADDX; }
+ YY_BREAK
+case 16:
+YY_RULE_SETUP
+#line 86 "uscan.l"
+{ return LIST; }
+ YY_BREAK
+case 17:
+YY_RULE_SETUP
+#line 87 "uscan.l"
+{ return DELETE; }
+ YY_BREAK
+case 18:
+YY_RULE_SETUP
+#line 88 "uscan.l"
+{ return DELETEX; }
+ YY_BREAK
+case 19:
+YY_RULE_SETUP
+#line 89 "uscan.l"
+{ return PWD; }
+ YY_BREAK
+case 20:
+YY_RULE_SETUP
+#line 90 "uscan.l"
+{ return CLEAR; }
+ YY_BREAK
+case 21:
+YY_RULE_SETUP
+#line 91 "uscan.l"
+{ return HELP; }
+ YY_BREAK
+case 22:
+YY_RULE_SETUP
+#line 92 "uscan.l"
+{ return HELP; }
+ YY_BREAK
+case 23:
+YY_RULE_SETUP
+#line 93 "uscan.l"
+{ return LCD; }
+ YY_BREAK
+case 24:
+YY_RULE_SETUP
+#line 94 "uscan.l"
+{ return LPWD; }
+ YY_BREAK
+case 25:
+YY_RULE_SETUP
+#line 95 "uscan.l"
+{ return EXTRACT; }
+ YY_BREAK
+case 26:
+YY_RULE_SETUP
+#line 96 "uscan.l"
+{ return SMB; }
+ YY_BREAK
+case 27:
+YY_RULE_SETUP
+#line 97 "uscan.l"
+{ return TAR; }
+ YY_BREAK
+case 28:
+YY_RULE_SETUP
+#line 98 "uscan.l"
+{ return MODE; }
+ YY_BREAK
+
+ /* dates */
+
+case 29:
+YY_RULE_SETUP
+#line 104 "uscan.l"
+{ return ll_parse_date(1, yytext); }
+ YY_BREAK
+case 30:
+YY_RULE_SETUP
+#line 105 "uscan.l"
+{ return ll_parse_date(2, yytext); }
+ YY_BREAK
+case 31:
+YY_RULE_SETUP
+#line 106 "uscan.l"
+{ return ll_parse_date(3, yytext); }
+ YY_BREAK
+case 32:
+YY_RULE_SETUP
+#line 107 "uscan.l"
+{ return ll_parse_date(4, yytext); }
+ YY_BREAK
+case 33:
+YY_RULE_SETUP
+#line 108 "uscan.l"
+{ return ll_parse_date(5, yytext); }
+ YY_BREAK
+
+ /* quoted file names */
+
+case 34:
+YY_RULE_SETUP
+#line 114 "uscan.l"
+{
+ if(string_buf != NULL) {
+ printf("ERROR:string_buf != NULL: %s\n",string_buf);
+ }
+ BEGIN(quotedpath);
+ strappend(string_buf, yytext);
+}
+ YY_BREAK
+case 35:
+YY_RULE_SETUP
+#line 122 "uscan.l"
+{
+ strappend(string_buf, yytext);
+}
+ YY_BREAK
+case 36:
+YY_RULE_SETUP
+#line 126 "uscan.l"
+{
+ /* escaped character (including quote) */
+ strappend(string_buf, yytext);
+}
+ YY_BREAK
+case 37:
+YY_RULE_SETUP
+#line 131 "uscan.l"
+{ /* saw closing quote - all done */
+ strappend(string_buf, yytext);
+ yylval.strval = string_buf;
+ string_buf = NULL;
+ BEGIN(INITIAL);
+ return PATH;
+}
+ YY_BREAK
+
+ /* file names */
+
+case 38:
+YY_RULE_SETUP
+#line 143 "uscan.l"
+{
+ yylval.strval = stralloc(yytext);
+ return PATH;
+}
+ YY_BREAK
+
+ /* whitespace */
+
+case 39:
+YY_RULE_SETUP
+#line 152 "uscan.l"
+; /* whitespace */
+ YY_BREAK
+
+ /* anything else */
+ /* everything should have been handled by now, so this rule is disabled */
+
+
+#if 0
+. { yyerror("invalid character"); }
+#endif
+
+case 40:
+YY_RULE_SETUP
+#line 165 "uscan.l"
+ECHO;
+ YY_BREAK
+#line 999 "uscan.c"
+case YY_STATE_EOF(INITIAL):
+case YY_STATE_EOF(quotedpath):
+ yyterminate();
+
+ case YY_END_OF_BUFFER:
+ {
+ /* Amount of text matched not including the EOB char. */
+ int yy_amount_of_matched_text = (int) (yy_cp - yytext_ptr) - 1;
+
+ /* Undo the effects of YY_DO_BEFORE_ACTION. */
+ *yy_cp = yy_hold_char;
+ YY_RESTORE_YY_MORE_OFFSET
+
+ if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_NEW )
+ {
+ /* We're scanning a new file or input source. It's
+ * possible that this happened because the user
+ * just pointed yyin at a new source and called
+ * yylex(). If so, then we have to assure
+ * consistency between yy_current_buffer and our
+ * globals. Here is the right place to do so, because
+ * this is the first action (other than possibly a
+ * back-up) that will match for the new input source.
+ */
+ yy_n_chars = yy_current_buffer->yy_n_chars;
+ yy_current_buffer->yy_input_file = yyin;
+ yy_current_buffer->yy_buffer_status = YY_BUFFER_NORMAL;
+ }
+
+ /* Note that here we test for yy_c_buf_p "<=" to the position
+ * of the first EOB in the buffer, since yy_c_buf_p will
+ * already have been incremented past the NUL character
+ * (since all states make transitions on EOB to the
+ * end-of-buffer state). Contrast this with the test
+ * in input().
+ */
+ if ( yy_c_buf_p <= &yy_current_buffer->yy_ch_buf[yy_n_chars] )
+ { /* This was really a NUL. */
+ yy_state_type yy_next_state;
+
+ yy_c_buf_p = yytext_ptr + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state();
+
+ /* Okay, we're now positioned to make the NUL
+ * transition. We couldn't have
+ * yy_get_previous_state() go ahead and do it
+ * for us because it doesn't know how to deal
+ * with the possibility of jamming (and we don't
+ * want to build jamming into it because then it
+ * will run more slowly).
+ */
+
+ yy_next_state = yy_try_NUL_trans( yy_current_state );
+
+ yy_bp = yytext_ptr + YY_MORE_ADJ;
+
+ if ( yy_next_state )
+ {
+ /* Consume the NUL. */
+ yy_cp = ++yy_c_buf_p;
+ yy_current_state = yy_next_state;
+ goto yy_match;
+ }
+
+ else
+ {
+ yy_cp = yy_c_buf_p;
+ goto yy_find_action;
+ }
+ }
+
+ else switch ( yy_get_next_buffer() )
+ {
+ case EOB_ACT_END_OF_FILE:
+ {
+ yy_did_buffer_switch_on_eof = 0;
+
+ if ( yywrap() )
+ {
+ /* Note: because we've taken care in
+ * yy_get_next_buffer() to have set up
+ * yytext, we can now set up
+ * yy_c_buf_p so that if some total
+ * hoser (like flex itself) wants to
+ * call the scanner after we return the
+ * YY_NULL, it'll still work - another
+ * YY_NULL will get returned.
+ */
+ yy_c_buf_p = yytext_ptr + YY_MORE_ADJ;
+
+ yy_act = YY_STATE_EOF(YY_START);
+ goto do_action;
+ }
+
+ else
+ {
+ if ( ! yy_did_buffer_switch_on_eof )
+ YY_NEW_FILE;
+ }
+ break;
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ yy_c_buf_p =
+ yytext_ptr + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state();
+
+ yy_cp = yy_c_buf_p;
+ yy_bp = yytext_ptr + YY_MORE_ADJ;
+ goto yy_match;
+
+ case EOB_ACT_LAST_MATCH:
+ yy_c_buf_p =
+ &yy_current_buffer->yy_ch_buf[yy_n_chars];
+
+ yy_current_state = yy_get_previous_state();
+
+ yy_cp = yy_c_buf_p;
+ yy_bp = yytext_ptr + YY_MORE_ADJ;
+ goto yy_find_action;
+ }
+ break;
+ }
+
+ default:
+ YY_FATAL_ERROR(
+ "fatal flex scanner internal error--no action found" );
+ } /* end of action switch */
+ } /* end of scanning one token */
+ } /* end of yylex */
+
+
+/* yy_get_next_buffer - try to read in a new buffer
+ *
+ * Returns a code representing an action:
+ * EOB_ACT_LAST_MATCH -
+ * EOB_ACT_CONTINUE_SCAN - continue scanning from current position
+ * EOB_ACT_END_OF_FILE - end of file
+ */
+
+static int yy_get_next_buffer()
+ {
+ register char *dest = yy_current_buffer->yy_ch_buf;
+ register char *source = yytext_ptr;
+ register int number_to_move, i;
+ int ret_val;
+
+ if ( yy_c_buf_p > &yy_current_buffer->yy_ch_buf[yy_n_chars + 1] )
+ YY_FATAL_ERROR(
+ "fatal flex scanner internal error--end of buffer missed" );
+
+ if ( yy_current_buffer->yy_fill_buffer == 0 )
+ { /* Don't try to fill the buffer, so this is an EOF. */
+ if ( yy_c_buf_p - yytext_ptr - YY_MORE_ADJ == 1 )
+ {
+ /* We matched a single character, the EOB, so
+ * treat this as a final EOF.
+ */
+ return EOB_ACT_END_OF_FILE;
+ }
+
+ else
+ {
+ /* We matched some text prior to the EOB, first
+ * process it.
+ */
+ return EOB_ACT_LAST_MATCH;
+ }
+ }
+
+ /* Try to read more data. */
+
+ /* First move last chars to start of buffer. */
+ number_to_move = (int) (yy_c_buf_p - yytext_ptr) - 1;
+
+ for ( i = 0; i < number_to_move; ++i )
+ *(dest++) = *(source++);
+
+ if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_EOF_PENDING )
+ /* don't do the read, it's not guaranteed to return an EOF,
+ * just force an EOF
+ */
+ yy_current_buffer->yy_n_chars = yy_n_chars = 0;
+
+ else
+ {
+ int num_to_read =
+ yy_current_buffer->yy_buf_size - number_to_move - 1;
+
+ while ( num_to_read <= 0 )
+ { /* Not enough room in the buffer - grow it. */
+#ifdef YY_USES_REJECT
+ YY_FATAL_ERROR(
+"input buffer overflow, can't enlarge buffer because scanner uses REJECT" );
+#else
+
+ /* just a shorter name for the current buffer */
+ YY_BUFFER_STATE b = yy_current_buffer;
+
+ int yy_c_buf_p_offset =
+ (int) (yy_c_buf_p - b->yy_ch_buf);
+
+ if ( b->yy_is_our_buffer )
+ {
+ int new_size = b->yy_buf_size * 2;
+
+ if ( new_size <= 0 )
+ b->yy_buf_size += b->yy_buf_size / 8;
+ else
+ b->yy_buf_size *= 2;
+
+ b->yy_ch_buf = (char *)
+ /* Include room in for 2 EOB chars. */
+ yy_flex_realloc( (void *) b->yy_ch_buf,
+ b->yy_buf_size + 2 );
+ }
+ else
+ /* Can't grow it, we don't own it. */
+ b->yy_ch_buf = 0;
+
+ if ( ! b->yy_ch_buf )
+ YY_FATAL_ERROR(
+ "fatal error - scanner input buffer overflow" );
+
+ yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset];
+
+ num_to_read = yy_current_buffer->yy_buf_size -
+ number_to_move - 1;
+#endif
+ }
+
+ if ( num_to_read > YY_READ_BUF_SIZE )
+ num_to_read = YY_READ_BUF_SIZE;
+
+ /* Read in more data. */
+ YY_INPUT( (&yy_current_buffer->yy_ch_buf[number_to_move]),
+ yy_n_chars, num_to_read );
+
+ yy_current_buffer->yy_n_chars = yy_n_chars;
+ }
+
+ if ( yy_n_chars == 0 )
+ {
+ if ( number_to_move == YY_MORE_ADJ )
+ {
+ ret_val = EOB_ACT_END_OF_FILE;
+ yyrestart( yyin );
+ }
+
+ else
+ {
+ ret_val = EOB_ACT_LAST_MATCH;
+ yy_current_buffer->yy_buffer_status =
+ YY_BUFFER_EOF_PENDING;
+ }
+ }
+
+ else
+ ret_val = EOB_ACT_CONTINUE_SCAN;
+
+ yy_n_chars += number_to_move;
+ yy_current_buffer->yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR;
+ yy_current_buffer->yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR;
+
+ yytext_ptr = &yy_current_buffer->yy_ch_buf[0];
+
+ return ret_val;
+ }
+
+
+/* yy_get_previous_state - get the state just before the EOB char was reached */
+
+static yy_state_type yy_get_previous_state()
+ {
+ register yy_state_type yy_current_state;
+ register char *yy_cp;
+
+ yy_current_state = yy_start;
+
+ for ( yy_cp = yytext_ptr + YY_MORE_ADJ; yy_cp < yy_c_buf_p; ++yy_cp )
+ {
+ register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
+ if ( yy_accept[yy_current_state] )
+ {
+ yy_last_accepting_state = yy_current_state;
+ yy_last_accepting_cpos = yy_cp;
+ }
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 131 )
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ }
+
+ return yy_current_state;
+ }
+
+
+/* yy_try_NUL_trans - try to make a transition on the NUL character
+ *
+ * synopsis
+ * next_state = yy_try_NUL_trans( current_state );
+ */
+
+#ifdef YY_USE_PROTOS
+static yy_state_type yy_try_NUL_trans( yy_state_type yy_current_state )
+#else
+static yy_state_type yy_try_NUL_trans( yy_current_state )
+yy_state_type yy_current_state;
+#endif
+ {
+ register int yy_is_jam;
+ register char *yy_cp = yy_c_buf_p;
+
+ register YY_CHAR yy_c = 1;
+ if ( yy_accept[yy_current_state] )
+ {
+ yy_last_accepting_state = yy_current_state;
+ yy_last_accepting_cpos = yy_cp;
+ }
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 131 )
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ yy_is_jam = (yy_current_state == 130);
+
+ return yy_is_jam ? 0 : yy_current_state;
+ }
+
+
+#ifndef YY_NO_UNPUT
+#ifdef YY_USE_PROTOS
+static void yyunput( int c, register char *yy_bp )
+#else
+static void yyunput( c, yy_bp )
+int c;
+register char *yy_bp;
+#endif
+ {
+ register char *yy_cp = yy_c_buf_p;
+
+ /* undo effects of setting up yytext */
+ *yy_cp = yy_hold_char;
+
+ if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 )
+ { /* need to shift things up to make room */
+ /* +2 for EOB chars. */
+ register int number_to_move = yy_n_chars + 2;
+ register char *dest = &yy_current_buffer->yy_ch_buf[
+ yy_current_buffer->yy_buf_size + 2];
+ register char *source =
+ &yy_current_buffer->yy_ch_buf[number_to_move];
+
+ while ( source > yy_current_buffer->yy_ch_buf )
+ *--dest = *--source;
+
+ yy_cp += (int) (dest - source);
+ yy_bp += (int) (dest - source);
+ yy_current_buffer->yy_n_chars =
+ yy_n_chars = yy_current_buffer->yy_buf_size;
+
+ if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 )
+ YY_FATAL_ERROR( "flex scanner push-back overflow" );
+ }
+
+ *--yy_cp = (char) c;
+
+
+ yytext_ptr = yy_bp;
+ yy_hold_char = *yy_cp;
+ yy_c_buf_p = yy_cp;
+ }
+#endif /* ifndef YY_NO_UNPUT */
+
+
+#ifndef YY_NO_INPUT
+#ifdef __cplusplus
+static int yyinput()
+#else
+static int input()
+#endif
+ {
+ int c;
+
+ *yy_c_buf_p = yy_hold_char;
+
+ if ( *yy_c_buf_p == YY_END_OF_BUFFER_CHAR )
+ {
+ /* yy_c_buf_p now points to the character we want to return.
+ * If this occurs *before* the EOB characters, then it's a
+ * valid NUL; if not, then we've hit the end of the buffer.
+ */
+ if ( yy_c_buf_p < &yy_current_buffer->yy_ch_buf[yy_n_chars] )
+ /* This was really a NUL. */
+ *yy_c_buf_p = '\0';
+
+ else
+ { /* need more input */
+ int offset = yy_c_buf_p - yytext_ptr;
+ ++yy_c_buf_p;
+
+ switch ( yy_get_next_buffer() )
+ {
+ case EOB_ACT_LAST_MATCH:
+ /* This happens because yy_g_n_b()
+ * sees that we've accumulated a
+ * token and flags that we need to
+ * try matching the token before
+ * proceeding. But for input(),
+ * there's no matching to consider.
+ * So convert the EOB_ACT_LAST_MATCH
+ * to EOB_ACT_END_OF_FILE.
+ */
+
+ /* Reset buffer status. */
+ yyrestart( yyin );
+
+ /* fall through */
+
+ case EOB_ACT_END_OF_FILE:
+ {
+ if ( yywrap() )
+ return EOF;
+
+ if ( ! yy_did_buffer_switch_on_eof )
+ YY_NEW_FILE;
+#ifdef __cplusplus
+ return yyinput();
+#else
+ return input();
+#endif
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ yy_c_buf_p = yytext_ptr + offset;
+ break;
+ }
+ }
+ }
+
+ c = *(unsigned char *) yy_c_buf_p; /* cast for 8-bit char's */
+ *yy_c_buf_p = '\0'; /* preserve yytext */
+ yy_hold_char = *++yy_c_buf_p;
+
+
+ return c;
+ }
+#endif /* YY_NO_INPUT */
+
+#ifdef YY_USE_PROTOS
+void yyrestart( FILE *input_file )
+#else
+void yyrestart( input_file )
+FILE *input_file;
+#endif
+ {
+ if ( ! yy_current_buffer )
+ yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE );
+
+ yy_init_buffer( yy_current_buffer, input_file );
+ yy_load_buffer_state();
+ }
+
+
+#ifdef YY_USE_PROTOS
+void yy_switch_to_buffer( YY_BUFFER_STATE new_buffer )
+#else
+void yy_switch_to_buffer( new_buffer )
+YY_BUFFER_STATE new_buffer;
+#endif
+ {
+ if ( yy_current_buffer == new_buffer )
+ return;
+
+ if ( yy_current_buffer )
+ {
+ /* Flush out information for old buffer. */
+ *yy_c_buf_p = yy_hold_char;
+ yy_current_buffer->yy_buf_pos = yy_c_buf_p;
+ yy_current_buffer->yy_n_chars = yy_n_chars;
+ }
+
+ yy_current_buffer = new_buffer;
+ yy_load_buffer_state();
+
+ /* We don't actually know whether we did this switch during
+ * EOF (yywrap()) processing, but the only time this flag
+ * is looked at is after yywrap() is called, so it's safe
+ * to go ahead and always set it.
+ */
+ yy_did_buffer_switch_on_eof = 1;
+ }
+
+
+#ifdef YY_USE_PROTOS
+void yy_load_buffer_state( void )
+#else
+void yy_load_buffer_state()
+#endif
+ {
+ yy_n_chars = yy_current_buffer->yy_n_chars;
+ yytext_ptr = yy_c_buf_p = yy_current_buffer->yy_buf_pos;
+ yyin = yy_current_buffer->yy_input_file;
+ yy_hold_char = *yy_c_buf_p;
+ }
+
+
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_create_buffer( FILE *file, int size )
+#else
+YY_BUFFER_STATE yy_create_buffer( file, size )
+FILE *file;
+int size;
+#endif
+ {
+ YY_BUFFER_STATE b;
+
+ b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) );
+ if ( ! b )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+ b->yy_buf_size = size;
+
+ /* yy_ch_buf has to be 2 characters longer than the size given because
+ * we need to put in 2 end-of-buffer characters.
+ */
+ b->yy_ch_buf = (char *) yy_flex_alloc( b->yy_buf_size + 2 );
+ if ( ! b->yy_ch_buf )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+ b->yy_is_our_buffer = 1;
+
+ yy_init_buffer( b, file );
+
+ return b;
+ }
+
+
+#ifdef YY_USE_PROTOS
+void yy_delete_buffer( YY_BUFFER_STATE b )
+#else
+void yy_delete_buffer( b )
+YY_BUFFER_STATE b;
+#endif
+ {
+ if ( ! b )
+ return;
+
+ if ( b == yy_current_buffer )
+ yy_current_buffer = (YY_BUFFER_STATE) 0;
+
+ if ( b->yy_is_our_buffer )
+ yy_flex_free( (void *) b->yy_ch_buf );
+
+ yy_flex_free( (void *) b );
+ }
+
+
+
+#ifdef YY_USE_PROTOS
+void yy_init_buffer( YY_BUFFER_STATE b, FILE *file )
+#else
+void yy_init_buffer( b, file )
+YY_BUFFER_STATE b;
+FILE *file;
+#endif
+
+
+ {
+ yy_flush_buffer( b );
+
+ b->yy_input_file = file;
+ b->yy_fill_buffer = 1;
+
+#if YY_ALWAYS_INTERACTIVE
+ b->yy_is_interactive = 1;
+#else
+#if YY_NEVER_INTERACTIVE
+ b->yy_is_interactive = 0;
+#else
+ b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
+#endif
+#endif
+ }
+
+
+#ifdef YY_USE_PROTOS
+void yy_flush_buffer( YY_BUFFER_STATE b )
+#else
+void yy_flush_buffer( b )
+YY_BUFFER_STATE b;
+#endif
+
+ {
+ if ( ! b )
+ return;
+
+ b->yy_n_chars = 0;
+
+ /* We always need two end-of-buffer characters. The first causes
+ * a transition to the end-of-buffer state. The second causes
+ * a jam in that state.
+ */
+ b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
+ b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
+
+ b->yy_buf_pos = &b->yy_ch_buf[0];
+
+ b->yy_at_bol = 1;
+ b->yy_buffer_status = YY_BUFFER_NEW;
+
+ if ( b == yy_current_buffer )
+ yy_load_buffer_state();
+ }
+
+
+#ifndef YY_NO_SCAN_BUFFER
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_scan_buffer( char *base, yy_size_t size )
+#else
+YY_BUFFER_STATE yy_scan_buffer( base, size )
+char *base;
+yy_size_t size;
+#endif
+ {
+ YY_BUFFER_STATE b;
+
+ if ( size < 2 ||
+ base[size-2] != YY_END_OF_BUFFER_CHAR ||
+ base[size-1] != YY_END_OF_BUFFER_CHAR )
+ /* They forgot to leave room for the EOB's. */
+ return 0;
+
+ b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) );
+ if ( ! b )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" );
+
+ b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */
+ b->yy_buf_pos = b->yy_ch_buf = base;
+ b->yy_is_our_buffer = 0;
+ b->yy_input_file = 0;
+ b->yy_n_chars = b->yy_buf_size;
+ b->yy_is_interactive = 0;
+ b->yy_at_bol = 1;
+ b->yy_fill_buffer = 0;
+ b->yy_buffer_status = YY_BUFFER_NEW;
+
+ yy_switch_to_buffer( b );
+
+ return b;
+ }
+#endif
+
+
+#ifndef YY_NO_SCAN_STRING
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_scan_string( yyconst char *yy_str )
+#else
+YY_BUFFER_STATE yy_scan_string( yy_str )
+yyconst char *yy_str;
+#endif
+ {
+ int len;
+ for ( len = 0; yy_str[len]; ++len )
+ ;
+
+ return yy_scan_bytes( yy_str, len );
+ }
+#endif
+
+
+#ifndef YY_NO_SCAN_BYTES
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_scan_bytes( yyconst char *bytes, int len )
+#else
+YY_BUFFER_STATE yy_scan_bytes( bytes, len )
+yyconst char *bytes;
+int len;
+#endif
+ {
+ YY_BUFFER_STATE b;
+ char *buf;
+ yy_size_t n;
+ int i;
+
+ /* Get memory for full buffer, including space for trailing EOB's. */
+ n = len + 2;
+ buf = (char *) yy_flex_alloc( n );
+ if ( ! buf )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
+
+ for ( i = 0; i < len; ++i )
+ buf[i] = bytes[i];
+
+ buf[len] = buf[len+1] = YY_END_OF_BUFFER_CHAR;
+
+ b = yy_scan_buffer( buf, n );
+ if ( ! b )
+ YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" );
+
+ /* It's okay to grow etc. this buffer, and we should throw it
+ * away when we're done.
+ */
+ b->yy_is_our_buffer = 1;
+
+ return b;
+ }
+#endif
+
+
+#ifndef YY_NO_PUSH_STATE
+#ifdef YY_USE_PROTOS
+static void yy_push_state( int new_state )
+#else
+static void yy_push_state( new_state )
+int new_state;
+#endif
+ {
+ if ( yy_start_stack_ptr >= yy_start_stack_depth )
+ {
+ yy_size_t new_size;
+
+ yy_start_stack_depth += YY_START_STACK_INCR;
+ new_size = yy_start_stack_depth * sizeof( int );
+
+ if ( ! yy_start_stack )
+ yy_start_stack = (int *) yy_flex_alloc( new_size );
+
+ else
+ yy_start_stack = (int *) yy_flex_realloc(
+ (void *) yy_start_stack, new_size );
+
+ if ( ! yy_start_stack )
+ YY_FATAL_ERROR(
+ "out of memory expanding start-condition stack" );
+ }
+
+ yy_start_stack[yy_start_stack_ptr++] = YY_START;
+
+ BEGIN(new_state);
+ }
+#endif
+
+
+#ifndef YY_NO_POP_STATE
+static void yy_pop_state()
+ {
+ if ( --yy_start_stack_ptr < 0 )
+ YY_FATAL_ERROR( "start-condition stack underflow" );
+
+ BEGIN(yy_start_stack[yy_start_stack_ptr]);
+ }
+#endif
+
+
+#ifndef YY_NO_TOP_STATE
+static int yy_top_state()
+ {
+ return yy_start_stack[yy_start_stack_ptr - 1];
+ }
+#endif
+
+#ifndef YY_EXIT_FAILURE
+#define YY_EXIT_FAILURE 2
+#endif
+
+#ifdef YY_USE_PROTOS
+static void yy_fatal_error( yyconst char msg[] )
+#else
+static void yy_fatal_error( msg )
+char msg[];
+#endif
+ {
+ (void) fprintf( stderr, "%s\n", msg );
+ exit( YY_EXIT_FAILURE );
+ }
+
+
+
+/* Redefine yyless() so it works in section 3 code. */
+
+#undef yyless
+#define yyless(n) \
+ do \
+ { \
+ /* Undo effects of setting up yytext. */ \
+ yytext[yyleng] = yy_hold_char; \
+ yy_c_buf_p = yytext + n; \
+ yy_hold_char = *yy_c_buf_p; \
+ *yy_c_buf_p = '\0'; \
+ yyleng = n; \
+ } \
+ while ( 0 )
+
+
+/* Internal utility routines. */
+
+#ifndef yytext_ptr
+#ifdef YY_USE_PROTOS
+static void yy_flex_strncpy( char *s1, yyconst char *s2, int n )
+#else
+static void yy_flex_strncpy( s1, s2, n )
+char *s1;
+yyconst char *s2;
+int n;
+#endif
+ {
+ register int i;
+ for ( i = 0; i < n; ++i )
+ s1[i] = s2[i];
+ }
+#endif
+
+#ifdef YY_NEED_STRLEN
+#ifdef YY_USE_PROTOS
+static int yy_flex_strlen( yyconst char *s )
+#else
+static int yy_flex_strlen( s )
+yyconst char *s;
+#endif
+ {
+ register int n;
+ for ( n = 0; s[n]; ++n )
+ ;
+
+ return n;
+ }
+#endif
+
+
+#ifdef YY_USE_PROTOS
+static void *yy_flex_alloc( yy_size_t size )
+#else
+static void *yy_flex_alloc( size )
+yy_size_t size;
+#endif
+ {
+ return (void *) malloc( size );
+ }
+
+#ifdef YY_USE_PROTOS
+static void *yy_flex_realloc( void *ptr, yy_size_t size )
+#else
+static void *yy_flex_realloc( ptr, size )
+void *ptr;
+yy_size_t size;
+#endif
+ {
+ /* The cast to (char *) in the following accommodates both
+ * implementations that use char* generic pointers, and those
+ * that use void* generic pointers. It works with the latter
+ * because both ANSI C and C++ allow castless assignment from
+ * any pointer type to void*, and deal with argument conversions
+ * as though doing an assignment.
+ */
+ return (void *) realloc( (char *) ptr, size );
+ }
+
+#ifdef YY_USE_PROTOS
+static void yy_flex_free( void *ptr )
+#else
+static void yy_flex_free( ptr )
+void *ptr;
+#endif
+ {
+ free( ptr );
+ }
+
+#if YY_MAIN
+int main()
+ {
+ yylex();
+ return 0;
+ }
+#endif
+#line 165 "uscan.l"
+
+
+int
+process_line(
+ char * line)
+{
+ YY_BUFFER_STATE b;
+ int result;
+
+ b = yy_scan_string(line); /* tell lex to scan lineread */
+ result = yyparse(); /* parse lineread and act */
+ yy_delete_buffer(b);
+ return result;
+}
+
+static int
+ll_parse_date(
+ int type,
+ char * text)
+{
+ time_t now;
+ struct tm *t;
+ int y=2000, m=0, d=1, h=0, mi=0, s=0;
+ int ret;
+
+ now = time((time_t *)NULL);
+ t = localtime(&now);
+ if (t) {
+ y = 1900+t->tm_year;
+ m = t->tm_mon+1;
+ d = t->tm_mday;
+ }
+ switch(type) {
+ case 1:
+ if (sscanf(text, "---%d", &d) != 1) {
+ yyerror("invalid date");
+ }
+ break;
+ case 2:
+ if (sscanf(text, "--%d-%d", &m, &d) != 2) {
+ yyerror("invalid date");
+ }
+ break;
+ case 3:
+ if (sscanf(text, "%d-%d-%d", &y, &m, &d) != 3) {
+ yyerror("invalid date");
+ }
+ break;
+ case 4:
+ if (sscanf(text, "%d-%d-%d-%d-%d-%d", &y, &m, &d, &h, &mi, &s) != 6) {
+ yyerror("invalid date");
+ }
+ break;
+ case 5:
+ if (sscanf(text, "%d-%d-%d-%d-%d", &y, &m, &d, &h, &mi) != 5) {
+ yyerror("invalid date");
+ }
+ break;
+ }
+
+ ret = PATH; /* cause a parse error */
+ if(y < 70) {
+ y += 2000;
+ } else if(y < 100) {
+ y += 1900;
+ }
+ if(y < 1000 || y > 9999) {
+ yyerror("invalid year");
+ } else if(m < 1 || m > 12) {
+ yyerror("invalid month");
+ } else if(d < 1 || d > 31) {
+ yyerror("invalid day");
+ } else if(h < 0 || h > 24) {
+ yyerror("invalid hour");
+ } else if(mi < 0 || mi > 59) {
+ yyerror("invalid minute");
+ } else if(s < 0 || s > 59) {
+ yyerror("invalid second");
+ } else if(type < 4) {
+ yylval.strval = alloc(DATE_ALLOC_SIZE);
+ snprintf(yylval.strval, DATE_ALLOC_SIZE, "%04d-%02d-%02d", y, m, d);
+ ret = DATE;
+ } else {
+ yylval.strval = alloc(DATE_ALLOC_SIZE);
+ snprintf(yylval.strval, DATE_ALLOC_SIZE, "%04d-%02d-%02d-%02d-%02d-%02d", y, m, d, h, mi, s);
+ ret = DATE;
+ }
+ return ret;
+}
+
+int
+yywrap(void)
+{
+ return 1;
+}
--- /dev/null
+/*
+ * amanda, the advanced maryland automatic network disk archiver
+ * Copyright (c) 1991-2000 University of Maryland at College Park
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of U.M. not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. U.M. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: the Amanda Development Team. Its members are listed in a
+ * file named AUTHORS, in the root directory of this distribution.
+ */
+/*
+ * $Id: uscan.l,v 1.3 2006/07/05 11:15:56 martinea Exp $
+ *
+ * lexer for amrecover interactive language
+ */
+%{
+#include "amanda.h"
+#include "uparse.h"
+
+/*
+ * We redefine this here to prevent compiler warning about ignoring fwrite
+ * return value...
+ */
+#undef ECHO
+#define ECHO do { \
+ if (fwrite(yytext, (size_t)yyleng, 1, yyout) <= 0) { \
+ yyerror("ECHO failure"); \
+ } \
+ } while (0)
+
+#define YY_NO_UNPUT
+
+#define DATE_ALLOC_SIZE sizeof("YYYY-MM-DD-HH-MM-SS") /* includes null */
+
+#define YY_DECL int yylex()
+extern int yylex(void);
+
+extern void yyerror(char *s);
+extern int yyparse(void);
+static int ll_parse_date(int type, char *text);
+int process_line(char *line);
+%}
+
+%x quotedpath
+
+%{
+static char *string_buf = NULL;
+%}
+
+%%
+
+%{
+ /* literal keyword tokens */
+%}
+
+listhost { return LISTHOST; }
+listdisk { return LISTDISK; }
+sethost { return SETHOST; }
+setdisk { return SETDISK; }
+setdate { return SETDATE; }
+setmode { return SETMODE; }
+settape { return SETTAPE; }
+cd { return CD; }
+cdx { return CDX; }
+quit { return QUIT; }
+exit { return QUIT; }
+history { return DHIST; }
+ls { return LS; }
+add { return ADD; }
+addx { return ADDX; }
+list { return LIST; }
+delete { return DELETE; }
+deletex { return DELETEX; }
+pwd { return PWD; }
+clear { return CLEAR; }
+help { return HELP; }
+\? { return HELP; }
+lcd { return LCD; }
+lpwd { return LPWD; }
+extract { return EXTRACT; }
+smb { return SMB; }
+tar { return TAR; }
+mode { return MODE; }
+
+%{
+ /* dates */
+%}
+
+---[0-9]+ { return ll_parse_date(1, yytext); }
+--[0-9]+-[0-9]+ { return ll_parse_date(2, yytext); }
+[0-9]+-[0-9]+-[0-9]+ { return ll_parse_date(3, yytext); }
+[0-9]+-[0-9]+-[0-9]+-[0-9]+-[0-9]+-[0-9]+ { return ll_parse_date(4, yytext); }
+[0-9]+-[0-9]+-[0-9]+-[0-9]+-[0-9]+ { return ll_parse_date(5, yytext); }
+
+%{
+ /* quoted file names */
+%}
+
+\" {
+ if(string_buf != NULL) {
+ printf("ERROR:string_buf != NULL: %s\n",string_buf);
+ }
+ BEGIN(quotedpath);
+ strappend(string_buf, yytext);
+}
+
+<quotedpath>[^\\\"]+ {
+ strappend(string_buf, yytext);
+}
+
+<quotedpath>\\. {
+ /* escaped character (including quote) */
+ strappend(string_buf, yytext);
+}
+
+<quotedpath>\" { /* saw closing quote - all done */
+ strappend(string_buf, yytext);
+ yylval.strval = string_buf;
+ string_buf = NULL;
+ BEGIN(INITIAL);
+ return PATH;
+}
+
+%{
+ /* file names */
+%}
+
+[^[:space:][:cntrl:]"]+ {
+ yylval.strval = stralloc(yytext);
+ return PATH;
+}
+
+%{
+ /* whitespace */
+%}
+
+[[:space:]]+ ; /* whitespace */
+
+%{
+ /* anything else */
+ /* everything should have been handled by now, so this rule is disabled */
+%}
+
+%{
+#if 0
+. { yyerror("invalid character"); }
+#endif
+%}
+
+%%
+
+int
+process_line(
+ char * line)
+{
+ YY_BUFFER_STATE b;
+ int result;
+
+ b = yy_scan_string(line); /* tell lex to scan lineread */
+ result = yyparse(); /* parse lineread and act */
+ yy_delete_buffer(b);
+ return result;
+}
+
+static int
+ll_parse_date(
+ int type,
+ char * text)
+{
+ time_t now;
+ struct tm *t;
+ int y=2000, m=0, d=1, h=0, mi=0, s=0;
+ int ret;
+
+ now = time((time_t *)NULL);
+ t = localtime(&now);
+ if (t) {
+ y = 1900+t->tm_year;
+ m = t->tm_mon+1;
+ d = t->tm_mday;
+ }
+ switch(type) {
+ case 1:
+ if (sscanf(text, "---%d", &d) != 1) {
+ yyerror("invalid date");
+ }
+ break;
+ case 2:
+ if (sscanf(text, "--%d-%d", &m, &d) != 2) {
+ yyerror("invalid date");
+ }
+ break;
+ case 3:
+ if (sscanf(text, "%d-%d-%d", &y, &m, &d) != 3) {
+ yyerror("invalid date");
+ }
+ break;
+ case 4:
+ if (sscanf(text, "%d-%d-%d-%d-%d-%d", &y, &m, &d, &h, &mi, &s) != 6) {
+ yyerror("invalid date");
+ }
+ break;
+ case 5:
+ if (sscanf(text, "%d-%d-%d-%d-%d", &y, &m, &d, &h, &mi) != 5) {
+ yyerror("invalid date");
+ }
+ break;
+ }
+
+ ret = PATH; /* cause a parse error */
+ if(y < 70) {
+ y += 2000;
+ } else if(y < 100) {
+ y += 1900;
+ }
+ if(y < 1000 || y > 9999) {
+ yyerror("invalid year");
+ } else if(m < 1 || m > 12) {
+ yyerror("invalid month");
+ } else if(d < 1 || d > 31) {
+ yyerror("invalid day");
+ } else if(h < 0 || h > 24) {
+ yyerror("invalid hour");
+ } else if(mi < 0 || mi > 59) {
+ yyerror("invalid minute");
+ } else if(s < 0 || s > 59) {
+ yyerror("invalid second");
+ } else if(type < 4) {
+ yylval.strval = alloc(DATE_ALLOC_SIZE);
+ snprintf(yylval.strval, DATE_ALLOC_SIZE, "%04d-%02d-%02d", y, m, d);
+ ret = DATE;
+ } else {
+ yylval.strval = alloc(DATE_ALLOC_SIZE);
+ snprintf(yylval.strval, DATE_ALLOC_SIZE, "%04d-%02d-%02d-%02d-%02d-%02d", y, m, d, h, mi, s);
+ ret = DATE;
+ }
+ return ret;
+}
+
+int
+yywrap(void)
+{
+ return 1;
+}
INCLUDES = -I$(top_builddir)/common-src \
-I$(top_srcdir)/common-src \
- -I$(top_srcdir)/client-src \
- -I$(top_srcdir)/tape-src
+ -I$(top_srcdir)/client-src
+
+LINT=@AMLINT@
+LINTFLAGS=@AMLINTFLAGS@
LIB_EXTENSION = la
LDADD = ../common-src/libamanda.$(LIB_EXTENSION) \
@LEXLIB@ \
- ../client-src/libamclient.$(LIB_EXTENSION)
-if WANT_SERVER
-LDADD += ../tape-src/libamtape.$(LIB_EXTENSION)
-endif
-LDADD += ../common-src/libamanda.$(LIB_EXTENSION) \
+ ../client-src/libamclient.$(LIB_EXTENSION) \
+ ../common-src/libamanda.$(LIB_EXTENSION) \
$(READLINE_LIBS)
-amrecover_SOURCES = amrecover.c \
+amrecover_CSRC = amrecover.c \
display_commands.c extract_list.c \
- help.c set_commands.c \
- uparse.y uscan.l
+ help.c set_commands.c
+
+amrecover_SOURCES = $(amrecover_CSRC) uparse.y uscan.l
noinst_HEADERS = amrecover.h uparse.h
AM_YFLAGS = -d
+# so that uscan.c is never generated before uparse.h
+# otherwise we might have makedepend problems
+$(srcdir)/uscan.c: $(srcdir)/uparse.h
+
+uscan.$(OBJEXT): $(srcdir)/uscan.c
+ $(CC) $(CFLAGS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CPPFLAGS) -c $<
+
+uparse.$(OBJEXT): $(srcdir)/uparse.c
+ $(CC) $(CFLAGS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CPPFLAGS) -c $<
+
+
install-exec-hook:
@list="$(sbin_PROGRAMS)"; \
for p in $$list; do \
chmod o-rwx $$pa; \
done
-# so that uscan.c is never generated before uparse.h
-# otherwise we might have makedepend problems
-uscan.c: uparse.h
+
+lint:
+ @f="$(amrecover_CSRC)"; \
+ (cd ../common-src; make listlibsrc); \
+ f="$$f "`cat ../common-src/listlibsrc.output`; \
+ (cd ../server-src; make listlibsrc); \
+ f="$$f "`cat ../server-src/listlibsrc.output`; \
+ echo $(LINT) $$f; \
+ $(LINT) $(LINTFLAGS) $(CPPFLAGS) $(DEFS) -I. -I../config $(INCLUDES) $$f;\
+ if [ $$? -ne 0 ]; then \
+ exit 1; \
+ fi; \
+ exit 0
+
host_triplet = @host@
target_triplet = @target@
sbin_PROGRAMS = amrecover$(EXEEXT)
-@WANT_SERVER_TRUE@am__append_1 = ../tape-src/libamtape.$(LIB_EXTENSION)
subdir = recover-src
DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \
$(srcdir)/Makefile.in uparse.c uparse.h uscan.c
am__installdirs = "$(DESTDIR)$(sbindir)"
sbinPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
PROGRAMS = $(sbin_PROGRAMS)
-am_amrecover_OBJECTS = amrecover.$(OBJEXT) display_commands.$(OBJEXT) \
- extract_list.$(OBJEXT) help.$(OBJEXT) set_commands.$(OBJEXT) \
- uparse.$(OBJEXT) uscan.$(OBJEXT)
+am__objects_1 = amrecover.$(OBJEXT) display_commands.$(OBJEXT) \
+ extract_list.$(OBJEXT) help.$(OBJEXT) set_commands.$(OBJEXT)
+am_amrecover_OBJECTS = $(am__objects_1) uparse.$(OBJEXT) \
+ uscan.$(OBJEXT)
amrecover_OBJECTS = $(am_amrecover_OBJECTS)
amrecover_LDADD = $(LDADD)
-@WANT_SERVER_TRUE@am__DEPENDENCIES_1 = \
-@WANT_SERVER_TRUE@ ../tape-src/libamtape.$(LIB_EXTENSION)
-am__DEPENDENCIES_2 =
+am__DEPENDENCIES_1 =
amrecover_DEPENDENCIES = ../common-src/libamanda.$(LIB_EXTENSION) \
../client-src/libamclient.$(LIB_EXTENSION) \
- $(am__DEPENDENCIES_1) ../common-src/libamanda.$(LIB_EXTENSION) \
- $(am__DEPENDENCIES_2)
+ ../common-src/libamanda.$(LIB_EXTENSION) $(am__DEPENDENCIES_1)
DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)/config
depcomp = $(SHELL) $(top_srcdir)/config/depcomp
am__depfiles_maybe = depfiles
AMANDA_TMPDIR = @AMANDA_TMPDIR@
AMDEP_FALSE = @AMDEP_FALSE@
AMDEP_TRUE = @AMDEP_TRUE@
+AMLINT = @AMLINT@
+AMLINTFLAGS = @AMLINTFLAGS@
AMPLOT_CAT_COMPRESS = @AMPLOT_CAT_COMPRESS@
AMPLOT_CAT_GZIP = @AMPLOT_CAT_GZIP@
AMPLOT_CAT_PACK = @AMPLOT_CAT_PACK@
AMPLOT_COMPRESS = @AMPLOT_COMPRESS@
AMTAR = @AMTAR@
+AM_CFLAGS = @AM_CFLAGS@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AWK = @AWK@
AWK_VAR_ASSIGNMENT_OPT = @AWK_VAR_ASSIGNMENT_OPT@
BINARY_OWNER = @BINARY_OWNER@
+BUILD_MAN_PAGES_FALSE = @BUILD_MAN_PAGES_FALSE@
+BUILD_MAN_PAGES_TRUE = @BUILD_MAN_PAGES_TRUE@
CAT = @CAT@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
target_vendor = @target_vendor@
INCLUDES = -I$(top_builddir)/common-src \
-I$(top_srcdir)/common-src \
- -I$(top_srcdir)/client-src \
- -I$(top_srcdir)/tape-src
+ -I$(top_srcdir)/client-src
+LINT = @AMLINT@
+LINTFLAGS = @AMLINTFLAGS@
LIB_EXTENSION = la
@WANT_RUNTIME_PSEUDO_RELOC_TRUE@AM_LDFLAGS = -Wl,-enable-runtime-pseudo-reloc
# need to list libamanda twice here, first to override the system library
# routines, and second to pick up any references in the other libraries.
###
-LDADD = ../common-src/libamanda.$(LIB_EXTENSION) @LEXLIB@ \
- ../client-src/libamclient.$(LIB_EXTENSION) $(am__append_1) \
- ../common-src/libamanda.$(LIB_EXTENSION) $(READLINE_LIBS)
-amrecover_SOURCES = amrecover.c \
+LDADD = ../common-src/libamanda.$(LIB_EXTENSION) \
+ @LEXLIB@ \
+ ../client-src/libamclient.$(LIB_EXTENSION) \
+ ../common-src/libamanda.$(LIB_EXTENSION) \
+ $(READLINE_LIBS)
+
+amrecover_CSRC = amrecover.c \
display_commands.c extract_list.c \
- help.c set_commands.c \
- uparse.y uscan.l
+ help.c set_commands.c
+amrecover_SOURCES = $(amrecover_CSRC) uparse.y uscan.l
noinst_HEADERS = amrecover.h uparse.h
AM_YFLAGS = -d
all: all-am
uninstall-sbinPROGRAMS
+# so that uscan.c is never generated before uparse.h
+# otherwise we might have makedepend problems
+$(srcdir)/uscan.c: $(srcdir)/uparse.h
+
+uscan.$(OBJEXT): $(srcdir)/uscan.c
+ $(CC) $(CFLAGS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CPPFLAGS) -c $<
+
+uparse.$(OBJEXT): $(srcdir)/uparse.c
+ $(CC) $(CFLAGS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CPPFLAGS) -c $<
+
install-exec-hook:
@list="$(sbin_PROGRAMS)"; \
for p in $$list; do \
chmod o-rwx $$pa; \
done
-# so that uscan.c is never generated before uparse.h
-# otherwise we might have makedepend problems
-uscan.c: uparse.h
+lint:
+ @f="$(amrecover_CSRC)"; \
+ (cd ../common-src; make listlibsrc); \
+ f="$$f "`cat ../common-src/listlibsrc.output`; \
+ (cd ../server-src; make listlibsrc); \
+ f="$$f "`cat ../server-src/listlibsrc.output`; \
+ echo $(LINT) $$f; \
+ $(LINT) $(LINTFLAGS) $(CPPFLAGS) $(DEFS) -I. -I../config $(INCLUDES) $$f;\
+ if [ $$? -ne 0 ]; then \
+ exit 1; \
+ fi; \
+ exit 0
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
* file named AUTHORS, in the root directory of this distribution.
*/
/*
- * $Id: amrecover.c,v 1.52 2006/01/14 04:37:19 paddy_s Exp $
+ * $Id: amrecover.c,v 1.73 2006/07/25 18:27:57 martinea Exp $
*
* an interactive program for recovering backed-up files
*/
#include "amanda.h"
#include "version.h"
-#ifdef HAVE_NETINET_IN_SYSTM_H
-#include <netinet/in_systm.h>
-#endif
-#include <netinet/in.h>
-#ifdef HAVE_NETINET_IP_H
-#include <netinet/ip.h>
-#endif
#include "stream.h"
#include "amfeatures.h"
#include "amrecover.h"
#include "getfsent.h"
#include "dgram.h"
#include "util.h"
+#include "clientconf.h"
+#include "protocol.h"
+#include "event.h"
+#include "security.h"
-#ifdef HAVE_LIBREADLINE
-# ifdef HAVE_READLINE_READLINE_H
-# include <readline/readline.h>
-# ifdef HAVE_READLINE_HISTORY_H
-# include <readline/history.h>
-# endif
-# else
-# ifdef HAVE_READLINE_H
-# include <readline.h>
-# ifdef HAVE_HISTORY_H
-# include <history.h>
-# endif
-# else
-# undef HAVE_LIBREADLINE
-# endif
-# endif
-#endif
-
-extern int process_line P((char *line));
-int guess_disk P((char *cwd, size_t cwd_len, char **dn_guess, char **mpt_guess));
+extern int process_line(char *line);
+int get_line(void);
+int grab_reply(int show);
+void sigint_handler(int signum);
+int main(int argc, char **argv);
-#define USAGE "Usage: amrecover [[-C] <config>] [-s <index-server>] [-t <tape-server>] [-d <tape-device>]\n"
+#define USAGE "Usage: amrecover [[-C] <config>] [-s <index-server>] [-t <tape-server>] [-d <tape-device>] [-o <clientconfigoption>]*\n"
char *config = NULL;
char *server_name = NULL;
int tape_server_socket;
char *tape_device_name = NULL;
am_feature_t *our_features = NULL;
+char *our_features_string = NULL;
am_feature_t *indexsrv_features = NULL;
am_feature_t *tapesrv_features = NULL;
-
-
-#ifndef HAVE_LIBREADLINE
-/*
- * simple readline() replacements
- */
-
-char *
-readline(prompt)
-char *prompt;
-{
- printf("%s",prompt);
- fflush(stdout); fflush(stderr);
- return agets(stdin);
-}
-
-#define add_history(x) /* add_history((x)) */
-
-#endif
-
+static char *errstr = NULL;
+char *authopt;
+int amindexd_alive = 0;
+
+static struct {
+ const char *name;
+ security_stream_t *fd;
+} streams[] = {
+#define MESGFD 0
+ { "MESG", NULL },
+};
+#define NSTREAMS (int)(sizeof(streams) / sizeof(streams[0]))
+
+static void amindexd_response(void *, pkt_t *, security_handle_t *);
+void stop_amindexd(void);
+char *amindexd_client_get_security_conf(char *, void *);
+
+static char* mesg_buffer = NULL;
/* gets a "line" from server and put in server_line */
/* server_line is terminated with \0, \r\n is striped */
/* returns -1 if error */
-int get_line ()
+int
+get_line(void)
{
- char *line = NULL;
- char *part = NULL;
- size_t len;
-
- while(1) {
- if((part = areads(server_socket)) == NULL) {
- int save_errno = errno;
-
- if(server_line) {
- fputs(server_line, stderr); /* show the last line read */
- fputc('\n', stderr);
- }
- if(save_errno != 0) {
- fprintf(stderr, "%s: Error reading line from server: %s\n",
- get_pname(),
- strerror(save_errno));
- } else {
- fprintf(stderr, "%s: Unexpected end of file, check amindexd*debug on server %s\n",
- get_pname(),
- server_name);
- }
- amfree(line);
- amfree(server_line);
- errno = save_errno;
+ ssize_t size;
+ char *newbuf, *s;
+ void *buf;
+
+ if (!mesg_buffer)
+ mesg_buffer = stralloc("");
+
+ while (!strstr(mesg_buffer,"\r\n")) {
+ size = security_stream_read_sync(streams[MESGFD].fd, &buf);
+ if(size < 0) {
return -1;
}
- if(line) {
- strappend(line, part);
- amfree(part);
- } else {
- line = part;
- part = NULL;
- }
- if((len = strlen(line)) > 0 && line[len-1] == '\r') {
- line[len-1] = '\0';
- server_line = newstralloc(server_line, line);
- amfree(line);
- return 0;
+ else if(size == 0) {
+ return -1;
}
- /*
- * Hmmm. We got a "line" from areads(), which means it saw
- * a '\n' (or EOF, etc), but there was not a '\r' before it.
- * Put a '\n' back in the buffer and loop for more.
- */
- strappend(line, "\n");
+ newbuf = alloc(strlen(mesg_buffer)+size+1);
+ strncpy(newbuf, mesg_buffer, (size_t)(strlen(mesg_buffer) + size));
+ memcpy(newbuf+strlen(mesg_buffer), buf, (size_t)size);
+ newbuf[strlen(mesg_buffer)+size] = '\0';
+ amfree(mesg_buffer);
+ mesg_buffer = newbuf;
}
+
+ s = strstr(mesg_buffer,"\r\n");
+ *s = '\0';
+ newbuf = stralloc(s+2);
+ server_line = newstralloc(server_line, mesg_buffer);
+ amfree(mesg_buffer);
+ mesg_buffer = newbuf;
+ return 0;
}
/* return -1 if error */
/* return code returned by server always occupies first 3 bytes of global
variable server_line */
-int grab_reply (show)
-int show;
+int
+grab_reply(
+ int show)
{
do {
if (get_line() == -1) {
/* get 1 line of reply */
/* returns -1 if error, 0 if last (or only) line, 1 if more to follow */
-int get_reply_line ()
+int
+get_reply_line(void)
{
if (get_line() == -1)
return -1;
/* returns pointer to returned line */
-char *reply_line ()
+char *
+reply_line(void)
{
return server_line;
}
/* returns 0 if server returned an error code (ie code starting with 5)
and non-zero otherwise */
-int server_happy ()
+int
+server_happy(void)
{
return server_line[0] != '5';
}
-int send_command(cmd)
-char *cmd;
+int
+send_command(
+ char * cmd)
{
/*
* NOTE: this routine is called from sigint_handler, so we must be
* our state at the time the interrupt happened. For instance,
* do not use any stdio or malloc routines here.
*/
- struct iovec msg[2];
- ssize_t bytes;
+ char *buffer;
- msg[0].iov_base = cmd;
- msg[0].iov_len = strlen(msg[0].iov_base);
- msg[1].iov_base = "\r\n";
- msg[1].iov_len = strlen(msg[1].iov_base);
- bytes = msg[0].iov_len + msg[1].iov_len;
+ buffer = alloc(strlen(cmd)+3);
+ strncpy(buffer, cmd, strlen(cmd));
+ buffer[strlen(cmd)] = '\r';
+ buffer[strlen(cmd)+1] = '\n';
+ buffer[strlen(cmd)+2] = '\0';
- if (writev(server_socket, msg, 2) < bytes) {
+ if(security_stream_write(streams[MESGFD].fd, buffer, strlen(buffer)) < 0) {
return -1;
}
+ amfree(buffer);
return (0);
}
/* send a command to the server, get reply and print to screen */
-int converse(cmd)
-char *cmd;
+int
+converse(
+ char * cmd)
{
if (send_command(cmd) == -1) return -1;
if (grab_reply(1) == -1) return -1;
/* same as converse() but reply not echoed to stdout */
-int exchange(cmd)
-char *cmd;
+int
+exchange(
+ char * cmd)
{
if (send_command(cmd) == -1) return -1;
if (grab_reply(0) == -1) return -1;
/* basic interrupt handler for when user presses ^C */
/* Bale out, letting server know before doing so */
-void sigint_handler(signum)
-int signum;
+void
+sigint_handler(
+ int signum)
{
/*
* NOTE: we must be **very** careful about what we do here since there
* routines. Also, use _exit() instead of exit() to make sure stdio
* buffer flushing is not attempted.
*/
+ (void)signum; /* Quiet unused parameter warning */
+
if (extract_restore_child_pid != -1)
(void)kill(extract_restore_child_pid, SIGKILL);
extract_restore_child_pid = -1;
- (void)send_command("QUIT");
+ if(amindexd_alive)
+ (void)send_command("QUIT");
+
_exit(1);
}
-void clean_pathname(s)
-char *s;
+void
+clean_pathname(
+ char * s)
{
size_t length;
length = strlen(s);
}
-/* try and guess the disk the user is currently on.
- Return -1 if error, 0 if disk not local, 1 if disk local,
- 2 if disk local but can't guess name */
-/* do this by looking for the longest mount point which matches the
- current directory */
-int guess_disk (cwd, cwd_len, dn_guess, mpt_guess)
- char *cwd, **dn_guess, **mpt_guess;
- size_t cwd_len;
-{
- size_t longest_match = 0;
- size_t current_length;
- size_t cwd_length;
- int local_disk = 0;
- generic_fsent_t fsent;
- char *fsname = NULL;
- char *disk_try = NULL;
-
- *dn_guess = *mpt_guess = NULL;
-
- if (getcwd(cwd, cwd_len) == NULL)
- return -1;
- cwd_length = strlen(cwd);
- dbprintf(("guess_disk: %d: \"%s\"\n", cwd_length, cwd));
-
- if (open_fstab() == 0)
- return -1;
-
- while (get_fstab_nextentry(&fsent))
- {
- current_length = fsent.mntdir ? strlen(fsent.mntdir) : (size_t)0;
- dbprintf(("guess_disk: %d: %d: \"%s\": \"%s\"\n",
- longest_match,
- current_length,
- fsent.mntdir ? fsent.mntdir : "(mntdir null)",
- fsent.fsname ? fsent.fsname : "(fsname null)"));
- if ((current_length > longest_match)
- && (current_length <= cwd_length)
- && (strncmp(fsent.mntdir, cwd, current_length) == 0))
- {
- longest_match = current_length;
- amfree(*mpt_guess);
- *mpt_guess = stralloc(fsent.mntdir);
- if(strncmp(fsent.fsname,DEV_PREFIX,(strlen(DEV_PREFIX))))
- {
- fsname = newstralloc(fsname, fsent.fsname);
- }
- else
- {
- fsname = newstralloc(fsname,fsent.fsname+strlen(DEV_PREFIX));
- }
- local_disk = is_local_fstype(&fsent);
- dbprintf(("guess_disk: local_disk = %d, fsname = \"%s\"\n",
- local_disk,
- fsname));
- }
- }
- close_fstab();
-
- if (longest_match == 0) {
- amfree(*mpt_guess);
- amfree(fsname);
- return -1; /* ? at least / should match */
- }
-
- if (!local_disk) {
- amfree(*mpt_guess);
- amfree(fsname);
- return 0;
- }
-
- /* have mount point now */
- /* disk name may be specified by mount point (logical name) or
- device name, have to determine */
- printf("Trying disk %s ...\n", *mpt_guess);
- disk_try = stralloc2("DISK ", *mpt_guess); /* try logical name */
- if (exchange(disk_try) == -1)
- exit(1);
- amfree(disk_try);
- if (server_happy())
- {
- *dn_guess = stralloc(*mpt_guess); /* logical is okay */
- amfree(fsname);
- return 1;
- }
- printf("Trying disk %s ...\n", fsname);
- disk_try = stralloc2("DISK ", fsname); /* try device name */
- if (exchange(disk_try) == -1)
- exit(1);
- amfree(disk_try);
- if (server_happy())
- {
- *dn_guess = stralloc(fsname); /* dev name is okay */
- amfree(fsname);
- return 1;
- }
-
- /* neither is okay */
- amfree(*mpt_guess);
- amfree(fsname);
- return 2;
-}
-
-
-void quit ()
+void
+quit(void)
{
quit_prog = 1;
(void)converse("QUIT");
+ stop_amindexd();
}
char *localhost = NULL;
-int main(argc, argv)
-int argc;
-char **argv;
+#ifdef DEFAULT_TAPE_SERVER
+# define DEFAULT_TAPE_SERVER_FAILOVER (DEFAULT_TAPE_SERVER)
+#else
+# define DEFAULT_TAPE_SERVER_FAILOVER (NULL)
+#endif
+
+int
+main(
+ int argc,
+ char ** argv)
{
- int my_port;
- struct servent *sp;
int i;
time_t timer;
char *lineread = NULL;
struct sigaction act, oact;
extern char *optarg;
extern int optind;
- char cwd[STR_SIZE], *dn_guess = NULL, *mpt_guess = NULL;
- char *service_name;
char *line = NULL;
+ char *conffile;
+ const security_driver_t *secdrv;
+ char *req = NULL;
+ int response_error;
+ int new_argc;
+ char **new_argv;
+ struct tm *tm;
safe_fd(-1, 0);
/* Don't die when child closes pipe */
signal(SIGPIPE, SIG_IGN);
- dbopen();
+ dbopen(DBG_SUBDIR_CLIENT);
#ifndef IGNORE_UID_CHECK
if (geteuid() != 0) {
erroutput_type |= ERR_SYSLOG;
error("amrecover must be run by root");
+ /*NOTREACHED*/
}
#endif
localhost = alloc(MAX_HOSTNAME_LENGTH+1);
if (gethostname(localhost, MAX_HOSTNAME_LENGTH) != 0) {
error("cannot determine local host name\n");
+ /*NOTREACHED*/
}
localhost[MAX_HOSTNAME_LENGTH] = '\0';
- config = newstralloc(config, DEFAULT_CONFIG);
- server_name = newstralloc(server_name, DEFAULT_SERVER);
-#ifdef DEFAULT_TAPE_SERVER
- tape_server_name = newstralloc(tape_server_name, DEFAULT_TAPE_SERVER);
-#else
- amfree(tape_server_name);
-#endif
- if (argc > 1 && argv[1][0] != '-')
- {
+ parse_client_conf(argc, argv, &new_argc, &new_argv);
+
+ if (new_argc > 1 && new_argv[1][0] != '-') {
/*
* If the first argument is not an option flag, then we assume
* it is a configuration name to match the syntax of the other
* Amanda utilities.
*/
- char **new_argv;
+ char **new_argv1;
- new_argv = (char **) alloc ((argc + 1 + 1) * sizeof (*new_argv));
- new_argv[0] = argv[0];
- new_argv[1] = "-C";
- for (i = 1; i < argc; i++)
- {
- new_argv[i + 1] = argv[i];
+ new_argv1 = (char **) alloc((size_t)((new_argc + 1 + 1) * sizeof(*new_argv1)));
+ new_argv1[0] = new_argv[0];
+ new_argv1[1] = "-C";
+ for (i = 1; i < new_argc; i++) {
+ new_argv1[i + 1] = new_argv[i];
}
- new_argv[i + 1] = NULL;
- argc++;
- argv = new_argv;
+ new_argv1[i + 1] = NULL;
+ new_argc++;
+ amfree(new_argv);
+ new_argv = new_argv1;
}
- while ((i = getopt(argc, argv, "C:s:t:d:U")) != EOF)
- {
- switch (i)
- {
+ while ((i = getopt(new_argc, new_argv, "C:s:t:d:U")) != EOF) {
+ switch (i) {
case 'C':
- config = newstralloc(config, optarg);
+ add_client_conf(CLN_CONF, optarg);
+ //config = newstralloc(config, optarg);
break;
case 's':
- server_name = newstralloc(server_name, optarg);
+ add_client_conf(CLN_INDEX_SERVER, optarg);
+ //server_name = newstralloc(server_name, optarg);
break;
case 't':
- tape_server_name = newstralloc(tape_server_name, optarg);
+ add_client_conf(CLN_TAPE_SERVER, optarg);
+ //tape_server_name = newstralloc(tape_server_name, optarg);
break;
case 'd':
- tape_device_name = newstralloc(tape_device_name, optarg);
+ add_client_conf(CLN_TAPEDEV, optarg);
+ //tape_device_name = newstralloc(tape_device_name, optarg);
break;
case 'U':
return 0;
}
}
- if (optind != argc)
- {
+ if (optind != new_argc) {
(void)fprintf(stderr, USAGE);
exit(1);
}
+ our_features = am_init_feature_set();
+ our_features_string = am_feature_to_string(our_features);
+
+ conffile = vstralloc(CONFIG_DIR, "/", "amanda-client.conf", NULL);
+ if (read_clientconf(conffile) > 0) {
+ error("error reading conffile: %s", conffile);
+ /*NOTREACHED*/
+ }
+ amfree(conffile);
+
+ config = stralloc(client_getconf_str(CLN_CONF));
+
+ conffile = vstralloc(CONFIG_DIR, "/", config, "/", "amanda-client.conf",
+ NULL);
+ if (read_clientconf(conffile) > 0) {
+ error("error reading conffile: %s", conffile);
+ /*NOTREACHED*/
+ }
+ amfree(conffile);
+
+ dbrename(config, DBG_SUBDIR_CLIENT);
+
+ report_bad_client_arg();
+
+ amfree(server_name);
+ server_name = getenv("AMANDA_SERVER");
+ if(!server_name) server_name = client_getconf_str(CLN_INDEX_SERVER);
+ server_name = stralloc(server_name);
+
+ amfree(tape_server_name);
+ tape_server_name = getenv("AMANDA_TAPESERVER");
+ if(!tape_server_name) tape_server_name = client_getconf_str(CLN_TAPE_SERVER);
+ tape_server_name = stralloc(tape_server_name);
+
+ amfree(tape_device_name);
+ tape_device_name = client_getconf_str(CLN_TAPEDEV);
+ if (tape_device_name)
+ tape_device_name = stralloc(tape_device_name);
+
+ authopt = stralloc(client_getconf_str(CLN_AUTH));
+
+
amfree(disk_name);
amfree(mount_point);
amfree(disk_path);
act.sa_handler = sigint_handler;
sigemptyset(&act.sa_mask);
act.sa_flags = 0;
- if (sigaction(SIGINT, &act, &oact) != 0)
- {
+ if (sigaction(SIGINT, &act, &oact) != 0) {
error("error setting signal handler: %s", strerror(errno));
+ /*NOTREACHED*/
}
- service_name = stralloc2("amandaidx", SERVICE_SUFFIX);
+ protocol_init();
+
+ /* We assume that amindexd support fe_amindexd_options_features */
+ /* and fe_amindexd_options_auth */
+ /* We should send a noop to really know */
+ req = vstralloc("SERVICE amindexd\n",
+ "OPTIONS ", "features=", our_features_string, ";",
+ "auth=", authopt, ";",
+ "\n", NULL);
+
+ secdrv = security_getdriver(authopt);
+ if (secdrv == NULL) {
+ error("no '%s' security driver available for host '%s'",
+ authopt, server_name);
+ /*NOTREACHED*/
+ }
+
+ protocol_sendreq(server_name, secdrv, amindexd_client_get_security_conf,
+ req, STARTUP_TIMEOUT, amindexd_response, &response_error);
+
+ amfree(req);
+ protocol_run();
printf("AMRECOVER Version %s. Contacting server on %s ...\n",
- version(), server_name);
- if ((sp = getservbyname(service_name, "tcp")) == NULL)
- {
- error("%s/tcp unknown protocol", service_name);
- }
- amfree(service_name);
- server_socket = stream_client_privileged(server_name,
- ntohs(sp->s_port),
- -1,
- -1,
- &my_port,
- 0);
- if (server_socket < 0)
- {
- error("cannot connect to %s: %s", server_name, strerror(errno));
- }
- if (my_port >= IPPORT_RESERVED)
- {
- error("did not get a reserved port: %d", my_port);
+ version(), server_name);
+
+ if(response_error != 0) {
+ fprintf(stderr,"%s\n",errstr);
+ exit(1);
}
#if 0
#endif
/* get server's banner */
- if (grab_reply(1) == -1)
+ if (grab_reply(1) == -1) {
+ aclose(server_socket);
exit(1);
- if (!server_happy())
- {
+ }
+ if (!server_happy()) {
dbclose();
aclose(server_socket);
exit(1);
}
- /* do the security thing */
- line = get_security();
- if (converse(line) == -1)
- exit(1);
- if (!server_happy())
- exit(1);
- memset(line, '\0', strlen(line));
- amfree(line);
-
/* try to get the features from the server */
{
- char *our_feature_string = NULL;
char *their_feature_string = NULL;
- our_features = am_init_feature_set();
- our_feature_string = am_feature_to_string(our_features);
- line = stralloc2("FEATURES ", our_feature_string);
+ line = stralloc2("FEATURES ", our_features_string);
if(exchange(line) == 0) {
their_feature_string = stralloc(server_line+13);
indexsrv_features = am_string_to_feature(their_feature_string);
else {
indexsrv_features = am_set_default_feature_set();
}
- amfree(our_feature_string);
amfree(their_feature_string);
amfree(line);
}
/* set the date of extraction to be today */
(void)time(&timer);
- strftime(dump_date, sizeof(dump_date), "%Y-%m-%d", localtime(&timer));
+ tm = localtime(&timer);
+ if (tm)
+ strftime(dump_date, sizeof(dump_date), "%Y-%m-%d", tm);
+ else
+ error("BAD DATE");
+
printf("Setting restore date to today (%s)\n", dump_date);
line = stralloc2("DATE ", dump_date);
- if (converse(line) == -1)
+ if (converse(line) == -1) {
+ aclose(server_socket);
exit(1);
+ }
amfree(line);
line = stralloc2("SCNF ", config);
- if (converse(line) == -1)
+ if (converse(line) == -1) {
+ aclose(server_socket);
exit(1);
+ }
amfree(line);
- if (server_happy())
- {
+ if (server_happy()) {
/* set host we are restoring to this host by default */
amfree(dump_hostname);
set_host(localhost);
if (dump_hostname)
- {
- /* get a starting disk and directory based on where
- we currently are */
- switch (guess_disk(cwd, sizeof(cwd), &dn_guess, &mpt_guess))
- {
- case 1:
- /* okay, got a guess. Set disk accordingly */
- printf("$CWD '%s' is on disk '%s' mounted at '%s'.\n",
- cwd, dn_guess, mpt_guess);
- set_disk(dn_guess, mpt_guess);
- set_directory(cwd);
- if (server_happy() && strcmp(cwd, mpt_guess) != 0)
- printf("WARNING: not on root of selected filesystem, check man-page!\n");
- amfree(dn_guess);
- amfree(mpt_guess);
- break;
-
- case 0:
- printf("$CWD '%s' is on a network mounted disk\n",
- cwd);
- printf("so you must 'sethost' to the server\n");
- /* fake an unhappy server */
- server_line[0] = '5';
- break;
-
- case 2:
- case -1:
- default:
- printf("Can't determine disk and mount point from $CWD '%s'\n", cwd);
- /* fake an unhappy server */
- server_line[0] = '5';
- break;
- }
- }
+ printf("Use the setdisk command to choose dump disk to recover\n");
+ else
+ printf("Use the sethost command to choose a host to recover\n");
+
}
quit_prog = 0;
- do
- {
+ do {
if ((lineread = readline("amrecover> ")) == NULL) {
clearerr(stdin);
putchar('\n');
return 0;
}
+static void
+amindexd_response(
+ void *datap,
+ pkt_t *pkt,
+ security_handle_t *sech)
+{
+ int ports[NSTREAMS], *response_error = datap, i;
+ char *p;
+ char *tok;
+ char *extra = NULL;
+
+ assert(response_error != NULL);
+ assert(sech != NULL);
+
+ if (pkt == NULL) {
+ errstr = newvstralloc(errstr, "[request failed: ",
+ security_geterror(sech), "]", NULL);
+ *response_error = 1;
+ return;
+ }
+
+ if (pkt->type == P_NAK) {
+#if defined(PACKET_DEBUG)
+ fprintf(stderr, "got nak response:\n----\n%s\n----\n\n", pkt->body);
+#endif
+
+ tok = strtok(pkt->body, " ");
+ if (tok == NULL || strcmp(tok, "ERROR") != 0)
+ goto bad_nak;
+
+ tok = strtok(NULL, "\n");
+ if (tok != NULL) {
+ errstr = newvstralloc(errstr, "NAK: ", tok, NULL);
+ *response_error = 1;
+ } else {
+bad_nak:
+ errstr = newstralloc(errstr, "request NAK");
+ *response_error = 2;
+ }
+ return;
+ }
+
+ if (pkt->type != P_REP) {
+ errstr = newvstralloc(errstr, "received strange packet type ",
+ pkt_type2str(pkt->type), ": ", pkt->body, NULL);
+ *response_error = 1;
+ return;
+ }
+
+#if defined(PACKET_DEBUG)
+ fprintf(stderr, "got response:\n----\n%s\n----\n\n", pkt->body);
+#endif
+
+ for(i = 0; i < NSTREAMS; i++) {
+ ports[i] = -1;
+ streams[i].fd = NULL;
+ }
+
+ p = pkt->body;
+ while((tok = strtok(p, " \n")) != NULL) {
+ p = NULL;
+
+ /*
+ * Error response packets have "ERROR" followed by the error message
+ * followed by a newline.
+ */
+ if (strcmp(tok, "ERROR") == 0) {
+ tok = strtok(NULL, "\n");
+ if (tok == NULL)
+ tok = "[bogus error packet]";
+ errstr = newstralloc(errstr, tok);
+ *response_error = 2;
+ return;
+ }
+
+
+ /*
+ * Regular packets have CONNECT followed by three streams
+ */
+ if (strcmp(tok, "CONNECT") == 0) {
+
+ /*
+ * Parse the three stream specifiers out of the packet.
+ */
+ for (i = 0; i < NSTREAMS; i++) {
+ tok = strtok(NULL, " ");
+ if (tok == NULL || strcmp(tok, streams[i].name) != 0) {
+ extra = vstralloc("CONNECT token is \"",
+ tok ? tok : "(null)",
+ "\": expected \"",
+ streams[i].name,
+ "\"",
+ NULL);
+ goto parse_error;
+ }
+ tok = strtok(NULL, " \n");
+ if (tok == NULL || sscanf(tok, "%d", &ports[i]) != 1) {
+ extra = vstralloc("CONNECT ",
+ streams[i].name,
+ " token is \"",
+ tok ? tok : "(null)",
+ "\": expected a port number",
+ NULL);
+ goto parse_error;
+ }
+ }
+ continue;
+ }
+
+ /*
+ * OPTIONS [options string] '\n'
+ */
+ if (strcmp(tok, "OPTIONS") == 0) {
+ tok = strtok(NULL, "\n");
+ if (tok == NULL) {
+ extra = stralloc("OPTIONS token is missing");
+ goto parse_error;
+ }
+/*
+ tok_end = tok + strlen(tok);
+ while((p = strchr(tok, ';')) != NULL) {
+ *p++ = '\0';
+#define sc "features="
+ if(strncmp(tok, sc, sizeof(sc)-1) == 0) {
+ tok += sizeof(sc) - 1;
+#undef sc
+ am_release_feature_set(their_features);
+ if((their_features = am_string_to_feature(tok)) == NULL) {
+ errstr = newvstralloc(errstr,
+ "OPTIONS: bad features value: ",
+ tok,
+ NULL);
+ goto parse_error;
+ }
+ }
+ tok = p;
+ }
+*/
+ continue;
+ }
+/*
+ extra = vstralloc("next token is \"",
+ tok ? tok : "(null)",
+ "\": expected \"CONNECT\", \"ERROR\" or \"OPTIONS\"",
+ NULL);
+ goto parse_error;
+*/
+ }
+
+ /*
+ * Connect the streams to their remote ports
+ */
+ for (i = 0; i < NSTREAMS; i++) {
+/*@i@*/ if (ports[i] == -1)
+ continue;
+ streams[i].fd = security_stream_client(sech, ports[i]);
+ if (streams[i].fd == NULL) {
+ errstr = newvstralloc(errstr,
+ "[could not connect ", streams[i].name, " stream: ",
+ security_geterror(sech), "]", NULL);
+ goto connect_error;
+ }
+ }
+ /*
+ * Authenticate the streams
+ */
+ for (i = 0; i < NSTREAMS; i++) {
+ if (streams[i].fd == NULL)
+ continue;
+ if (security_stream_auth(streams[i].fd) < 0) {
+ errstr = newvstralloc(errstr,
+ "[could not authenticate ", streams[i].name, " stream: ",
+ security_stream_geterror(streams[i].fd), "]", NULL);
+ goto connect_error;
+ }
+ }
+
+ /*
+ * The MESGFD and DATAFD streams are mandatory. If we didn't get
+ * them, complain.
+ */
+ if (streams[MESGFD].fd == NULL) {
+ errstr = newstralloc(errstr, "[couldn't open MESG streams]");
+ goto connect_error;
+ }
+
+ /* everything worked */
+ *response_error = 0;
+ amindexd_alive = 1;
+ return;
+
+parse_error:
+ errstr = newvstralloc(errstr,
+ "[parse of reply message failed: ",
+ extra ? extra : "(no additional information)",
+ "]",
+ NULL);
+ amfree(extra);
+ *response_error = 2;
+ return;
+
+connect_error:
+ stop_amindexd();
+ *response_error = 1;
+}
+
+/*
+ * This is called when everything needs to shut down so event_loop()
+ * will exit.
+ */
+void
+stop_amindexd(void)
+{
+ int i;
+
+ amindexd_alive = 0;
+ for (i = 0; i < NSTREAMS; i++) {
+ if (streams[i].fd != NULL) {
+ security_stream_close(streams[i].fd);
+ streams[i].fd = NULL;
+ }
+ }
+}
+
char *
-get_security()
+amindexd_client_get_security_conf(
+ char * string,
+ void * arg)
{
- struct passwd *pwptr;
+ (void)arg; /* Quiet unused parameter warning */
+
+ if(!string || !*string)
+ return(NULL);
- if((pwptr = getpwuid(getuid())) == NULL)
- error("can't get login name for my uid %ld", (long)getuid());
- return stralloc2("SECURITY USER ", pwptr->pw_name);
+ if(strcmp(string, "auth")==0) {
+ return(client_getconf_str(CLN_AUTH));
+ }
+ else if(strcmp(string, "ssh_keys")==0) {
+ return(client_getconf_str(CLN_SSH_KEYS));
+ }
+ return(NULL);
}
* file named AUTHORS, in the root directory of this distribution.
*/
/*
- * $Id: amrecover.h,v 1.17 2005/12/31 00:02:10 paddy_s Exp $
+ * $Id: amrecover.h,v 1.19 2006/05/25 01:47:14 johnfranks Exp $
*
* data structures and declarations for amrecover
*/
#include "amanda.h"
#include "amfeatures.h"
+#define STARTUP_TIMEOUT 60
+
typedef struct DIR_ITEM
{
char *date;
int level;
char *tape;
char *path;
- int fileno;
+ off_t fileno;
struct DIR_ITEM *next;
}
extern int quit_prog; /* set when time to exit parser */
extern char *tape_server_name;
extern char *tape_device_name;
+extern char *authopt;
extern am_feature_t *our_features;
+extern char *our_features_string;
extern am_feature_t *indexsrv_features;
extern am_feature_t *tapesrv_features;
extern pid_t extract_restore_child_pid;
-extern void free_dir_item P((DIR_ITEM *item));
+extern void free_dir_item(DIR_ITEM *item);
-extern int converse P((char *cmd));
-extern int exchange P((char *cmd));
-extern int server_happy P((void));
-extern int send_command P((char *cmd));
-extern int get_reply_line P((void));
-extern char *reply_line P((void));
+extern int converse(char *cmd);
+extern int exchange(char *cmd);
+extern int server_happy(void);
+extern int send_command(char *cmd);
+extern int get_reply_line(void);
+extern char *reply_line(void);
-extern void quit P((void));
+extern void quit(void);
-extern void help_list P((void)); /* list commands */
+extern void help_list(void); /* list commands */
-extern void set_disk P((char *dsk, char *mtpt));
-extern void list_disk P((char *amdevice));
-extern void set_host P((char *host));
-extern int set_date P((char *date));
-extern void set_directory P((char *dir));
-extern void cd_glob P((char *dir));
-extern void cd_regex P((char *dir));
-extern void cd_dir P((char *dir, char *default_dir));
-extern void set_tape P((char *tape));
-extern void show_directory P((void));
-extern void set_mode P((int mode));
-extern void show_mode P((void));
+extern void set_disk(char *dsk, char *mtpt);
+extern void list_disk(char *amdevice);
+extern void set_host(const char *host);
+extern void list_host(void);
+extern int set_date(char *date);
+extern void set_directory(char *dir);
+extern void cd_glob(char *dir);
+extern void cd_regex(char *dir);
+extern void cd_dir(char *dir, char *default_dir);
+extern void set_tape(char *tape);
+extern void show_directory(void);
+extern void set_mode(int mode);
+extern void show_mode(void);
-extern void list_disk_history P((void));
-extern void list_directory P((void));
-extern DIR_ITEM *get_dir_list P((void));
-extern DIR_ITEM *get_next_dir_item P((DIR_ITEM *this));
-extern void suck_dir_list_from_server P((void));
-extern void clear_dir_list P((void));
-extern void clean_pathname P((char *s));
-extern void display_extract_list P((char *file));
-extern void clear_extract_list P((void));
-extern int is_extract_list_nonempty P((void));
-extern void add_glob P((char *glob));
-extern void add_regex P((char *regex));
-extern void add_file P((char *path, char *regex));
-extern void delete_glob P((char *glob));
-extern void delete_regex P((char *regex));
-extern void delete_file P((char *path, char *regex));
+extern void list_disk_history(void);
+extern void list_directory(void);
+extern DIR_ITEM *get_dir_list(void);
+extern DIR_ITEM *get_next_dir_item(DIR_ITEM *this);
+extern void suck_dir_list_from_server(void);
+extern void clear_dir_list(void);
+extern void clean_pathname(char *s);
+extern void display_extract_list(char *file);
+extern void clear_extract_list(void);
+extern int is_extract_list_nonempty(void);
+extern void add_glob(char *glob);
+extern void add_regex(char *regex);
+extern void add_file(char *path, char *regex);
+extern void delete_glob(char *glob);
+extern void delete_regex(char *regex);
+extern void delete_file(char *path, char *regex);
-extern void extract_files P((void));
+extern void extract_files(void);
#ifdef SAMBA_CLIENT
#define SAMBA_SMBCLIENT 0
#define SAMBA_TAR 1
#endif
-extern char *get_security P((void));
+extern char *get_security(void);
+extern void stop_amindexd(void);
* file named AUTHORS, in the root directory of this distribution.
*/
/*
- * $Id: display_commands.c,v 1.19 2006/03/09 20:06:11 johnfranks Exp $
+ * $Id: display_commands.c,v 1.22 2006/07/05 19:42:17 martinea Exp $
*
* implements the directory-display related commands in amrecover
*/
#include "amanda.h"
#include "amrecover.h"
+#include "util.h"
+
+DIR_ITEM *get_dir_list(void);
+DIR_ITEM *get_next_dir_item(DIR_ITEM *this);
+
+void clear_dir_list(void);
+void free_dir_item(DIR_ITEM *item);
+static int add_dir_list_item(char *date,
+ int level,
+ char *tape,
+ off_t fileno,
+ char *path);
+void list_disk_history(void);
+void suck_dir_list_from_server(void);
+void list_directory(void);
static DIR_ITEM *dir_list = NULL;
-DIR_ITEM *get_dir_list P((void))
+DIR_ITEM *
+get_dir_list(void)
{
return dir_list;
}
-DIR_ITEM *get_next_dir_item(this)
-DIR_ITEM *this;
+DIR_ITEM *
+get_next_dir_item(
+ DIR_ITEM * this)
{
+ /*@ignore@*/
return this->next;
+ /*@end@*/
}
-void clear_dir_list P((void))
+void
+clear_dir_list(void)
{
free_dir_item(dir_list); /* Frees all items from dir_list to end of list */
dir_list = NULL;
}
-void free_dir_item P((DIR_ITEM *item)) {
+void
+free_dir_item(
+ DIR_ITEM * item)
+{
DIR_ITEM *next;
while (item != NULL) {
}
/* add item to list if path not already on list */
-static int add_dir_list_item(date, level, tape, fileno, path)
-char *date;
-int level;
-char *tape;
-int fileno;
-char *path;
+static int
+add_dir_list_item(
+ char * date,
+ int level,
+ char * tape,
+ off_t fileno,
+ char * path)
{
DIR_ITEM *next;
- dbprintf(("add_dir_list_item: Adding \"%s\" \"%d\" \"%s\" \"%d\" \"%s\"\n",
- date, level, tape, fileno, path));
+ dbprintf(("add_dir_list_item: Adding \"%s\" \"%d\" \"%s\" \""
+ OFF_T_FMT "\" \"%s\"\n",
+ date, level, tape, (OFF_T_FMT_TYPE)fileno, path));
next = (DIR_ITEM *)alloc(sizeof(DIR_ITEM));
memset(next, 0, sizeof(DIR_ITEM));
}
-void list_disk_history P((void))
+void
+list_disk_history(void)
{
if (converse("DHST") == -1)
exit(1);
}
-void suck_dir_list_from_server P((void))
+void
+suck_dir_list_from_server(void)
{
char *cmd = NULL;
char *err = NULL;
int i;
char *l = NULL;
- char *date, *date_undo, date_undo_ch = '\0';
- int level, fileno;
+ char *date;
+ int level = 0;
+ off_t fileno = (off_t)-1;
char *tape, *tape_undo, tape_undo_ch = '\0';
- char *dir;
+ char *dir, *qdir;
char *disk_path_slash = NULL;
char *disk_path_slash_dot = NULL;
char *s;
disk_path_slash_dot = stralloc2(disk_path_slash, ".");
amfree(cmd);
amfree(err);
- date_undo = tape_undo = NULL;
+ tape_undo = NULL;
/* skip the last line -- duplicate of the preamble */
while ((i = get_reply_line()) != 0)
{
if(err) {
if(cmd == NULL) {
if(tape_undo) *tape_undo = tape_undo_ch;
- date_undo = tape_undo = NULL;
+ tape_undo = NULL;
cmd = stralloc(l); /* save for the error report */
}
continue; /* throw the rest of the lines away */
}
date = s - 1;
skip_non_whitespace(s, ch);
- date_undo = s - 1;
- date_undo_ch = *date_undo;
- *date_undo = '\0';
+ *(s - 1) = '\0';
skip_whitespace(s, ch);
if(ch == '\0' || sscanf(s - 1, "%d", &level) != 1) {
if(am_has_feature(indexsrv_features, fe_amindexd_fileno_in_OLSD)) {
skip_whitespace(s, ch);
- if(ch == '\0' || sscanf(s - 1, "%d", &fileno) != 1) {
+ if(ch == '\0' || sscanf(s - 1, OFF_T_FMT,
+ (OFF_T_FMT_TYPE *)&fileno) != 1) {
err = "bad reply: cannot parse fileno field";
continue;
}
skip_integer(s, ch);
}
else {
- fileno = -1;
+ fileno = (off_t)-1;
}
skip_whitespace(s, ch);
err = "bad reply: missing directory field";
continue;
}
- dir = s - 1;
+ qdir = s - 1;
+ dir = unquote_string(qdir);
/* add a '.' if it a the entry for the current directory */
- if(strcmp(disk_path,dir)==0 || strcmp(disk_path_slash,dir)==0) {
- dir = disk_path_slash_dot;
+ if((strcmp(disk_path,dir)==0) || (strcmp(disk_path_slash,dir)==0)) {
+ amfree(dir);
+ dir = stralloc(disk_path_slash_dot);
}
add_dir_list_item(date, level, tape, fileno, dir);
+ amfree(dir);
}
amfree(disk_path_slash_dot);
amfree(disk_path_slash);
if(*err) {
puts(err);
}
- puts(cmd);
+ if (cmd)
+ puts(cmd);
clear_dir_list();
}
amfree(cmd);
}
-void list_directory P((void))
+void
+list_directory(void)
{
size_t i;
DIR_ITEM *item;
FILE *fp;
char *pager;
char *pager_command;
+ char *quoted;
if (disk_path == NULL) {
- printf("Must select a disk before listing files\n");
+ printf("Must select a disk before listing files; use the setdisk command.\n");
return;
}
i = strlen(disk_path);
if (i != 1)
i++; /* so disk_path != "/" */
- for (item = get_dir_list(); item != NULL; item=get_next_dir_item(item))
- fprintf(fp, "%s %s\n", item->date, item->path+i);
+ for (item = get_dir_list(); item != NULL; item=get_next_dir_item(item)) {
+ quoted = quote_string(item->path + i);
+ fprintf(fp, "%s %s\n", item->date, quoted);
+ amfree(quoted);
+ }
apclose(fp);
}
* file named AUTHORS, in the root directory of this distribution.
*/
/*
- * $Id: extract_list.c,v 1.97 2006/03/09 16:51:41 martinea Exp $
+ * $Id: extract_list.c,v 1.117 2006/08/24 01:57:15 paddy_s Exp $
*
* implements the "extract" command in amrecover
*/
#include "findpass.h"
#endif
#include "util.h"
+#include "clientconf.h"
+#include "protocol.h"
+#include "event.h"
+#include "security.h"
-typedef struct EXTRACT_LIST_ITEM
-{
+typedef struct EXTRACT_LIST_ITEM {
char *path;
-
struct EXTRACT_LIST_ITEM *next;
}
EXTRACT_LIST_ITEM;
-typedef struct EXTRACT_LIST
-{
+typedef struct EXTRACT_LIST {
char *date; /* date tape created */
- int level; /* level of dump */
+ int level; /* level of dump */
char *tape; /* tape label */
- int fileno; /* fileno on tape */
- EXTRACT_LIST_ITEM *files; /* files to get off tape */
+ off_t fileno; /* fileno on tape */
+ EXTRACT_LIST_ITEM *files; /* files to get off tape */
struct EXTRACT_LIST *next;
}
#define SKIP_TAPE 2
#define RETRY_TAPE 3
-char *dump_device_name = NULL;
+static struct {
+ const char *name;
+ security_stream_t *fd;
+} amidxtaped_streams[] = {
+#define CTLFD 0
+ { "CTL", NULL },
+#define DATAFD 1
+ { "DATA", NULL },
+};
+#define NSTREAMS (int)(sizeof(amidxtaped_streams) / sizeof(amidxtaped_streams[0]))
+
+
+static void amidxtaped_response(void *, pkt_t *, security_handle_t *);
+static void stop_amidxtaped(void);
+char *amidxtaped_client_get_security_conf(char *, void *);
+static char *dump_device_name = NULL;
+static char *errstr;
+static char *amidxtaped_line = NULL;
extern char *localhost;
pid_t extract_restore_child_pid = -1;
static EXTRACT_LIST *extract_list = NULL;
-static int tape_control_sock = -1;
-static int tape_data_sock = -1;
+static const security_driver_t *amidxtaped_secdrv;
#ifdef SAMBA_CLIENT
unsigned short samba_extract_method = SAMBA_TAR;
#define READ_TIMEOUT 240*60
-static int okay_to_continue P((int, int, int));
-void writer_intermediary P((int ctl_fd, int data_fd, EXTRACT_LIST *elist));
-
+EXTRACT_LIST *first_tape_list(void);
+EXTRACT_LIST *next_tape_list(EXTRACT_LIST *list);
+static int is_empty_dir(char *fname);
+int is_extract_list_nonempty(void);
+int length_of_tape_list(EXTRACT_LIST *tape_list);
+void add_file(char *path, char *regex);
+void add_glob(char *glob);
+void add_regex(char *regex);
+void clear_extract_list(void);
+void clean_tape_list(EXTRACT_LIST *tape_list);
+void clean_extract_list(void);
+void check_file_overwrite(char *filename);
+void delete_file(char *path, char *regex);
+void delete_glob(char *glob);
+void delete_regex(char *regex);
+void delete_tape_list(EXTRACT_LIST *tape_list);
+void display_extract_list(char *file);
+void extract_files(void);
+void read_file_header(char *buffer,
+ dumpfile_t *file,
+ size_t buflen,
+ int tapedev);
+static int add_extract_item(DIR_ITEM *ditem);
+static int delete_extract_item(DIR_ITEM *ditem);
+static int extract_files_setup(char *label, off_t fsf);
+static int okay_to_continue(int allow_tape,
+ int allow_skip,
+ int allow_retry);
+static ssize_t read_buffer(int datafd,
+ char *buffer,
+ size_t buflen,
+ long timeout_s);
+static void clear_tape_list(EXTRACT_LIST *tape_list);
+static void extract_files_child(int in_fd, EXTRACT_LIST *elist);
+static void send_to_tape_server(security_stream_t *stream, char *cmd);
+int writer_intermediary(EXTRACT_LIST *elist);
+int get_amidxtaped_line(void);
+static void read_amidxtaped_data(void *, void *, ssize_t);
/*
* Function: ssize_t read_buffer(datafd, buffer, buflen, timeout_s)
*/
static ssize_t
-read_buffer(datafd, buffer, buflen, timeout_s)
-int datafd;
-char *buffer;
-size_t buflen;
+read_buffer(
+ int datafd,
+ char * buffer,
+ size_t buflen,
+ long timeout_s)
{
ssize_t size = 0;
fd_set readset;
struct timeval timeout;
char *dataptr;
- size_t spaceleft;
+ ssize_t spaceleft;
int nfound;
- if(datafd < 0 || datafd >= FD_SETSIZE) {
+ if(datafd < 0 || datafd >= (int)FD_SETSIZE) {
errno = EMFILE; /* out of range */
return -1;
}
dataptr = buffer;
- spaceleft = buflen;
+ spaceleft = (ssize_t)buflen;
do {
FD_ZERO(&readset);
continue;
/* Select says data is available, so read it. */
- size = read(datafd, dataptr, spaceleft);
+ size = read(datafd, dataptr, (size_t)spaceleft);
if (size < 0) {
if ((errno == EINTR) || (errno == EAGAIN)) {
continue;
dataptr += size;
} while ((size > 0) && (spaceleft > 0));
- return (((buflen-spaceleft) > 0) ? (buflen-spaceleft) : size);
+ return ((((ssize_t)buflen-spaceleft) > 0) ? ((ssize_t)buflen-spaceleft) : size);
}
-EXTRACT_LIST *first_tape_list P((void))
+EXTRACT_LIST *
+first_tape_list(void)
{
return extract_list;
}
-EXTRACT_LIST *next_tape_list(list)
-EXTRACT_LIST *list;
+EXTRACT_LIST *
+next_tape_list(
+ /*@keep@*/EXTRACT_LIST *list)
{
if (list == NULL)
return NULL;
return list->next;
}
-static void clear_tape_list(tape_list)
-EXTRACT_LIST *tape_list;
+static void
+clear_tape_list(
+ EXTRACT_LIST * tape_list)
{
EXTRACT_LIST_ITEM *this, *next;
/* remove a tape list from the extract list, clearing the tape list
beforehand if necessary */
-void delete_tape_list(tape_list)
-EXTRACT_LIST *tape_list;
+void
+delete_tape_list(
+ EXTRACT_LIST *tape_list)
{
EXTRACT_LIST *this, *prev;
/* return the number of files on a tape's list */
-int length_of_tape_list(tape_list)
-EXTRACT_LIST *tape_list;
+int
+length_of_tape_list(
+ EXTRACT_LIST *tape_list)
{
EXTRACT_LIST_ITEM *fn;
int n;
}
-void clear_extract_list P((void))
+void
+clear_extract_list(void)
{
while (extract_list != NULL)
delete_tape_list(extract_list);
}
+void
+clean_tape_list(
+ EXTRACT_LIST *tape_list)
+{
+ EXTRACT_LIST_ITEM *fn1, *pfn1, *ofn1;
+ EXTRACT_LIST_ITEM *fn2, *pfn2, *ofn2;
+ int remove_fn1;
+ int remove_fn2;
+
+ pfn1 = NULL;
+ fn1 = tape_list->files;
+ while (fn1 != NULL) {
+ remove_fn1 = 0;
+
+ pfn2 = fn1;
+ fn2 = fn1->next;
+ while (fn2 != NULL && remove_fn1 == 0) {
+ remove_fn2 = 0;
+ if(strcmp(fn1->path, fn2->path) == 0) {
+ remove_fn2 = 1;
+ } else if (strncmp(fn1->path, fn2->path, strlen(fn1->path)) == 0 &&
+ ((strlen(fn2->path) > strlen(fn1->path) &&
+ fn2->path[strlen(fn1->path)] == '/') ||
+ (fn1->path[strlen(fn1->path)-1] == '/'))) {
+ remove_fn2 = 1;
+ } else if (strncmp(fn2->path, fn1->path, strlen(fn2->path)) == 0 &&
+ ((strlen(fn1->path) > strlen(fn2->path) &&
+ fn1->path[strlen(fn2->path)] == '/') ||
+ (fn2->path[strlen(fn2->path)-1] == '/'))) {
+ remove_fn1 = 1;
+ break;
+ }
+
+ if (remove_fn2) {
+ dbprintf(("removing path %s, it is included in %s\n",
+ fn2->path, fn1->path));
+ ofn2 = fn2;
+ fn2 = fn2->next;
+ amfree(ofn2->path);
+ amfree(ofn2);
+ pfn2->next = fn2;
+ } else if (remove_fn1 == 0) {
+ pfn2 = fn2;
+ fn2 = fn2->next;
+ }
+ }
+
+ if(remove_fn1 != 0) {
+ /* fn2->path is always valid */
+ /*@i@*/ dbprintf(("removing path %s, it is included in %s\n",
+ /*@i@*/ fn1->path, fn2->path));
+ ofn1 = fn1;
+ fn1 = fn1->next;
+ amfree(ofn1->path);
+ if(pfn1 == NULL) {
+ amfree(tape_list->files);
+ tape_list->files = fn1;
+ } else {
+ amfree(pfn1->next);
+ pfn1->next = fn1;
+ }
+ } else {
+ pfn1 = fn1;
+ fn1 = fn1->next;
+ }
+ }
+}
+
+
+void
+clean_extract_list(void)
+{
+ EXTRACT_LIST *this;
+
+ for (this = extract_list; this != NULL; this = this->next)
+ clean_tape_list(this);
+}
+
+
+int add_to_unlink_list(char *path);
+int do_unlink_list(void);
+void free_unlink_list(void);
+
+typedef struct s_unlink_list {
+ char *path;
+ struct s_unlink_list *next;
+} t_unlink_list;
+t_unlink_list *unlink_list = NULL;
+
+int
+add_to_unlink_list(
+ char *path)
+{
+ t_unlink_list *ul;
+
+ if (!unlink_list) {
+ unlink_list = alloc(SIZEOF(*unlink_list));
+ unlink_list->path = stralloc(path);
+ unlink_list->next = NULL;
+ } else {
+ for (ul = unlink_list; ul != NULL; ul = ul->next) {
+ if (strcmp(ul->path, path) == 0)
+ return 0;
+ }
+ ul = alloc(SIZEOF(*ul));
+ ul->path = stralloc(path);
+ ul->next = unlink_list;
+ unlink_list = ul;
+ }
+ return 1;
+}
+
+int
+do_unlink_list(void)
+{
+ t_unlink_list *ul;
+ int ret = 1;
+
+ for (ul = unlink_list; ul != NULL; ul = ul->next) {
+ if (unlink(ul->path) < 0) {
+ fprintf(stderr,"Can't unlink %s: %s\n", ul->path, strerror(errno));
+ ret = 0;
+ }
+ }
+ return ret;
+}
+
+
+void
+free_unlink_list(void)
+{
+ t_unlink_list *ul, *ul1;
+
+ for (ul = unlink_list; ul != NULL; ul = ul1) {
+ amfree(ul->path);
+ ul1 = ul->next;
+ amfree(ul);
+ }
+
+ unlink_list = NULL;
+}
+
+
+
+void
+check_file_overwrite(
+ char *dir)
+{
+ EXTRACT_LIST *this;
+ EXTRACT_LIST_ITEM *fn;
+ struct stat stat_buf;
+ char *filename;
+ char *path, *s;
+
+ for (this = extract_list; this != NULL; this = this->next) {
+ for (fn = this->files; fn != NULL ; fn = fn->next) {
+
+ /* Check path component of fn->path */
+
+ path = stralloc2(dir, fn->path);
+ if (path[strlen(path)-1] == '/') {
+ path[strlen(path)-1] = '\0';
+ }
+
+ s = path + strlen(dir) + 1;
+ while((s = strchr(s, '/'))) {
+ *s = '\0';
+ if (lstat(path, &stat_buf) == 0) {
+ if(!S_ISDIR(stat_buf.st_mode)) {
+ if (add_to_unlink_list(path)) {
+ printf("WARNING: %s is not a directory, "
+ "it will be deleted.\n",
+ path);
+ }
+ }
+ }
+ else if (errno != ENOENT) {
+ printf("Can't stat %s: %s\n", path, strerror(errno));
+ }
+ *s = '/';
+ s++;
+ }
+ amfree(path);
+
+ /* Check fn->path */
+
+ filename = stralloc2(dir, fn->path);
+ if (filename[strlen(filename)-1] == '/') {
+ filename[strlen(filename)-1] = '\0';
+ }
+
+ if (lstat(filename, &stat_buf) == 0) {
+ if(S_ISDIR(stat_buf.st_mode)) {
+ if(!is_empty_dir(filename)) {
+ printf("WARNING: All existing files in %s "
+ "will be deleted.\n", filename);
+ }
+ } else if(S_ISREG(stat_buf.st_mode)) {
+ printf("WARNING: Existing file %s will be overwritten\n",
+ filename);
+ } else {
+ if (add_to_unlink_list(filename)) {
+ printf("WARNING: Existing entry %s will be deleted\n",
+ filename);
+ }
+ }
+ } else if (errno != ENOENT) {
+ printf("Can't stat %s: %s\n", filename, strerror(errno));
+ }
+ amfree(filename);
+ }
+ }
+}
+
+
/* returns -1 if error */
/* returns 0 on succes */
/* returns 1 if already added */
-static int add_extract_item(ditem)
-DIR_ITEM *ditem;
+static int
+add_extract_item(
+ DIR_ITEM *ditem)
{
EXTRACT_LIST *this, *this1;
EXTRACT_LIST_ITEM *that, *curr;
/* returns -1 if error */
/* returns 0 on deletion */
/* returns 1 if not there */
-static int delete_extract_item(ditem)
-DIR_ITEM *ditem;
+static int
+delete_extract_item(
+ DIR_ITEM *ditem)
{
EXTRACT_LIST *this;
EXTRACT_LIST_ITEM *that, *prev;
}
-void add_glob(glob)
-char *glob;
+void
+add_glob(
+ char * glob)
{
char *regex;
char *regex_path;
char *s;
-
- regex = glob_to_regex(glob);
- dbprintf(("add_glob (%s) -> %s\n", glob, regex));
+ char *uqglob = unquote_string(glob);
+
+ regex = glob_to_regex(uqglob);
+ dbprintf(("add_glob (%s) -> %s\n", uqglob, regex));
if ((s = validate_regexp(regex)) != NULL) {
- printf("\"%s\" is not a valid shell wildcard pattern: ", glob);
+ printf("%s is not a valid shell wildcard pattern: ", glob);
puts(s);
- return;
+ } else {
+ /*
+ * glob_to_regex() anchors the beginning of the pattern with ^,
+ * but we will be tacking it onto the end of the current directory
+ * in add_file, so strip that off. Also, it anchors the end with
+ * $, but we need to match an optional trailing /, so tack that on
+ * the end.
+ */
+ regex_path = stralloc(regex + 1);
+ regex_path[strlen(regex_path) - 1] = '\0';
+ strappend(regex_path, "[/]*$");
+ add_file(uqglob, regex_path);
+ amfree(regex_path);
}
- /*
- * glob_to_regex() anchors the beginning of the pattern with ^,
- * but we will be tacking it onto the end of the current directory
- * in add_file, so strip that off. Also, it anchors the end with
- * $, but we need to match an optional trailing /, so tack that on
- * the end.
- */
- regex_path = stralloc(regex + 1);
amfree(regex);
- regex_path[strlen(regex_path) - 1] = '\0';
- strappend(regex_path, "[/]*$");
- add_file(glob, regex_path);
- amfree(regex_path);
+ amfree(uqglob);
}
-void add_regex(regex)
-char *regex;
+void
+add_regex(
+ char * regex)
{
char *s;
-
- if ((s = validate_regexp(regex)) != NULL) {
+ char *uqregex = unquote_string(regex);
+
+ if ((s = validate_regexp(uqregex)) != NULL) {
printf("\"%s\" is not a valid regular expression: ", regex);
puts(s);
- return;
+ } else {
+ add_file(uqregex, regex);
}
- add_file(regex, regex);
+ amfree(uqregex);
}
-void add_file(path, regex)
-char *path;
-char *regex;
+void
+add_file(
+ char * path,
+ char * regex)
{
DIR_ITEM *ditem, lditem;
char *path_on_disk = NULL;
char *cmd = NULL;
char *err = NULL;
int i;
- int j;
+ ssize_t j;
char *dir, *dir_undo, dir_undo_ch = '\0';
char *ditem_path = NULL;
char *l = NULL;
int added;
- char *s, *fp;
+ char *s, *fp, *quoted;
int ch;
int found_one;
+ int dir_entries;
if (disk_path == NULL) {
printf("Must select directory before adding files\n");
dbprintf(("add_file: Looking for \"%s\"\n", regex));
- /* remove "/" at end of path */
- j = strlen(regex)-1;
- while(j >= 0 && regex[j] == '/') regex[j--] = '\0';
+ if(strcmp(regex, "/[/]*$") == 0) { /* "/" behave like "." */
+ regex = "\\.[/]*$";
+ }
+ else if(strcmp(regex, "[^/]*[/]*$") == 0) { /* "*" */
+ //regex =
+ regex = "([^/.]|\\.[^/]+|[^/.][^/]*)[/]*$";
+ } else {
+ /* remove "/" at end of path */
+ j = (ssize_t)(strlen(regex) - 1);
+ while(j >= 0 && regex[j] == '/')
+ regex[j--] = '\0';
+ }
/* convert path (assumed in cwd) to one on disk */
if (strcmp(disk_path, "/") == 0) {
if (*regex == '/') {
- if (strcmp(regex, "/[/]*$") == 0) {
- /* We want '/' to match everything in directory... */
- path_on_disk = stralloc("/[^/]*[/]*$");
- } else {
- /* No mods needed if already starts with '/' */
- path_on_disk = stralloc(regex);
- }
+ /* No mods needed if already starts with '/' */
+ path_on_disk = stralloc(regex);
} else {
/* Prepend '/' */
path_on_disk = stralloc2("/", regex);
regex, path_on_disk));
found_one = 0;
+ dir_entries = 0;
for (ditem=get_dir_list(); ditem!=NULL; ditem=get_next_dir_item(ditem))
{
- dbprintf(("add_file: Pondering ditem->path=\"%s\"\n", ditem->path));
+ dir_entries++;
+ quoted = quote_string(ditem->path);
+ dbprintf(("add_file: Pondering ditem->path=%s\n", quoted));
+ amfree(quoted);
if (match(path_on_disk, ditem->path)
|| match(path_on_disk_slash, ditem->path))
{
found_one = 1;
- j = strlen(ditem->path);
+ j = (ssize_t)strlen(ditem->path);
if((j > 0 && ditem->path[j-1] == '/')
|| (j > 1 && ditem->path[j-2] == '/' && ditem->path[j-1] == '.'))
{ /* It is a directory */
-
ditem_path = newstralloc(ditem_path, ditem->path);
clean_pathname(ditem_path);
amfree(path_on_disk_slash);
exit(1);
}
- if(i==0) /* assume something wrong */
- {
+ if(i==0) { /* assume something wrong */
amfree(ditem_path);
amfree(path_on_disk);
amfree(path_on_disk_slash);
added=0;
lditem.path = newstralloc(lditem.path, ditem->path);
/* skip the last line -- duplicate of the preamble */
- while ((i = get_reply_line()) != 0)
- {
+
+ while ((i = get_reply_line()) != 0) {
if (i == -1) {
amfree(ditem_path);
amfree(path_on_disk);
skip_non_whitespace(s, ch);
s[-1] = '\0';
lditem.date = newstralloc(lditem.date, fp);
- s[-1] = ch;
+ s[-1] = (char)ch;
skip_whitespace(s, ch);
if(ch == '\0' || sscanf(s - 1, "%d", &lditem.level) != 1) {
skip_non_whitespace(s, ch);
s[-1] = '\0';
lditem.tape = newstralloc(lditem.tape, fp);
- s[-1] = ch;
+ s[-1] = (char)ch;
if(am_has_feature(indexsrv_features, fe_amindexd_fileno_in_ORLD)) {
skip_whitespace(s, ch);
- if(ch == '\0' || sscanf(s - 1, "%d", &lditem.fileno) != 1) {
+ if(ch == '\0' || sscanf(s - 1, OFF_T_FMT,
+ (OFF_T_FMT_TYPE *)&lditem.fileno) != 1) {
err = "bad reply: cannot parse fileno field";
continue;
}
continue;
}
dir = s - 1;
- skip_non_whitespace(s, ch);
+ skip_quoted_string(s, ch);
dir_undo = s - 1;
dir_undo_ch = *dir_undo;
*dir_undo = '\0';
printf("System error\n");
dbprintf(("add_file: (Failed) System error\n"));
break;
+
case 0:
+ quoted = quote_string(lditem.path);
printf("Added dir %s at date %s\n",
- ditem_path, lditem.date);
+ quoted, lditem.date);
dbprintf(("add_file: (Successful) Added dir %s at date %s\n",
- ditem_path,lditem.date));
+ quoted, lditem.date));
+ amfree(quoted);
added=1;
break;
+
case 1:
break;
}
if(!server_happy()) {
puts(reply_line());
} else if(err) {
- puts(err);
- puts(cmd);
+ if (*err)
+ puts(err);
+ if (cmd)
+ puts(cmd);
} else if(added == 0) {
- printf("dir %s already added\n", ditem_path);
- dbprintf(("add_file: dir %s already added\n", ditem_path));
+ quoted = quote_string(ditem_path);
+ printf("dir %s already added\n", quoted);
+ dbprintf(("add_file: dir %s already added\n", quoted));
+ amfree(quoted);
}
}
else /* It is a file */
printf("System error\n");
dbprintf(("add_file: (Failed) System error\n"));
break;
+
case 0:
- printf("Added %s\n", ditem->path);
- dbprintf(("add_file: (Successful) Added %s\n",
- ditem->path));
+ quoted = quote_string(ditem->path);
+ printf("Added file %s\n", quoted);
+ dbprintf(("add_file: (Successful) Added %s\n", quoted));
+ amfree(quoted);
break;
+
case 1:
- printf("File %s already added\n", ditem->path);
- dbprintf(("add_file: file %s already added\n",
- ditem->path));
- break;
+ quoted = quote_string(ditem->path);
+ printf("File %s already added\n", quoted);
+ dbprintf(("add_file: file %s already added\n", quoted));
+ amfree(quoted);
}
}
}
}
- if (cmd != NULL)
- amfree(cmd);
+
+ amfree(cmd);
amfree(ditem_path);
amfree(path_on_disk);
amfree(path_on_disk_slash);
+ amfree(lditem.path);
+ amfree(lditem.date);
+ amfree(lditem.tape);
+
if(! found_one) {
- printf("File %s doesn't exist in directory\n", path);
+ quoted = quote_string(path);
+ printf("File %s doesn't exist in directory\n", quoted);
dbprintf(("add_file: (Failed) File %s doesn't exist in directory\n",
- path));
+ quoted));
+ amfree(quoted);
}
}
-void delete_glob(glob)
-char *glob;
+void
+delete_glob(
+ char * glob)
{
char *regex;
char *regex_path;
char *s;
-
- regex = glob_to_regex(glob);
- dbprintf(("delete_glob (%s) -> %s\n", glob, regex));
+ char *uqglob = unquote_string(glob);
+
+ regex = glob_to_regex(uqglob);
+ dbprintf(("delete_glob (%s) -> %s\n", uqglob, regex));
if ((s = validate_regexp(regex)) != NULL) {
printf("\"%s\" is not a valid shell wildcard pattern: ", glob);
puts(s);
- return;
+ } else {
+ /*
+ * glob_to_regex() anchors the beginning of the pattern with ^,
+ * but we will be tacking it onto the end of the current directory
+ * in add_file, so strip that off. Also, it anchors the end with
+ * $, but we need to match an optional trailing /, so tack that on
+ * the end.
+ */
+ regex_path = stralloc(regex + 1);
+ regex_path[strlen(regex_path) - 1] = '\0';
+ strappend(regex_path, "[/]*$");
+ delete_file(uqglob, regex_path);
+ amfree(regex_path);
}
- /*
- * glob_to_regex() anchors the beginning of the pattern with ^,
- * but we will be tacking it onto the end of the current directory
- * in add_file, so strip that off. Also, it anchors the end with
- * $, but we need to match an optional trailing /, so tack that on
- * the end.
- */
- regex_path = stralloc(regex + 1);
amfree(regex);
- regex_path[strlen(regex_path) - 1] = '\0';
- strappend(regex_path, "[/]*$");
- delete_file(glob, regex_path);
- amfree(regex_path);
+ amfree(uqglob);
}
-void delete_regex(regex)
-char *regex;
+void
+delete_regex(
+ char * regex)
{
char *s;
+ char *uqregex = unquote_string(regex);
if ((s = validate_regexp(regex)) != NULL) {
printf("\"%s\" is not a valid regular expression: ", regex);
puts(s);
- return;
+ } else {
+ delete_file(uqregex, uqregex);
}
- delete_file(regex, regex);
+ amfree(uqregex);
}
-void delete_file(path, regex)
-char *path;
-char *regex;
+void
+delete_file(
+ char * path,
+ char * regex)
{
DIR_ITEM *ditem, lditem;
char *path_on_disk = NULL;
char *cmd = NULL;
char *err = NULL;
int i;
- int j;
- char *date, *date_undo, date_undo_ch = '\0';
+ ssize_t j;
+ char *date;
char *tape, *tape_undo, tape_undo_ch = '\0';
- char *dir, *dir_undo, dir_undo_ch = '\0';
- int level, fileno;
+ char *dir_undo, dir_undo_ch = '\0';
+ int level = 0;
+ off_t fileno;
char *ditem_path = NULL;
char *l = NULL;
int deleted;
char *s;
int ch;
int found_one;
+ char *quoted;
if (disk_path == NULL) {
printf("Must select directory before deleting files\n");
memset(&lditem, 0, sizeof(lditem)); /* Prevent use of bogus data... */
dbprintf(("delete_file: Looking for \"%s\"\n", path));
- /* remove "/" at the end of the path */
- j = strlen(regex)-1;
- while(j >= 0 && regex[j] == '/') regex[j--] = '\0';
+
+ if (strcmp(regex, "[^/]*[/]*$") == 0) {
+ /* Looking for * find everything but single . */
+ regex = "([^/.]|\\.[^/]+|[^/.][^/]*)[/]*$";
+ } else {
+ /* remove "/" at end of path */
+ j = (ssize_t)(strlen(regex) - 1);
+ while(j >= 0 && regex[j] == '/') regex[j--] = '\0';
+ }
/* convert path (assumed in cwd) to one on disk */
- if (strcmp(disk_path, "/") == 0)
- path_on_disk = stralloc2("/", regex);
- else {
+ if (strcmp(disk_path, "/") == 0) {
+ if (*regex == '/') {
+ if (strcmp(regex, "/[/]*$") == 0) {
+ /* We want "/" to match the directory itself: "/." */
+ path_on_disk = stralloc("/\\.[/]*$");
+ } else {
+ /* No mods needed if already starts with '/' */
+ path_on_disk = stralloc(regex);
+ }
+ } else {
+ /* Prepend '/' */
+ path_on_disk = stralloc2("/", regex);
+ }
+ } else {
char *clean_disk_path = clean_regex(disk_path);
path_on_disk = vstralloc(clean_disk_path, "/", regex, NULL);
amfree(clean_disk_path);
found_one = 0;
for (ditem=get_dir_list(); ditem!=NULL; ditem=get_next_dir_item(ditem))
{
- dbprintf(("delete_file: Pondering ditem->path=\"%s\"\n", ditem->path));
+ quoted = quote_string(ditem->path);
+ dbprintf(("delete_file: Pondering ditem->path=%s\n", quoted));
+ amfree(quoted);
if (match(path_on_disk, ditem->path)
|| match(path_on_disk_slash, ditem->path))
{
found_one = 1;
- j = strlen(ditem->path);
+ j = (ssize_t)strlen(ditem->path);
if((j > 0 && ditem->path[j-1] == '/')
|| (j > 1 && ditem->path[j-2] == '/' && ditem->path[j-1] == '.'))
{ /* It is a directory */
deleted=0;
lditem.path = newstralloc(lditem.path, ditem->path);
amfree(cmd);
- date_undo = tape_undo = dir_undo = NULL;
+ tape_undo = dir_undo = NULL;
/* skip the last line -- duplicate of the preamble */
while ((i = get_reply_line()) != 0)
{
if(cmd == NULL) {
if(tape_undo) *tape_undo = tape_undo_ch;
if(dir_undo) *dir_undo = dir_undo_ch;
- date_undo = tape_undo = dir_undo = NULL;
+ tape_undo = dir_undo = NULL;
cmd = stralloc(l); /* save for the error report */
}
continue; /* throw the rest of the lines away */
}
date = s - 1;
skip_non_whitespace(s, ch);
- date_undo = s - 1;
- date_undo_ch = *date_undo;
- *date_undo = '\0';
+ *(s - 1) = '\0';
skip_whitespace(s, ch);
if(ch == '\0' || sscanf(s - 1, "%d", &level) != 1) {
if(am_has_feature(indexsrv_features, fe_amindexd_fileno_in_ORLD)) {
skip_whitespace(s, ch);
- if(ch == '\0' || sscanf(s - 1, "%d", &fileno) != 1) {
+ if(ch == '\0' || sscanf(s - 1, OFF_T_FMT,
+ (OFF_T_FMT_TYPE *)&fileno) != 1) {
err = "bad reply: cannot parse fileno field";
continue;
}
err = "bad reply: missing directory field";
continue;
}
- dir = s - 1;
skip_non_whitespace(s, ch);
dir_undo = s - 1;
dir_undo_ch = *dir_undo;
if(!server_happy()) {
puts(reply_line());
} else if(err) {
- if(*err) {
+ if (*err)
puts(err);
- }
- puts(cmd);
+ if (cmd)
+ puts(cmd);
} else if(deleted == 0) {
printf("Warning - dir '%s' not on tape list\n",
ditem_path);
/* print extract list into file. If NULL ptr passed print to screen */
-void display_extract_list(file)
-char *file;
+void
+display_extract_list(
+ char * file)
{
EXTRACT_LIST *this;
EXTRACT_LIST_ITEM *that;
FILE *fp;
char *pager;
char *pager_command;
+ char *uqfile;
if (file == NULL)
{
}
else
{
- if ((fp = fopen(file, "w")) == NULL)
+ uqfile = unquote_string(file);
+ if ((fp = fopen(uqfile, "w")) == NULL)
{
- printf("Can't open file '%s' to print extract list into\n", file);
+ printf("Can't open file %s to print extract list into\n", file);
+ amfree(uqfile);
return;
}
+ amfree(uqfile);
}
for (this = extract_list; this != NULL; this = this->next)
}
+static int
+is_empty_dir(
+ char *fname)
+{
+ DIR *dir;
+ struct dirent *entry;
+ int gotentry;
+
+ if((dir = opendir(fname)) == NULL)
+ return 1;
+
+ gotentry = 0;
+ while(!gotentry && (entry = readdir(dir)) != NULL) {
+ gotentry = !is_dot_or_dotdot(entry->d_name);
+ }
+
+ closedir(dir);
+ return !gotentry;
+
+}
+
/* returns 0 if extract list empty and 1 if it isn't */
-int is_extract_list_nonempty P((void))
+int
+is_extract_list_nonempty(void)
{
return (extract_list != NULL);
}
/* prints continue prompt and waits for response,
returns 0 if don't, non-0 if do */
-static int okay_to_continue(allow_tape, allow_skip, allow_retry)
- int allow_tape;
- int allow_skip;
- int allow_retry;
+static int
+okay_to_continue(
+ int allow_tape,
+ int allow_skip,
+ int allow_retry)
{
int ch;
int ret = -1;
break;
}
s = line;
- while ((ch = *s++) != '\0' && isspace(ch)) {}
+ while ((ch = *s++) != '\0' && isspace(ch)) {
+ (void)ch; /* Quiet empty loop compiler warning */
+ }
if (ch == '?') {
if (get_tape) {
printf("Enter a new device ([host:]device) or \"default\"\n");
ret = SKIP_TAPE;
}
}
+ /*@ignore@*/
amfree(line);
+ /*@end@*/
return ret;
}
-static void send_to_tape_server(tss, cmd)
-int tss;
-char *cmd;
+static void
+send_to_tape_server(
+ security_stream_t * stream,
+ char * cmd)
{
char *msg = stralloc2(cmd, "\r\n");
- if (fullwrite(tss, msg, strlen(msg)) < 0)
+ if (security_stream_write(stream, msg, strlen(msg)) < 0)
{
error("Error writing to tape server");
exit(101);
+ /*NOTREACHED*/
}
amfree(msg);
}
/* start up connection to tape server and set commands to initiate
transfer of dump image.
Return tape server socket on success, -1 on error. */
-static int extract_files_setup(label, fsf)
-char *label;
-int fsf;
+static int
+extract_files_setup(
+ char * label,
+ off_t fsf)
{
- struct servent *sp;
- int my_port, my_data_port;
char *disk_regex = NULL;
char *host_regex = NULL;
- char *service_name = NULL;
- char *line = NULL;
char *clean_datestamp, *ch, *ch1;
- char *our_feature_string = NULL;
char *tt = NULL;
+ char *req;
+ int response_error;
- service_name = stralloc2("amidxtape", SERVICE_SUFFIX);
-
- /* get tape server details */
- if ((sp = getservbyname(service_name, "tcp")) == NULL)
- {
- printf("%s/tcp unknown protocol - config error?\n", service_name);
- amfree(service_name);
- return -1;
+ amidxtaped_secdrv = security_getdriver(authopt);
+ if (amidxtaped_secdrv == NULL) {
+ error("no '%s' security driver available for host '%s'",
+ authopt, tape_server_name);
}
- amfree(service_name);
- seteuid(0); /* it either works ... */
- setegid(0);
- tape_control_sock = stream_client_privileged(tape_server_name,
- ntohs(sp->s_port),
- -1,
- STREAM_BUFSIZE,
- &my_port,
- 0);
- if (tape_control_sock < 0)
- {
- printf("cannot connect to %s: %s\n", tape_server_name, strerror(errno));
- return -1;
- }
- if (my_port >= IPPORT_RESERVED) {
- aclose(tape_control_sock);
- printf("did not get a reserved port: %d\n", my_port);
+
+ /* We assume that amidxtaped support fe_amidxtaped_options_features */
+ /* and fe_amidxtaped_options_auth */
+ /* We should send a noop to really know */
+ req = vstralloc("SERVICE amidxtaped\n",
+ "OPTIONS ", "features=", our_features_string, ";",
+ "auth=", authopt, ";",
+ "\n", NULL);
+ protocol_sendreq(tape_server_name, amidxtaped_secdrv,
+ amidxtaped_client_get_security_conf, req, STARTUP_TIMEOUT,
+ amidxtaped_response, &response_error);
+ amfree(req);
+ protocol_run();
+ if(response_error != 0) {
return -1;
}
-
- setegid(getgid());
- seteuid(getuid()); /* put it back */
-
- /* do the security thing */
- line = get_security();
- send_to_tape_server(tape_control_sock, line);
- memset(line, '\0', strlen(line));
- amfree(line);
disk_regex = alloc(strlen(disk_name) * 2 + 3);
}
}
*ch = '\0';
-
/* push our feature list off to the tape server */
/* XXX assumes that index server and tape server are equivalent, ew */
+
if(am_has_feature(indexsrv_features, fe_amidxtaped_exchange_features)){
- char buffer[32768] = "\0";
-
- our_feature_string = am_feature_to_string(our_features);
- tt = newstralloc2(tt, "FEATURES=", our_feature_string);
- send_to_tape_server(tape_control_sock, tt);
- if (read(tape_control_sock, buffer, sizeof(buffer)) <= 0) {
- error("Could not read features from control socket\n");
- /* NOTREACHED */
+ tt = newstralloc2(tt, "FEATURES=", our_features_string);
+ send_to_tape_server(amidxtaped_streams[CTLFD].fd, tt);
+ get_amidxtaped_line();
+ if(strncmp(amidxtaped_line,"FEATURES=",9) == 0) {
+ tapesrv_features = am_string_to_feature(amidxtaped_line+9);
+ } else {
+ fprintf(stderr, "amrecover - expecting FEATURES line from amidxtaped\n");
+ stop_amidxtaped();
+ amfree(disk_regex);
+ amfree(host_regex);
+ amfree(clean_datestamp);
+ return -1;
}
-
- tapesrv_features = am_string_to_feature(buffer);
- amfree(our_feature_string);
+ am_release_feature_set(tapesrv_features);
}
if(am_has_feature(indexsrv_features, fe_amidxtaped_config)) {
tt = newstralloc2(tt, "CONFIG=", config);
- send_to_tape_server(tape_control_sock, tt);
+ send_to_tape_server(amidxtaped_streams[CTLFD].fd, tt);
}
if(am_has_feature(indexsrv_features, fe_amidxtaped_label) &&
label && label[0] != '/') {
tt = newstralloc2(tt,"LABEL=",label);
- send_to_tape_server(tape_control_sock, tt);
+ send_to_tape_server(amidxtaped_streams[CTLFD].fd, tt);
}
if(am_has_feature(indexsrv_features, fe_amidxtaped_fsf)) {
char v_fsf[100];
- snprintf(v_fsf, 99, "%d", fsf);
+ snprintf(v_fsf, 99, OFF_T_FMT, (OFF_T_FMT_TYPE)fsf);
tt = newstralloc2(tt, "FSF=",v_fsf);
- send_to_tape_server(tape_control_sock, tt);
+ send_to_tape_server(amidxtaped_streams[CTLFD].fd, tt);
}
- send_to_tape_server(tape_control_sock, "HEADER");
+ send_to_tape_server(amidxtaped_streams[CTLFD].fd, "HEADER");
tt = newstralloc2(tt, "DEVICE=", dump_device_name);
- send_to_tape_server(tape_control_sock, tt);
+ send_to_tape_server(amidxtaped_streams[CTLFD].fd, tt);
tt = newstralloc2(tt, "HOST=", host_regex);
- send_to_tape_server(tape_control_sock, tt);
+ send_to_tape_server(amidxtaped_streams[CTLFD].fd, tt);
tt = newstralloc2(tt, "DISK=", disk_regex);
- send_to_tape_server(tape_control_sock, tt);
+ send_to_tape_server(amidxtaped_streams[CTLFD].fd, tt);
tt = newstralloc2(tt, "DATESTAMP=", clean_datestamp);
- send_to_tape_server(tape_control_sock, tt);
- send_to_tape_server(tape_control_sock, "END");
+ send_to_tape_server(amidxtaped_streams[CTLFD].fd, tt);
+ send_to_tape_server(amidxtaped_streams[CTLFD].fd, "END");
amfree(tt);
}
else if(am_has_feature(indexsrv_features, fe_amidxtaped_nargs)) {
* "diskname"
* "datestamp"
*/
- send_to_tape_server(tape_control_sock, "6");
- send_to_tape_server(tape_control_sock, "-h");
- send_to_tape_server(tape_control_sock, "-p");
- send_to_tape_server(tape_control_sock, dump_device_name);
- send_to_tape_server(tape_control_sock, host_regex);
- send_to_tape_server(tape_control_sock, disk_regex);
- send_to_tape_server(tape_control_sock, clean_datestamp);
+ send_to_tape_server(amidxtaped_streams[CTLFD].fd, "6");
+ send_to_tape_server(amidxtaped_streams[CTLFD].fd, "-h");
+ send_to_tape_server(amidxtaped_streams[CTLFD].fd, "-p");
+ send_to_tape_server(amidxtaped_streams[CTLFD].fd, dump_device_name);
+ send_to_tape_server(amidxtaped_streams[CTLFD].fd, host_regex);
+ send_to_tape_server(amidxtaped_streams[CTLFD].fd, disk_regex);
+ send_to_tape_server(amidxtaped_streams[CTLFD].fd, clean_datestamp);
dbprintf(("Started amidxtaped with arguments \"6 -h -p %s %s %s %s\"\n",
dump_device_name, host_regex, disk_regex, clean_datestamp));
}
- /*
- * split-restoring amidxtaped versions will expect to set up a data
- * connection for dumpfile data, distinct from the socket we're already
- * using for control data
- */
-
- if(am_has_feature(tapesrv_features, fe_recover_splits)){
- char buffer[32768];
- int data_port = -1;
- int nread;
-
- nread = read(tape_control_sock, buffer, sizeof(buffer));
-
- if (nread <= 0) {
- error("Could not read from control socket: %s\n",
- strerror(errno));
- /* NOTREACHED */
- }
-
- buffer[nread] = '\0';
- if (sscanf(buffer, "CONNECT %d\n", &data_port) != 1) {
- error("Recieved invalid port number message from control socket: %s\n",
- buffer);
- /* NOTREACHED */
- }
-
- tape_data_sock = stream_client_privileged(server_name,
- data_port,
- -1,
- STREAM_BUFSIZE,
- &my_data_port,
- 0);
- if(tape_data_sock == -1){
- error("Unable to make data connection to server: %s\n",
- strerror(errno));
- /* NOTREACHED */
- }
-
- amfree(our_feature_string);
-
- line = get_security();
-
- send_to_tape_server(tape_data_sock, line);
- memset(line, '\0', strlen(line));
- amfree(line);
- }
-
amfree(disk_regex);
amfree(host_regex);
amfree(clean_datestamp);
- return tape_control_sock;
+ return 0;
}
-void read_file_header(buffer, file, buflen, tapedev)
-char *buffer;
-dumpfile_t *file;
-size_t buflen;
-int tapedev;
/*
* Reads the first block of a tape file.
*/
+
+void
+read_file_header(
+ char * buffer,
+ dumpfile_t *file,
+ size_t buflen,
+ int tapedev)
{
ssize_t bytes_read;
-
bytes_read = read_buffer(tapedev, buffer, buflen, READ_TIMEOUT);
if(bytes_read < 0) {
error("error reading header (%s), check amidxtaped.*.debug on server",
strerror(errno));
- /* NOTREACHED */
+ /*NOTREACHED*/
}
if((size_t)bytes_read < buflen) {
get_pname(), (int)bytes_read, (bytes_read == 1) ? "" : "s");
print_header(stdout, file);
error("Can't read file header");
- /* NOTREACHED */
+ /*NOTREACHED*/
}
/* bytes_read == buflen */
- parse_file_header(buffer, file, bytes_read);
+ parse_file_header(buffer, file, (size_t)bytes_read);
}
-enum dumptypes {IS_UNKNOWN, IS_DUMP, IS_GNUTAR, IS_TAR, IS_SAMBA, IS_SAMBA_TAR};
-
-static void extract_files_child(in_fd, elist)
- int in_fd;
- EXTRACT_LIST *elist;
+enum dumptypes {
+ IS_UNKNOWN,
+ IS_DUMP,
+ IS_GNUTAR,
+ IS_TAR,
+ IS_SAMBA,
+ IS_SAMBA_TAR
+};
+
+static void
+extract_files_child(
+ int in_fd,
+ EXTRACT_LIST * elist)
{
int save_errno;
int extra_params = 0;
if (dup2(in_fd, STDIN_FILENO) == -1)
{
error("dup2 failed in extract_files_child: %s", strerror(errno));
- /* NOTREACHED */
+ /*NOTREACHED*/
}
/* read the file header */
if(file.type != F_DUMPFILE) {
print_header(stdout, &file);
error("bad header");
- /* NOTREACHED */
+ /*NOTREACHED*/
}
if (file.program != NULL) {
break;
}
- restore_args = (char **)alloc((extra_params + files_off_tape + 1)
- * sizeof(char *));
+ restore_args = (char **)alloc((size_t)((extra_params + files_off_tape + 1)
+ * sizeof(char *)));
switch(dumptype) {
case IS_SAMBA:
#ifdef SAMBA_CLIENT
* some extraction program, really) and the socket from which we're reading, so
* that we can do things like prompt for human interaction for multiple tapes.
*/
-void writer_intermediary(ctl_fd, data_fd, elist)
- int ctl_fd, data_fd;
- EXTRACT_LIST *elist;
+int
+writer_intermediary(
+ EXTRACT_LIST * elist)
{
int child_pipe[2];
pid_t pid;
- char buffer[DISK_BLOCK_BYTES];
- ssize_t s;
- ssize_t bytes_read;
amwait_t extractor_status;
- int max_fd, nfound;
- fd_set readset, selectset;
- struct timeval timeout;
-
- /*
- * If there's no distinct data channel (such as if we're talking to an
- * older server), don't bother doing anything complicated. Just run the
- * extraction.
- */
- if(data_fd == -1){
- extract_files_child(ctl_fd, elist);
- /* NOTREACHED */
- }
if(pipe(child_pipe) == -1) {
error("extract_list - error setting up pipe to extractor: %s\n",
- strerror(errno));
- /* NOTREACHED */
+ strerror(errno));
+ /*NOTREACHED*/
}
/* okay, ready to extract. fork a child to do the actual work */
/* never gets out of this clause */
aclose(child_pipe[1]);
extract_files_child(child_pipe[0], elist);
- /* NOTREACHED */
+ /*NOTREACHED*/
}
/* This is the parent */
if (pid == -1) {
- error("writer_intermediary - error forking child");
- /* NOTREACHED */
+ printf("writer_intermediary - error forking child");
+ return -1;
}
aclose(child_pipe[0]);
- if(data_fd > ctl_fd) max_fd = data_fd+1;
- else max_fd = ctl_fd+1;
- FD_ZERO(&readset);
- FD_SET(data_fd, &readset);
- FD_SET(ctl_fd, &readset);
+ security_stream_read(amidxtaped_streams[DATAFD].fd,
+ read_amidxtaped_data, &(child_pipe[1]));
- do {
- timeout.tv_sec = READ_TIMEOUT;
- timeout.tv_usec = 0;
- FD_COPY(&readset, &selectset);
-
- nfound = select(max_fd, (SELECT_ARG_TYPE *)(&selectset), NULL, NULL,
- &timeout);
- if(nfound < 0) {
- fprintf(stderr,"select error: %s\n", strerror(errno));
- break;
- }
-
- if (nfound == 0) { /* timeout */
- fprintf(stderr, "timeout waiting %d seconds for restore\n",
- READ_TIMEOUT);
- fprintf(stderr, "increase READ_TIMEOUT in recover-src/extract_list.c if your tape is slow\n");
- break;
- }
-
- if(FD_ISSET(ctl_fd, &selectset)) {
- bytes_read = read(ctl_fd, buffer, sizeof(buffer)-1);
- switch(bytes_read) {
- case -1:
- if ((errno != EINTR) && (errno != EAGAIN)) {
- if (errno != EPIPE) {
- fprintf(stderr,"writer ctl fd read error: %s",
- strerror(errno));
- }
- FD_CLR(ctl_fd, &readset);
- }
- break;
-
- case 0:
- FD_CLR(ctl_fd, &readset);
- break;
-
- default: {
- char desired_tape[MAX_TAPE_LABEL_BUF];
+ while(get_amidxtaped_line() >= 0) {
+ char desired_tape[MAX_TAPE_LABEL_BUF];
- buffer[bytes_read] = '\0';
- /* if prompted for a tape, relay said prompt to the user */
- if(sscanf(buffer, "FEEDME %s\n", desired_tape) == 1) {
- int done = 0;
- while (!done) {
- char *input = NULL;
- printf("Please insert tape %s. Continue? [Y|n]: ",
- desired_tape);
- fflush(stdout);
-
- input = agets(stdin); /* strips \n */
- if (strcasecmp("", input) == 0||
- strcasecmp("y", input) == 0||
- strcasecmp("yes", input) == 0) {
- send_to_tape_server(tape_control_sock, "OK");
- done = 1;
- } else if (strcasecmp("n", input) == 0||
- strcasecmp("no", input) == 0) {
- send_to_tape_server(tape_control_sock, "ERROR");
- /* Abort!
- We are the middle process, so just die. */
- exit(EXIT_FAILURE);
- }
- amfree(input);
- }
- } else {
- fprintf(stderr, "Strange message from tape server: %s", buffer);
-
- break;
+ /* if prompted for a tape, relay said prompt to the user */
+ if(sscanf(amidxtaped_line, "FEEDME %132s\n", desired_tape) == 1) {
+ int done;
+ printf("Load tape %s now\n", desired_tape);
+ done = okay_to_continue(am_has_feature(indexsrv_features,
+ fe_amrecover_feedme_tape),
+ 0, 0);
+ if (done == 1) {
+ if (am_has_feature(indexsrv_features,
+ fe_amrecover_feedme_tape)) {
+ char *reply = stralloc2("TAPE ", tape_device_name);
+ send_to_tape_server(amidxtaped_streams[CTLFD].fd, reply);
+ amfree(reply);
+ } else {
+ send_to_tape_server(amidxtaped_streams[CTLFD].fd, "OK");
}
+ } else {
+ send_to_tape_server(amidxtaped_streams[CTLFD].fd, "ERROR");
+ break;
}
- }
- }
-
- /* now read some dump data */
- if(FD_ISSET(data_fd, &selectset)) {
- bytes_read = read(data_fd, buffer, sizeof(buffer)-1);
- switch(bytes_read) {
- case -1:
- if ((errno != EINTR) && (errno != EAGAIN)) {
- if (errno != EPIPE) {
- fprintf(stderr,"writer data fd read error: %s",
- strerror(errno));
- }
- FD_CLR(data_fd, &readset);
- }
- break;
-
- case 0:
- FD_CLR(data_fd, &readset);
- break;
-
- default:
- /*
- * spit what we got from the server to the child
- * process handling actual dumpfile extraction
- */
- if((s = fullwrite(child_pipe[1], buffer, bytes_read)) < 0){
- if(errno == EPIPE) {
- error("%s: pipe data reader has quit: %s\n",
- get_pname(), strerror(errno));
- /* NOTREACHED */
- }
- error("Write error to extract child: %s\n",
- strerror(errno));
- /* NOTREACHED */
- }
- break;
- }
+ } else if(strncmp(amidxtaped_line, "MESSAGE ", 8) == 0) {
+ printf("%s\n",&amidxtaped_line[8]);
+ } else {
+ fprintf(stderr, "Strange message from tape server: %s",
+ amidxtaped_line);
+ break;
}
- } while(FD_ISSET(ctl_fd, &readset) || FD_ISSET(data_fd, &readset));
+ }
+ /* CTL might be close before DATA */
+ event_loop(0);
aclose(child_pipe[1]);
waitpid(pid, &extractor_status, 0);
if(WEXITSTATUS(extractor_status) != 0){
int ret = WEXITSTATUS(extractor_status);
if(ret == 255) ret = -1;
- error("Extractor child exited with status %d\n", ret);
- /* NOTREACHED */
+ printf("Extractor child exited with status %d\n", ret);
+ return -1;
}
-
- exit(0);
+ return(0);
}
/* exec restore to do the actual restoration */
/* does the actual extraction of files */
-/* The original design had the dump image being returned exactly as it
- appears on the tape, and this routine getting from the index server
- whether or not it is compressed, on the assumption that the tape
- server may not know how to uncompress it. But
- - Amrestore can't do that. It returns either compressed or uncompressed
- (always). Amrestore assumes it can uncompress files. It is thus a good
- idea to run the tape server on a machine with gzip.
- - The information about compression in the disklist is really only
- for future dumps. It is possible to change compression on a drive
- so the information in the disklist may not necessarily relate to
- the dump image on the tape.
- Consequently the design was changed to assuming that amrestore can
- uncompress any dump image and have it return an uncompressed file
- always. */
-void extract_files P((void))
+/*
+ * The original design had the dump image being returned exactly as it
+ * appears on the tape, and this routine getting from the index server
+ * whether or not it is compressed, on the assumption that the tape
+ * server may not know how to uncompress it. But
+ * - Amrestore can't do that. It returns either compressed or uncompressed
+ * (always). Amrestore assumes it can uncompress files. It is thus a good
+ * idea to run the tape server on a machine with gzip.
+ * - The information about compression in the disklist is really only
+ * for future dumps. It is possible to change compression on a drive
+ * so the information in the disklist may not necessarily relate to
+ * the dump image on the tape.
+ * Consequently the design was changed to assuming that amrestore can
+ * uncompress any dump image and have it return an uncompressed file
+ * always.
+ */
+void
+extract_files(void)
{
EXTRACT_LIST *elist;
- pid_t pid;
- amwait_t child_stat;
- char buf[STR_SIZE];
+ char cwd[STR_SIZE];
char *l;
int first;
int otc;
- tapelist_t *tlist = NULL;
+ tapelist_t *tlist = NULL, *a_tlist;
if (!is_extract_list_nonempty())
{
return;
}
+ clean_extract_list();
+
/* get tape device name from index server if none specified */
if (tape_server_name == NULL) {
tape_server_name = newstralloc(tape_server_name, server_name);
}
first=1;
- for (elist = first_tape_list(); elist != NULL; elist = next_tape_list(elist))
+ for (elist = first_tape_list(); elist != NULL; elist = next_tape_list(elist)) {
if(elist->tape[0]!='/') {
if(first) {
printf("\nExtracting files using tape drive %s on host %s.\n",
else
printf(" ");
tlist = unmarshal_tapelist_str(elist->tape);
- for( ; tlist != NULL; tlist = tlist->next)
- printf(" %s", tlist->label);
+ for(a_tlist = tlist ; a_tlist != NULL; a_tlist = a_tlist->next)
+ printf(" %s", a_tlist->label);
printf("\n");
- amfree(tlist);
+ free_tapelist(tlist);
}
+ }
first=1;
- for (elist = first_tape_list(); elist != NULL; elist = next_tape_list(elist))
+ for (elist = first_tape_list(); elist != NULL; elist = next_tape_list(elist)) {
if(elist->tape[0]=='/') {
if(first) {
printf("\nExtracting files from holding disk on host %s.\n",
else
printf(" ");
tlist = unmarshal_tapelist_str(elist->tape);
- for( ; tlist != NULL; tlist = tlist->next)
- printf(" %s", tlist->label);
+ for(a_tlist = tlist; a_tlist != NULL; a_tlist = a_tlist->next)
+ printf(" %s", a_tlist->label);
printf("\n");
- amfree(tlist);
+ free_tapelist(tlist);
}
+ }
printf("\n");
- getcwd(buf, sizeof(buf));
- printf("Restoring files into directory %s\n", buf);
+
+ if (getcwd(cwd, sizeof(cwd)) == NULL) {
+ perror("extract_list: Current working directory unavailable");
+ exit(1);
+ }
+
+ printf("Restoring files into directory %s\n", cwd);
+ check_file_overwrite(cwd);
+
#ifdef SAMBA_CLIENT
if (samba_extract_method == SAMBA_SMBCLIENT)
printf("(unless it is a Samba backup, that will go through to the SMB server)\n");
return;
printf("\n");
+ if (!do_unlink_list()) {
+ fprintf(stderr, "Can't recover because I can't cleanup the cwd (%s)\n",
+ cwd);
+ return;
+ }
+ free_unlink_list();
+
while ((elist = first_tape_list()) != NULL)
{
if(elist->tape[0]=='/') {
dump_device_name = newstralloc(dump_device_name, elist->tape);
printf("Extracting from file ");
tlist = unmarshal_tapelist_str(dump_device_name);
- for( ; tlist != NULL; tlist = tlist->next)
- printf(" %s", tlist->label);
+ for(a_tlist = tlist; a_tlist != NULL; a_tlist = a_tlist->next)
+ printf(" %s", a_tlist->label);
printf("\n");
- amfree(tlist);
+ free_tapelist(tlist);
}
else {
printf("Extracting files using tape drive %s on host %s.\n",
tape_device_name, tape_server_name);
tlist = unmarshal_tapelist_str(elist->tape);
printf("Load tape %s now\n", tlist->label);
- amfree(tlist);
+ free_tapelist(tlist);
otc = okay_to_continue(1,1,0);
if (otc == 0)
return;
dump_datestamp = newstralloc(dump_datestamp, elist->date);
/* connect to the tape handler daemon on the tape drive server */
- if ((tape_control_sock = extract_files_setup(elist->tape, elist->fileno)) == -1)
+ if ((extract_files_setup(elist->tape, elist->fileno)) == -1)
{
fprintf(stderr, "amrecover - can't talk to tape server\n");
return;
}
- /* okay, ready to extract. fork a child to do the actual work */
- if ((pid = fork()) == 0)
- {
- /* this is the child process */
- /* never gets out of this clause */
- writer_intermediary(tape_control_sock, tape_data_sock, elist);
- /*NOT REACHED*/
- }
- /* this is the parent */
- if (pid == -1)
- {
- perror("extract_list - error forking child");
- exit(1);
- }
+ /* if the server have fe_amrecover_feedme_tape, it has asked for
+ * the tape itself, even if the restore didn't succeed, we should
+ * remove it.
+ */
+ if(writer_intermediary(elist) == 0 ||
+ am_has_feature(indexsrv_features, fe_amrecover_feedme_tape))
+ delete_tape_list(elist); /* tape done so delete from list */
- /* store the child pid globally so that it can be killed on intr */
- extract_restore_child_pid = pid;
+ stop_amidxtaped();
+ }
+}
- /* wait for the child process to finish */
- if ((pid = waitpid(-1, &child_stat, 0)) == (pid_t)-1)
- {
- perror("extract_list - error waiting for child");
- exit(1);
- }
+static void
+amidxtaped_response(
+ void * datap,
+ pkt_t * pkt,
+ security_handle_t * sech)
+{
+ int ports[NSTREAMS], *response_error = datap, i;
+ char *p;
+ char *tok;
+ char *extra = NULL;
+
+ assert(response_error != NULL);
+ assert(sech != NULL);
+ memset(ports, -1, SIZEOF(ports));
+
+ security_close_connection(sech, dump_hostname);
+ if (pkt == NULL) {
+ errstr = newvstralloc(errstr, "[request failed: ",
+ security_geterror(sech), "]", NULL);
+ *response_error = 1;
+ return;
+ }
+
+ if (pkt->type == P_NAK) {
+#if defined(PACKET_DEBUG)
+ fprintf(stderr, "got nak response:\n----\n%s\n----\n\n", pkt->body);
+#endif
+
+ tok = strtok(pkt->body, " ");
+ if (tok == NULL || strcmp(tok, "ERROR") != 0)
+ goto bad_nak;
- if(tape_data_sock != -1) {
- aclose(tape_data_sock);
+ tok = strtok(NULL, "\n");
+ if (tok != NULL) {
+ errstr = newvstralloc(errstr, "NAK: ", tok, NULL);
+ *response_error = 1;
+ } else {
+bad_nak:
+ errstr = newstralloc(errstr, "request NAK");
+ *response_error = 2;
}
+ return;
+ }
- if (pid == extract_restore_child_pid)
- {
- extract_restore_child_pid = -1;
+ if (pkt->type != P_REP) {
+ errstr = newvstralloc(errstr, "received strange packet type ",
+ pkt_type2str(pkt->type), ": ", pkt->body, NULL);
+ *response_error = 1;
+ return;
+ }
+
+#if defined(PACKET_DEBUG)
+ fprintf(stderr, "got response:\n----\n%s\n----\n\n", pkt->body);
+#endif
+
+ for(i = 0; i < NSTREAMS; i++) {
+ ports[i] = -1;
+ amidxtaped_streams[i].fd = NULL;
+ }
+
+ p = pkt->body;
+ while((tok = strtok(p, " \n")) != NULL) {
+ p = NULL;
+
+ /*
+ * Error response packets have "ERROR" followed by the error message
+ * followed by a newline.
+ */
+ if (strcmp(tok, "ERROR") == 0) {
+ tok = strtok(NULL, "\n");
+ if (tok == NULL)
+ tok = "[bogus error packet]";
+ errstr = newstralloc(errstr, tok);
+ *response_error = 2;
+ return;
}
- else
- {
- fprintf(stderr, "extract list - unknown child terminated?\n");
- exit(1);
+
+
+ /*
+ * Regular packets have CONNECT followed by three streams
+ */
+ if (strcmp(tok, "CONNECT") == 0) {
+
+ /*
+ * Parse the three stream specifiers out of the packet.
+ */
+ for (i = 0; i < NSTREAMS; i++) {
+ tok = strtok(NULL, " ");
+ if (tok == NULL || strcmp(tok, amidxtaped_streams[i].name) != 0) {
+ extra = vstralloc("CONNECT token is \"",
+ tok ? tok : "(null)",
+ "\": expected \"",
+ amidxtaped_streams[i].name,
+ "\"",
+ NULL);
+ goto parse_error;
+ }
+ tok = strtok(NULL, " \n");
+ if (tok == NULL || sscanf(tok, "%d", &ports[i]) != 1) {
+ extra = vstralloc("CONNECT ",
+ amidxtaped_streams[i].name,
+ " token is \"",
+ tok ? tok : "(null)",
+ "\": expected a port number",
+ NULL);
+ goto parse_error;
+ }
+ }
+ continue;
}
- if ((WIFEXITED(child_stat) != 0) && (WEXITSTATUS(child_stat) != 0))
- {
- fprintf(stderr,
- "extract_list - child returned non-zero status: %d\n",
- WEXITSTATUS(child_stat));
- otc = okay_to_continue(0,0,1);
- if(otc == 0)
- return;
- else if(otc == 1) {
- delete_tape_list(elist); /* tape failed so delete from list */
+
+ /*
+ * OPTIONS [options string] '\n'
+ */
+ if (strcmp(tok, "OPTIONS") == 0) {
+ tok = strtok(NULL, "\n");
+ if (tok == NULL) {
+ extra = stralloc("OPTIONS token is missing");
+ goto parse_error;
}
- else { /* RETRY_TAPE */
+/*
+ while((p = strchr(tok, ';')) != NULL) {
+ *p++ = '\0';
+#define sc "features="
+ if(strncmp(tok, sc, sizeof(sc)-1) == 0) {
+ tok += sizeof(sc) - 1;
+#undef sc
+ am_release_feature_set(their_features);
+ if((their_features = am_string_to_feature(tok)) == NULL) {
+ errstr = newvstralloc(errstr,
+ "OPTIONS: bad features value: ",
+ tok,
+ NULL);
+ goto parse_error;
+ }
+ }
+ tok = p;
}
+*/
+ continue;
}
- else {
- delete_tape_list(elist); /* tape done so delete from list */
+/*
+ extra = vstralloc("next token is \"",
+ tok ? tok : "(null)",
+ "\": expected \"CONNECT\", \"ERROR\" or \"OPTIONS\"",
+ NULL);
+ goto parse_error;
+*/
+ }
+
+ /*
+ * Connect the streams to their remote ports
+ */
+ for (i = 0; i < NSTREAMS; i++) {
+ if (ports[i] == -1)
+ continue;
+ amidxtaped_streams[i].fd = security_stream_client(sech, ports[i]);
+ dbprintf(("amidxtaped_streams[%d].fd = %p\n",i, amidxtaped_streams[i].fd));
+ if (amidxtaped_streams[i].fd == NULL) {
+ errstr = newvstralloc(errstr,
+ "[could not connect ", amidxtaped_streams[i].name, " stream: ",
+ security_geterror(sech), "]", NULL);
+ goto connect_error;
}
}
+ /*
+ * Authenticate the streams
+ */
+ for (i = 0; i < NSTREAMS; i++) {
+ if (amidxtaped_streams[i].fd == NULL)
+ continue;
+ if (security_stream_auth(amidxtaped_streams[i].fd) < 0) {
+ errstr = newvstralloc(errstr,
+ "[could not authenticate ", amidxtaped_streams[i].name, " stream: ",
+ security_stream_geterror(amidxtaped_streams[i].fd), "]", NULL);
+ goto connect_error;
+ }
+ }
+
+ /*
+ * The CTLFD and DATAFD streams are mandatory. If we didn't get
+ * them, complain.
+ */
+ if (amidxtaped_streams[CTLFD].fd == NULL) {
+ errstr = newstralloc(errstr, "[couldn't open CTL streams]");
+ goto connect_error;
+ }
+ if (amidxtaped_streams[DATAFD].fd == NULL) {
+ errstr = newstralloc(errstr, "[couldn't open DATA streams]");
+ goto connect_error;
+ }
+
+ /* everything worked */
+ *response_error = 0;
+ return;
+
+parse_error:
+ errstr = newvstralloc(errstr,
+ "[parse of reply message failed: ",
+ extra ? extra : "(no additional information)",
+ "]",
+ NULL);
+ amfree(extra);
+ *response_error = 2;
+ return;
+
+connect_error:
+ stop_amidxtaped();
+ *response_error = 1;
+}
+
+/*
+ * This is called when everything needs to shut down so event_loop()
+ * will exit.
+ */
+static void
+stop_amidxtaped(void)
+{
+ int i;
+
+ for (i = 0; i < NSTREAMS; i++) {
+ if (amidxtaped_streams[i].fd != NULL) {
+ security_stream_close(amidxtaped_streams[i].fd);
+ amidxtaped_streams[i].fd = NULL;
+ }
+ }
+}
+
+static char* ctl_buffer = NULL;
+/* gets a "line" from server and put in server_line */
+/* server_line is terminated with \0, \r\n is striped */
+/* returns -1 if error */
+
+int
+get_amidxtaped_line(void)
+{
+ ssize_t size;
+ char *newbuf, *s;
+ void *buf;
+
+ amfree(amidxtaped_line);
+ if (!ctl_buffer)
+ ctl_buffer = stralloc("");
+
+ while (!strstr(ctl_buffer,"\r\n")) {
+ size = security_stream_read_sync(amidxtaped_streams[CTLFD].fd, &buf);
+ if(size < 0) {
+ return -1;
+ }
+ else if(size == 0) {
+ return -1;
+ }
+ newbuf = alloc(strlen(ctl_buffer)+size+1);
+ strncpy(newbuf, ctl_buffer, (size_t)(strlen(ctl_buffer) + size + 1));
+ memcpy(newbuf+strlen(ctl_buffer), buf, (size_t)size);
+ newbuf[strlen(ctl_buffer)+size] = '\0';
+ amfree(ctl_buffer);
+ ctl_buffer = newbuf;
+ }
+
+ s = strstr(ctl_buffer,"\r\n");
+ *s = '\0';
+ newbuf = stralloc(s+2);
+ amidxtaped_line = stralloc(ctl_buffer);
+ amfree(ctl_buffer);
+ ctl_buffer = newbuf;
+ return 0;
+}
+
+
+static void
+read_amidxtaped_data(
+ void * cookie,
+ void * buf,
+ ssize_t size)
+{
+ int fd;
+
+ assert(cookie != NULL);
+
+ fd = *(int *)cookie;
+ if (size < 0) {
+ errstr = newstralloc2(errstr, "amidxtaped read: ",
+ security_stream_geterror(amidxtaped_streams[DATAFD].fd));
+ return;
+ }
+
+ /*
+ * EOF. Stop and return.
+ */
+ if (size == 0) {
+ security_stream_close(amidxtaped_streams[DATAFD].fd);
+ amidxtaped_streams[DATAFD].fd = NULL;
+ /*
+ * If the mesg fd has also shut down, then we're done.
+ */
+ return;
+ }
+
+ assert(buf != NULL);
+
+ /*
+ * We ignore errors while writing to the index file.
+ */
+ (void)fullwrite(fd, buf, (size_t)size);
+ security_stream_read(amidxtaped_streams[DATAFD].fd, read_amidxtaped_data, cookie);
+}
+
+char *
+amidxtaped_client_get_security_conf(
+ char * string,
+ void * arg)
+{
+ (void)arg; /* Quiet unused parameter warning */
+
+ if(!string || !*string)
+ return(NULL);
+
+ if(strcmp(string, "auth")==0) {
+ return(client_getconf_str(CLN_AUTH));
+ }
+ if(strcmp(string, "ssh_keys")==0) {
+ return(client_getconf_str(CLN_SSH_KEYS));
+ }
+ return(NULL);
}
* file named AUTHORS, in the root directory of this distribution.
*/
/*
- * $Id: help.c,v 1.8 2002/03/06 19:23:20 martinea Exp $
+ * $Id: help.c,v 1.12 2006/05/25 01:47:14 johnfranks Exp $
*
* implements the "help" command in amrecover
*/
+#include "amanda.h"
#include "amrecover.h"
/* print a list of valid commands */
-void help_list P((void))
+void
+help_list(void)
{
printf("valid commands are:\n\n");
printf("mode - show the method used to extract SMB shares\n");
printf("pwd - show cwd on virtual file system\n");
printf("quit\n");
- printf("listdisk [diskdevice] - list disks\n");
+ printf("listhost - list hosts\n");
+ printf("listdisk [diskdevice] - list disks\n");
printf("setdate {YYYY-MM-DD|--MM-DD|---DD} - set date of look\n");
- printf("setdisk diskname [mountpoint] - select disk on dump host\n");
- printf("sethost host - select dump host\n");
- printf("settape [host:][device|default] - select tape server and/or device\n");
- printf("setmode smb|tar - select the method used to extract SMB shares\n");
+ printf(" {YYYY-MM-DD-HH-MM-SS} - set date of look\n");
+ printf("setdisk diskname [mountpoint] - select disk on dump host\n");
+ printf("sethost host - select dump host\n");
+ printf("settape [host:][device|default] - select tape server and/or device\n");
+ printf("setmode smb|tar - select the method used to extract SMB shares\n");
printf("\n");
}
* file named AUTHORS, in the root directory of this distribution.
*/
/*
- * $Id: set_commands.c,v 1.23 2004/02/11 13:15:18 martinea Exp $
+ * $Id: set_commands.c,v 1.26 2006/07/05 13:14:58 martinea Exp $
*
* implements the "set" commands in amrecover
*/
#endif /* SAMBA_CLIENT */
/* sets a date, mapping given date into standard form if needed */
-int set_date(date)
-char *date;
+int
+set_date(
+ char * date)
{
char *cmd = NULL;
}
}
amfree(cmd);
-
return 0;
}
-void set_host(host)
-char *host;
+void
+set_host(
+ const char *host)
{
char *cmd = NULL;
struct hostent *hp;
amfree(cmd);
}
+void
+list_host(void)
+{
+ char *cmd = NULL;
+
+ cmd = stralloc("LISTHOST");
+ if (converse(cmd) == -1)
+ exit(1);
+ amfree(cmd);
+}
-void set_disk(dsk, mtpt)
-char *dsk;
-char *mtpt;
+void
+set_disk(
+ char * dsk,
+ char * mtpt)
{
char *cmd = NULL;
}
}
-void list_disk(amdevice)
-char *amdevice;
+void
+list_disk(
+ char * amdevice)
{
char *cmd = NULL;
}
}
-void cd_glob(glob)
-char *glob;
+void
+cd_glob(
+ char * glob)
{
char *regex;
char *regex_path;
amfree(path_on_disk);
}
-void cd_regex(regex)
-char *regex;
+void
+cd_regex(
+ char * regex)
{
char *s;
amfree(path_on_disk);
}
-void cd_dir(path_on_disk, default_dir)
-char *path_on_disk;
-char *default_dir;
+void
+cd_dir(
+ char * path_on_disk,
+ char * default_dir)
{
char *path_on_disk_slash = NULL;
char *dir = NULL;
dir[strlen(dir)-1] = '\0'; /* remove last / */
/* remove everything before the last / */
dir1 = rindex(dir,'/');
- dir1++;
- dir2 = stralloc(dir1);
- amfree(dir);
- dir = dir2;
+ if (dir1) {
+ dir1++;
+ dir2 = stralloc(dir1);
+ amfree(dir);
+ dir = dir2;
+ }
}
}
}
amfree(dir);
}
-void set_directory(dir)
-char *dir;
+void
+set_directory(
+ char * dir)
{
char *cmd = NULL;
char *new_dir = NULL;
if(strcmp(dir,".")==0) {
show_directory(); /* say where we are */
return;
+ /*NOTREACHED*/
}
if (disk_name == NULL) {
printf("Must select disk before setting directory\n");
return;
+ /*NOTREACHED*/
}
ldir = stralloc(dir);
mount_point);
amfree(ldir);
return;
+ /*NOTREACHED*/
}
new_dir = stralloc(ldir+strlen(mount_point));
if (strlen(new_dir) == 0) {
/* at top of disk */
printf("Invalid directory - Can't cd outside mount point \"%s\"\n",
mount_point);
+ /*@ignore@*/
amfree(new_dir);
+ /*@end@*/
amfree(ldir);
return;
+ /*NOTREACHED*/
}
de = strrchr(new_dir, '/'); /* always at least 1 */
if (de == new_dir)
*de = '\0';
}
} else {
+ /*@ignore@*/
if (strcmp(new_dir, "/") != 0) {
strappend(new_dir, "/");
}
strappend(new_dir, ldir);
+ /*@end@*/
}
}
cmd = stralloc2("OISD ", new_dir);
- if (exchange(cmd) == -1)
+ if (exchange(cmd) == -1) {
exit(1);
+ /*NOTREACHED*/
+ }
amfree(cmd);
+
if (server_happy())
{
disk_path = newstralloc(disk_path, new_dir);
printf("Invalid directory - %s\n", dir);
}
+ /*@ignore@*/
amfree(new_dir);
amfree(ldir);
+ /*@end@*/
}
/* prints the current working directory */
-void show_directory P((void))
+void
+show_directory(void)
{
if (mount_point == NULL || disk_path == NULL)
printf("Must select disk first\n");
/* set the tape server and device */
-void set_tape (tape)
- char *tape;
+void
+set_tape(
+ char * tape)
{
char *tapedev = strchr(tape, ':');
server_name);
}
-void set_mode (mode)
-int mode;
+void
+set_mode(
+ int mode)
{
#ifdef SAMBA_CLIENT
if (mode == SAMBA_SMBCLIENT) {
samba_extract_method = SAMBA_TAR;
}
}
+#else
+ (void)mode; /* Quiet unused parameter warning */
#endif /* SAMBA_CLIENT */
}
-void show_mode (void)
+void
+show_mode(void)
{
#ifdef SAMBA_CLIENT
printf ("SAMBA dumps are extracted ");
/* Put the tokens into the symbol table, so that GDB and other debuggers
know about them. */
enum yytokentype {
- LISTDISK = 258,
- SETHOST = 259,
- SETDISK = 260,
- SETDATE = 261,
- SETTAPE = 262,
- SETMODE = 263,
- CD = 264,
- CDX = 265,
- QUIT = 266,
- DHIST = 267,
- LS = 268,
- ADD = 269,
- ADDX = 270,
- EXTRACT = 271,
- LIST = 272,
- DELETE = 273,
- DELETEX = 274,
- PWD = 275,
- CLEAR = 276,
- HELP = 277,
- LCD = 278,
- LPWD = 279,
- MODE = 280,
- SMB = 281,
- TAR = 282,
- PATH = 283,
- DATE = 284
+ LISTHOST = 258,
+ LISTDISK = 259,
+ SETHOST = 260,
+ SETDISK = 261,
+ SETDATE = 262,
+ SETTAPE = 263,
+ SETMODE = 264,
+ CD = 265,
+ CDX = 266,
+ QUIT = 267,
+ DHIST = 268,
+ LS = 269,
+ ADD = 270,
+ ADDX = 271,
+ EXTRACT = 272,
+ LIST = 273,
+ DELETE = 274,
+ DELETEX = 275,
+ PWD = 276,
+ CLEAR = 277,
+ HELP = 278,
+ LCD = 279,
+ LPWD = 280,
+ MODE = 281,
+ SMB = 282,
+ TAR = 283,
+ PATH = 284,
+ DATE = 285
};
#endif
/* Tokens. */
-#define LISTDISK 258
-#define SETHOST 259
-#define SETDISK 260
-#define SETDATE 261
-#define SETTAPE 262
-#define SETMODE 263
-#define CD 264
-#define CDX 265
-#define QUIT 266
-#define DHIST 267
-#define LS 268
-#define ADD 269
-#define ADDX 270
-#define EXTRACT 271
-#define LIST 272
-#define DELETE 273
-#define DELETEX 274
-#define PWD 275
-#define CLEAR 276
-#define HELP 277
-#define LCD 278
-#define LPWD 279
-#define MODE 280
-#define SMB 281
-#define TAR 282
-#define PATH 283
-#define DATE 284
+#define LISTHOST 258
+#define LISTDISK 259
+#define SETHOST 260
+#define SETDISK 261
+#define SETDATE 262
+#define SETTAPE 263
+#define SETMODE 264
+#define CD 265
+#define CDX 266
+#define QUIT 267
+#define DHIST 268
+#define LS 269
+#define ADD 270
+#define ADDX 271
+#define EXTRACT 272
+#define LIST 273
+#define DELETE 274
+#define DELETEX 275
+#define PWD 276
+#define CLEAR 277
+#define HELP 278
+#define LCD 279
+#define LPWD 280
+#define MODE 281
+#define SMB 282
+#define TAR 283
+#define PATH 284
+#define DATE 285
#include "amanda.h"
#include "amrecover.h"
-void yyerror P((char *s));
-extern int yylex P((void));
+void yyerror(char *s);
+extern int yylex(void);
+extern char * yytext;
+
/* Enabling traces. */
#endif
#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
-#line 40 "uparse.y"
+#line 42 "uparse.y"
typedef union YYSTYPE {
- int intval;
- double floatval;
- char *strval;
- int subtok;
+ int intval;
+ double floatval;
+ char * strval;
+ int subtok;
} YYSTYPE;
/* Line 196 of yacc.c. */
-#line 158 "uparse.c"
+#line 162 "uparse.c"
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1
# define YYSTYPE_IS_TRIVIAL 1
/* Line 219 of yacc.c. */
-#line 170 "uparse.c"
+#line 174 "uparse.c"
#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__)
# define YYSIZE_T __SIZE_TYPE__
#endif
/* YYFINAL -- State number of the termination state. */
-#define YYFINAL 54
+#define YYFINAL 55
/* YYLAST -- Last index in YYTABLE. */
-#define YYLAST 44
+#define YYLAST 45
/* YYNTOKENS -- Number of terminals. */
-#define YYNTOKENS 30
+#define YYNTOKENS 31
/* YYNNTS -- Number of nonterminals. */
#define YYNNTS 16
/* YYNRULES -- Number of rules. */
-#define YYNRULES 47
+#define YYNRULES 49
/* YYNRULES -- Number of states. */
-#define YYNSTATES 60
+#define YYNSTATES 61
/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
#define YYUNDEFTOK 2
-#define YYMAXUTOK 284
+#define YYMAXUTOK 285
#define YYTRANSLATE(YYX) \
((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
- 25, 26, 27, 28, 29
+ 25, 26, 27, 28, 29, 30
};
#if YYDEBUG
static const unsigned char yyprhs[] =
{
0, 0, 3, 5, 7, 9, 11, 13, 15, 17,
- 19, 21, 23, 26, 28, 31, 34, 38, 41, 44,
- 46, 49, 52, 55, 58, 60, 62, 65, 67, 69,
- 71, 73, 75, 78, 81, 83, 86, 89, 91, 94,
- 97, 99, 102, 105, 107, 109, 112, 114
+ 19, 21, 23, 24, 26, 29, 31, 34, 37, 41,
+ 44, 47, 49, 52, 55, 58, 61, 63, 65, 68,
+ 70, 72, 74, 76, 78, 81, 84, 86, 89, 92,
+ 94, 97, 100, 102, 105, 108, 110, 112, 115, 117
};
/* YYRHS -- A `-1'-separated list of the rules' RHS. */
static const yysigned_char yyrhs[] =
{
- 31, 0, -1, 32, -1, 33, -1, 34, -1, 35,
- -1, 37, -1, 39, -1, 41, -1, 43, -1, 44,
- -1, 45, -1, 3, 28, -1, 3, -1, 6, 29,
- -1, 4, 28, -1, 5, 28, 28, -1, 5, 28,
- -1, 7, 28, -1, 7, -1, 9, 28, -1, 10,
- 28, -1, 8, 26, -1, 8, 27, -1, 12, -1,
- 13, -1, 17, 28, -1, 17, -1, 20, -1, 21,
- -1, 25, -1, 11, -1, 14, 36, -1, 36, 28,
- -1, 28, -1, 15, 38, -1, 38, 28, -1, 28,
- -1, 18, 40, -1, 40, 28, -1, 28, -1, 19,
- 42, -1, 42, 28, -1, 28, -1, 24, -1, 23,
- 28, -1, 22, -1, 16, -1
+ 32, 0, -1, 33, -1, 34, -1, 35, -1, 36,
+ -1, 38, -1, 40, -1, 42, -1, 44, -1, 45,
+ -1, 46, -1, -1, 3, -1, 4, 29, -1, 4,
+ -1, 7, 30, -1, 5, 29, -1, 6, 29, 29,
+ -1, 6, 29, -1, 8, 29, -1, 8, -1, 10,
+ 29, -1, 11, 29, -1, 9, 27, -1, 9, 28,
+ -1, 13, -1, 14, -1, 18, 29, -1, 18, -1,
+ 21, -1, 22, -1, 26, -1, 12, -1, 15, 37,
+ -1, 37, 29, -1, 29, -1, 16, 39, -1, 39,
+ 29, -1, 29, -1, 19, 41, -1, 41, 29, -1,
+ 29, -1, 20, 43, -1, 43, 29, -1, 29, -1,
+ 25, -1, 24, 29, -1, 23, -1, 17, -1
};
/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
static const unsigned char yyrline[] =
{
- 0, 63, 63, 64, 65, 66, 67, 68, 69, 70,
- 71, 72, 76, 77, 78, 79, 80, 81, 82, 83,
- 84, 85, 86, 91, 99, 100, 101, 102, 103, 104,
- 105, 109, 113, 117, 118, 122, 126, 127, 131, 135,
- 136, 140, 144, 145, 149, 150, 159, 163
+ 0, 65, 65, 66, 67, 68, 69, 70, 71, 72,
+ 73, 74, 75, 84, 85, 86, 87, 88, 89, 90,
+ 91, 92, 93, 94, 95, 100, 108, 109, 110, 111,
+ 112, 113, 114, 118, 122, 126, 127, 131, 135, 136,
+ 140, 144, 145, 149, 153, 154, 158, 159, 168, 172
};
#endif
First, the terminals, then, starting at YYNTOKENS, nonterminals. */
static const char *const yytname[] =
{
- "$end", "error", "$undefined", "LISTDISK", "SETHOST", "SETDISK",
- "SETDATE", "SETTAPE", "SETMODE", "CD", "CDX", "QUIT", "DHIST", "LS",
- "ADD", "ADDX", "EXTRACT", "LIST", "DELETE", "DELETEX", "PWD", "CLEAR",
- "HELP", "LCD", "LPWD", "MODE", "SMB", "TAR", "PATH", "DATE", "$accept",
- "ucommand", "set_command", "display_command", "quit_command",
+ "$end", "error", "$undefined", "LISTHOST", "LISTDISK", "SETHOST",
+ "SETDISK", "SETDATE", "SETTAPE", "SETMODE", "CD", "CDX", "QUIT", "DHIST",
+ "LS", "ADD", "ADDX", "EXTRACT", "LIST", "DELETE", "DELETEX", "PWD",
+ "CLEAR", "HELP", "LCD", "LPWD", "MODE", "SMB", "TAR", "PATH", "DATE",
+ "$accept", "ucommand", "set_command", "display_command", "quit_command",
"add_command", "add_path", "addx_command", "addx_path", "delete_command",
"delete_path", "deletex_command", "deletex_path", "local_command",
"help_command", "extract_command", 0
{
0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
265, 266, 267, 268, 269, 270, 271, 272, 273, 274,
- 275, 276, 277, 278, 279, 280, 281, 282, 283, 284
+ 275, 276, 277, 278, 279, 280, 281, 282, 283, 284,
+ 285
};
# endif
/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
static const unsigned char yyr1[] =
{
- 0, 30, 31, 31, 31, 31, 31, 31, 31, 31,
- 31, 31, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 33, 33, 33, 33, 33, 33,
- 33, 34, 35, 36, 36, 37, 38, 38, 39, 40,
- 40, 41, 42, 42, 43, 43, 44, 45
+ 0, 31, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 33, 33, 33, 33, 33, 33, 33,
+ 33, 33, 33, 33, 33, 33, 34, 34, 34, 34,
+ 34, 34, 34, 35, 36, 37, 37, 38, 39, 39,
+ 40, 41, 41, 42, 43, 43, 44, 44, 45, 46
};
/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
static const unsigned char yyr2[] =
{
0, 2, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 2, 1, 2, 2, 3, 2, 2, 1,
- 2, 2, 2, 2, 1, 1, 2, 1, 1, 1,
- 1, 1, 2, 2, 1, 2, 2, 1, 2, 2,
- 1, 2, 2, 1, 1, 2, 1, 1
+ 1, 1, 0, 1, 2, 1, 2, 2, 3, 2,
+ 2, 1, 2, 2, 2, 2, 1, 1, 2, 1,
+ 1, 1, 1, 1, 2, 2, 1, 2, 2, 1,
+ 2, 2, 1, 2, 2, 1, 1, 2, 1, 1
};
/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
means the default is an error. */
static const unsigned char yydefact[] =
{
- 0, 13, 0, 0, 0, 19, 0, 0, 0, 31,
- 24, 25, 0, 0, 47, 27, 0, 0, 28, 29,
- 46, 0, 44, 30, 0, 2, 3, 4, 5, 6,
- 7, 8, 9, 10, 11, 12, 15, 17, 14, 18,
- 22, 23, 20, 21, 34, 32, 37, 35, 26, 40,
- 38, 43, 41, 45, 1, 16, 33, 36, 39, 42
+ 12, 13, 15, 0, 0, 0, 21, 0, 0, 0,
+ 33, 26, 27, 0, 0, 49, 29, 0, 0, 30,
+ 31, 48, 0, 46, 32, 0, 2, 3, 4, 5,
+ 6, 7, 8, 9, 10, 11, 14, 17, 19, 16,
+ 20, 24, 25, 22, 23, 36, 34, 39, 37, 28,
+ 42, 40, 45, 43, 47, 1, 18, 35, 38, 41,
+ 44
};
/* YYDEFGOTO[NTERM-NUM]. */
static const yysigned_char yydefgoto[] =
{
- -1, 24, 25, 26, 27, 28, 45, 29, 47, 30,
- 50, 31, 52, 32, 33, 34
+ -1, 25, 26, 27, 28, 29, 46, 30, 48, 31,
+ 51, 32, 53, 33, 34, 35
};
/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
#define YYPACT_NINF -6
static const yysigned_char yypact[] =
{
- -3, -5, -1, 0, 1, 3, -2, 4, 5, -6,
- -6, -6, 6, 7, -6, 8, 9, 10, -6, -6,
- -6, 11, -6, -6, 26, -6, -6, -6, -6, -6,
- -6, -6, -6, -6, -6, -6, -6, 12, -6, -6,
- -6, -6, -6, -6, -6, 13, -6, 14, -6, -6,
- 15, -6, 16, -6, -6, -6, -6, -6, -6, -6
+ -3, -6, -5, -1, 0, 1, 3, -2, 4, 5,
+ -6, -6, -6, 6, 7, -6, 8, 9, 10, -6,
+ -6, -6, 11, -6, -6, 27, -6, -6, -6, -6,
+ -6, -6, -6, -6, -6, -6, -6, -6, 12, -6,
+ -6, -6, -6, -6, -6, -6, 13, -6, 14, -6,
+ -6, 15, -6, 16, -6, -6, -6, -6, -6, -6,
+ -6
};
/* YYPGOTO[NTERM-NUM]. */
{
1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
- 21, 22, 23, 35, 40, 41, 54, 36, 37, 0,
- 38, 39, 42, 43, 44, 46, 48, 49, 51, 53,
- 55, 56, 57, 58, 59
+ 21, 22, 23, 24, 36, 41, 42, 55, 37, 38,
+ 0, 39, 40, 43, 44, 45, 47, 49, 50, 52,
+ 54, 56, 57, 58, 59, 60
};
static const yysigned_char yycheck[] =
{
3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
- 23, 24, 25, 28, 26, 27, 0, 28, 28, -1,
- 29, 28, 28, 28, 28, 28, 28, 28, 28, 28,
- 28, 28, 28, 28, 28
+ 23, 24, 25, 26, 29, 27, 28, 0, 29, 29,
+ -1, 30, 29, 29, 29, 29, 29, 29, 29, 29,
+ 29, 29, 29, 29, 29, 29
};
/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
{
0, 3, 4, 5, 6, 7, 8, 9, 10, 11,
12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
- 22, 23, 24, 25, 31, 32, 33, 34, 35, 37,
- 39, 41, 43, 44, 45, 28, 28, 28, 29, 28,
- 26, 27, 28, 28, 28, 36, 28, 38, 28, 28,
- 40, 28, 42, 28, 0, 28, 28, 28, 28, 28
+ 22, 23, 24, 25, 26, 32, 33, 34, 35, 36,
+ 38, 40, 42, 44, 45, 46, 29, 29, 29, 30,
+ 29, 27, 28, 29, 29, 29, 37, 29, 39, 29,
+ 29, 41, 29, 43, 29, 0, 29, 29, 29, 29,
+ 29
};
#define yyerrok (yyerrstatus = 0)
switch (yyn)
{
case 12:
-#line 76 "uparse.y"
- { list_disk((yyvsp[0].strval)); amfree((yyvsp[0].strval)); }
+#line 75 "uparse.y"
+ {
+ char * errstr = vstralloc("Invalid command: ", yytext, NULL);
+ yyerror(errstr);
+ amfree(errstr);
+ YYERROR;
+ }
break;
case 13:
-#line 77 "uparse.y"
- { list_disk(NULL); }
+#line 84 "uparse.y"
+ { list_host(); }
break;
case 14:
-#line 78 "uparse.y"
- { set_date((yyvsp[0].strval)); amfree((yyvsp[0].strval)); }
+#line 85 "uparse.y"
+ { list_disk((yyvsp[0].strval)); amfree((yyvsp[0].strval)); }
break;
case 15:
-#line 79 "uparse.y"
- { set_host((yyvsp[0].strval)); amfree((yyvsp[0].strval)); }
+#line 86 "uparse.y"
+ { list_disk(NULL); }
break;
case 16:
-#line 80 "uparse.y"
- { set_disk((yyvsp[-1].strval), (yyvsp[0].strval)); amfree((yyvsp[-1].strval)); amfree((yyvsp[0].strval)); }
+#line 87 "uparse.y"
+ { set_date((yyvsp[0].strval)); amfree((yyvsp[0].strval)); }
break;
case 17:
-#line 81 "uparse.y"
- { set_disk((yyvsp[0].strval), NULL); amfree((yyvsp[0].strval)); }
+#line 88 "uparse.y"
+ { set_host((yyvsp[0].strval)); amfree((yyvsp[0].strval)); }
break;
case 18:
-#line 82 "uparse.y"
- { set_tape((yyvsp[0].strval)); amfree((yyvsp[0].strval)); }
+#line 89 "uparse.y"
+ { set_disk((yyvsp[-1].strval), (yyvsp[0].strval)); amfree((yyvsp[-1].strval)); amfree((yyvsp[0].strval)); }
break;
case 19:
-#line 83 "uparse.y"
- { set_tape(""); }
+#line 90 "uparse.y"
+ { set_disk((yyvsp[0].strval), NULL); amfree((yyvsp[0].strval)); }
break;
case 20:
-#line 84 "uparse.y"
- { cd_glob((yyvsp[0].strval)); amfree((yyvsp[0].strval)); }
+#line 91 "uparse.y"
+ { set_tape((yyvsp[0].strval)); amfree((yyvsp[0].strval)); }
break;
case 21:
-#line 85 "uparse.y"
- { cd_regex((yyvsp[0].strval)); amfree((yyvsp[0].strval)); }
+#line 92 "uparse.y"
+ { set_tape(""); }
break;
case 22:
-#line 86 "uparse.y"
+#line 93 "uparse.y"
+ { cd_glob((yyvsp[0].strval)); amfree((yyvsp[0].strval)); }
+ break;
+
+ case 23:
+#line 94 "uparse.y"
+ { cd_regex((yyvsp[0].strval)); amfree((yyvsp[0].strval)); }
+ break;
+
+ case 24:
+#line 95 "uparse.y"
{
#ifdef SAMBA_CLIENT
set_mode(SAMBA_SMBCLIENT);
}
break;
- case 23:
-#line 91 "uparse.y"
+ case 25:
+#line 100 "uparse.y"
{
#ifdef SAMBA_CLIENT
set_mode(SAMBA_TAR);
}
break;
- case 24:
-#line 99 "uparse.y"
+ case 26:
+#line 108 "uparse.y"
{ list_disk_history(); }
break;
- case 25:
-#line 100 "uparse.y"
+ case 27:
+#line 109 "uparse.y"
{ list_directory(); }
break;
- case 26:
-#line 101 "uparse.y"
+ case 28:
+#line 110 "uparse.y"
{ display_extract_list((yyvsp[0].strval)); amfree((yyvsp[0].strval)); }
break;
- case 27:
-#line 102 "uparse.y"
+ case 29:
+#line 111 "uparse.y"
{ display_extract_list(NULL); }
break;
- case 28:
-#line 103 "uparse.y"
+ case 30:
+#line 112 "uparse.y"
{ show_directory(); }
break;
- case 29:
-#line 104 "uparse.y"
+ case 31:
+#line 113 "uparse.y"
{ clear_extract_list(); }
break;
- case 30:
-#line 105 "uparse.y"
+ case 32:
+#line 114 "uparse.y"
{ show_mode (); }
break;
- case 31:
-#line 109 "uparse.y"
+ case 33:
+#line 118 "uparse.y"
{ quit(); }
break;
- case 33:
-#line 117 "uparse.y"
+ case 35:
+#line 126 "uparse.y"
{ add_glob((yyvsp[0].strval)); amfree((yyvsp[0].strval)); }
break;
- case 34:
-#line 118 "uparse.y"
+ case 36:
+#line 127 "uparse.y"
{ add_glob((yyvsp[0].strval)); amfree((yyvsp[0].strval)); }
break;
- case 36:
-#line 126 "uparse.y"
+ case 38:
+#line 135 "uparse.y"
{ add_regex((yyvsp[0].strval)); amfree((yyvsp[0].strval)); }
break;
- case 37:
-#line 127 "uparse.y"
+ case 39:
+#line 136 "uparse.y"
{ add_regex((yyvsp[0].strval)); amfree((yyvsp[0].strval)); }
break;
- case 39:
-#line 135 "uparse.y"
+ case 41:
+#line 144 "uparse.y"
{ delete_glob((yyvsp[0].strval)); amfree((yyvsp[0].strval)); }
break;
- case 40:
-#line 136 "uparse.y"
+ case 42:
+#line 145 "uparse.y"
{ delete_glob((yyvsp[0].strval)); amfree((yyvsp[0].strval)); }
break;
- case 42:
-#line 144 "uparse.y"
+ case 44:
+#line 153 "uparse.y"
{ delete_regex((yyvsp[0].strval)); amfree((yyvsp[0].strval)); }
break;
- case 43:
-#line 145 "uparse.y"
+ case 45:
+#line 154 "uparse.y"
{ delete_regex((yyvsp[0].strval)); amfree((yyvsp[0].strval)); }
break;
- case 44:
-#line 149 "uparse.y"
+ case 46:
+#line 158 "uparse.y"
{ char buf[STR_SIZE]; puts(getcwd(buf, sizeof(buf))); }
break;
- case 45:
-#line 150 "uparse.y"
+ case 47:
+#line 159 "uparse.y"
{
if (chdir((yyvsp[0].strval)) == -1) {
perror((yyvsp[0].strval));
}
break;
- case 46:
-#line 159 "uparse.y"
+ case 48:
+#line 168 "uparse.y"
{ help_list(); }
break;
- case 47:
-#line 163 "uparse.y"
+ case 49:
+#line 172 "uparse.y"
{ extract_files(); }
break;
}
/* Line 1126 of yacc.c. */
-#line 1379 "uparse.c"
+#line 1402 "uparse.c"
\f
yyvsp -= yylen;
yyssp -= yylen;
}
-#line 167 "uparse.y"
+#line 176 "uparse.y"
-void yyerror(s)
-char *s;
+void
+yyerror(
+ char * s)
{
- printf("Invalid command - %s\n", s);
+ printf("%s\n", s);
}
-
-
/* Put the tokens into the symbol table, so that GDB and other debuggers
know about them. */
enum yytokentype {
- LISTDISK = 258,
- SETHOST = 259,
- SETDISK = 260,
- SETDATE = 261,
- SETTAPE = 262,
- SETMODE = 263,
- CD = 264,
- CDX = 265,
- QUIT = 266,
- DHIST = 267,
- LS = 268,
- ADD = 269,
- ADDX = 270,
- EXTRACT = 271,
- LIST = 272,
- DELETE = 273,
- DELETEX = 274,
- PWD = 275,
- CLEAR = 276,
- HELP = 277,
- LCD = 278,
- LPWD = 279,
- MODE = 280,
- SMB = 281,
- TAR = 282,
- PATH = 283,
- DATE = 284
+ LISTHOST = 258,
+ LISTDISK = 259,
+ SETHOST = 260,
+ SETDISK = 261,
+ SETDATE = 262,
+ SETTAPE = 263,
+ SETMODE = 264,
+ CD = 265,
+ CDX = 266,
+ QUIT = 267,
+ DHIST = 268,
+ LS = 269,
+ ADD = 270,
+ ADDX = 271,
+ EXTRACT = 272,
+ LIST = 273,
+ DELETE = 274,
+ DELETEX = 275,
+ PWD = 276,
+ CLEAR = 277,
+ HELP = 278,
+ LCD = 279,
+ LPWD = 280,
+ MODE = 281,
+ SMB = 282,
+ TAR = 283,
+ PATH = 284,
+ DATE = 285
};
#endif
/* Tokens. */
-#define LISTDISK 258
-#define SETHOST 259
-#define SETDISK 260
-#define SETDATE 261
-#define SETTAPE 262
-#define SETMODE 263
-#define CD 264
-#define CDX 265
-#define QUIT 266
-#define DHIST 267
-#define LS 268
-#define ADD 269
-#define ADDX 270
-#define EXTRACT 271
-#define LIST 272
-#define DELETE 273
-#define DELETEX 274
-#define PWD 275
-#define CLEAR 276
-#define HELP 277
-#define LCD 278
-#define LPWD 279
-#define MODE 280
-#define SMB 281
-#define TAR 282
-#define PATH 283
-#define DATE 284
+#define LISTHOST 258
+#define LISTDISK 259
+#define SETHOST 260
+#define SETDISK 261
+#define SETDATE 262
+#define SETTAPE 263
+#define SETMODE 264
+#define CD 265
+#define CDX 266
+#define QUIT 267
+#define DHIST 268
+#define LS 269
+#define ADD 270
+#define ADDX 271
+#define EXTRACT 272
+#define LIST 273
+#define DELETE 274
+#define DELETEX 275
+#define PWD 276
+#define CLEAR 277
+#define HELP 278
+#define LCD 279
+#define LPWD 280
+#define MODE 281
+#define SMB 282
+#define TAR 283
+#define PATH 284
+#define DATE 285
#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
-#line 40 "uparse.y"
+#line 42 "uparse.y"
typedef union YYSTYPE {
- int intval;
- double floatval;
- char *strval;
- int subtok;
+ int intval;
+ double floatval;
+ char * strval;
+ int subtok;
} YYSTYPE;
/* Line 1447 of yacc.c. */
-#line 103 "uparse.h"
+#line 105 "uparse.h"
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1
# define YYSTYPE_IS_TRIVIAL 1
* file named AUTHORS, in the root directory of this distribution.
*/
/*
- * $Id: uparse.y,v 1.11 2003/01/01 23:28:17 martinea Exp $
+ * $Id: uparse.y,v 1.13 2006/05/25 01:47:14 johnfranks Exp $
*
* parser for amrecover interactive language
*/
#include "amanda.h"
#include "amrecover.h"
-void yyerror P((char *s));
-extern int yylex P((void));
+void yyerror(char *s);
+extern int yylex(void);
+extern char * yytext;
+
%}
/* DECLARATIONS */
%union {
- int intval;
- double floatval;
- char *strval;
- int subtok;
+ int intval;
+ double floatval;
+ char * strval;
+ int subtok;
}
/* literal keyword tokens */
-%token LISTDISK SETHOST SETDISK SETDATE SETTAPE SETMODE
+%token LISTHOST LISTDISK SETHOST SETDISK SETDATE SETTAPE SETMODE
%token CD CDX QUIT DHIST LS ADD ADDX EXTRACT
%token LIST DELETE DELETEX PWD CLEAR HELP LCD LPWD MODE SMB TAR
| local_command
| help_command
| extract_command
+ | {
+ char * errstr = vstralloc("Invalid command: ", yytext, NULL);
+ yyerror(errstr);
+ amfree(errstr);
+ YYERROR;
+ } /* Quiets compiler warnings about unused label */
;
set_command:
- LISTDISK PATH { list_disk($2); amfree($2); }
+ LISTHOST { list_host(); }
+ | LISTDISK PATH { list_disk($2); amfree($2); }
| LISTDISK { list_disk(NULL); }
| SETDATE DATE { set_date($2); amfree($2); }
| SETHOST PATH { set_host($2); amfree($2); }
/* ADDITIONAL C CODE */
%%
-void yyerror(s)
-char *s;
+void
+yyerror(
+ char * s)
{
- printf("Invalid command - %s\n", s);
+ printf("%s\n", s);
}
-
-
*yy_cp = '\0'; \
yy_c_buf_p = yy_cp;
-#define YY_NUM_RULES 38
-#define YY_END_OF_BUFFER 39
-static yyconst short int yy_accept[121] =
+#define YY_NUM_RULES 40
+#define YY_END_OF_BUFFER 41
+static yyconst short int yy_accept[131] =
{ 0,
- 0, 0, 0, 0, 39, 31, 37, 32, 31, 31,
- 21, 31, 31, 31, 31, 31, 31, 31, 31, 31,
- 31, 31, 36, 35, 33, 38, 31, 37, 31, 31,
- 31, 31, 7, 31, 31, 31, 31, 31, 31, 31,
- 31, 12, 31, 31, 31, 31, 31, 31, 36, 34,
- 31, 31, 31, 13, 8, 31, 31, 31, 31, 31,
- 31, 22, 31, 31, 31, 18, 31, 31, 25, 26,
- 28, 31, 31, 14, 31, 31, 10, 31, 20, 31,
- 15, 23, 27, 9, 31, 31, 31, 31, 29, 30,
- 19, 31, 31, 31, 31, 31, 31, 31, 31, 31,
-
- 16, 31, 31, 31, 31, 31, 31, 31, 31, 17,
- 24, 11, 31, 4, 3, 2, 5, 6, 1, 0
+ 0, 0, 0, 0, 41, 40, 39, 38, 34, 38,
+ 38, 22, 38, 38, 38, 38, 38, 38, 38, 38,
+ 38, 38, 38, 35, 37, 40, 39, 38, 38, 38,
+ 38, 38, 8, 38, 38, 38, 38, 38, 38, 38,
+ 38, 13, 38, 38, 38, 38, 38, 38, 35, 36,
+ 38, 38, 38, 14, 9, 38, 38, 38, 38, 38,
+ 38, 23, 38, 38, 38, 19, 38, 38, 26, 27,
+ 29, 38, 38, 15, 38, 38, 11, 38, 21, 38,
+ 16, 24, 28, 10, 38, 38, 38, 38, 30, 31,
+ 20, 38, 38, 38, 38, 38, 38, 38, 38, 38,
+
+ 38, 38, 17, 38, 38, 38, 38, 38, 38, 38,
+ 38, 38, 38, 18, 25, 12, 38, 38, 5, 4,
+ 3, 6, 7, 38, 2, 1, 33, 38, 32, 0
} ;
static yyconst int yy_ec[256] =
{ 0,
1, 1, 1, 1, 1, 1, 1, 1, 2, 3,
- 1, 1, 2, 1, 1, 1, 1, 1, 1, 1,
+ 2, 2, 2, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 2, 1, 4, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 5, 1, 1, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 1, 1, 1,
- 1, 1, 7, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 8, 1, 1, 1, 1, 9, 10, 11, 12,
-
- 13, 1, 1, 14, 15, 1, 16, 17, 18, 1,
- 19, 20, 21, 22, 23, 24, 25, 1, 26, 27,
- 28, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1
+ 1, 2, 4, 5, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 6, 4, 4, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 4, 4, 4,
+ 4, 4, 8, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 9, 4, 4, 4, 4, 10, 11, 12, 13,
+
+ 14, 4, 4, 15, 16, 4, 17, 18, 19, 4,
+ 20, 21, 22, 23, 24, 25, 26, 4, 27, 28,
+ 29, 4, 4, 4, 4, 4, 1, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4
} ;
-static yyconst int yy_meta[29] =
+static yyconst int yy_meta[30] =
{ 0,
- 1, 2, 3, 4, 1, 1, 1, 3, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1
+ 1, 1, 2, 3, 4, 3, 3, 3, 5, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3
} ;
-static yyconst short int yy_base[124] =
+static yyconst short int yy_base[135] =
{ 0,
- 0, 0, 26, 28, 142, 0, 139, 143, 135, 32,
- 0, 127, 23, 125, 110, 26, 31, 117, 109, 109,
- 30, 124, 0, 143, 143, 128, 0, 129, 39, 124,
- 44, 117, 101, 114, 109, 32, 108, 101, 111, 99,
- 95, 0, 108, 107, 103, 93, 106, 93, 0, 143,
- 108, 47, 52, 86, 0, 103, 98, 86, 87, 88,
- 83, 0, 82, 93, 91, 0, 79, 47, 0, 0,
- 96, 95, 94, 0, 77, 74, 0, 88, 0, 77,
- 83, 0, 0, 0, 51, 75, 74, 83, 85, 84,
- 0, 76, 77, 65, 71, 61, 61, 60, 70, 61,
-
- 50, 46, 41, 45, 54, 48, 39, 49, 42, 0,
- 0, 0, 17, 0, 0, 0, 0, 0, 0, 143,
- 71, 75, 78
+ 0, 0, 25, 26, 161, 162, 30, 0, 162, 154,
+ 30, 0, 146, 25, 144, 129, 25, 28, 136, 128,
+ 128, 28, 143, 0, 162, 0, 43, 0, 44, 145,
+ 47, 138, 122, 135, 130, 32, 129, 122, 132, 120,
+ 116, 0, 129, 128, 124, 114, 127, 114, 0, 162,
+ 129, 49, 52, 107, 0, 124, 119, 107, 108, 109,
+ 104, 0, 103, 114, 112, 0, 100, 47, 0, 0,
+ 117, 116, 115, 0, 98, 95, 0, 109, 0, 98,
+ 48, 0, 0, 0, 54, 97, 96, 105, 107, 61,
+ 0, 99, 100, 88, 94, 89, 83, 83, 82, 92,
+
+ 83, 96, 74, 76, 71, 75, 74, 83, 79, 70,
+ 80, 79, 67, 0, 0, 0, 72, 58, 0, 0,
+ 0, 0, 0, 64, 0, 0, 69, 62, 58, 162,
+ 76, 79, 84, 87
} ;
-static yyconst short int yy_def[124] =
+static yyconst short int yy_def[135] =
{ 0,
- 120, 1, 121, 121, 120, 122, 120, 120, 122, 122,
- 122, 122, 122, 122, 122, 122, 122, 122, 122, 122,
- 122, 122, 123, 120, 120, 120, 122, 120, 122, 122,
- 122, 122, 122, 122, 122, 122, 122, 122, 122, 122,
- 122, 122, 122, 122, 122, 122, 122, 122, 123, 120,
- 122, 122, 122, 122, 122, 122, 122, 122, 122, 122,
- 122, 122, 122, 122, 122, 122, 122, 122, 122, 122,
- 122, 122, 122, 122, 122, 122, 122, 122, 122, 122,
- 122, 122, 122, 122, 122, 122, 122, 122, 122, 122,
- 122, 122, 122, 122, 122, 122, 122, 122, 122, 122,
-
- 122, 122, 122, 122, 122, 122, 122, 122, 122, 122,
- 122, 122, 122, 122, 122, 122, 122, 122, 122, 0,
- 120, 120, 120
+ 130, 1, 131, 131, 130, 130, 130, 132, 130, 132,
+ 132, 132, 132, 132, 132, 132, 132, 132, 132, 132,
+ 132, 132, 132, 133, 130, 134, 130, 132, 132, 132,
+ 132, 132, 132, 132, 132, 132, 132, 132, 132, 132,
+ 132, 132, 132, 132, 132, 132, 132, 132, 133, 130,
+ 132, 132, 132, 132, 132, 132, 132, 132, 132, 132,
+ 132, 132, 132, 132, 132, 132, 132, 132, 132, 132,
+ 132, 132, 132, 132, 132, 132, 132, 132, 132, 132,
+ 132, 132, 132, 132, 132, 132, 132, 132, 132, 132,
+ 132, 132, 132, 132, 132, 132, 132, 132, 132, 132,
+
+ 132, 132, 132, 132, 132, 132, 132, 132, 132, 132,
+ 132, 132, 132, 132, 132, 132, 132, 132, 132, 132,
+ 132, 132, 132, 132, 132, 132, 132, 132, 132, 0,
+ 130, 130, 130, 130
} ;
-static yyconst short int yy_nxt[172] =
+static yyconst short int yy_nxt[192] =
{ 0,
- 6, 7, 6, 8, 9, 10, 11, 6, 12, 6,
- 13, 14, 15, 16, 6, 6, 17, 18, 6, 19,
- 20, 6, 21, 22, 6, 6, 6, 6, 24, 25,
- 24, 25, 119, 26, 33, 26, 30, 31, 37, 34,
- 38, 39, 46, 51, 52, 40, 58, 47, 30, 31,
- 41, 72, 52, 42, 118, 59, 73, 53, 85, 96,
- 86, 117, 116, 115, 87, 97, 114, 113, 112, 111,
- 88, 23, 23, 23, 23, 27, 110, 27, 49, 49,
- 109, 108, 107, 106, 105, 104, 103, 102, 101, 90,
- 89, 100, 99, 98, 95, 94, 93, 92, 91, 90,
-
- 89, 71, 84, 83, 82, 81, 80, 79, 78, 77,
- 76, 75, 74, 71, 70, 69, 68, 67, 66, 65,
- 64, 63, 62, 61, 60, 57, 56, 55, 54, 53,
- 28, 50, 48, 45, 44, 43, 36, 35, 32, 29,
- 28, 120, 5, 120, 120, 120, 120, 120, 120, 120,
- 120, 120, 120, 120, 120, 120, 120, 120, 120, 120,
- 120, 120, 120, 120, 120, 120, 120, 120, 120, 120,
- 120
+ 6, 7, 7, 8, 9, 10, 11, 12, 8, 13,
+ 8, 14, 15, 16, 17, 8, 8, 18, 19, 8,
+ 20, 21, 8, 22, 23, 8, 8, 8, 8, 25,
+ 25, 27, 27, 26, 26, 30, 31, 33, 37, 39,
+ 38, 46, 34, 40, 27, 27, 47, 58, 41, 51,
+ 52, 42, 30, 31, 72, 52, 59, 73, 53, 85,
+ 95, 86, 96, 97, 129, 87, 102, 90, 129, 98,
+ 127, 88, 124, 113, 128, 127, 24, 24, 24, 24,
+ 24, 28, 126, 28, 49, 49, 49, 50, 125, 50,
+ 50, 50, 123, 122, 121, 120, 119, 118, 117, 116,
+
+ 115, 114, 113, 112, 111, 110, 109, 108, 107, 106,
+ 105, 104, 103, 89, 101, 100, 99, 94, 93, 92,
+ 91, 90, 89, 71, 84, 83, 82, 81, 80, 79,
+ 78, 77, 76, 75, 74, 71, 70, 69, 68, 67,
+ 66, 65, 64, 63, 62, 61, 60, 57, 56, 55,
+ 54, 53, 48, 45, 44, 43, 36, 35, 32, 29,
+ 130, 5, 130, 130, 130, 130, 130, 130, 130, 130,
+ 130, 130, 130, 130, 130, 130, 130, 130, 130, 130,
+ 130, 130, 130, 130, 130, 130, 130, 130, 130, 130,
+ 130
+
} ;
-static yyconst short int yy_chk[172] =
+static yyconst short int yy_chk[192] =
{ 0,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 3, 3,
- 4, 4, 113, 3, 13, 4, 10, 10, 16, 13,
- 16, 17, 21, 29, 29, 17, 36, 21, 31, 31,
- 17, 52, 52, 17, 109, 36, 53, 53, 68, 85,
- 68, 108, 107, 106, 68, 85, 105, 104, 103, 102,
- 68, 121, 121, 121, 121, 122, 101, 122, 123, 123,
- 100, 99, 98, 97, 96, 95, 94, 93, 92, 90,
- 89, 88, 87, 86, 81, 80, 78, 76, 75, 73,
-
- 72, 71, 67, 65, 64, 63, 61, 60, 59, 58,
- 57, 56, 54, 51, 48, 47, 46, 45, 44, 43,
- 41, 40, 39, 38, 37, 35, 34, 33, 32, 30,
- 28, 26, 22, 20, 19, 18, 15, 14, 12, 9,
- 7, 5, 120, 120, 120, 120, 120, 120, 120, 120,
- 120, 120, 120, 120, 120, 120, 120, 120, 120, 120,
- 120, 120, 120, 120, 120, 120, 120, 120, 120, 120,
- 120
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 3,
+ 4, 7, 7, 3, 4, 11, 11, 14, 17, 18,
+ 17, 22, 14, 18, 27, 27, 22, 36, 18, 29,
+ 29, 18, 31, 31, 52, 52, 36, 53, 53, 68,
+ 81, 68, 81, 85, 129, 68, 90, 90, 128, 85,
+ 124, 68, 113, 113, 127, 127, 131, 131, 131, 131,
+ 131, 132, 118, 132, 133, 133, 133, 134, 117, 134,
+ 134, 134, 112, 111, 110, 109, 108, 107, 106, 105,
+
+ 104, 103, 102, 101, 100, 99, 98, 97, 96, 95,
+ 94, 93, 92, 89, 88, 87, 86, 80, 78, 76,
+ 75, 73, 72, 71, 67, 65, 64, 63, 61, 60,
+ 59, 58, 57, 56, 54, 51, 48, 47, 46, 45,
+ 44, 43, 41, 40, 39, 38, 37, 35, 34, 33,
+ 32, 30, 23, 21, 20, 19, 16, 15, 13, 10,
+ 5, 130, 130, 130, 130, 130, 130, 130, 130, 130,
+ 130, 130, 130, 130, 130, 130, 130, 130, 130, 130,
+ 130, 130, 130, 130, 130, 130, 130, 130, 130, 130,
+ 130
+
} ;
static yy_state_type yy_last_accepting_state;
#line 1 "uscan.l"
#define INITIAL 0
/*
- * Amanda, The Advanced Maryland Automatic Network Disk Archiver
+ * amanda, the advanced maryland automatic network disk archiver
* Copyright (c) 1991-2000 University of Maryland at College Park
* All Rights Reserved.
*
* file named AUTHORS, in the root directory of this distribution.
*/
/*
- * $Id: uscan.l,v 1.22 2004/02/11 13:03:29 martinea Exp $
+ * $Id: uscan.l,v 1.27 2006/07/05 11:15:56 martinea Exp $
*
* lexer for amrecover interactive language
*/
#line 32 "uscan.l"
#include "amanda.h"
-#undef ECHO
#include "uparse.h"
+/*
+ * We redefine this here to prevent compiler warning about ignoring fwrite
+ * return value...
+ */
+#undef ECHO
+#define ECHO do { \
+ if (fwrite(yytext, (size_t)yyleng, 1, yyout) <= 0) { \
+ yyerror("ECHO failure"); \
+ } \
+} while (0)
+
#define YY_NO_UNPUT
-#define DATE_ALLOC_SIZE sizeof("YYYY-MM-DD") /* includes null */
+#define DATE_ALLOC_SIZE sizeof("YYYY-MM-DD-HH-MM-SS") /* includes null */
+
+#define YY_DECL int yylex(void)
+extern int yylex(void);
-extern void yyerror P((char *s));
-extern int yyparse P((void));
-static int ll_parse_date P((int type, char *text));
-#define quotedstring 1
+extern void yyerror(char *s);
+extern int yyparse(void);
+static int ll_parse_date(int type, char *text);
+int process_line(char *line);
+#define quotedpath 1
-#line 48 "uscan.l"
+#line 62 "uscan.l"
static char *string_buf = NULL;
-#line 494 "uscan.c"
+#line 517 "uscan.c"
/* Macros after this point can all be overridden by user definitions in
* section 1.
register char *yy_cp = NULL, *yy_bp = NULL;
register int yy_act;
-#line 51 "uscan.l"
+#line 65 "uscan.l"
/* literal keyword tokens */
-#line 652 "uscan.c"
+#line 675 "uscan.c"
if ( yy_init )
{
while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
{
yy_current_state = (int) yy_def[yy_current_state];
- if ( yy_current_state >= 121 )
+ if ( yy_current_state >= 131 )
yy_c = yy_meta[(unsigned int) yy_c];
}
yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
++yy_cp;
}
- while ( yy_base[yy_current_state] != 143 );
+ while ( yy_base[yy_current_state] != 162 );
yy_find_action:
yy_act = yy_accept[yy_current_state];
case 1:
YY_RULE_SETUP
-#line 57 "uscan.l"
-{ return LISTDISK; }
+#line 71 "uscan.l"
+{ return LISTHOST; }
YY_BREAK
case 2:
YY_RULE_SETUP
-#line 58 "uscan.l"
-{ return SETHOST; }
+#line 72 "uscan.l"
+{ return LISTDISK; }
YY_BREAK
case 3:
YY_RULE_SETUP
-#line 59 "uscan.l"
-{ return SETDISK; }
+#line 73 "uscan.l"
+{ return SETHOST; }
YY_BREAK
case 4:
YY_RULE_SETUP
-#line 60 "uscan.l"
-{ return SETDATE; }
+#line 74 "uscan.l"
+{ return SETDISK; }
YY_BREAK
case 5:
YY_RULE_SETUP
-#line 61 "uscan.l"
-{ return SETMODE; }
+#line 75 "uscan.l"
+{ return SETDATE; }
YY_BREAK
case 6:
YY_RULE_SETUP
-#line 62 "uscan.l"
-{ return SETTAPE; }
+#line 76 "uscan.l"
+{ return SETMODE; }
YY_BREAK
case 7:
YY_RULE_SETUP
-#line 63 "uscan.l"
-{ return CD; }
+#line 77 "uscan.l"
+{ return SETTAPE; }
YY_BREAK
case 8:
YY_RULE_SETUP
-#line 64 "uscan.l"
-{ return CDX; }
+#line 78 "uscan.l"
+{ return CD; }
YY_BREAK
case 9:
YY_RULE_SETUP
-#line 65 "uscan.l"
-{ return QUIT; }
+#line 79 "uscan.l"
+{ return CDX; }
YY_BREAK
case 10:
YY_RULE_SETUP
-#line 66 "uscan.l"
+#line 80 "uscan.l"
{ return QUIT; }
YY_BREAK
case 11:
YY_RULE_SETUP
-#line 67 "uscan.l"
-{ return DHIST; }
+#line 81 "uscan.l"
+{ return QUIT; }
YY_BREAK
case 12:
YY_RULE_SETUP
-#line 68 "uscan.l"
-{ return LS; }
+#line 82 "uscan.l"
+{ return DHIST; }
YY_BREAK
case 13:
YY_RULE_SETUP
-#line 69 "uscan.l"
-{ return ADD; }
+#line 83 "uscan.l"
+{ return LS; }
YY_BREAK
case 14:
YY_RULE_SETUP
-#line 70 "uscan.l"
-{ return ADDX; }
+#line 84 "uscan.l"
+{ return ADD; }
YY_BREAK
case 15:
YY_RULE_SETUP
-#line 71 "uscan.l"
-{ return LIST; }
+#line 85 "uscan.l"
+{ return ADDX; }
YY_BREAK
case 16:
YY_RULE_SETUP
-#line 72 "uscan.l"
-{ return DELETE; }
+#line 86 "uscan.l"
+{ return LIST; }
YY_BREAK
case 17:
YY_RULE_SETUP
-#line 73 "uscan.l"
-{ return DELETEX; }
+#line 87 "uscan.l"
+{ return DELETE; }
YY_BREAK
case 18:
YY_RULE_SETUP
-#line 74 "uscan.l"
-{ return PWD; }
+#line 88 "uscan.l"
+{ return DELETEX; }
YY_BREAK
case 19:
YY_RULE_SETUP
-#line 75 "uscan.l"
-{ return CLEAR; }
+#line 89 "uscan.l"
+{ return PWD; }
YY_BREAK
case 20:
YY_RULE_SETUP
-#line 76 "uscan.l"
-{ return HELP; }
+#line 90 "uscan.l"
+{ return CLEAR; }
YY_BREAK
case 21:
YY_RULE_SETUP
-#line 77 "uscan.l"
+#line 91 "uscan.l"
{ return HELP; }
YY_BREAK
case 22:
YY_RULE_SETUP
-#line 78 "uscan.l"
-{ return LCD; }
+#line 92 "uscan.l"
+{ return HELP; }
YY_BREAK
case 23:
YY_RULE_SETUP
-#line 79 "uscan.l"
-{ return LPWD; }
+#line 93 "uscan.l"
+{ return LCD; }
YY_BREAK
case 24:
YY_RULE_SETUP
-#line 80 "uscan.l"
-{ return EXTRACT; }
+#line 94 "uscan.l"
+{ return LPWD; }
YY_BREAK
case 25:
YY_RULE_SETUP
-#line 81 "uscan.l"
-{ return SMB; }
+#line 95 "uscan.l"
+{ return EXTRACT; }
YY_BREAK
case 26:
YY_RULE_SETUP
-#line 82 "uscan.l"
-{ return TAR; }
+#line 96 "uscan.l"
+{ return SMB; }
YY_BREAK
case 27:
YY_RULE_SETUP
-#line 83 "uscan.l"
+#line 97 "uscan.l"
+{ return TAR; }
+ YY_BREAK
+case 28:
+YY_RULE_SETUP
+#line 98 "uscan.l"
{ return MODE; }
YY_BREAK
/* dates */
-case 28:
-YY_RULE_SETUP
-#line 89 "uscan.l"
-{ return ll_parse_date(1, yytext); }
- YY_BREAK
case 29:
YY_RULE_SETUP
-#line 90 "uscan.l"
-{ return ll_parse_date(2, yytext); }
+#line 104 "uscan.l"
+{ return ll_parse_date(1, yytext); }
YY_BREAK
case 30:
YY_RULE_SETUP
-#line 91 "uscan.l"
-{ return ll_parse_date(3, yytext); }
+#line 105 "uscan.l"
+{ return ll_parse_date(2, yytext); }
YY_BREAK
-
- /* file names */
-
case 31:
YY_RULE_SETUP
-#line 97 "uscan.l"
-{
- yylval.strval = stralloc(yytext); return PATH;
-}
+#line 106 "uscan.l"
+{ return ll_parse_date(3, yytext); }
YY_BREAK
-
- /* quoted file names */
-
case 32:
YY_RULE_SETUP
-#line 105 "uscan.l"
-{ if(string_buf != NULL) {printf("ERROR:string_buf != NULL: %s\n",string_buf);}; BEGIN(quotedstring); }
+#line 107 "uscan.l"
+{ return ll_parse_date(4, yytext); }
YY_BREAK
case 33:
YY_RULE_SETUP
-#line 107 "uscan.l"
-{ /* saw closing quote - all done */
- BEGIN(INITIAL);
- if(string_buf) {
- yylval.strval = string_buf;
- string_buf = NULL;
- } else {
- yylval.strval = "";
- }
- return PATH;
-}
+#line 108 "uscan.l"
+{ return ll_parse_date(5, yytext); }
YY_BREAK
+
+ /* quoted file names */
+
case 34:
YY_RULE_SETUP
-#line 118 "uscan.l"
+#line 114 "uscan.l"
{
- /* escaped quote */
- strappend(string_buf, "\\\"");
+ if(string_buf != NULL) {
+ printf("ERROR:string_buf != NULL: %s\n",string_buf);
+ }
+ BEGIN(quotedpath);
+ strappend(string_buf, yytext);
}
YY_BREAK
case 35:
YY_RULE_SETUP
-#line 123 "uscan.l"
+#line 122 "uscan.l"
{
- /* error - unterminated string constant */
- yyerror("unterminated string");
- amfree(string_buf);
+ strappend(string_buf, yytext);
}
YY_BREAK
case 36:
YY_RULE_SETUP
-#line 129 "uscan.l"
-{ strappend(string_buf, yytext); }
+#line 126 "uscan.l"
+{
+ /* escaped character (including quote) */
+ strappend(string_buf, yytext);
+}
+ YY_BREAK
+case 37:
+YY_RULE_SETUP
+#line 131 "uscan.l"
+{ /* saw closing quote - all done */
+ strappend(string_buf, yytext);
+ yylval.strval = string_buf;
+ string_buf = NULL;
+ BEGIN(INITIAL);
+ return PATH;
+}
+ YY_BREAK
+
+ /* file names */
+
+case 38:
+YY_RULE_SETUP
+#line 143 "uscan.l"
+{
+ yylval.strval = stralloc(yytext);
+ return PATH;
+}
YY_BREAK
/* whitespace */
-case 37:
+case 39:
YY_RULE_SETUP
-#line 135 "uscan.l"
+#line 152 "uscan.l"
; /* whitespace */
YY_BREAK
. { yyerror("invalid character"); }
#endif
-case 38:
+case 40:
YY_RULE_SETUP
-#line 148 "uscan.l"
+#line 165 "uscan.l"
ECHO;
YY_BREAK
-#line 964 "uscan.c"
+#line 999 "uscan.c"
case YY_STATE_EOF(INITIAL):
-case YY_STATE_EOF(quotedstring):
+case YY_STATE_EOF(quotedpath):
yyterminate();
case YY_END_OF_BUFFER:
while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
{
yy_current_state = (int) yy_def[yy_current_state];
- if ( yy_current_state >= 121 )
+ if ( yy_current_state >= 131 )
yy_c = yy_meta[(unsigned int) yy_c];
}
yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
{
yy_current_state = (int) yy_def[yy_current_state];
- if ( yy_current_state >= 121 )
+ if ( yy_current_state >= 131 )
yy_c = yy_meta[(unsigned int) yy_c];
}
yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
- yy_is_jam = (yy_current_state == 120);
+ yy_is_jam = (yy_current_state == 130);
return yy_is_jam ? 0 : yy_current_state;
}
return 0;
}
#endif
-#line 148 "uscan.l"
+#line 165 "uscan.l"
-int process_line(line)
-char *line;
+int
+process_line(
+ char * line)
{
YY_BUFFER_STATE b;
int result;
return result;
}
-static int ll_parse_date(type, text)
-int type;
-char *text;
+static int
+ll_parse_date(
+ int type,
+ char * text)
{
time_t now;
struct tm *t;
- int y, m, d;
+ int y=2000, m=0, d=1, h=0, mi=0, s=0;
int ret;
now = time((time_t *)NULL);
t = localtime(&now);
- y = 1900+t->tm_year;
- m = t->tm_mon+1;
- d = t->tm_mday;
- if(type == 1) {
- sscanf(text, "---%d", &d);
- } else if(type == 2) {
- sscanf(text, "--%d-%d", &m, &d);
- } else {
- sscanf(text, "%d-%d-%d", &y, &m, &d);
- if(y < 70) {
- y += 2000;
- } else if(y < 100) {
- y += 1900;
+ if (t) {
+ y = 1900+t->tm_year;
+ m = t->tm_mon+1;
+ d = t->tm_mday;
+ }
+ switch(type) {
+ case 1:
+ if (sscanf(text, "---%d", &d) != 1) {
+ yyerror("invalid date");
+ }
+ break;
+ case 2:
+ if (sscanf(text, "--%d-%d", &m, &d) != 2) {
+ yyerror("invalid date");
+ }
+ break;
+ case 3:
+ if (sscanf(text, "%d-%d-%d", &y, &m, &d) != 3) {
+ yyerror("invalid date");
+ }
+ break;
+ case 4:
+ if (sscanf(text, "%d-%d-%d-%d-%d-%d", &y, &m, &d, &h, &mi, &s) != 6) {
+ yyerror("invalid date");
+ }
+ break;
+ case 5:
+ if (sscanf(text, "%d-%d-%d-%d-%d", &y, &m, &d, &h, &mi) != 5) {
+ yyerror("invalid date");
}
+ break;
}
+
ret = PATH; /* cause a parse error */
+ if(y < 70) {
+ y += 2000;
+ } else if(y < 100) {
+ y += 1900;
+ }
if(y < 1000 || y > 9999) {
yyerror("invalid year");
} else if(m < 1 || m > 12) {
yyerror("invalid month");
} else if(d < 1 || d > 31) {
yyerror("invalid day");
- } else {
+ } else if(h < 0 || h > 24) {
+ yyerror("invalid hour");
+ } else if(mi < 0 || mi > 59) {
+ yyerror("invalid minute");
+ } else if(s < 0 || s > 59) {
+ yyerror("invalid second");
+ } else if(type < 4) {
yylval.strval = alloc(DATE_ALLOC_SIZE);
snprintf(yylval.strval, DATE_ALLOC_SIZE, "%04d-%02d-%02d", y, m, d);
ret = DATE;
+ } else {
+ yylval.strval = alloc(DATE_ALLOC_SIZE);
+ snprintf(yylval.strval, DATE_ALLOC_SIZE, "%04d-%02d-%02d-%02d-%02d-%02d", y, m, d, h, mi, s);
+ ret = DATE;
}
return ret;
}
-int yywrap() {
+int
+yywrap(void)
+{
return 1;
}
+
/*
- * Amanda, The Advanced Maryland Automatic Network Disk Archiver
+ * amanda, the advanced maryland automatic network disk archiver
* Copyright (c) 1991-2000 University of Maryland at College Park
* All Rights Reserved.
*
* file named AUTHORS, in the root directory of this distribution.
*/
/*
- * $Id: uscan.l,v 1.22 2004/02/11 13:03:29 martinea Exp $
+ * $Id: uscan.l,v 1.27 2006/07/05 11:15:56 martinea Exp $
*
* lexer for amrecover interactive language
*/
%{
#include "amanda.h"
-#undef ECHO
#include "uparse.h"
+/*
+ * We redefine this here to prevent compiler warning about ignoring fwrite
+ * return value...
+ */
+#undef ECHO
+#define ECHO do { \
+ if (fwrite(yytext, (size_t)yyleng, 1, yyout) <= 0) { \
+ yyerror("ECHO failure"); \
+ } \
+} while (0)
+
#define YY_NO_UNPUT
-#define DATE_ALLOC_SIZE sizeof("YYYY-MM-DD") /* includes null */
+#define DATE_ALLOC_SIZE sizeof("YYYY-MM-DD-HH-MM-SS") /* includes null */
+
+#define YY_DECL int yylex(void)
+extern int yylex(void);
-extern void yyerror P((char *s));
-extern int yyparse P((void));
-static int ll_parse_date P((int type, char *text));
+extern void yyerror(char *s);
+extern int yyparse(void);
+static int ll_parse_date(int type, char *text);
+int process_line(char *line);
%}
-%x quotedstring
+%x quotedpath
%{
static char *string_buf = NULL;
/* literal keyword tokens */
%}
+listhost { return LISTHOST; }
listdisk { return LISTDISK; }
-sethost { return SETHOST; }
-setdisk { return SETDISK; }
-setdate { return SETDATE; }
-setmode { return SETMODE; }
-settape { return SETTAPE; }
-cd { return CD; }
-cdx { return CDX; }
-quit { return QUIT; }
-exit { return QUIT; }
-history { return DHIST; }
-ls { return LS; }
-add { return ADD; }
-addx { return ADDX; }
-list { return LIST; }
-delete { return DELETE; }
-deletex { return DELETEX; }
-pwd { return PWD; }
-clear { return CLEAR; }
-help { return HELP; }
-\? { return HELP; }
-lcd { return LCD; }
-lpwd { return LPWD; }
-extract { return EXTRACT; }
-smb { return SMB; }
-tar { return TAR; }
-mode { return MODE; }
+sethost { return SETHOST; }
+setdisk { return SETDISK; }
+setdate { return SETDATE; }
+setmode { return SETMODE; }
+settape { return SETTAPE; }
+cd { return CD; }
+cdx { return CDX; }
+quit { return QUIT; }
+exit { return QUIT; }
+history { return DHIST; }
+ls { return LS; }
+add { return ADD; }
+addx { return ADDX; }
+list { return LIST; }
+delete { return DELETE; }
+deletex { return DELETEX; }
+pwd { return PWD; }
+clear { return CLEAR; }
+help { return HELP; }
+\? { return HELP; }
+lcd { return LCD; }
+lpwd { return LPWD; }
+extract { return EXTRACT; }
+smb { return SMB; }
+tar { return TAR; }
+mode { return MODE; }
%{
/* dates */
---[0-9]+ { return ll_parse_date(1, yytext); }
--[0-9]+-[0-9]+ { return ll_parse_date(2, yytext); }
[0-9]+-[0-9]+-[0-9]+ { return ll_parse_date(3, yytext); }
+[0-9]+-[0-9]+-[0-9]+-[0-9]+-[0-9]+-[0-9]+ { return ll_parse_date(4, yytext); }
+[0-9]+-[0-9]+-[0-9]+-[0-9]+-[0-9]+ { return ll_parse_date(5, yytext); }
%{
- /* file names */
+ /* quoted file names */
%}
-[^ \t\r"]+ {
- yylval.strval = stralloc(yytext); return PATH;
+\" {
+ if(string_buf != NULL) {
+ printf("ERROR:string_buf != NULL: %s\n",string_buf);
+ }
+ BEGIN(quotedpath);
+ strappend(string_buf, yytext);
}
-%{
- /* quoted file names */
-%}
+<quotedpath>[^\\\"]+ {
+ strappend(string_buf, yytext);
+}
-\" { if(string_buf != NULL) {printf("ERROR:string_buf != NULL: %s\n",string_buf);}; BEGIN(quotedstring); }
+<quotedpath>\\. {
+ /* escaped character (including quote) */
+ strappend(string_buf, yytext);
+}
-<quotedstring>\" { /* saw closing quote - all done */
- BEGIN(INITIAL);
- if(string_buf) {
+<quotedpath>\" { /* saw closing quote - all done */
+ strappend(string_buf, yytext);
yylval.strval = string_buf;
string_buf = NULL;
- } else {
- yylval.strval = "";
- }
- return PATH;
+ BEGIN(INITIAL);
+ return PATH;
}
-<quotedstring>\\\" {
- /* escaped quote */
- strappend(string_buf, "\\\"");
-}
+%{
+ /* file names */
+%}
-<quotedstring>\n {
- /* error - unterminated string constant */
- yyerror("unterminated string");
- amfree(string_buf);
+[^[:space:][:cntrl:]"]+ {
+ yylval.strval = stralloc(yytext);
+ return PATH;
}
-<quotedstring>[^\\\n\"]+ { strappend(string_buf, yytext); }
-
%{
/* whitespace */
%}
-[ \t\r]+ ; /* whitespace */
+[[:space:]]+ ; /* whitespace */
%{
/* anything else */
%%
-int process_line(line)
-char *line;
+int
+process_line(
+ char * line)
{
YY_BUFFER_STATE b;
int result;
return result;
}
-static int ll_parse_date(type, text)
-int type;
-char *text;
+static int
+ll_parse_date(
+ int type,
+ char * text)
{
time_t now;
struct tm *t;
- int y, m, d;
+ int y=2000, m=0, d=1, h=0, mi=0, s=0;
int ret;
now = time((time_t *)NULL);
t = localtime(&now);
- y = 1900+t->tm_year;
- m = t->tm_mon+1;
- d = t->tm_mday;
- if(type == 1) {
- sscanf(text, "---%d", &d);
- } else if(type == 2) {
- sscanf(text, "--%d-%d", &m, &d);
- } else {
- sscanf(text, "%d-%d-%d", &y, &m, &d);
- if(y < 70) {
- y += 2000;
- } else if(y < 100) {
- y += 1900;
+ if (t) {
+ y = 1900+t->tm_year;
+ m = t->tm_mon+1;
+ d = t->tm_mday;
+ }
+ switch(type) {
+ case 1:
+ if (sscanf(text, "---%d", &d) != 1) {
+ yyerror("invalid date");
+ }
+ break;
+ case 2:
+ if (sscanf(text, "--%d-%d", &m, &d) != 2) {
+ yyerror("invalid date");
+ }
+ break;
+ case 3:
+ if (sscanf(text, "%d-%d-%d", &y, &m, &d) != 3) {
+ yyerror("invalid date");
+ }
+ break;
+ case 4:
+ if (sscanf(text, "%d-%d-%d-%d-%d-%d", &y, &m, &d, &h, &mi, &s) != 6) {
+ yyerror("invalid date");
}
+ break;
+ case 5:
+ if (sscanf(text, "%d-%d-%d-%d-%d", &y, &m, &d, &h, &mi) != 5) {
+ yyerror("invalid date");
+ }
+ break;
}
+
ret = PATH; /* cause a parse error */
+ if(y < 70) {
+ y += 2000;
+ } else if(y < 100) {
+ y += 1900;
+ }
if(y < 1000 || y > 9999) {
yyerror("invalid year");
} else if(m < 1 || m > 12) {
yyerror("invalid month");
} else if(d < 1 || d > 31) {
yyerror("invalid day");
- } else {
+ } else if(h < 0 || h > 24) {
+ yyerror("invalid hour");
+ } else if(mi < 0 || mi > 59) {
+ yyerror("invalid minute");
+ } else if(s < 0 || s > 59) {
+ yyerror("invalid second");
+ } else if(type < 4) {
yylval.strval = alloc(DATE_ALLOC_SIZE);
snprintf(yylval.strval, DATE_ALLOC_SIZE, "%04d-%02d-%02d", y, m, d);
ret = DATE;
+ } else {
+ yylval.strval = alloc(DATE_ALLOC_SIZE);
+ snprintf(yylval.strval, DATE_ALLOC_SIZE, "%04d-%02d-%02d-%02d-%02d-%02d", y, m, d, h, mi, s);
+ ret = DATE;
}
return ret;
}
-int yywrap() {
+int
+yywrap(void)
+{
return 1;
}
+
# arrangements to build forward-reference header files
.SUFFIXES: .ih .h
.c.ih:
- sh ./mkh $(MKHFLAGS) -p $< >$@
+ sh ./mkh -A $(MKHFLAGS) -p $< >$@
default: r
REGEXH=regex.h
REGEXHSRC=regex2.h $(REGSRC)
$(REGEXH): $(REGEXHSRC) mkh
- sh ./mkh $(MKHFLAGS) -i _REGEX_H_ $(REGEXHSRC) >regex.tmp
+ sh ./mkh -A $(MKHFLAGS) -i _REGEX_H_ $(REGEXHSRC) >regex.tmp
cmp -s regex.tmp regex.h 2>/dev/null || cp regex.tmp regex.h
rm -f regex.tmp
# don't do this one unless you know what you're doing
spotless: clean
rm -f mkh regex.h
+
+lint:
+
+#ifndef CCLASS_H
+#define CCLASS_H
+
/* character-class table */
static struct cclass {
char *name;
NULL, NULL, ""
}
};
+
+#endif /* !CCLASS_H */
+#ifndef CNAME_H
+#define CNAME_H
+
/* character-name table */
static struct cname {
char *name;
{ "DEL", '\177' },
{ NULL, 0 }
};
+
+#endif /* !CNAME_H */
-#include <stdio.h>
-#include <string.h>
-#include <ctype.h>
-#include <limits.h>
-#include <stdlib.h>
-#include <sys/types.h>
+#include "amanda.h"
#include <regex.h>
#include "utils.h"
static char buf[10];
if (isprint(ch) || ch == ' ')
- snprintf(buf, sizeof(buf), "%c", ch);
+ snprintf(buf, SIZEOF(buf), "%c", ch);
else
- snprintf(buf, sizeof(buf), "\\%o", ch);
+ snprintf(buf, SIZEOF(buf), "\\%o", ch);
return(buf);
}
+#include "amanda.h"
+
/*
* The matching engine and friends. This file is #included by regexec.c
* after suitable #defines of a variety of macros used herein, so that
== size_t nmatch, regmatch_t pmatch[], int eflags);
*/
static int /* 0 success, REG_NOMATCH failure */
-matcher(g, string, nmatch, pmatch, eflags)
-register struct re_guts *g;
-const char *string;
-size_t nmatch;
-regmatch_t pmatch[];
-int eflags;
+matcher(
+ struct re_guts * g,
+ const char * string,
+ size_t nmatch,
+ regmatch_t pmatch[],
+ int eflags)
{
register const char *endp;
- register int i;
+ register size_t i;
struct match mv;
register struct match *m = &mv;
register const char *dp;
- const register sopno gf = g->firststate+1; /* +1 for OEND */
- const register sopno gl = g->laststate;
+ const sopno gf = g->firststate+1; /* +1 for OEND */
+ const sopno gl = g->laststate;
const char *start;
const char *stop;
if (g->cflags®_NOSUB)
nmatch = 0;
if (eflags®_STARTEND) {
- start = string + pmatch[0].rm_so;
- stop = string + pmatch[0].rm_eo;
+ start = string + (int)pmatch[0].rm_so;
+ stop = string + (int)pmatch[0].rm_eo;
} else {
start = string;
stop = start + strlen(start);
/* prescreening; this does wonders for this rather slow code */
if (g->must != NULL) {
- for (dp = start; dp < stop; dp++)
- if (*dp == g->must[0] && stop - dp >= g->mlen &&
- memcmp(dp, g->must, (size_t)g->mlen) == 0)
+ for (dp = start; dp < stop; dp++) {
+ if ((*dp == g->must[0]) &&
+ ((sopno)(stop - dp) >= g->mlen) &&
+ (memcmp(dp, g->must, (size_t)g->mlen) == 0)) {
break;
+ }
+ }
if (dp == stop) /* we didn't find g->must */
return(REG_NOMATCH);
}
/* match struct setup */
+ memset(m, 0, SIZEOF(*m));
m->g = g;
m->eflags = eflags;
m->pmatch = NULL;
SETUP(m->fresh);
SETUP(m->tmp);
SETUP(m->empty);
- CLEAR(m->empty);
/* this loop does only one repetition except for backrefs */
for (;;) {
endp = fast(m, start, stop, gf, gl);
- if (endp == NULL) { /* a miss */
+ if ((endp == NULL) || (m->coldp == NULL)) { /* a miss */
STATETEARDOWN(m);
return(REG_NOMATCH);
}
+
if (nmatch == 0 && !g->backrefs)
break; /* no further info needed */
- /* where? */
- assert(m->coldp != NULL);
for (;;) {
NOTE("finding start");
endp = slow(m, m->coldp, stop, gf, gl);
/* oh my, he wants the subexpressions... */
if (m->pmatch == NULL)
- m->pmatch = (regmatch_t *)malloc((m->g->nsub + 1) *
- sizeof(regmatch_t));
+ m->pmatch = (regmatch_t *)alloc((m->g->nsub + 1) *
+ SIZEOF(regmatch_t));
if (m->pmatch == NULL) {
STATETEARDOWN(m);
return(REG_ESPACE);
}
for (i = 1; i <= m->g->nsub; i++)
- m->pmatch[i].rm_so = m->pmatch[i].rm_eo = -1;
+ m->pmatch[i].rm_so = m->pmatch[i].rm_eo = (regoff_t)-1;
if (!g->backrefs && !(m->eflags®_BACKR)) {
NOTE("dissecting");
dp = dissect(m, m->coldp, endp, gf, gl);
} else {
- if (g->nplus > 0 && m->lastpos == NULL)
- m->lastpos = (const char **)malloc((g->nplus+1) *
- sizeof(const char *));
+ if (g->nplus > 0 && m->lastpos == NULL) {
+ m->lastpos = (const char **)
+ alloc(((size_t)g->nplus+1) *
+ SIZEOF(const char *));
+ }
if (g->nplus > 0 && m->lastpos == NULL) {
free(m->pmatch);
STATETEARDOWN(m);
}
/* fill in the details if requested */
+ /*@ignore@*/
if (nmatch > 0) {
- pmatch[0].rm_so = m->coldp - m->offp;
- pmatch[0].rm_eo = endp - m->offp;
+ pmatch[0].rm_so = (regoff_t)(m->coldp - m->offp);
+ pmatch[0].rm_eo = (regoff_t)(endp - m->offp);
}
+ /*@end@*/
if (nmatch > 1) {
assert(m->pmatch != NULL);
for (i = 1; i < nmatch; i++)
if (i <= m->g->nsub)
pmatch[i] = m->pmatch[i];
else {
- pmatch[i].rm_so = -1;
- pmatch[i].rm_eo = -1;
+ pmatch[i].rm_so = (regoff_t)-1;
+ pmatch[i].rm_eo = (regoff_t)-1;
}
}
/*
- dissect - figure out what matched what, no back references
- == static const char *dissect(register struct match *m, char *start, \
- == char *stop, sopno startst, sopno stopst);
+ == static const char *dissect(register struct match *m, const char *start, \
+ == const char *stop, sopno startst, sopno stopst);
*/
static const char * /* == stop (success) always */
-dissect(m, start, stop, startst, stopst)
-register struct match *m;
-const char *start;
-const char *stop;
-sopno startst;
-sopno stopst;
+dissect(
+ struct match * m,
+ const char * start,
+ const char * stop,
+ sopno startst,
+ sopno stopst)
{
- register int i;
- register sopno ss; /* start sop of current subRE */
- register sopno es; /* end sop of current subRE */
+ size_t i;
+ register sopno ss; /* start sop of current subRE */
+ register sopno es; /* end sop of current subRE */
register const char *sp; /* start of string matched by it */
register const char *stp; /* string matched by it cannot pass here */
- register const char *rest; /* start of rest of string */
+ register const char *rest = NULL;/* start of rest of string */
register const char *tail; /* string unmatched by rest of RE */
- register sopno ssub; /* start sop of subsubRE */
- register sopno esub; /* end sop of subsubRE */
+ register sopno ssub; /* start sop of subsubRE */
+ register sopno esub; /* end sop of subsubRE */
register const char *ssp; /* start of string matched by subsubRE */
register const char *sep; /* end of string matched by subsubRE */
register const char *oldssp; /* previous ssp */
case OQUEST_:
es += OPND(m->g->strip[es]);
break;
+
case OCH_:
while (OP(m->g->strip[es]) != O_CH)
es += OPND(m->g->strip[es]);
/* figure out what it matched */
switch (OP(m->g->strip[ss])) {
case OEND:
- assert(nope);
break;
+
case OCHAR:
sp++;
break;
+
case OBOL:
case OEOL:
case OBOW:
case OEOW:
break;
+
case OANY:
case OANYOF:
sp++;
break;
+
case OBACK_:
case O_BACK:
- assert(nope);
break;
+
/* cases where length of match is hard to find */
case OQUEST_:
stp = stop;
+ rest = slow(m, sp, stp, ss, es);
for (;;) {
/* how long could this one be? */
- rest = slow(m, sp, stp, ss, es);
assert(rest != NULL); /* it did match */
/* could the rest match the rest? */
tail = slow(m, rest, stop, es, stopst);
/* no -- try a shorter match for this one */
stp = rest - 1;
assert(stp >= sp); /* it did work */
+ rest = slow(m, sp, stp, ss, es);
}
ssub = ss + 1;
esub = es - 1;
if (slow(m, sp, rest, ssub, esub) != NULL) {
dp = dissect(m, sp, rest, ssub, esub);
assert(dp == rest);
- } else /* no */
- assert(sp == rest);
+ }
sp = rest;
break;
+
case OPLUS_:
stp = stop;
for (;;) {
esub = es - 1;
ssp = sp;
oldssp = ssp;
+ sep = slow(m, ssp, rest, ssub, esub);
for (;;) { /* find last match of innards */
- sep = slow(m, ssp, rest, ssub, esub);
if (sep == NULL || sep == ssp)
break; /* failed or matched null */
oldssp = ssp; /* on to next try */
ssp = sep;
+ sep = slow(m, ssp, rest, ssub, esub);
}
if (sep == NULL) {
/* last successful match */
assert(slow(m, ssp, sep, ssub, esub) == rest);
dp = dissect(m, ssp, sep, ssub, esub);
assert(dp == sep);
- sp = rest;
+ sp = dp;
break;
+
case OCH_:
stp = stop;
for (;;) {
ssub = ss + 1;
esub = ss + OPND(m->g->strip[ss]) - 1;
assert(OP(m->g->strip[esub]) == OOR1);
+ /*@ignore@*/
for (;;) { /* find first matching branch */
if (slow(m, sp, rest, ssub, esub) == rest)
break; /* it matched all of it */
}
dp = dissect(m, sp, rest, ssub, esub);
assert(dp == rest);
- sp = rest;
+ sp = dp;
+ /*@end@*/
break;
+
case O_PLUS:
case O_QUEST:
case OOR1:
case OOR2:
case O_CH:
- assert(nope);
break;
+
case OLPAREN:
- i = OPND(m->g->strip[ss]);
+ i = (size_t)OPND(m->g->strip[ss]);
assert(0 < i && i <= m->g->nsub);
- m->pmatch[i].rm_so = sp - m->offp;
+ m->pmatch[i].rm_so = (regoff_t)(sp - m->offp);
break;
+
case ORPAREN:
- i = OPND(m->g->strip[ss]);
+ i = (size_t)OPND(m->g->strip[ss]);
assert(0 < i && i <= m->g->nsub);
- m->pmatch[i].rm_eo = sp - m->offp;
+ m->pmatch[i].rm_eo = (regoff_t)(sp - m->offp);
break;
+
default: /* uh oh */
- assert(nope);
break;
}
}
== const char *stop, sopno startst, sopno stopst, sopno lev);
*/
static const char * /* == stop (success) or NULL (failure) */
-backref(m, start, stop, startst, stopst, lev)
-register struct match *m;
-const char *start;
-const char *stop;
-sopno startst;
-sopno stopst;
-sopno lev; /* PLUS nesting level */
+backref(
+ struct match * m,
+ const char * start,
+ const char * stop,
+ sopno startst,
+ sopno stopst,
+ sopno lev) /* PLUS nesting level */
{
- register int i;
+ register size_t i;
register sopno ss; /* start sop of current subRE */
register const char *sp;/* start of string matched by it */
register sopno ssub; /* start sop of subsubRE */
return(NULL);
break;
case OBOL:
- if ( (sp == m->beginp && !(m->eflags®_NOTBOL)) ||
+ if (!((sp == m->beginp && !(m->eflags®_NOTBOL)) ||
(sp < m->endp && *(sp-1) == '\n' &&
- (m->g->cflags®_NEWLINE)) )
- { /* yes */ }
- else
+ (m->g->cflags®_NEWLINE)))) {
return(NULL);
+ }
break;
case OEOL:
- if ( (sp == m->endp && !(m->eflags®_NOTEOL)) ||
+ if (!((sp == m->endp && !(m->eflags®_NOTEOL)) ||
(sp < m->endp && *sp == '\n' &&
- (m->g->cflags®_NEWLINE)) )
- { /* yes */ }
- else
+ (m->g->cflags®_NEWLINE)))) {
return(NULL);
+ }
break;
case OBOW:
- if (( (sp == m->beginp && !(m->eflags®_NOTBOL)) ||
- (sp < m->endp && *(sp-1) == '\n' &&
- (m->g->cflags®_NEWLINE)) ||
- (sp > m->beginp &&
- !ISWORD(*(sp-1))) ) &&
- (sp < m->endp && ISWORD(*sp)) )
- { /* yes */ }
- else
+ if (!(((sp == m->beginp && !(m->eflags®_NOTBOL))
+ || ((sp < m->endp) && (*(sp-1) == '\n')
+ && (m->g->cflags & REG_NEWLINE))
+ || (((sp > m->beginp) && !ISWORD(*(sp-1)))
+ && (sp < m->endp && ISWORD(*sp)))))) {
return(NULL);
+ }
break;
case OEOW:
- if (( (sp == m->endp && !(m->eflags®_NOTEOL)) ||
+ if (!(((sp == m->endp && !(m->eflags®_NOTEOL)) ||
(sp < m->endp && *sp == '\n' &&
(m->g->cflags®_NEWLINE)) ||
(sp < m->endp && !ISWORD(*sp)) ) &&
- (sp > m->beginp && ISWORD(*(sp-1))) )
- { /* yes */ }
- else
+ (sp > m->beginp && ISWORD(*(sp-1))))) {
return(NULL);
+ }
break;
case O_QUEST:
break;
s = m->g->strip[ss];
switch (OP(s)) {
case OBACK_: /* the vilest depths */
- i = OPND(s);
+ i = (size_t)OPND(s);
assert(0 < i && i <= m->g->nsub);
- if (m->pmatch[i].rm_eo == -1)
+ if (m->pmatch[i].rm_eo == (regoff_t)-1)
return(NULL);
- assert(m->pmatch[i].rm_so != -1);
- len = m->pmatch[i].rm_eo - m->pmatch[i].rm_so;
- assert(stop - m->beginp >= len);
+ assert(m->pmatch[i].rm_so != (regoff_t)-1);
+ len = (size_t)(m->pmatch[i].rm_eo - m->pmatch[i].rm_so);
+ assert((size_t)(stop - m->beginp) >= len);
if (sp > stop - len)
return(NULL); /* not enough left to match */
- ssp = m->offp + m->pmatch[i].rm_so;
+ ssp = m->offp + (size_t)m->pmatch[i].rm_so;
if (memcmp(sp, ssp, len) != 0)
return(NULL);
while (m->g->strip[ss] != SOP(O_BACK, i))
ss++;
return(backref(m, sp+len, stop, ss+1, stopst, lev));
- break;
+
case OQUEST_: /* to null or not */
dp = backref(m, sp, stop, ss+1, stopst, lev);
if (dp != NULL)
return(dp); /* not */
return(backref(m, sp, stop, ss+OPND(s)+1, stopst, lev));
- break;
+
case OPLUS_:
assert(m->lastpos != NULL);
assert(lev+1 <= m->g->nplus);
m->lastpos[lev+1] = sp;
return(backref(m, sp, stop, ss+1, stopst, lev+1));
- break;
+
case O_PLUS:
if (sp == m->lastpos[lev]) /* last pass matched null */
return(backref(m, sp, stop, ss+1, stopst, lev-1));
dp = backref(m, sp, stop, ss-OPND(s)+1, stopst, lev);
if (dp == NULL)
return(backref(m, sp, stop, ss+1, stopst, lev-1));
- else
- return(dp);
- break;
+ return(dp);
+
case OCH_: /* find the right one, if any */
ssub = ss + 1;
esub = ss + OPND(s) - 1;
return(dp);
/* that one missed, try next one */
if (OP(m->g->strip[esub]) == O_CH)
- return(NULL); /* there is none */
+ break;
esub++;
assert(OP(m->g->strip[esub]) == OOR2);
ssub = esub + 1;
else
assert(OP(m->g->strip[esub]) == O_CH);
}
- break;
+ return(NULL); /* there is none */
+
case OLPAREN: /* must undo assignment if rest fails */
- i = OPND(s);
+ i = (size_t)OPND(s);
assert(0 < i && i <= m->g->nsub);
offsave = m->pmatch[i].rm_so;
- m->pmatch[i].rm_so = sp - m->offp;
+ m->pmatch[i].rm_so = (regoff_t)(sp - m->offp);
dp = backref(m, sp, stop, ss+1, stopst, lev);
if (dp != NULL)
return(dp);
m->pmatch[i].rm_so = offsave;
return(NULL);
- break;
+
case ORPAREN: /* must undo assignment if rest fails */
- i = OPND(s);
+ i = (size_t)OPND(s);
assert(0 < i && i <= m->g->nsub);
offsave = m->pmatch[i].rm_eo;
- m->pmatch[i].rm_eo = sp - m->offp;
+ m->pmatch[i].rm_eo = (regoff_t)(sp - m->offp);
dp = backref(m, sp, stop, ss+1, stopst, lev);
if (dp != NULL)
return(dp);
m->pmatch[i].rm_eo = offsave;
return(NULL);
- break;
+
default: /* uh oh */
- assert(nope);
break;
}
-
- /* "can't happen" */
- assert(nope);
- /* NOTREACHED */
return((const char *)NULL); /* dummy */
}
== const char *stop, sopno startst, sopno stopst);
*/
static const char * /* where tentative match ended, or NULL */
-fast(m, start, stop, startst, stopst)
-register struct match *m;
-const char *start;
-const char *stop;
-sopno startst;
-sopno stopst;
+fast(
+ struct match * m,
+ const char * start,
+ const char * stop,
+ sopno startst,
+ sopno stopst)
{
register states st = m->st;
register states fresh = m->fresh;
== const char *stop, sopno startst, sopno stopst);
*/
static const char * /* where it ended */
-slow(m, start, stop, startst, stopst)
-register struct match *m;
-const char *start;
-const char *stop;
-sopno startst;
-sopno stopst;
+slow(
+ struct match * m,
+ const char * start,
+ const char * stop,
+ sopno startst,
+ sopno stopst)
{
register states st = m->st;
register states empty = m->empty;
== #define NNONCHAR (CODEMAX-CHAR_MAX)
*/
static states
-step(g, start, stop, bef, ch, aft)
-register struct re_guts *g;
-sopno start; /* start state within strip */
-sopno stop; /* state after stop state within strip */
-register states bef; /* states reachable before */
-int ch; /* character or NONCHAR code */
-register states aft; /* states already known reachable after */
+step(
+ struct re_guts * g,
+ sopno start, /* start state within strip */
+ sopno stop, /* state after stop state within strip */
+ register states bef, /* states reachable before */
+ int ch, /* character or NONCHAR code */
+ states aft) /* states already known reachable after */
{
register cset *cs;
register sop s;
register sopno pc;
- register onestate here; /* note, macros know this name */
+ register sopno here; /* note, macros know this name */
register sopno look;
- register long i;
+ register unsigned long i;
for (pc = start, INIT(here, pc); pc != stop; pc++, INC(here)) {
s = g->strip[pc];
break;
case O_PLUS: /* both forward and back */
FWD(aft, aft, 1);
- i = ISSETBACK(aft, OPND(s));
+ i = (unsigned long)ISSETBACK(aft, OPND(s));
BACK(aft, aft, OPND(s));
if (!i && ISSETBACK(aft, OPND(s))) {
/* oho, must reconsider loop body */
FWD(aft, aft, 1);
break;
default: /* ooooops... */
- assert(nope);
break;
}
}
== #endif
*/
static void
-print(m, caption, st, ch, d)
-struct match *m;
-char *caption;
-states st;
-int ch;
-FILE *d;
+print(
+ struct match * m,
+ char * caption,
+ states st,
+ int ch,
+ FILE * d)
{
register struct re_guts *g = m->g;
register int i;
== #endif
*/
static void
-at(m, title, start, stop, startst, stopst)
-struct match *m;
-const char *title;
-const char *start;
-const char *stop;
-sopno startst;
-sopno stopst;
+at(
+ struct match * m,
+ const char * title,
+ const char * start,
+ const char * stop,
+ sopno startst,
+ sopno stopst)
{
if (!(m->eflags®_TRACE))
return;
* the non-debug compilation anyway, so it doesn't matter much.
*/
static char * /* -> representation */
-pchar(ch)
-int ch;
+pchar(
+ int ch)
{
static char pbuf[10];
if (isprint(ch) || ch == ' ')
- snprintf(pbuf, sizeof(pbuf), "%c", ch);
+ snprintf(pbuf, SIZEOF(pbuf), "%c", ch);
else
- snprintf(pbuf, sizeof(pbuf), "\\%o", ch);
+ snprintf(pbuf, SIZEOF(pbuf), "\\%o", ch);
return(pbuf);
}
#endif
-#include <stdio.h>
-#include <string.h>
-#include <sys/types.h>
+#include "amanda.h"
#include <regex.h>
-#include <assert.h>
#include "main.ih"
err = regcomp(&re, argv[optind++], copts);
if (err) {
- len = regerror(err, &re, erbuf, sizeof(erbuf));
+ len = regerror(err, &re, erbuf, SIZEOF(erbuf));
fprintf(stderr, "error %s, %d/%d `%s'\n",
- eprint(err), len, sizeof(erbuf), erbuf);
+ eprint(err), len, SIZEOF(erbuf), erbuf);
exit(status);
}
regprint(&re, stdout);
}
err = regexec(&re, argv[optind], (size_t)NS, subs, eopts);
if (err) {
- len = regerror(err, &re, erbuf, sizeof(erbuf));
+ len = regerror(err, &re, erbuf, SIZEOF(erbuf));
fprintf(stderr, "error %s, %d/%d `%s'\n",
- eprint(err), len, sizeof(erbuf), erbuf);
+ eprint(err), len, SIZEOF(erbuf), erbuf);
exit(status);
}
if (!(copts®_NOSUB)) {
char *bpname = "REG_BADPAT";
regex_t re;
- while (fgets(inbuf, sizeof(inbuf), in) != NULL) {
+ while (fgets(inbuf, (int)sizeof(inbuf), in) != NULL) {
line++;
if (inbuf[0] == '#' || inbuf[0] == '\n')
continue; /* NOTE CONTINUE */
options('c', f[1]) &~ REG_EXTENDED);
}
- ne = regerror(REG_BADPAT, (regex_t *)NULL, erbuf, sizeof(erbuf));
+ ne = regerror(REG_BADPAT, (regex_t *)NULL, erbuf, SIZEOF(erbuf));
if (strcmp(erbuf, badpat) != 0 || ne != strlen(badpat)+1) {
fprintf(stderr, "end: regerror() test gave `%s' not `%s'\n",
erbuf, badpat);
erbuf, SHORT-1, badpat);
status = 1;
}
- ne = regerror(REG_ITOA|REG_BADPAT, (regex_t *)NULL, erbuf, sizeof(erbuf));
+ ne = regerror(REG_ITOA|REG_BADPAT, (regex_t *)NULL, erbuf, SIZEOF(erbuf));
if (strcmp(erbuf, bpname) != 0 || ne != strlen(bpname)+1) {
fprintf(stderr, "end: regerror() ITOA test gave `%s' not `%s'\n",
erbuf, bpname);
status = 1;
}
re.re_endp = bpname;
- ne = regerror(REG_ATOI, &re, erbuf, sizeof(erbuf));
+ ne = regerror(REG_ATOI, &re, erbuf, SIZEOF(erbuf));
if (atoi(erbuf) != (int)REG_BADPAT) {
fprintf(stderr, "end: regerror() ATOI test gave `%s' not `%ld'\n",
erbuf, (long)REG_BADPAT);
char f0copy[1000];
char f2copy[1000];
- strncpy(f0copy, f0, sizeof(f0copy)-1);
- f0copy[sizeof(f0copy)-1] = '\0';
+ strncpy(f0copy, f0, SIZEOF(f0copy)-1);
+ f0copy[SIZEOF(f0copy)-1] = '\0';
re.re_endp = (opts®_PEND) ? f0copy + strlen(f0copy) : NULL;
fixstr(f0copy);
err = regcomp(&re, f0copy, opts);
if (err != 0 && (!opt('C', f1) || err != efind(f2))) {
/* unexpected error or wrong error */
- len = regerror(err, &re, erbuf, sizeof(erbuf));
+ len = regerror(err, &re, erbuf, SIZEOF(erbuf));
fprintf(stderr, "%d: %s error %s, %d/%d `%s'\n",
line, type, eprint(err), len,
- sizeof(erbuf), erbuf);
+ SIZEOF(erbuf), erbuf);
status = 1;
} else if (err == 0 && opt('C', f1)) {
/* unexpected success */
return;
}
- strncpy(f2copy, f2, sizeof(f2copy)-1);
- f2copy[sizeof(f2copy)-1] = '\0';
+ strncpy(f2copy, f2, SIZEOF(f2copy)-1);
+ f2copy[SIZEOF(f2copy)-1] = '\0';
fixstr(f2copy);
if (options('e', f1)®_STARTEND) {
if (err != 0 && (f3 != NULL || err != REG_NOMATCH)) {
/* unexpected error or wrong error */
- len = regerror(err, &re, erbuf, sizeof(erbuf));
+ len = regerror(err, &re, erbuf, SIZEOF(erbuf));
fprintf(stderr, "%d: %s exec error %s, %d/%d `%s'\n",
line, type, eprint(err), len,
- sizeof(erbuf), erbuf);
+ SIZEOF(erbuf), erbuf);
status = 1;
} else if (err != 0) {
/* nothing more to check */
(sub.rm_so != -1 && sub.rm_eo == -1) ||
(sub.rm_so != -1 && sub.rm_so < 0) ||
(sub.rm_eo != -1 && sub.rm_eo < 0) ) {
- snprintf(grump, sizeof(grump),
+ snprintf(grump, SIZEOF(grump),
"start %ld end %ld", (long)sub.rm_so,
(long)sub.rm_eo);
return(grump);
/* check for in range */
if (sub.rm_eo > strlen(str)) {
- snprintf(grump, sizeof(grump),
+ snprintf(grump, SIZEOF(grump),
"start %ld end %ld, past end of string",
(long)sub.rm_so, (long)sub.rm_eo);
return(grump);
/* check for not supposed to match */
if (should == NULL) {
- snprintf(grump, sizeof(grump), "matched `%.*s'", len, p);
+ snprintf(grump, SIZEOF(grump), "matched `%.*s'", len, p);
return(grump);
}
/* check for wrong match */
if (len != shlen || strncmp(p, should, (size_t)shlen) != 0) {
- snprintf(grump, sizeof(grump),
+ snprintf(grump, SIZEOF(grump),
"matched `%.*s' instead", len, p);
return(grump);
}
if (shlen == 0)
shlen = 1; /* force check for end-of-string */
if (strncmp(p, at, shlen) != 0) {
- snprintf(grump, sizeof(grump), "matched null at `%.20s'", p);
+ snprintf(grump, SIZEOF(grump), "matched null at `%.20s'", p);
return(grump);
}
return(NULL);
static char epbuf[100];
size_t len;
- len = regerror(REG_ITOA|err, (regex_t *)NULL, epbuf, sizeof(epbuf));
- assert(len <= sizeof(epbuf));
+ len = regerror(REG_ITOA|err, (regex_t *)NULL, epbuf, SIZEOF(epbuf));
+ assert(len <= SIZEOF(epbuf));
return(epbuf);
}
size_t n;
regex_t re;
- snprintf(efbuf, sizeof(efbuf), "REG_%s", name);
- assert(strlen(efbuf) < sizeof(efbuf));
+ snprintf(efbuf, SIZEOF(efbuf), "REG_%s", name);
+ assert(strlen(efbuf) < SIZEOF(efbuf));
re.re_endp = efbuf;
- (void) regerror(REG_ATOI, &re, efbuf, sizeof(efbuf));
+ (void) regerror(REG_ATOI, &re, efbuf, SIZEOF(efbuf));
return(atoi(efbuf));
}
"'/^\([^#\/][^\/]*[a-zA-Z0-9_)]\)(\(.*\))/s;;\1(/*\2*/);'
shift
;;
+ -A) # funny Amanda P macro
+ peel="$peel
+ "'/^\([^#\/][^\/]*[a-zA-Z0-9_)]\)(\(.*\))/s;;\1 P((\2));'
+ shift
+ ;;
-b) # funny Berkeley __P macro
peel="$peel
"'/^\([^#\/][^\/]*[a-zA-Z0-9_)]\)(\(.*\))/s;;\1 __P((\2));'
-#include <sys/types.h>
-#include <stdio.h>
-#include <string.h>
-#include <ctype.h>
-#include <limits.h>
-#include <stdlib.h>
+#include "amanda.h"
#include <regex.h>
-
#include "utils.h"
#include "regex2.h"
char *end; /* end of string (-> NUL normally) */
int error; /* has an error been seen? */
sop *strip; /* malloced strip */
- sopno ssize; /* malloced strip size (allocated) */
- sopno slen; /* malloced strip length (used) */
+ size_t ssize; /* malloced strip size (allocated) */
+ size_t slen; /* malloced strip length (used) */
int ncsalloc; /* number of csets allocated */
struct re_guts *g;
# define NPAREN 10 /* we need to remember () 1-9 for back refs */
#define MUSTEAT(c, e) (REQUIRE(MORE() && GETNEXT() == (c), e))
#define MUSTNOTSEE(c, e) (REQUIRE(!MORE() || PEEK() != (c), e))
#define EMIT(op, sopnd) doemit(p, (sop)(op), (size_t)(sopnd))
-#define INSERT(op, pos) doinsert(p, (sop)(op), HERE()-(pos)+1, pos)
-#define AHEAD(pos) dofwd(p, pos, HERE()-(pos))
-#define ASTERN(sop, pos) EMIT(sop, HERE()-pos)
-#define HERE() (p->slen)
-#define THERE() (p->slen - 1)
-#define THERETHERE() (p->slen - 2)
-#define DROP(n) (p->slen -= (n))
+#define INSERT(op, pos) doinsert(p, (sop)(op), HERE()-(size_t)(pos)+1, (size_t)pos)
+#define AHEAD(pos) dofwd(p, (size_t)pos, HERE()-(size_t)(pos))
+#define ASTERN(sop, pos) EMIT(sop, HERE()-(size_t)(pos))
+#define HERE() (size_t)(p->slen)
+#define THERE() (size_t)(p->slen - 1)
+#define THERETHERE() (size_t)(p->slen - 2)
+#define DROP(n) (p->slen = p->slen - (size_t)(n))
#ifndef NDEBUG
static int never = 0; /* for use in asserts; shuts lint up */
#define never 0 /* some <assert.h>s have bugs too */
#endif
+static void p_ere(struct parse *p, int stop);
+static void p_ere_exp(struct parse *p);
+static void p_str(struct parse *p);
+static void p_bre(struct parse *p, int end1, int end2);
+static int p_simp_re(struct parse *p, int starordinary);
+static int p_count(struct parse *p);
+static void p_bracket(struct parse *p);
+static void p_b_term(struct parse *p, cset *cs);
+static void p_b_cclass(struct parse *p, cset *cs);
+static void p_b_eclass(struct parse *p, cset *cs);
+static char p_b_symbol(struct parse *p);
+static char p_b_coll_elem(struct parse *p, int endc);
+static char othercase(int ch);
+static void bothcases(struct parse *p, int ch);
+static void ordinary(struct parse *p, int ch);
+static void nonnewline(struct parse *p);
+static void repeat(struct parse *p, sopno start, int from, int to);
+static int seterr(struct parse *p, int e);
+static cset * allocset(struct parse *p);
+static void freeset(struct parse *p, cset *cs);
+static int freezeset(struct parse *p, cset *cs);
+static int firstch(struct parse *p, cset *cs);
+static int nch(struct parse *p, cset *cs);
+static void mcadd(struct parse *p, cset *cs, char *cp);
+static void mcinvert(struct parse *p, cset *cs);
+static void mccase(struct parse *p, cset *cs);
+static int isinsets(struct re_guts *g, int c);
+static int samesets(struct re_guts *g, int c1, int c2);
+static void categorize(struct parse *p, struct re_guts *g);
+static sopno dupl(struct parse *p, sopno start, sopno finish);
+static void doemit(struct parse *p, sop op, size_t opnd);
+static void doinsert(struct parse *p, sop op, size_t opnd, sopno pos);
+static void dofwd(struct parse *p, sopno pos, sop value);
+static void enlarge(struct parse *p, sopno size);
+static void stripsnug(struct parse *p, struct re_guts *g);
+static void findmust(struct parse *p, struct re_guts *g);
+static sopno pluscount(struct parse *p, struct re_guts *g);
+
+
/*
- regcomp - interface for parser and compilation
= extern int regcomp(regex_t *, const char *, int);
= #define REG_DUMP 0200
*/
int /* 0 success, otherwise REG_something */
-regcomp(preg, pattern, cflags)
-regex_t *preg;
-const char *pattern;
-int cflags;
+regcomp(
+ regex_t * preg,
+ const char *pattern,
+ int cflags)
{
struct parse pa;
- register struct re_guts *g;
- register struct parse *p = &pa;
- register int i;
- register size_t len;
+ struct re_guts *g;
+ struct parse *p = &pa;
+ int i;
+ size_t len;
#ifdef REDEBUG
# define GOODFLAGS(f) (f)
#else
#endif
cflags = GOODFLAGS(cflags);
+#if !defined(__lint) /* Lint global check knows nobody calls with this combo */
if ((cflags®_EXTENDED) && (cflags®_NOSPEC))
return(REG_INVARG);
- if (cflags®_PEND) {
+ if (cflags & REG_PEND) {
+ /*@ignore@*/
if (preg->re_endp < pattern)
return(REG_INVARG);
- len = preg->re_endp - pattern;
+ len = (size_t)(preg->re_endp - pattern);
+ /*@end@*/
} else
+#endif
len = strlen((char *)pattern);
/* do the mallocs early so failure handling is easy */
- g = (struct re_guts *)malloc(sizeof(struct re_guts) +
- (NC-1)*sizeof(cat_t));
+ g = (struct re_guts *)malloc(SIZEOF(struct re_guts) +
+ (NC-1)*SIZEOF(cat_t));
if (g == NULL)
return(REG_ESPACE);
- p->ssize = len/(size_t)2*(size_t)3 + (size_t)1; /* ugh */
- p->strip = (sop *)malloc(p->ssize * sizeof(sop));
+ p->ssize = (sopno)(((len / (size_t)2) * (size_t)3) + (size_t)1);
+ p->strip = (sop *)malloc((size_t)p->ssize * SIZEOF(sop));
p->slen = 0;
if (p->strip == NULL) {
free((char *)g);
g->nsub = 0;
g->ncategories = 1; /* category 0 is "everything else" */
g->categories = &g->catspace[-(CHAR_MIN)];
- (void) memset((char *)g->catspace, 0, NC*sizeof(cat_t));
+ (void) memset((char *)g->catspace, 0, NC*SIZEOF(cat_t));
g->backrefs = 0;
/* do it */
EMIT(OEND, 0);
- g->firststate = THERE();
- if (cflags®_EXTENDED)
+ g->firststate = (sopno)THERE();
+ if (cflags & REG_EXTENDED)
p_ere(p, OUT);
- else if (cflags®_NOSPEC)
+ else if (cflags & REG_NOSPEC)
p_str(p);
else
p_bre(p, OUT, OUT);
findmust(p, g);
g->nplus = pluscount(p, g);
g->magic = MAGIC2;
+ /*@ignore@*/
preg->re_nsub = g->nsub;
preg->re_g = g;
preg->re_magic = MAGIC1;
+ /*@end@*/
#ifndef REDEBUG
/* not debugging, so can't rely on the assert() in regexec() */
if (g->iflags&BAD)
/*
- p_ere - ERE parser top level, concatenation and alternation
- == static void p_ere(register struct parse *p, int stop);
+ == static void p_ere(struct parse *p, int stop);
*/
static void
-p_ere(p, stop)
-register struct parse *p;
-int stop; /* character this ERE should end at */
+p_ere(
+ struct parse * p,
+ int stop) /* character this ERE should end at */
{
- register char c;
- register sopno prevback = 0;
- register sopno prevfwd = 0;
- register sopno conc;
- register int first = 1; /* is this the first alternative? */
+ char c;
+ sopno prevback = 0;
+ sopno prevfwd = 0;
+ sopno conc;
+ int first = 1; /* is this the first alternative? */
for (;;) {
/* do a bunch of concatenated expressions */
conc = HERE();
while (MORE() && (c = PEEK()) != '|' && c != stop)
p_ere_exp(p);
- REQUIRE(HERE() != conc, REG_EMPTY); /* require nonempty */
+ (void)REQUIRE(HERE() != conc, REG_EMPTY); /* require nonempty */
if (!EAT('|'))
break; /* NOTE BREAK OUT */
/*
- p_ere_exp - parse one subERE, an atom possibly followed by a repetition op
- == static void p_ere_exp(register struct parse *p);
+ == static void p_ere_exp(struct parse *p);
*/
static void
-p_ere_exp(p)
-register struct parse *p;
+p_ere_exp(
+ struct parse * p)
{
- register char c;
- register sopno pos;
- register int count;
- register int count2;
- register sopno subno;
+ char c;
+ sopno pos;
+ int count;
+ int count2;
+ sopno subno;
int wascaret = 0;
assert(MORE()); /* caller should have ensured this */
pos = HERE();
switch (c) {
case '(':
- REQUIRE(MORE(), REG_EPAREN);
+ (void)REQUIRE(MORE(), REG_EPAREN);
p->g->nsub++;
subno = p->g->nsub;
if (subno < NPAREN)
assert(p->pend[subno] != 0);
}
EMIT(ORPAREN, subno);
- MUSTEAT(')', REG_EPAREN);
+ (void)MUSTEAT(')', REG_EPAREN);
break;
#ifndef POSIX_MISTAKE
case ')': /* happens only if no current unmatched ( */
p_bracket(p);
break;
case '\\':
- REQUIRE(MORE(), REG_EESCAPE);
+ (void)REQUIRE(MORE(), REG_EESCAPE);
c = GETNEXT();
ordinary(p, c);
break;
case '{': /* okay as ordinary except if digit follows */
- REQUIRE(!MORE() || !isdigit(PEEK()), REG_BADRPT);
+ (void)REQUIRE(!MORE() || !isdigit(PEEK()), REG_BADRPT);
/* FALLTHROUGH */
default:
ordinary(p, c);
return; /* no repetition, we're done */
NEXT();
- REQUIRE(!wascaret, REG_BADRPT);
+ (void)REQUIRE(!wascaret, REG_BADRPT);
switch (c) {
case '*': /* implemented as +? */
/* this case does not require the (y|) trick, noKLUDGE */
if (EAT(',')) {
if (isdigit(PEEK())) {
count2 = p_count(p);
- REQUIRE(count <= count2, REG_BADBR);
+ (void)REQUIRE(count <= count2, REG_BADBR);
} else /* single number with comma */
- count2 = INFINITY;
+ count2 = (int)REINFINITY;
} else /* just a single number */
count2 = count;
repeat(p, pos, count, count2);
if (!EAT('}')) { /* error heuristics */
while (MORE() && PEEK() != '}')
NEXT();
- REQUIRE(MORE(), REG_EBRACE);
+ (void)REQUIRE(MORE(), REG_EBRACE);
SETERROR(REG_BADBR);
}
break;
/*
- p_str - string (no metacharacters) "parser"
- == static void p_str(register struct parse *p);
+ == static void p_str(struct parse *p);
*/
static void
-p_str(p)
-register struct parse *p;
+p_str(
+ struct parse * p)
{
- REQUIRE(MORE(), REG_EMPTY);
+ (void)REQUIRE(MORE(), REG_EMPTY);
while (MORE())
ordinary(p, GETNEXT());
}
/*
- p_bre - BRE parser top level, anchoring and concatenation
- == static void p_bre(register struct parse *p, register int end1, \
- == register int end2);
+ == static void p_bre(struct parse *p, register int end1, \
+ == int end2);
* Giving end1 as OUT essentially eliminates the end1/end2 check.
*
* This implementation is a bit of a kludge, in that a trailing $ is first
* The amount of lookahead needed to avoid this kludge is excessive.
*/
static void
-p_bre(p, end1, end2)
-register struct parse *p;
-register int end1; /* first terminating character */
-register int end2; /* second terminating character */
+p_bre(
+ struct parse * p,
+ int end1, /* first terminating character */
+ int end2) /* second terminating character */
{
- register sopno start = HERE();
- register int first = 1; /* first subexpression? */
- register int wasdollar = 0;
+ sopno start = HERE();
+ int first = 1; /* first subexpression? */
+ int wasdollar = 0;
if (EAT('^')) {
EMIT(OBOL, 0);
p->g->neol++;
}
- REQUIRE(HERE() != start, REG_EMPTY); /* require nonempty */
+ (void)REQUIRE(HERE() != start, REG_EMPTY); /* require nonempty */
}
/*
- p_simp_re - parse a simple RE, an atom possibly followed by a repetition
- == static int p_simp_re(register struct parse *p, int starordinary);
+ == static int p_simp_re(struct parse *p, int starordinary);
*/
static int /* was the simple RE an unbackslashed $? */
-p_simp_re(p, starordinary)
-register struct parse *p;
-int starordinary; /* is a leading * an ordinary character? */
+p_simp_re(
+ struct parse * p,
+ int starordinary)/* is a leading * an ordinary character? */
{
- register int c;
- register int count;
- register int count2;
- register sopno pos;
- register int i;
- register sopno subno;
+ int c;
+ int count;
+ int count2;
+ sopno pos;
+ int i;
+ sopno subno;
# define BACKSL (1<<CHAR_BIT)
pos = HERE(); /* repetion op, if any, covers from here */
assert(MORE()); /* caller should have ensured this */
c = GETNEXT();
if (c == '\\') {
- REQUIRE(MORE(), REG_EESCAPE);
+ (void)REQUIRE(MORE(), REG_EESCAPE);
c = BACKSL | (unsigned char)GETNEXT();
}
switch (c) {
assert(p->pend[subno] != 0);
}
EMIT(ORPAREN, subno);
- REQUIRE(EATTWO('\\', ')'), REG_EPAREN);
+ (void)REQUIRE(EATTWO('\\', ')'), REG_EPAREN);
break;
case BACKSL|')': /* should not get here -- must be user */
case BACKSL|'}':
i = (c&~BACKSL) - '0';
assert(i < NPAREN);
if (p->pend[i] != 0) {
- assert(i <= p->g->nsub);
+ assert(i <= (int)p->g->nsub);
EMIT(OBACK_, i);
assert(p->pbegin[i] != 0);
assert(OP(p->strip[p->pbegin[i]]) == OLPAREN);
assert(OP(p->strip[p->pend[i]]) == ORPAREN);
- (void) dupl(p, p->pbegin[i]+1, p->pend[i]);
+ (void)dupl(p, p->pbegin[i]+1, p->pend[i]);
EMIT(O_BACK, i);
} else
SETERROR(REG_ESUBREG);
p->g->backrefs = 1;
break;
case '*':
- REQUIRE(starordinary, REG_BADRPT);
+ (void)REQUIRE(starordinary, REG_BADRPT);
/* FALLTHROUGH */
default:
ordinary(p, c &~ BACKSL);
if (EAT(',')) {
if (MORE() && isdigit(PEEK())) {
count2 = p_count(p);
- REQUIRE(count <= count2, REG_BADBR);
+ (void)REQUIRE(count <= count2, REG_BADBR);
} else /* single number with comma */
- count2 = INFINITY;
+ count2 = REINFINITY;
} else /* just a single number */
count2 = count;
repeat(p, pos, count, count2);
if (!EATTWO('\\', '}')) { /* error heuristics */
while (MORE() && !SEETWO('\\', '}'))
NEXT();
- REQUIRE(MORE(), REG_EBRACE);
+ (void)REQUIRE(MORE(), REG_EBRACE);
SETERROR(REG_BADBR);
}
} else if (c == (unsigned char)'$') /* $ (but not \$) ends it */
/*
- p_count - parse a repetition count
- == static int p_count(register struct parse *p);
+ == static int p_count(struct parse *p);
*/
static int /* the value */
-p_count(p)
-register struct parse *p;
+p_count(
+ struct parse * p)
{
- register int count = 0;
- register int ndigits = 0;
+ int count = 0;
+ int ndigits = 0;
while (MORE() && isdigit(PEEK()) && count <= DUPMAX) {
count = count*10 + (GETNEXT() - '0');
ndigits++;
}
- REQUIRE(ndigits > 0 && count <= DUPMAX, REG_BADBR);
+ (void)REQUIRE(ndigits > 0 && count <= DUPMAX, REG_BADBR);
return(count);
}
/*
- p_bracket - parse a bracketed character list
- == static void p_bracket(register struct parse *p);
+ == static void p_bracket(struct parse *p);
*
* Note a significant property of this code: if the allocset() did SETERROR,
* no set operations are done.
*/
static void
-p_bracket(p)
-register struct parse *p;
+p_bracket(
+ struct parse * p)
{
- register cset *cs = allocset(p);
- register int invert = 0;
+ cset *cs = allocset(p);
+ int invert = 0;
/* Dept of Truly Sickening Special-Case Kludges */
if (p->next + 5 < p->end && strncmp(p->next, "[:<:]]", 6) == 0) {
p_b_term(p, cs);
if (EAT('-'))
CHadd(cs, '-');
- MUSTEAT(']', REG_EBRACK);
+ (void)MUSTEAT(']', REG_EBRACK);
if (p->error != 0) /* don't mess things up further */
return;
if (p->g->cflags®_ICASE) {
- register int i;
- register int ci;
+ int i;
+ int ci;
for (i = p->g->csetsize - 1; i >= 0; i--)
if (CHIN(cs, i) && isalpha(i)) {
mccase(p, cs);
}
if (invert) {
- register int i;
+ int i;
for (i = p->g->csetsize - 1; i >= 0; i--)
if (CHIN(cs, i))
/*
- p_b_term - parse one term of a bracketed character list
- == static void p_b_term(register struct parse *p, register cset *cs);
+ == static void p_b_term(struct parse *p, register cset *cs);
*/
static void
-p_b_term(p, cs)
-register struct parse *p;
-register cset *cs;
+p_b_term(
+ struct parse * p,
+ cset * cs)
{
- register char c;
- register char start, finish;
- register int i;
+ char c;
+ char start, finish;
+ int i;
/* classify what we've got */
switch ((MORE()) ? PEEK() : '\0') {
case '[':
- c = (MORE2()) ? PEEK2() : '\0';
+ c = (char)((MORE2()) ? PEEK2() : '\0');
break;
case '-':
SETERROR(REG_ERANGE);
return; /* NOTE RETURN */
- break;
+
default:
c = '\0';
break;
switch (c) {
case ':': /* character class */
NEXT2();
- REQUIRE(MORE(), REG_EBRACK);
+ (void)REQUIRE(MORE(), REG_EBRACK);
c = PEEK();
- REQUIRE(c != '-' && c != ']', REG_ECTYPE);
+ (void)REQUIRE(c != '-' && c != ']', REG_ECTYPE);
p_b_cclass(p, cs);
- REQUIRE(MORE(), REG_EBRACK);
- REQUIRE(EATTWO(':', ']'), REG_ECTYPE);
+ (void)REQUIRE(MORE(), REG_EBRACK);
+ (void)REQUIRE(EATTWO(':', ']'), REG_ECTYPE);
break;
case '=': /* equivalence class */
NEXT2();
- REQUIRE(MORE(), REG_EBRACK);
+ (void)REQUIRE(MORE(), REG_EBRACK);
c = PEEK();
- REQUIRE(c != '-' && c != ']', REG_ECOLLATE);
+ (void)REQUIRE(c != '-' && c != ']', REG_ECOLLATE);
p_b_eclass(p, cs);
- REQUIRE(MORE(), REG_EBRACK);
- REQUIRE(EATTWO('=', ']'), REG_ECOLLATE);
+ (void)REQUIRE(MORE(), REG_EBRACK);
+ (void)REQUIRE(EATTWO('=', ']'), REG_ECOLLATE);
break;
default: /* symbol, ordinary character, or range */
/* xxx revision needed for multichar stuff */
- start = p_b_symbol(p);
+ start = (char)p_b_symbol(p);
if (SEE('-') && MORE2() && PEEK2() != ']') {
/* range */
NEXT();
if (EAT('-'))
finish = '-';
else
- finish = p_b_symbol(p);
+ finish = (char)p_b_symbol(p);
} else
finish = start;
/* xxx what about signed chars here... */
- REQUIRE(start <= finish, REG_ERANGE);
+ (void)REQUIRE(start <= finish, REG_ERANGE);
for (i = start; i <= finish; i++)
CHadd(cs, i);
break;
/*
- p_b_cclass - parse a character-class name and deal with it
- == static void p_b_cclass(register struct parse *p, register cset *cs);
+ == static void p_b_cclass(struct parse *p, register cset *cs);
*/
static void
-p_b_cclass(p, cs)
-register struct parse *p;
-register cset *cs;
+p_b_cclass(
+ struct parse * p,
+ cset * cs)
{
- register char *sp = p->next;
- register struct cclass *cp;
- register size_t len;
- register char *u;
- register char c;
+ char *sp = p->next;
+ struct cclass *cp;
+ size_t len;
+ char *u;
+ char c;
while (MORE() && isalpha(PEEK()))
NEXT();
- len = p->next - sp;
+ len = (size_t)(p->next - sp);
for (cp = cclasses; cp->name != NULL; cp++)
if (strncmp(cp->name, sp, len) == 0 && cp->name[len] == '\0')
break;
/*
- p_b_eclass - parse an equivalence-class name and deal with it
- == static void p_b_eclass(register struct parse *p, register cset *cs);
+ == static void p_b_eclass(struct parse *p, register cset *cs);
*
* This implementation is incomplete. xxx
*/
static void
-p_b_eclass(p, cs)
-register struct parse *p;
-register cset *cs;
+p_b_eclass(
+ struct parse * p,
+ cset * cs)
{
- register char c;
+ char c;
- c = p_b_coll_elem(p, '=');
+ c = (char)p_b_coll_elem(p, '=');
CHadd(cs, c);
}
/*
- p_b_symbol - parse a character or [..]ed multicharacter collating symbol
- == static char p_b_symbol(register struct parse *p);
+ == static char p_b_symbol(struct parse *p);
*/
static char /* value of symbol */
-p_b_symbol(p)
-register struct parse *p;
+p_b_symbol(
+ struct parse * p)
{
- register char value;
+ char value;
- REQUIRE(MORE(), REG_EBRACK);
+ (void)REQUIRE(MORE(), REG_EBRACK);
if (!EATTWO('[', '.'))
return(GETNEXT());
/* collating symbol */
- value = p_b_coll_elem(p, '.');
- REQUIRE(EATTWO('.', ']'), REG_ECOLLATE);
+ value = (char)p_b_coll_elem(p, '.');
+ (void)REQUIRE(EATTWO('.', ']'), REG_ECOLLATE);
return(value);
}
/*
- p_b_coll_elem - parse a collating-element name and look it up
- == static char p_b_coll_elem(register struct parse *p, int endc);
+ == static char p_b_coll_elem(struct parse *p, int endc);
*/
static char /* value of collating element */
-p_b_coll_elem(p, endc)
-register struct parse *p;
-int endc; /* name ended by endc,']' */
+p_b_coll_elem(
+ struct parse * p,
+ int endc) /* name ended by endc,']' */
{
- register char *sp = p->next;
- register struct cname *cp;
- register int len;
+ char *sp = p->next;
+ struct cname *cp;
+ size_t len;
while (MORE() && !SEETWO(endc, ']'))
NEXT();
if (!MORE()) {
SETERROR(REG_EBRACK);
- return(0);
+ return((char)0);
}
- len = p->next - sp;
+ len = (size_t)(p->next - sp);
for (cp = cnames; cp->name != NULL; cp++)
if (strncmp(cp->name, sp, len) == 0 && cp->name[len] == '\0')
return(cp->code); /* known name */
if (len == 1)
return(*sp); /* single character */
SETERROR(REG_ECOLLATE); /* neither */
- return(0);
+ return((char)0);
}
/*
== static char othercase(int ch);
*/
static char /* if no counterpart, return ch */
-othercase(ch)
-int ch;
+othercase(
+ int ch)
{
assert(isalpha(ch));
if (isupper(ch))
/*
- bothcases - emit a dualcase version of a two-case character
- == static void bothcases(register struct parse *p, int ch);
+ == static void bothcases(struct parse *p, int ch);
*
* Boy, is this implementation ever a kludge...
*/
static void
-bothcases(p, ch)
-register struct parse *p;
-int ch;
+bothcases(
+ struct parse * p,
+ int ch)
{
- register char *oldnext = p->next;
- register char *oldend = p->end;
- char bracket[3];
+ char *oldnext = p->next;
+ char *oldend = p->end;
+ static char bracket[3];
assert(othercase(ch) != ch); /* p_bracket() would recurse */
p->next = bracket;
p->end = bracket+2;
- bracket[0] = ch;
+ bracket[0] = (char)ch;
bracket[1] = ']';
bracket[2] = '\0';
p_bracket(p);
/*
- ordinary - emit an ordinary character
- == static void ordinary(register struct parse *p, register int ch);
+ == static void ordinary(struct parse *p, register int ch);
*/
static void
-ordinary(p, ch)
-register struct parse *p;
-register int ch;
+ordinary(
+ struct parse * p,
+ int ch)
{
- register cat_t *cap = p->g->categories;
+ cat_t *cap = p->g->categories;
if ((p->g->cflags®_ICASE) && isalpha(ch) && othercase(ch) != ch)
bothcases(p, ch);
else {
EMIT(OCHAR, (unsigned char)ch);
if (cap[ch] == 0)
- cap[ch] = p->g->ncategories++;
+ cap[ch] = (cat_t)(p->g->ncategories++);
}
}
/*
- nonnewline - emit REG_NEWLINE version of OANY
- == static void nonnewline(register struct parse *p);
+ == static void nonnewline(struct parse *p);
*
* Boy, is this implementation ever a kludge...
*/
static void
-nonnewline(p)
-register struct parse *p;
+nonnewline(
+ struct parse * p)
{
- register char *oldnext = p->next;
- register char *oldend = p->end;
- char bracket[4];
+ char *oldnext = p->next;
+ char *oldend = p->end;
+ static char bracket[4];
p->next = bracket;
p->end = bracket+3;
/*
- repeat - generate code for a bounded repetition, recursively if needed
- == static void repeat(register struct parse *p, sopno start, int from, int to);
+ == static void repeat(struct parse *p, sopno start, int from, int to);
*/
static void
-repeat(p, start, from, to)
-register struct parse *p;
-sopno start; /* operand from here to end of strip */
-int from; /* repeated from this number */
-int to; /* to this number of times (maybe INFINITY) */
+repeat(
+ struct parse * p,
+ sopno start, /* operand from here to end of strip */
+ int from, /* repeated from this number */
+ int to) /* to this number of times (maybe REINFINITY) */
{
- register sopno finish = HERE();
+ sopno finish = HERE();
# define N 2
# define INF 3
# define REP(f, t) ((f)*8 + (t))
-# define MAP(n) (((n) <= 1) ? (n) : ((n) == INFINITY) ? INF : N)
- register sopno copy;
+# define MAP(n) (((n) <= 1) ? (n) : ((n) == REINFINITY) ? INF : N)
+ sopno copy;
if (p->error != 0) /* head off possible runaway recursion */
return;
/*
- seterr - set an error condition
- == static int seterr(register struct parse *p, int e);
+ == static int seterr(struct parse *p, int e);
*/
static int /* useless but makes type checking happy */
-seterr(p, e)
-register struct parse *p;
-int e;
+seterr(
+ struct parse * p,
+ int e)
{
if (p->error == 0) /* keep earliest error condition */
p->error = e;
/*
- allocset - allocate a set of characters for []
- == static cset *allocset(register struct parse *p);
+ == static cset *allocset(struct parse *p);
*/
static cset *
-allocset(p)
-register struct parse *p;
+allocset(
+ struct parse * p)
{
- register int no = p->g->ncsets++;
- register size_t nc;
- register size_t nbytes;
- register cset *cs;
- register size_t css = (size_t)p->g->csetsize;
- register int i;
+ int no = p->g->ncsets++;
+ int nc;
+ size_t nbytes;
+ cset *cs;
+ size_t css = (size_t)p->g->csetsize;
+ int i;
if (no >= p->ncsalloc) { /* need another column of space */
p->ncsalloc += CHAR_BIT;
assert(nc % CHAR_BIT == 0);
nbytes = nc / CHAR_BIT * css;
if (p->g->sets == NULL)
- p->g->sets = (cset *)malloc(nc * sizeof(cset));
+ p->g->sets = (cset *)malloc(nc * SIZEOF(cset));
else
p->g->sets = (cset *)realloc((char *)p->g->sets,
- nc * sizeof(cset));
+ (size_t)nc * SIZEOF(cset));
if (p->g->setbits == NULL)
p->g->setbits = (uch *)malloc(nbytes);
else {
p->g->setbits = (uch *)realloc((char *)p->g->setbits,
nbytes);
/* xxx this isn't right if setbits is now NULL */
- for (i = 0; i < no; i++)
- p->g->sets[i].ptr = p->g->setbits + css*(i/CHAR_BIT);
+ if (p->g->sets && p->g->setbits)
+ for (i = 0; i < no; i++)
+ p->g->sets[i].ptr = p->g->setbits + css*(i/CHAR_BIT);
}
if (p->g->sets != NULL && p->g->setbits != NULL)
(void) memset((char *)p->g->setbits + (nbytes - css),
assert(p->g->sets != NULL); /* xxx */
cs = &p->g->sets[no];
cs->ptr = p->g->setbits + css*((no)/CHAR_BIT);
- cs->mask = 1 << ((no) % CHAR_BIT);
+ cs->mask = (uch)(1 << ((no) % CHAR_BIT));
cs->hash = 0;
cs->smultis = 0;
cs->multis = NULL;
/*
- freeset - free a now-unused set
- == static void freeset(register struct parse *p, register cset *cs);
+ == static void freeset(struct parse *p, register cset *cs);
*/
static void
-freeset(p, cs)
-register struct parse *p;
-register cset *cs;
+freeset(
+ struct parse * p,
+ cset * cs)
{
- register int i;
- register cset *top = &p->g->sets[p->g->ncsets];
- register size_t css = (size_t)p->g->csetsize;
+ int i;
+ cset *top = &p->g->sets[p->g->ncsets];
+ int css = p->g->csetsize;
for (i = 0; i < css; i++)
CHsub(cs, i);
/*
- freezeset - final processing on a set of characters
- == static int freezeset(register struct parse *p, register cset *cs);
+ == static int freezeset(struct parse *p, register cset *cs);
*
* The main task here is merging identical sets. This is usually a waste
* of time (although the hash code minimizes the overhead), but can win
* the same value!
*/
static int /* set number */
-freezeset(p, cs)
-register struct parse *p;
-register cset *cs;
+freezeset(
+ struct parse * p,
+ cset * cs)
{
- register uch h = cs->hash;
- register int i;
- register cset *top = &p->g->sets[p->g->ncsets];
- register cset *cs2;
- register size_t css = (size_t)p->g->csetsize;
+ uch h = cs->hash;
+ int i;
+ cset *top = &p->g->sets[p->g->ncsets];
+ cset *cs2;
+ int css = p->g->csetsize;
/* look for an earlier one which is the same */
for (cs2 = &p->g->sets[0]; cs2 < top; cs2++)
/*
- firstch - return first character in a set (which must have at least one)
- == static int firstch(register struct parse *p, register cset *cs);
+ == static int firstch(struct parse *p, register cset *cs);
*/
static int /* character; there is no "none" value */
-firstch(p, cs)
-register struct parse *p;
-register cset *cs;
+firstch(
+ struct parse * p,
+ cset * cs)
{
- register int i;
- register size_t css = (size_t)p->g->csetsize;
+ int i;
+ int css = p->g->csetsize;
for (i = 0; i < css; i++)
if (CHIN(cs, i))
/*
- nch - number of characters in a set
- == static int nch(register struct parse *p, register cset *cs);
+ == static int nch(struct parse *p, register cset *cs);
*/
static int
-nch(p, cs)
-register struct parse *p;
-register cset *cs;
+nch(
+ struct parse * p,
+ cset * cs)
{
- register int i;
- register size_t css = (size_t)p->g->csetsize;
- register int n = 0;
+ int i;
+ int css = p->g->csetsize;
+ int n = 0;
for (i = 0; i < css; i++)
if (CHIN(cs, i))
/*
- mcadd - add a collating element to a cset
- == static void mcadd(register struct parse *p, register cset *cs, \
- == register char *cp);
+ == static void mcadd(struct parse *p, register cset *cs, \
+ == char *cp);
*/
static void
-mcadd(p, cs, cp)
-register struct parse *p;
-register cset *cs;
-register char *cp;
+mcadd(
+ struct parse * p,
+ cset * cs,
+ char * cp)
{
- register size_t oldend = cs->smultis;
+ size_t oldend = cs->smultis;
cs->smultis += strlen(cp) + 1;
if (cs->multis == NULL)
cs->multis = malloc(cs->smultis);
else
- cs->multis = realloc(cs->multis, cs->smultis);
+ cs->multis = realloc(cs->multis, (size_t)cs->smultis);
if (cs->multis == NULL) {
SETERROR(REG_ESPACE);
return;
}
- (void) strcpy(cs->multis + oldend - 1, cp);
+ (void) strncpy(cs->multis + oldend - 1, cp, cs->smultis - (oldend - 1));
cs->multis[cs->smultis - 1] = '\0';
}
-#if 0
-/*
- * - mcsub - subtract a collating element from a cset
- * == static void mcsub(register cset *cs, register char *cp);
- */
-static void
-mcsub(cs, cp)
-register cset *cs;
-register char *cp;
-{
- register char *fp = mcfind(cs, cp);
- register size_t len = strlen(fp);
-
- assert(fp != NULL);
- (void) memmove(fp, fp + len + 1,
- cs->smultis - (fp + len + 1 - cs->multis));
- cs->smultis -= len;
-
- if (cs->smultis == 0) {
- free(cs->multis);
- cs->multis = NULL;
- return;
- }
-
- cs->multis = realloc(cs->multis, cs->smultis);
- assert(cs->multis != NULL);
-}
-
-/*
- * - mcin - is a collating element in a cset?
- * == static int mcin(register cset *cs, register char *cp);
- */
-static int
-mcin(cs, cp)
-register cset *cs;
-register char *cp;
-{
- return(mcfind(cs, cp) != NULL);
-}
-
-/*
- * - mcfind - find a collating element in a cset
- * == static char *mcfind(register cset *cs, register char *cp);
- */
-static char *
-mcfind(cs, cp)
-register cset *cs;
-register char *cp;
-{
- register char *p;
-
- if (cs->multis == NULL)
- return(NULL);
- for (p = cs->multis; *p != '\0'; p += strlen(p) + 1)
- if (strcmp(cp, p) == 0)
- return(p);
- return(NULL);
-}
-#endif /* 0 */
/*
- mcinvert - invert the list of collating elements in a cset
- == static void mcinvert(register struct parse *p, register cset *cs);
+ == static void mcinvert(struct parse *p, register cset *cs);
*
* This would have to know the set of possibilities. Implementation
* is deferred.
*/
static void
-mcinvert(p, cs)
-register struct parse *p;
-register cset *cs;
+mcinvert(
+ struct parse * p,
+ cset * cs)
{
+ (void)p; /* Quiet unused parameter warning */
+ (void)cs; /* Quiet unused parameter warning */
assert(cs->multis == NULL); /* xxx */
}
/*
- mccase - add case counterparts of the list of collating elements in a cset
- == static void mccase(register struct parse *p, register cset *cs);
+ == static void mccase(struct parse *p, register cset *cs);
*
* This would have to know the set of possibilities. Implementation
* is deferred.
*/
static void
-mccase(p, cs)
-register struct parse *p;
-register cset *cs;
+mccase(
+ struct parse * p,
+ cset * cs)
{
+ (void)p; /* Quiet unused parameter warning */
+ (void)cs; /* Quiet unused parameter warning */
assert(cs->multis == NULL); /* xxx */
}
/*
- isinsets - is this character in any sets?
- == static int isinsets(register struct re_guts *g, int c);
+ == static int isinsets(struct re_guts *g, int c);
*/
static int /* predicate */
-isinsets(g, c)
-register struct re_guts *g;
-int c;
+isinsets(
+ struct re_guts * g,
+ int c)
{
- register uch *col;
- register int i;
- register int ncols = (g->ncsets+(CHAR_BIT-1)) / CHAR_BIT;
- register unsigned uc = (unsigned char)c;
+ uch *col;
+ int i;
+ int ncols = (g->ncsets+(CHAR_BIT-1)) / CHAR_BIT;
+ unsigned uc = (unsigned char)c;
for (i = 0, col = g->setbits; i < ncols; i++, col += g->csetsize)
if (col[uc] != 0)
/*
- samesets - are these two characters in exactly the same sets?
- == static int samesets(register struct re_guts *g, int c1, int c2);
+ == static int samesets(struct re_guts *g, int c1, int c2);
*/
static int /* predicate */
-samesets(g, c1, c2)
-register struct re_guts *g;
-int c1;
-int c2;
+samesets(
+ struct re_guts * g,
+ int c1,
+ int c2)
{
- register uch *col;
- register int i;
- register int ncols = (g->ncsets+(CHAR_BIT-1)) / CHAR_BIT;
- register unsigned uc1 = (unsigned char)c1;
- register unsigned uc2 = (unsigned char)c2;
+ uch *col;
+ int i;
+ int ncols = (g->ncsets+(CHAR_BIT-1)) / CHAR_BIT;
+ unsigned uc1 = (unsigned char)c1;
+ unsigned uc2 = (unsigned char)c2;
for (i = 0, col = g->setbits; i < ncols; i++, col += g->csetsize)
if (col[uc1] != col[uc2])
/*
- categorize - sort out character categories
- == static void categorize(struct parse *p, register struct re_guts *g);
+ == static void categorize(struct parse *p, struct re_guts *g);
*/
static void
-categorize(p, g)
-struct parse *p;
-register struct re_guts *g;
+categorize(
+ struct parse * p,
+ struct re_guts * g)
{
- register cat_t *cats = g->categories;
- register int c;
- register int c2;
- register cat_t cat;
+ cat_t *cats = g->categories;
+ int c;
+ int c2;
+ cat_t cat;
/* avoid making error situations worse */
if (p->error != 0)
for (c = CHAR_MIN; c <= CHAR_MAX; c++)
if (cats[c] == 0 && isinsets(g, c)) {
- cat = g->ncategories++;
+ cat = (cat_t)g->ncategories++;
cats[c] = cat;
for (c2 = c+1; c2 <= CHAR_MAX; c2++)
if (cats[c2] == 0 && samesets(g, c, c2))
/*
- dupl - emit a duplicate of a bunch of sops
- == static sopno dupl(register struct parse *p, sopno start, sopno finish);
+ == static sopno dupl(struct parse *p, sopno start, sopno finish);
*/
static sopno /* start of duplicate */
-dupl(p, start, finish)
-register struct parse *p;
-sopno start; /* from here */
-sopno finish; /* to this less one */
+dupl(
+ struct parse * p,
+ sopno start, /* from here */
+ sopno finish) /* to this less one */
{
- register sopno ret = HERE();
- register sopno len = finish - start;
+ sopno ret = HERE();
+ size_t len = (size_t)(finish - start);
assert(finish >= start);
if (len == 0)
return(ret);
enlarge(p, p->ssize + len); /* this many unexpected additions */
- assert(p->ssize >= p->slen + len);
+ assert(p->ssize >= (p->slen + len));
(void) memcpy((char *)(p->strip + p->slen),
- (char *)(p->strip + start), (size_t)len*sizeof(sop));
+ (char *)(p->strip + start), ((size_t)len * SIZEOF(sop)));
p->slen += len;
return(ret);
}
/*
- doemit - emit a strip operator
- == static void doemit(register struct parse *p, sop op, size_t opnd);
+ == static void doemit(struct parse *p, sop op, size_t opnd);
*
* It might seem better to implement this as a macro with a function as
* hard-case backup, but it's just too big and messy unless there are
* some changes to the data structures. Maybe later.
*/
static void
-doemit(p, op, opnd)
-register struct parse *p;
-sop op;
-size_t opnd;
+doemit(
+ struct parse * p,
+ sop op,
+ size_t opnd)
{
/* avoid making error situations worse */
if (p->error != 0)
return;
/* deal with oversize operands ("can't happen", more or less) */
- assert(opnd < 1<<OPSHIFT);
+ assert(opnd < (1 << OPSHIFT));
/* deal with undersized strip */
if (p->slen >= p->ssize)
/*
- doinsert - insert a sop into the strip
- == static void doinsert(register struct parse *p, sop op, size_t opnd, sopno pos);
+ == static void doinsert(struct parse *p, sop op, size_t opnd, sopno pos);
*/
static void
-doinsert(p, op, opnd, pos)
-register struct parse *p;
-sop op;
-size_t opnd;
-sopno pos;
+doinsert(
+ struct parse * p,
+ sop op,
+ size_t opnd,
+ sopno pos)
{
- register sopno sn;
- register sop s;
- register int i;
+ sopno sn;
+ sop s;
+ int i;
/* avoid making error situations worse */
if (p->error != 0)
}
memmove((char *)&p->strip[pos+1], (char *)&p->strip[pos],
- (HERE()-pos-1)*sizeof(sop));
+ (HERE() - (size_t)pos - 1) * SIZEOF(sop));
p->strip[pos] = s;
}
/*
- dofwd - complete a forward reference
- == static void dofwd(register struct parse *p, sopno pos, sop value);
+ == static void dofwd(struct parse *p, sopno pos, sop value);
*/
static void
-dofwd(p, pos, value)
-register struct parse *p;
-register sopno pos;
-sop value;
+dofwd(
+ struct parse * p,
+ sopno pos,
+ sop value)
{
/* avoid making error situations worse */
if (p->error != 0)
assert(value < 1<<OPSHIFT);
p->strip[pos] = OP(p->strip[pos]) | value;
-}
-
+}
/*
- enlarge - enlarge the strip
- == static void enlarge(register struct parse *p, sopno size);
+ == static void enlarge(struct parse *p, sopno size);
*/
static void
-enlarge(p, size)
-register struct parse *p;
-register sopno size;
+enlarge(
+ struct parse * p,
+ sopno size)
{
- register sop *sp;
+ sop *sp;
- if (p->ssize >= size)
+ assert(size <= (sopno)SSIZE_MAX);
+ if (p->ssize >= (size_t)size)
return;
- sp = (sop *)realloc(p->strip, size*sizeof(sop));
+ sp = (sop *)realloc(p->strip, (size_t)size * SIZEOF(sop));
if (sp == NULL) {
SETERROR(REG_ESPACE);
return;
}
p->strip = sp;
- p->ssize = size;
+ p->ssize = (size_t)size;
}
/*
- stripsnug - compact the strip
- == static void stripsnug(register struct parse *p, register struct re_guts *g);
+ == static void stripsnug(struct parse *p, register struct re_guts *g);
*/
static void
-stripsnug(p, g)
-register struct parse *p;
-register struct re_guts *g;
+stripsnug(
+ /*@keep@*/ struct parse * p,
+ /*@keep@*/ struct re_guts *g)
{
g->nstates = p->slen;
- g->strip = (sop *)realloc((char *)p->strip, p->slen * sizeof(sop));
+ g->strip = (sop *)realloc((char *)p->strip,
+ (size_t)p->slen * SIZEOF(sop));
if (g->strip == NULL) {
SETERROR(REG_ESPACE);
g->strip = p->strip;
/*
- findmust - fill in must and mlen with longest mandatory literal string
- == static void findmust(register struct parse *p, register struct re_guts *g);
+ == static void findmust(struct parse *p, register struct re_guts *g);
*
* This algorithm could do fancy things like analyzing the operands of |
* for common subsequences. Someday. This code is simple and finds most
* Note that must and mlen got initialized during setup.
*/
static void
-findmust(p, g)
-struct parse *p;
-register struct re_guts *g;
+findmust(
+ struct parse * p,
+ struct re_guts * g)
{
- register sop *scan;
+ sop *scan;
sop *start;
- register sop *newstart = NULL;
- register sopno newlen;
- register sop s;
- register char *cp;
- register sopno i;
+ sop *newstart = NULL;
+ sopno newlen;
+ sop s;
+ char *cp;
+ sopno i;
/* avoid making error situations worse */
if (p->error != 0)
cp = g->must;
scan = start;
for (i = g->mlen; i > 0; i--) {
- while (OP(s = *scan++) != OCHAR)
- continue;
+ s = *scan++;
+ while (OP(s) != OCHAR)
+ s = *scan++;
assert(cp < g->must + g->mlen);
*cp++ = (char)OPND(s);
}
/*
- pluscount - count + nesting
- == static sopno pluscount(register struct parse *p, register struct re_guts *g);
+ == static sopno pluscount(struct parse *p, register struct re_guts *g);
*/
static sopno /* nesting depth */
-pluscount(p, g)
-struct parse *p;
-register struct re_guts *g;
+pluscount(
+ struct parse * p,
+ struct re_guts * g)
{
- register sop *scan;
- register sop s;
- register sopno plusnest = 0;
- register sopno maxnest = 0;
+ sop *scan;
+ sop s;
+ sopno plusnest = 0;
+ sopno maxnest = 0;
if (p->error != 0)
return(0); /* there may not be an OEND */
-#include <sys/types.h>
-#include <stdio.h>
-#include <string.h>
-#include <ctype.h>
-#include <limits.h>
-#include <stdlib.h>
+#include "amanda.h"
#include <regex.h>
-
#include "utils.h"
#include "regerror.ih"
*/
/* ARGSUSED */
size_t
-regerror(errcode, preg, errbuf, errbuf_size)
-int errcode;
-const regex_t *preg;
-char *errbuf;
-size_t errbuf_size;
+regerror(
+ int errcode,
+ const regex_t *preg,
+ char * errbuf,
+ size_t errbuf_size)
{
register struct rerr *r;
register size_t len;
char convbuf[50];
if (errcode == REG_ATOI)
- s = regatoi(preg, convbuf, sizeof(convbuf));
+ s = regatoi(preg, convbuf, SIZEOF(convbuf));
else {
for (r = rerrs; r->code >= 0; r++)
if (r->code == target)
if (errcode®_ITOA) {
if (r->code >= 0) {
- strncpy(convbuf, r->name, sizeof(convbuf)-1);
- convbuf[sizeof(convbuf)-1] = '\0';
+ strncpy(convbuf, r->name, SIZEOF(convbuf)-1);
+ convbuf[SIZEOF(convbuf)-1] = '\0';
} else {
- snprintf(convbuf, sizeof(convbuf),
- "REG_0x%x", target);
+ snprintf(convbuf, SIZEOF(convbuf),
+ "REG_0x%x", (unsigned)target);
}
- assert(strlen(convbuf) < sizeof(convbuf));
+ assert(strlen(convbuf) < SIZEOF(convbuf));
s = convbuf;
} else
s = r->explain;
len = strlen(s) + 1;
if (errbuf_size > 0) {
- if (errbuf_size > len)
- (void) strcpy(errbuf, s);
- else {
- (void) strncpy(errbuf, s, errbuf_size-1);
- errbuf[errbuf_size-1] = '\0';
- }
+ (void) strncpy(errbuf, s, errbuf_size-1);
+ errbuf[errbuf_size-1] = '\0';
}
return(len);
/*
- regatoi - internal routine to implement REG_ATOI
- == static char *regatoi(const regex_t *preg, char *localbuf, int buflen);
+ == static char *regatoi(const regex_t *preg, char *localbuf, size_t buflen);
*/
static char *
-regatoi(preg, localbuf, buflen)
-const regex_t *preg;
-char *localbuf;
-int buflen;
+regatoi(
+ const regex_t * preg,
+ char * localbuf,
+ size_t buflen)
{
register struct rerr *r;
- for (r = rerrs; r->code >= 0; r++)
+ for (r = rerrs; r->code >= 0; r++) {
+ /*@ignore@*/
if (strcmp(r->name, preg->re_endp) == 0)
break;
+ /*@end@*/
+ }
if (r->code < 0)
return("0");
+#ifndef REGEX2_H
+#define REGEX2_H
+
/*
* First, the stuff that ends up in the outside-world include file
= typedef off_t regoff_t;
* immediately *preceding* "execution" of that operator.
*/
typedef unsigned long sop; /* strip operator */
-typedef long sopno;
+typedef unsigned long sopno;
#define OPRMASK 0xf8000000
#define OPDMASK 0x07ffffff
#define OPSHIFT ((unsigned)27)
char *multis; /* -> char[smulti] ab\0cd\0ef\0\0 */
} cset;
/* note that CHadd and CHsub are unsafe, and CHIN doesn't yield 0/1 */
-#define CHadd(cs, c) ((cs)->ptr[(uch)(c)] |= (cs)->mask, (cs)->hash += (c))
-#define CHsub(cs, c) ((cs)->ptr[(uch)(c)] &= ~(cs)->mask, (cs)->hash -= (c))
+#define CHadd(cs, c) do { \
+ (cs)->ptr[(uch)(c)] = (uch)((cs)->ptr[(uch)(c)] | (cs)->mask); \
+ (cs)->hash = (uch)((cs)->hash + (c)); \
+} while (0)
+
+#define CHsub(cs, c) do { \
+ (cs)->ptr[(uch)(c)] = (uch)((cs)->ptr[(uch)(c)] & ~(cs)->mask); \
+ (cs)->hash = (uch)((cs)->hash - (c)); \
+} while (0)
+
#define CHIN(cs, c) ((cs)->ptr[(uch)(c)] & (cs)->mask)
#define MCadd(p, cs, cp) mcadd(p, cs, cp) /* regcomp() internal fns */
#define MCsub(p, cs, cp) mcsub(p, cs, cp)
int ncategories; /* how many character categories */
cat_t *categories; /* ->catspace[-CHAR_MIN] */
char *must; /* match must contain this string */
- int mlen; /* length of must */
+ sopno mlen; /* length of must */
size_t nsub; /* copy of re_nsub */
int backrefs; /* does it use back references? */
sopno nplus; /* how deep does it nest +s? */
/* misc utilities */
#define OUT (CHAR_MAX+1) /* a non-character value */
#define ISWORD(c) (isalnum(c) || (c) == '_')
+
+#endif /* !REGEX2_H */
* macros that code uses. This lets the same code operate on two different
* representations for state sets.
*/
-#include <sys/types.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <limits.h>
-#include <ctype.h>
+#include "amanda.h"
#include <regex.h>
-
#include "utils.h"
#include "regex2.h"
-#ifndef NDEBUG
-static int nope = 0; /* for use in asserts; shuts lint up */
-#endif
+#undef ISSET
/* macros for manipulating states, small version */
-#define states long
+#define states unsigned long
#define states1 states /* for later use in regexec() decision */
-#define CLEAR(v) ((v) = 0)
+#define CLEAR(v) (((v) = 0), (void)(v))
#define SET0(v, n) ((v) &= ~(MAKE_UNSIGNED_LONG(1) << (n)))
#define SET1(v, n) ((v) |= (MAKE_UNSIGNED_LONG(1)) << (n))
#define ISSET(v, n) ((v) & ((MAKE_UNSIGNED_LONG(1)) << (n)))
-#define ASSIGN(d, s) ((d) = (s))
+#define ASSIGN(d, s) ((d) = (s), (void)(d))
#define EQ(a, b) ((a) == (b))
#define STATEVARS int dummy /* dummy version */
#define STATESETUP(m, n) /* nothing */
#define STATETEARDOWN(m) /* nothing */
#define SETUP(v) ((v) = 0)
-#define onestate long
-#define INIT(o, n) ((o) = (unsigned long)1 << (n))
+#define onestate sopno
+#define INIT(o, n) ((o) = (sopno)1 << (n))
#define INC(o) ((o) <<= 1)
#define ISSTATEIN(v, o) ((v) & (o))
/* some abbreviations; note that some of these know variable names! */
/* do "if I'm here, I can also be there" etc without branches */
#define FWD(dst, src, n) ((dst) |= ((unsigned long)(src)&(here)) << (n))
#define BACK(dst, src, n) ((dst) |= ((unsigned long)(src)&(here)) >> (n))
-#define ISSETBACK(v, n) ((v) & ((unsigned long)here >> (n)))
+#define ISSETBACK(v, n) ((v) & ((long)here >> (n)))
/* function names */
#define SNAMES /* engine.c looks after details */
/* macros for manipulating states, large version */
#define states char *
-#define CLEAR(v) memset(v, 0, m->g->nstates)
+#define CLEAR(v) memset((v), 0, (size_t)m->g->nstates)
#define SET0(v, n) ((v)[n] = 0)
#define SET1(v, n) ((v)[n] = 1)
#define ISSET(v, n) ((v)[n])
-#define ASSIGN(d, s) memcpy(d, s, m->g->nstates)
-#define EQ(a, b) (memcmp(a, b, m->g->nstates) == 0)
+#define ASSIGN(d, s) memcpy((d), (s), (size_t)m->g->nstates)
+#define EQ(a, b) (memcmp((a), (b), (size_t)m->g->nstates) == 0)
#define STATEVARS int vn; char *space
-#define STATESETUP(m, nv) { (m)->space = malloc((nv)*(m)->g->nstates); \
- if ((m)->space == NULL) return(REG_ESPACE); \
- (m)->vn = 0; }
+#define STATESETUP(m, nv) do { \
+ (m)->space = malloc((size_t)(nv)*(size_t)(m)->g->nstates); \
+ if ((m)->space == NULL) \
+ return(REG_ESPACE); \
+ (m)->vn = 0; \
+} while (0);
+
#define STATETEARDOWN(m) { free((m)->space); }
#define SETUP(v) ((v) = &m->space[m->vn++ * m->g->nstates])
#define onestate int
/*
- regexec - interface for matching
- = extern int regexec(const regex_t *, const char *, size_t, \
- = regmatch_t [], int);
+ = int regexec(regex_t *preg, const char *string, size_t nmatch, regmatch_t pmatch[], int eflags);
= #define REG_NOTBOL 00001
= #define REG_NOTEOL 00002
= #define REG_STARTEND 00004
* have been prototyped.
*/
int /* 0 success, REG_NOMATCH failure */
-regexec(preg, string, nmatch, pmatch, eflags)
-const regex_t *preg;
-const char *string;
-size_t nmatch;
-regmatch_t pmatch[];
-int eflags;
+regexec(
+ regex_t *preg,
+ const char *string,
+ size_t nmatch,
+ regmatch_t pmatch[],
+ int eflags)
{
+ /*@ignore@*/
register struct re_guts *g = preg->re_g;
#ifdef REDEBUG
# define GOODFLAGS(f) (f)
if (preg->re_magic != MAGIC1 || g->magic != MAGIC2)
return(REG_BADPAT);
+ /*@end@*/
assert(!(g->iflags&BAD));
if (g->iflags&BAD) /* backstop for no-debug case */
return(REG_BADPAT);
eflags = GOODFLAGS(eflags);
- if (g->nstates <= CHAR_BIT*sizeof(states1) && !(eflags®_LARGE))
+ if ((g->nstates <= ((sopno)(CHAR_BIT * SIZEOF(states1))) &&
+ !(eflags & REG_LARGE)))
return(smatcher(g, string, nmatch, pmatch, eflags));
- else
- return(lmatcher(g, string, nmatch, pmatch, eflags));
+ return(lmatcher(g, string, nmatch, pmatch, eflags));
}
-#include <sys/types.h>
-#include <stdio.h>
-#include <stdlib.h>
+#include "amanda.h"
#include <regex.h>
-
#include "utils.h"
#include "regex2.h"
= extern void regfree(regex_t *);
*/
void
-regfree(preg)
-regex_t *preg;
+regfree(
+ regex_t *preg)
{
register struct re_guts *g;
+ /*@ignore@*/
if (preg->re_magic != MAGIC1) /* oops */
return; /* nice to complain, but hard */
if (g == NULL || g->magic != MAGIC2) /* oops again */
return;
preg->re_magic = 0; /* mark it invalid */
+ /*@end@*/
g->magic = 0; /* mark it invalid */
if (g->strip != NULL)
+#include <amanda.h>
#include <stdio.h>
#include <string.h>
= int split(char *string, char *fields[], int nfields, char *sep);
*/
int /* number of fields, including overflow */
-split(string, fields, nfields, sep)
-char *string;
-char *fields[]; /* list is not NULL-terminated */
-int nfields; /* number of entries available in fields[] */
-char *sep; /* "" white, "c" single char, "ab" [ab]+ */
+split(
+ char * string,
+ char * fields[], /* list is not NULL-terminated */
+ int nfields, /* number of entries available in fields[] */
+ char * sep) /* "" white, "c" single char, "ab" [ab]+ */
{
register char *p = string;
register char c; /* latest character */
* pgm str sep n splits str by sep n times
*/
int
-main(argc, argv)
-int argc;
-char *argv[];
+main(
+ int argc,
+ char * argv[])
{
char buf[512];
register int n;
if (argc > 4)
for (n = atoi(argv[3]); n > 0; n--) {
- strncpy(buf, argv[1], sizeof(buf)-1);
- buf[sizeof(buf)-1] = '\0';
+ strncpy(buf, argv[1], SIZEOF(buf)-1);
+ buf[SIZEOF(buf)-1] = '\0';
}
else if (argc > 3)
for (n = atoi(argv[3]); n > 0; n--) {
- strncpy(buf, argv[1], sizeof(buf)-1);
- buf[sizeof(buf)-1] = '\0';
+ strncpy(buf, argv[1], SIZEOF(buf)-1);
+ buf[SIZEOF(buf)-1] = '\0';
(void) split(buf, fields, MNF, argv[2]);
}
else if (argc > 2)
dosplit(argv[1], argv[2]);
else if (argc > 1)
- while (fgets(buf, sizeof(buf), stdin) != NULL) {
+ while (fgets(buf, (int)sizeof(buf), stdin) != NULL) {
buf[strlen(buf)-1] = '\0'; /* stomp newline */
dosplit(buf, argv[1]);
}
exit(0);
}
-dosplit(string, seps)
-char *string;
-char *seps;
+int
+dosplit(
+ char * string,
+ char * seps)
{
# define NF 5
char *fields[NF];
print(nf, NF, fields);
}
-print(nf, nfp, fields)
-int nf;
-int nfp;
-char *fields[];
+int
+print(
+ int nf,
+ int nfp,
+ char *fields[])
{
register int fn;
register int bound;
NULL, NULL, 0, { NULL },
};
-regress()
+int
+regress(void)
{
char buf[512];
register int n;
register char *f;
for (n = 0; tests[n].str != NULL; n++) {
- strncpy(buf, tests[n].str, sizeof(buf)-1);
- buf[sizeof(buf)-1] = '\0';
+ strncpy(buf, tests[n].str, SIZEOF(buf)-1);
+ buf[SIZEOF(buf)-1] = '\0';
fields[RNF] = NULL;
nf = split(buf, fields, RNF, tests[n].seps);
printit = 0;
+#ifndef REGEX_UTILS_H
+#define REGEX_UTILS_H
+
/* utility definitions */
#ifdef _POSIX2_RE_DUP_MAX
#define DUPMAX _POSIX2_RE_DUP_MAX
#else
#define DUPMAX 255
#endif
-#define INFINITY (DUPMAX + 1)
+#define REINFINITY (DUPMAX + 1)
#define NC (CHAR_MAX - CHAR_MIN + 1)
typedef unsigned char uch;
#endif
#endif
#include <assert.h>
-
/* for old systems with bcopy() but no memmove() */
#ifdef USEBCOPY
#define memmove(d, s, c) bcopy(s, d, c)
#endif
+
+#endif /* !REGEX_UTILS_H */
INCLUDES = -I$(top_builddir)/common-src \
-I$(top_srcdir)/common-src \
-I$(top_srcdir)/tape-src \
- -I$(top_srcdir)/server-src
+ -I$(top_srcdir)/server-src \
+ -I$(top_srcdir)/amandad-src
+
+LINT=@AMLINT@
+LINTFLAGS=@AMLINTFLAGS@
lib_LTLIBRARIES = librestore.la
LIB_EXTENSION = la
# routines, and second to pick up any references in the other libraries.
###
-LDADD = librestore.$(LIB_EXTENSION) \
- ../common-src/libamanda.$(LIB_EXTENSION)
+LDADD = librestore.$(LIB_EXTENSION) \
+ ../common-src/libamanda.$(LIB_EXTENSION) \
+ $(READLINE_LIBS)
+amidxtaped_LDADD = $(LDADD) ../amandad-src/libamandad.$(LIB_EXTENSION)
amidxtaped_SOURCES = amidxtaped.c
amfetchdump_SOURCES = amfetchdump.c
echo chgrp $(SETUID_GROUP) $$pa; \
chgrp $(SETUID_GROUP) $$pa; \
done
+
+lint:
+ @ for p in $(libexec_PROGRAMS) $(sbin_PROGRAMS); do \
+ f="$$p.c $(librestore_la_SOURCES)"; \
+ (cd ../common-src; make listlibsrc); \
+ f="$$f "`cat ../common-src/listlibsrc.output`; \
+ (cd ../server-src; make listlibsrc); \
+ f="$$f "`cat ../server-src/listlibsrc.output`; \
+ (cd ../tape-src; make listlibsrc); \
+ f="$$f "`cat ../tape-src/listlibsrc.output`; \
+ echo $(LINT) $$f; \
+ $(LINT) $(LINTFLAGS) $(CPPFLAGS) $(DEFS) -I. -I../config \
+ $(INCLUDES) $$f; \
+ if [ $$? -ne 0 ]; then \
+ exit 1; \
+ fi; \
+ done; \
+ exit 0
+
am_amfetchdump_OBJECTS = amfetchdump.$(OBJEXT)
amfetchdump_OBJECTS = $(am_amfetchdump_OBJECTS)
amfetchdump_LDADD = $(LDADD)
+am__DEPENDENCIES_1 =
amfetchdump_DEPENDENCIES = librestore.$(LIB_EXTENSION) \
- ../common-src/libamanda.$(LIB_EXTENSION)
+ ../common-src/libamanda.$(LIB_EXTENSION) $(am__DEPENDENCIES_1)
am_amidxtaped_OBJECTS = amidxtaped.$(OBJEXT)
amidxtaped_OBJECTS = $(am_amidxtaped_OBJECTS)
-amidxtaped_LDADD = $(LDADD)
-amidxtaped_DEPENDENCIES = librestore.$(LIB_EXTENSION) \
- ../common-src/libamanda.$(LIB_EXTENSION)
+am__DEPENDENCIES_2 = librestore.$(LIB_EXTENSION) \
+ ../common-src/libamanda.$(LIB_EXTENSION) $(am__DEPENDENCIES_1)
+amidxtaped_DEPENDENCIES = $(am__DEPENDENCIES_2) \
+ ../amandad-src/libamandad.$(LIB_EXTENSION)
amrestore_SOURCES = amrestore.c
amrestore_OBJECTS = amrestore.$(OBJEXT)
amrestore_LDADD = $(LDADD)
amrestore_DEPENDENCIES = librestore.$(LIB_EXTENSION) \
- ../common-src/libamanda.$(LIB_EXTENSION)
+ ../common-src/libamanda.$(LIB_EXTENSION) $(am__DEPENDENCIES_1)
DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)/config
depcomp = $(SHELL) $(top_srcdir)/config/depcomp
am__depfiles_maybe = depfiles
AMANDA_TMPDIR = @AMANDA_TMPDIR@
AMDEP_FALSE = @AMDEP_FALSE@
AMDEP_TRUE = @AMDEP_TRUE@
+AMLINT = @AMLINT@
+AMLINTFLAGS = @AMLINTFLAGS@
AMPLOT_CAT_COMPRESS = @AMPLOT_CAT_COMPRESS@
AMPLOT_CAT_GZIP = @AMPLOT_CAT_GZIP@
AMPLOT_CAT_PACK = @AMPLOT_CAT_PACK@
AMPLOT_COMPRESS = @AMPLOT_COMPRESS@
AMTAR = @AMTAR@
+AM_CFLAGS = @AM_CFLAGS@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AWK = @AWK@
AWK_VAR_ASSIGNMENT_OPT = @AWK_VAR_ASSIGNMENT_OPT@
BINARY_OWNER = @BINARY_OWNER@
+BUILD_MAN_PAGES_FALSE = @BUILD_MAN_PAGES_FALSE@
+BUILD_MAN_PAGES_TRUE = @BUILD_MAN_PAGES_TRUE@
CAT = @CAT@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
INCLUDES = -I$(top_builddir)/common-src \
-I$(top_srcdir)/common-src \
-I$(top_srcdir)/tape-src \
- -I$(top_srcdir)/server-src
+ -I$(top_srcdir)/server-src \
+ -I$(top_srcdir)/amandad-src
+LINT = @AMLINT@
+LINTFLAGS = @AMLINTFLAGS@
lib_LTLIBRARIES = librestore.la
LIB_EXTENSION = la
# need to list libamanda twice here, first to override the system library
# routines, and second to pick up any references in the other libraries.
###
-LDADD = librestore.$(LIB_EXTENSION) \
- ../common-src/libamanda.$(LIB_EXTENSION)
+LDADD = librestore.$(LIB_EXTENSION) \
+ ../common-src/libamanda.$(LIB_EXTENSION) \
+ $(READLINE_LIBS)
+amidxtaped_LDADD = $(LDADD) ../amandad-src/libamandad.$(LIB_EXTENSION)
amidxtaped_SOURCES = amidxtaped.c
amfetchdump_SOURCES = amfetchdump.c
librestore_la_SOURCES = restore.c
echo chgrp $(SETUID_GROUP) $$pa; \
chgrp $(SETUID_GROUP) $$pa; \
done
+
+lint:
+ @ for p in $(libexec_PROGRAMS) $(sbin_PROGRAMS); do \
+ f="$$p.c $(librestore_la_SOURCES)"; \
+ (cd ../common-src; make listlibsrc); \
+ f="$$f "`cat ../common-src/listlibsrc.output`; \
+ (cd ../server-src; make listlibsrc); \
+ f="$$f "`cat ../server-src/listlibsrc.output`; \
+ (cd ../tape-src; make listlibsrc); \
+ f="$$f "`cat ../tape-src/listlibsrc.output`; \
+ echo $(LINT) $$f; \
+ $(LINT) $(LINTFLAGS) $(CPPFLAGS) $(DEFS) -I. -I../config \
+ $(INCLUDES) $$f; \
+ if [ $$? -ne 0 ]; then \
+ exit 1; \
+ fi; \
+ done; \
+ exit 0
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
* file named AUTHORS, in the root directory of this distribution.
*/
/*
- * $Id: amfetchdump.c,v 1.7 2006/03/14 13:12:01 martinea Exp $
+ * $Id: amfetchdump.c,v 1.16 2006/08/24 01:57:15 paddy_s Exp $
*
* retrieves specific dumps from a set of amanda tapes
*/
#define CREAT_MODE 0640
-extern char *rst_conf_logdir;
extern char *rst_conf_logfile;
extern char *config_dir;
int get_lock = 0;
/* local functions */
-void errexit P((void));
-void handle_sigpipe P((int sig));
-tapelist_t *list_needed_tapes P((match_list_t *match_list));
-void usage P((void));
-int main P((int argc, char **argv));
+void errexit(void);
+tapelist_t *list_needed_tapes(match_list_t *match_list);
+void usage(void);
+int main(int argc, char **argv);
/* exit routine */
-static int parent_pid = -1;
-static void cleanup P((void));
+static pid_t parent_pid = -1;
+static void cleanup(void);
+
-void errexit()
/*
* Do exit(2) after an error, rather than exit(1).
*/
+
+void
+errexit(void)
{
exit(2);
}
-void usage()
/*
* Print usage message and terminate.
*/
+
+void
+usage(void)
{
- fprintf(stderr, "Usage: amfetchdump [options] config hostname [diskname [datestamp [level [hostname [diskname [datestamp [level ... ]]]]]]]\n\n");
+ fprintf(stderr, "Usage: amfetchdump [options] config hostname [diskname [datestamp [level [hostname [diskname [datestamp [level ... ]]]]]]] [-o configoption]*\n\n");
fprintf(stderr, "Goes and grabs a dump from tape, moving tapes around and assembling parts as\n");
fprintf(stderr, "necessary. Files are restored to the current directory, unless otherwise\nspecified.\n\n");
fprintf(stderr, " -p Pipe exactly *one* complete dumpfile to stdout, instead of to disk.\n");
- fprintf(stderr, " -o <output dir> Restore files to this directory.\n");
+ fprintf(stderr, " -O <output dir> Restore files to this directory.\n");
fprintf(stderr, " -d <device> Force restoration from a particular tape device.\n");
fprintf(stderr, " -c Compress output, fastest method available.\n");
fprintf(stderr, " -C Compress output, best filesize method available.\n");
* files we want from said tapes while we're at it (the whole find_result
* should do fine)
*/
-tapelist_t *list_needed_tapes(match_list)
-match_list_t *match_list;
+tapelist_t *
+list_needed_tapes(
+ match_list_t * match_list)
{
needed_tape_t *needed_tapes = NULL, *curtape = NULL;
disklist_t diskqp;
}
if(read_diskfile(conf_diskfile, &diskqp) != 0) {
error("could not load disklist \"%s\"", conf_diskfile);
+ /*NOTREACHED*/
}
if (*conf_tapelist == '/') {
conf_tapelist = stralloc(conf_tapelist);
}
if(read_tapelist(conf_tapelist)) {
error("could not load tapelist \"%s\"", conf_tapelist);
+ /*NOTREACHED*/
}
amfree(conf_diskfile);
amfree(conf_tapelist);
/* Grab a find_output_t of all logged dumps */
- alldumps = find_dump(1, &diskqp);
+ alldumps = find_dump(1, &diskqp);
free_disklist(&diskqp);
if(alldumps == NULL){
fprintf(stderr, "No dump records found\n");
exit(1);
}
-
+
/* Compare all known dumps to our match list, note what we'll need */
for(me = match_list; me; me = me->next) {
find_result_t *curmatch = NULL;
for(curmatch = matches; curmatch; curmatch = curmatch->next){
int havetape = 0;
if(strcmp("OK", curmatch->status)){
- fprintf(stderr,"Dump %d %s %s %d had status '%s', skipping\n",
- curmatch->datestamp, curmatch->hostname,
+ fprintf(stderr,"Dump %s %s %s %d had status '%s', skipping\n",
+ curmatch->timestamp, curmatch->hostname,
curmatch->diskname, curmatch->level,
curmatch->status);
continue;
for(curtape = needed_tapes; curtape; curtape = curtape->next) {
if(!strcmp(curtape->label, curmatch->label)){
find_result_t *rsttemp = NULL;
- find_result_t *rstfile = alloc(sizeof(find_result_t));
+ find_result_t *rstfile = alloc(SIZEOF(find_result_t));
int keep = 1;
- memcpy(rstfile, curmatch, sizeof(find_result_t));
+ memcpy(rstfile, curmatch, SIZEOF(find_result_t));
havetape = 1;
rsttemp;
rsttemp=rsttemp->next){
if(rstfile->filenum == rsttemp->filenum){
- fprintf(stderr, "Seeing multiple entries for tape %s file %d, using most recent\n", curtape->label, rstfile->filenum);
+ fprintf(stderr, "Seeing multiple entries for tape "
+ "%s file " OFF_T_FMT ", using most recent\n",
+ curtape->label,
+ (OFF_T_FMT_TYPE)rstfile->filenum);
keep = 0;
}
}
}
}
if(!havetape){
- find_result_t *rstfile = alloc(sizeof(find_result_t));
+ find_result_t *rstfile = alloc(SIZEOF(find_result_t));
needed_tape_t *newtape =
- alloc(sizeof(needed_tape_t));
- memcpy(rstfile, curmatch, sizeof(find_result_t));
+ alloc(SIZEOF(needed_tape_t));
+ memcpy(rstfile, curmatch, SIZEOF(find_result_t));
rstfile->next = NULL;
newtape->files = rstfile;
if(curmatch->filenum < 1) newtape->isafile = 1;
if(numtapes == 0){
fprintf(stderr, "No matching dumps found\n");
exit(1);
+ /* NOTREACHED */
}
/* stick that list in a structure that librestore will understand */
return(tapes);
}
-int main(argc, argv)
-int argc;
-char **argv;
+
/*
* Parses command line, then loops through all files on tape, restoring
* files that match the command line criteria.
*/
+
+int
+main(
+ int argc,
+ char ** argv)
{
extern int optind;
int opt;
int arg_state;
rst_flags_t *rst_flags;
struct passwd *pwent;
+ int new_argc, my_argc;
+ char **new_argv, **my_argv;
- for(fd = 3; fd < FD_SETSIZE; fd++) {
+ for(fd = 3; fd < (int)FD_SETSIZE; fd++) {
/*
* Make sure nobody spoofs us with a lot of extra open files
* that would cause an open we do to get a very high file
set_pname("amfetchdump");
+ dbopen(DBG_SUBDIR_SERVER);
+
#ifdef FORCE_USERID
/* we'd rather not run as root */
if(geteuid() == 0) {
if(client_uid == (uid_t) -1) {
error("error [cannot find user %s in passwd file]\n", CLIENT_LOGIN);
+ /*NOTREACHED*/
}
+ /*@ignore@*/
initgroups(CLIENT_LOGIN, client_gid);
+ /*@end@*/
setgid(client_gid);
setuid(client_uid);
}
onerror(errexit);
- if(argc <= 1) usage();
+ parse_server_conf(argc, argv, &new_argc, &new_argv);
+ my_argc = new_argc;
+ my_argv = new_argv;
+
+ if(my_argc <= 1) {
+ usage();
+ /*NOTREACHED*/
+ }
rst_flags = new_rst_flags();
rst_flags->wait_tape_prompt = 1;
-
+
/* handle options */
- while( (opt = getopt(argc, argv, "alht:scCpb:nwi:d:o:")) != -1) {
+ while( (opt = getopt(my_argc, my_argv, "alht:scCpb:nwi:d:O:")) != -1) {
switch(opt) {
- case 'b': rst_flags->compress = 1; break;
- rst_flags->blocksize = strtol(optarg, &e, 10);
+ case 'b':
+ rst_flags->blocksize = (ssize_t)strtol(optarg, &e, 10);
if(*e == 'k' || *e == 'K') {
rst_flags->blocksize *= 1024;
} else if(*e == 'm' || *e == 'M') {
rst_flags->blocksize *= 1024 * 1024;
} else if(*e != '\0') {
error("invalid blocksize value \"%s\"", optarg);
+ /*NOTREACHED*/
}
if(rst_flags->blocksize < DISK_BLOCK_BYTES) {
error("minimum block size is %dk", DISK_BLOCK_BYTES / 1024);
+ /*NOTREACHED*/
}
break;
case 'c': rst_flags->compress = 1; break;
- case 'o': rst_flags->restore_dir = stralloc(optarg) ; break;
+ case 'O': rst_flags->restore_dir = stralloc(optarg) ; break;
case 'd': rst_flags->alt_tapedev = stralloc(optarg) ; break;
case 'C':
rst_flags->compress = 1;
rst_flags->comp_type = COMPRESS_BEST_OPT;
break;
case 'p': rst_flags->pipe_to_fd = fileno(stdout); break;
- case 's': rst_flags->fsf = 0; break;
+ case 's': rst_flags->fsf = (off_t)0; break;
case 'l': rst_flags->leave_comp = 1; break;
case 'i': rst_flags->inventory_log = stralloc(optarg); break;
case 'n': rst_flags->inline_assemble = 0; break;
case 'h': rst_flags->headers = 1; break;
default:
usage();
+ /*NOTREACHED*/
}
}
rst_flags->leave_comp = 1;
if(rst_flags->compress){
error("Cannot force compression when doing inventory/search");
+ /*NOTREACHED*/
}
fprintf(stderr, "Doing inventory/search, dumps will not be uncompressed or assembled on-the-fly.\n");
}
}
/* make sure our options all make sense otherwise */
- if(check_rst_flags(rst_flags) == -1) usage();
+ if(check_rst_flags(rst_flags) == -1) {
+ usage();
+ /*NOTREACHED*/
+ }
- config_name = argv[optind++];
+ config_name = my_argv[optind++];
config_dir = vstralloc(CONFIG_DIR, "/", config_name, "/", NULL);
conffile = stralloc2(config_dir, CONFFILE_NAME);
if (read_conffile(conffile)) {
error("errors processing config file \"%s\"", conffile);
+ /*NOTREACHED*/
}
amfree(conffile);
+ dbrename(config_name, DBG_SUBDIR_SERVER);
- if((argc - optind) < 1 && !rst_flags->inventory_log){
+ if((my_argc - optind) < 1 && !rst_flags->inventory_log){
fprintf(stderr, "Not enough arguments\n\n");
usage();
+ /*NOTREACHED*/
}
#define ARG_GET_HOST 0
#define ARG_GET_LEVL 3
arg_state = ARG_GET_HOST;
- while(optind < argc) {
+ while(optind < my_argc) {
switch(arg_state) {
case ARG_GET_HOST:
/*
* New host/disk/date/level set, so allocate a match_list.
*/
- me = alloc(sizeof(*me));
- me->hostname = argv[optind++];
+ me = alloc(SIZEOF(*me));
+ me->hostname = my_argv[optind++];
me->diskname = "";
me->datestamp = "";
me->level = "";
fprintf(stderr, "%s: bad hostname regex \"%s\": %s\n",
get_pname(), me->hostname, errstr);
usage();
+ /*NOTREACHED*/
}
arg_state = ARG_GET_DISK;
break;
case ARG_GET_DISK:
- me->diskname = argv[optind++];
+ me->diskname = my_argv[optind++];
if(me->diskname[0] != '\0'
&& (errstr=validate_regexp(me->diskname)) != NULL) {
fprintf(stderr, "%s: bad diskname regex \"%s\": %s\n",
get_pname(), me->diskname, errstr);
usage();
+ /*NOTREACHED*/
}
arg_state = ARG_GET_DATE;
break;
case ARG_GET_DATE:
- me->datestamp = argv[optind++];
+ me->datestamp = my_argv[optind++];
if(me->datestamp[0] != '\0'
&& (errstr=validate_regexp(me->datestamp)) != NULL) {
fprintf(stderr, "%s: bad datestamp regex \"%s\": %s\n",
get_pname(), me->datestamp, errstr);
usage();
+ /*NOTREACHED*/
}
arg_state = ARG_GET_LEVL;
break;
case ARG_GET_LEVL:
- me->level = argv[optind++];
+ me->level = my_argv[optind++];
if(me->level[0] != '\0'
&& (errstr=validate_regexp(me->level)) != NULL) {
fprintf(stderr, "%s: bad level regex \"%s\": %s\n",
get_pname(), me->level, errstr);
usage();
+ /*NOTREACHED*/
}
}
}
/* XXX I don't think this can happen */
if(match_list == NULL && !rst_flags->inventory_log) {
- match_list = alloc(sizeof(*match_list));
+ match_list = alloc(SIZEOF(*match_list));
match_list->hostname = "";
match_list->diskname = "";
match_list->datestamp = "";
/* Decide what tapes we'll need */
needed_tapes = list_needed_tapes(match_list);
-
+
parent_pid = getpid();
atexit(cleanup);
get_lock = lock_logfile(); /* config is loaded, should be ok here */
+ if(get_lock == 0) {
+ error("%s exists: amdump or amflush is already running, or you must run amcleanup", rst_conf_logfile);
+ }
search_tapes(NULL, 1, needed_tapes, match_list, rst_flags, NULL);
cleanup();
else flush_open_outputs(0, NULL);
free_rst_flags(rst_flags);
+ free_new_argv(new_argc, new_argv);
return(0);
}
if(get_lock) unlink(rst_conf_logfile);
}
}
-
* Authors: the Amanda Development Team. Its members are listed in a
* file named AUTHORS, in the root directory of this distribution.
*/
-/* $Id: amidxtaped.c,v 1.58 2006/03/14 13:12:01 martinea Exp $
+/* $Id: amidxtaped.c,v 1.73 2006/07/25 19:06:46 martinea Exp $
*
* This daemon extracts a dump image off a tape for amrecover and
* returns it over the network. It basically, reads a number of
#include "logfile.h"
#include "amfeatures.h"
#include "stream.h"
+#include "amandad.h"
#define TIMEOUT 30
static char *pgm = "amidxtaped"; /* in case argv[0] is not set */
-extern char *rst_conf_logdir;
extern char *rst_conf_logfile;
extern char *config_dir;
static int get_lock = 0;
+static int from_amandad;
static am_feature_t *our_features = NULL;
static am_feature_t *their_features = NULL;
+static g_option_t *g_options = NULL;
+static int ctlfdin, ctlfdout, datafdout;
+static char *amandad_auth = NULL;
-static char *get_client_line P((void));
-static char *get_client_line_fd P((int));
-static void check_security_buffer P((char*));
+static char *get_client_line(void);
+static void check_security_buffer(char *);
+static char *get_client_line_fd(int);
/* exit routine */
-static int parent_pid = -1;
-static void cleanup P((void));
+static pid_t parent_pid = -1;
+static void cleanup(void);
+
+int main(int argc, char **argv);
/* get a line from client - line terminated by \r\n */
static char *
-get_client_line()
+get_client_line(void)
{
static char *line = NULL;
char *part = NULL;
- int len;
+ size_t len;
amfree(line);
while(1) {
amfree(part);
dbclose();
exit(1);
- /* NOTREACHED */
+ /*NOTREACHED*/
}
if(line) {
strappend(line, part);
/* get a line from client - line terminated by \r\n */
static char *
-get_client_line_fd(fd)
-int fd;
+get_client_line_fd(
+ int fd)
{
static char *line = NULL;
- static int line_size = 0;
+ static size_t line_size = 0;
char *s = line;
- int len = 0;
+ size_t len = 0;
char c;
- int nb;
+ ssize_t nb;
if(line == NULL) { /* first time only, allocate initial buffer */
- s = line = malloc(128);
+ s = line = alloc(128);
line_size = 128;
}
while(1) {
continue;
}
dbprintf(("%s: Control pipe read error - %s\n",
- pgm, strerror(errno)));
+ pgm, strerror(errno)));
break;
}
line = realloc(line, line_size);
if (line == NULL) {
error("Memory reallocation failure");
- /* NOTREACHED */
+ /*NOTREACHED*/
}
s = &line[len];
}
}
-void check_security_buffer(buffer)
- char *buffer;
+void
+check_security_buffer(
+ char * buffer)
{
socklen_t i;
struct sockaddr_in addr;
char *s, *fp, ch;
char *errstr = NULL;
-
- i = sizeof (addr);
- if (getpeername(0, (struct sockaddr *)&addr, &i) == -1)
- error("getpeername: %s", strerror(errno));
- if (addr.sin_family != AF_INET || ntohs(addr.sin_port) == 20) {
- error("connection rejected from %s family %d port %d",
+
+ dbprintf(("%s: check_security_buffer(buffer='%s')\n",
+ debug_prefix(NULL), buffer));
+
+ i = SIZEOF(addr);
+ if (getpeername(0, (struct sockaddr *)&addr, &i) == -1) {
+ error("getpeername: %s", strerror(errno));
+ /*NOTREACHED*/
+ }
+ if ((addr.sin_family != (sa_family_t)AF_INET)
+ || (ntohs(addr.sin_port) == 20)) {
+ error("connection rejected from %s family %d port %d",
inet_ntoa(addr.sin_addr), addr.sin_family, htons(addr.sin_port));
- }
-
- /* do the security thing */
- s = buffer;
- ch = *s++;
-
- skip_whitespace(s, ch);
- if (ch == '\0') {
- error("cannot parse SECURITY line");
- }
- fp = s-1;
- skip_non_whitespace(s, ch);
- s[-1] = '\0';
- if (strcmp(fp, "SECURITY") != 0) {
- error("cannot parse SECURITY line");
- }
- skip_whitespace(s, ch);
- if (!check_security(&addr, s-1, 0, &errstr)) {
- error("security check failed: %s", errstr);
- }
+ /*NOTREACHED*/
+ }
+
+ /* do the security thing */
+ s = buffer;
+ ch = *s++;
+
+ skip_whitespace(s, ch);
+ if (ch == '\0') {
+ error("cannot parse SECURITY line");
+ /*NOTREACHED*/
+ }
+ fp = s-1;
+ skip_non_whitespace(s, ch);
+ s[-1] = '\0';
+ if (strcmp(fp, "SECURITY") != 0) {
+ error("cannot parse SECURITY line");
+ /*NOTREACHED*/
+ }
+ skip_whitespace(s, ch);
+ if (!check_security(&addr, s-1, 0, &errstr)) {
+ error("security check failed: %s", errstr);
+ /*NOTREACHED*/
+ }
}
-int main(argc, argv)
-int argc;
-char **argv;
+int
+main(
+ int argc,
+ char ** argv)
{
char *buf = NULL;
- int data_sock = -1, data_port = -1;
+ int data_sock = -1;
+ in_port_t data_port = (in_port_t)-1;
socklen_t socklen;
struct sockaddr_in addr;
match_list_t *match_list;
rst_flags_t *rst_flags;
int use_changer = 0;
FILE *prompt_stream = NULL;
- int re_end = 0;
+ int re_end;
char *re_config = NULL;
char *conf_tapetype;
tapetype_t *tape;
+ char *line;
- safe_fd(-1, 0);
+ safe_fd(DATA_FD_OFFSET, 4);
safe_cd();
/* Don't die when child closes pipe */
set_pname(pgm);
+ if(argv && argv[1] && strcmp(argv[1], "amandad") == 0) {
+ from_amandad = 1;
+ if(argv[2])
+ amandad_auth = argv[2];
+ }
+ else {
+ from_amandad = 0;
+ safe_fd(-1, 0);
+ }
+
#ifdef FORCE_USERID
/* we'd rather not run as root */
if(geteuid() == 0) {
if(client_uid == (uid_t) -1) {
error("error [cannot find user %s in passwd file]\n", CLIENT_LOGIN);
+ /*NOTREACHED*/
}
+ /*@ignore@*/
initgroups(CLIENT_LOGIN, client_gid);
+ /*@end@*/
setgid(client_gid);
setuid(client_uid);
}
chats to stderr, which we don't want going to client */
/* if no debug file, ship to bit bucket */
(void)close(STDERR_FILENO);
- dbopen();
+ dbopen(DBG_SUBDIR_SERVER);
startclock();
dbprintf(("%s: version %s\n", pgm, version()));
#ifdef DEBUG_CODE
debug_prefix_time(NULL)));
}
- socklen = sizeof (addr);
- if (getpeername(0, (struct sockaddr *)&addr, &socklen) == -1)
- error("getpeername: %s", strerror(errno));
- if (addr.sin_family != AF_INET || ntohs(addr.sin_port) == 20) {
- error("connection rejected from %s family %d port %d",
- inet_ntoa(addr.sin_addr), addr.sin_family, htons(addr.sin_port));
- }
+ if(from_amandad == 0) {
+ socklen = SIZEOF(addr);
+ if (getpeername(0, (struct sockaddr *)&addr, &socklen) == -1) {
+ error("getpeername: %s", strerror(errno));
+ /*NOTREACHED*/
+ }
+ if ((addr.sin_family != (sa_family_t)AF_INET)
+ || (ntohs(addr.sin_port) == 20)) {
+ error("connection rejected from %s family %d port %d",
+ inet_ntoa(addr.sin_addr), addr.sin_family,
+ htons(addr.sin_port));
+ /*NOTREACHED*/
+ }
- /* do the security thing */
- amfree(buf);
- buf = stralloc(get_client_line());
- check_security_buffer(buf);
+ /* do the security thing */
+ amfree(buf);
+ buf = stralloc(get_client_line());
+ check_security_buffer(buf);
+ }
+ else {
+ ctlfdout = DATA_FD_OFFSET + 0;
+ ctlfdin = DATA_FD_OFFSET + 1;
+ datafdout = DATA_FD_OFFSET + 2;
+ close(DATA_FD_OFFSET +3);
+
+ /* read the REQ packet */
+ for(; (line = agets(stdin)) != NULL; free(line)) {
+#define sc "OPTIONS "
+ if(strncmp(line, sc, sizeof(sc)-1) == 0) {
+#undef sc
+ g_options = parse_g_options(line+8, 1);
+ if(!g_options->hostname) {
+ g_options->hostname = alloc(MAX_HOSTNAME_LENGTH+1);
+ gethostname(g_options->hostname, MAX_HOSTNAME_LENGTH);
+ g_options->hostname[MAX_HOSTNAME_LENGTH] = '\0';
+ }
+ }
+ }
+ amfree(line);
+
+ if(amandad_auth && g_options->auth) {
+ if(strcasecmp(amandad_auth, g_options->auth) != 0) {
+ printf("ERROR recover program ask for auth=%s while amidxtaped is configured for '%s'\n",
+ g_options->auth, amandad_auth);
+ error("ERROR recover program ask for auth=%s while amidxtaped is configured for '%s'",
+ g_options->auth, amandad_auth);
+ /*NOTREACHED*/
+ }
+ }
+ /* send the REP packet */
+ printf("CONNECT CTL %d DATA %d\n", DATA_FD_OFFSET, DATA_FD_OFFSET+1);
+ printf("\n");
+ fflush(stdout);
+ fflush(stdin);
+ if ((dup2(ctlfdout, fileno(stdout)) < 0)
+ || (dup2(ctlfdin, fileno(stdin)) < 0)) {
+ error("amandad: Failed to setup stdin or stdout");
+ /*NOTREACHED*/
+ }
+ }
/* get the number of arguments */
- match_list = alloc(sizeof(match_list_t));
+ match_list = alloc(SIZEOF(match_list_t));
match_list->next = NULL;
match_list->hostname = "";
match_list->datestamp = "";
match_list->level = "";
match_list->diskname = "";
- do {
+ for (re_end = 0; re_end == 0; ) {
amfree(buf);
buf = stralloc(get_client_line());
if(strncmp(buf, "LABEL=", 6) == 0) {
tapes = unmarshal_tapelist_str(buf+6);
}
else if(strncmp(buf, "FSF=", 4) == 0) {
- rst_flags->fsf = atoi(buf + 4);
+ rst_flags->fsf = OFF_T_ATOI(buf + 4);
}
else if(strncmp(buf, "HEADER", 6) == 0) {
rst_flags->headers = 1;
their_features = am_string_to_feature(their_feature_string);
amfree(their_feature_string);
our_feature_string = am_feature_to_string(our_features);
- printf("%s", our_feature_string);
+ if(from_amandad == 1)
+ printf("FEATURES=%s\r\n", our_feature_string);
+ else
+ printf("%s", our_feature_string);
fflush(stdout);
amfree(our_feature_string);
}
/* XXX does nothing? amrestore_nargs = atoi(buf); */
re_end = 1;
}
- else {
- }
- } while (re_end == 0);
+ }
amfree(buf);
if(!tapes && rst_flags->alt_tapedev){
re_config = NULL;
}
amfree(conffile);
+
+ dbrename(config_name, DBG_SUBDIR_SERVER);
}
- if(tapes &&
+ if(tapes &&
(!rst_flags->alt_tapedev ||
(re_config && ( strcmp(rst_flags->alt_tapedev,
getconf_str(CNF_AMRECOVER_CHANGER)) == 0 ||
/* We need certain options, if restoring from more than one tape */
if(tapes->next && !am_has_feature(their_features, fe_recover_splits)) {
error("%s: Client must support split dumps to restore requested data.", get_pname());
- /* NOTREACHED */
+ /*NOTREACHED*/
}
dbprintf(("%s: Restoring from changer, checking labels\n", get_pname()));
rst_flags->check_labels = 1;
}
/* If we'll be stepping on the tape server's devices, lock them. */
- if(re_config &&
+ if(re_config &&
(use_changer || (rst_flags->alt_tapedev &&
strcmp(rst_flags->alt_tapedev,
getconf_str(CNF_TAPEDEV)) == 0) ) ) {
/* Read the default block size from the tape type */
if(re_config && (conf_tapetype = getconf_str(CNF_TAPETYPE)) != NULL) {
tape = lookup_tapetype(conf_tapetype);
- rst_flags->blocksize = tape->blocksize * 1024;
+ rst_flags->blocksize = tapetype_get_blocksize(tape) * 1024;
}
- if(rst_flags->fsf && re_config &&
- getconf_int(CNF_AMRECOVER_DO_FSF) == 0) {
- rst_flags->fsf = 0;
+ if(rst_flags->fsf && re_config &&
+ getconf_boolean(CNF_AMRECOVER_DO_FSF) == 0) {
+ rst_flags->fsf = (off_t)0;
}
- if(re_config && getconf_int(CNF_AMRECOVER_CHECK_LABEL) == 0) {
+ if (!use_changer && re_config &&
+ getconf_boolean(CNF_AMRECOVER_CHECK_LABEL) == 0) {
rst_flags->check_labels = 0;
}
/* establish a distinct data connection for dumpfile data */
- if(am_has_feature(their_features, fe_recover_splits)){
- int data_fd;
- char *buf;
-
- dbprintf(("%s: Client understands split dumpfiles\n", get_pname()));
-
- if((data_sock = stream_server(&data_port, STREAM_BUFSIZE, -1)) < 0){
- error("%s: could not create data socket: %s", get_pname(),
- strerror(errno));
- }
- dbprintf(("%s: Local port %d set aside for data\n", get_pname(),
- data_port));
-
- printf("CONNECT %d\n", data_port); /* tell client where to connect */
- fflush(stdout);
-
- if((data_fd = stream_accept(data_sock, TIMEOUT, -1, -1)) < 0){
- error("stream_accept failed for client data connection: %s\n",
- strerror(errno));
+ if(am_has_feature(their_features, fe_recover_splits)) {
+ if(from_amandad == 1) {
+ rst_flags->pipe_to_fd = datafdout;
+ prompt_stream = stdout;
}
+ else {
+ int data_fd;
+ char *buf;
- buf = get_client_line_fd(data_fd);
+ dbprintf(("%s: Client understands split dumpfiles\n",get_pname()));
- check_security_buffer(buf);
- rst_flags->pipe_to_fd = data_fd;
- prompt_stream = stdout;
+ if((data_sock = stream_server(&data_port, STREAM_BUFSIZE,
+ STREAM_BUFSIZE, 0)) < 0){
+ error("%s: could not create data socket: %s", get_pname(),
+ strerror(errno));
+ /*NOTREACHED*/
+ }
+ dbprintf(("%s: Local port %d set aside for data\n", get_pname(), data_port));
+
+ /* tell client where to connect */
+ printf("CONNECT %hu\n", (unsigned short)data_port);
+ fflush(stdout);
+
+ if((data_fd = stream_accept(data_sock, TIMEOUT, STREAM_BUFSIZE,
+ STREAM_BUFSIZE)) < 0){
+ error("stream_accept failed for client data connection: %s\n",
+ strerror(errno));
+ /*NOTREACHED*/
+ }
+
+ buf = get_client_line_fd(data_fd);
+
+ check_security_buffer(buf);
+ rst_flags->pipe_to_fd = data_fd;
+ prompt_stream = stdout;
+ }
}
else {
rst_flags->pipe_to_fd = fileno(stdout);
}
dbprintf(("%s: Sending output to file descriptor %d\n",
get_pname(), rst_flags->pipe_to_fd));
-
-
+
+
+ if(get_lock == 0 &&
+ re_config &&
+ (use_changer || (rst_flags->alt_tapedev &&
+ strcmp(rst_flags->alt_tapedev,
+ getconf_str(CNF_TAPEDEV)) == 0) ) ) {
+ send_message(prompt_stream, rst_flags, their_features,
+ "%s exists: amdump or amflush is already running, "
+ "or you must run amcleanup",
+ rst_conf_logfile);
+ error("%s exists: amdump or amflush is already running, "
+ "or you must run amcleanup",
+ rst_conf_logfile);
+ }
+
/* make sure our restore flags aren't crazy */
- if(check_rst_flags(rst_flags) == -1){
- if(rst_flags->pipe_to_fd != -1) aclose(rst_flags->pipe_to_fd);
+ if (check_rst_flags(rst_flags) == -1) {
+ if (rst_flags->pipe_to_fd != -1)
+ aclose(rst_flags->pipe_to_fd);
+ send_message(prompt_stream, rst_flags, their_features,
+ "restore flags are crazy");
exit(1);
}
-
+
/* actual restoration */
search_tapes(prompt_stream, use_changer, tapes, match_list, rst_flags,
their_features);
dbprintf(("%s: Restoration finished\n", debug_prefix_time(NULL)));
-
+
/* cleanup */
if(rst_flags->pipe_to_fd != -1) aclose(rst_flags->pipe_to_fd);
free_tapelist(tapes);
-
+
am_release_feature_set(their_features);
amfree(rst_flags->alt_tapedev);
if(get_lock) unlink(rst_conf_logfile);
}
}
-
* file named AUTHORS, in the root directory of this distribution.
*/
/*
- * $Id: amrestore.c,v 1.56.2.1 2006/04/07 10:52:17 martinea Exp $
+ * $Id: amrestore.c,v 1.63 2006/07/25 18:58:10 martinea Exp $
*
* retrieves files from an amanda tape
*/
#define CREAT_MODE 0640
-static int file_number;
+static off_t file_number;
static pid_t comp_enc_pid = -1;
static int tapedev;
-static long filefsf = -1;
+static off_t filefsf = (off_t)-1;
/* local functions */
-static void errexit P((void));
-static void usage P((void));
-int main P((int argc, char **argv));
+static void errexit(void);
+static void usage(void);
+int main(int argc, char **argv);
-static void errexit()
/*
* Do exit(2) after an error, rather than exit(1).
*/
+
+static void
+errexit(void)
{
exit(2);
}
-static void usage()
/*
* Print usage message and terminate.
*/
+
+static void
+usage(void)
{
- error("Usage: amrestore [-b blocksize] [-r|-c] [-p] [-h] [-f fileno] [-l label] tape-device|holdingfile [hostname [diskname [datestamp [hostname [diskname [datestamp ... ]]]]]]");
+ error("Usage: amrestore [-b blocksize] [-r|-c] [-p] [-h] [-f fileno] "
+ "[-l label] tape-device|holdingfile [hostname [diskname [datestamp "
+ "[hostname [diskname [datestamp ... ]]]]]]");
+ /*NOTREACHED*/
}
-int main(argc, argv)
-int argc;
-char **argv;
+
/*
* Parses command line, then loops through all files on tape, restoring
* files that match the command line criteria.
*/
+
+int
+main(
+ int argc,
+ char ** argv)
{
extern int optind;
int opt;
char *label = NULL;
rst_flags_t *rst_flags;
int count_error;
- size_t read_result;
+ long tmplong;
+ ssize_t read_result;
safe_fd(-1, 0);
set_pname("amrestore");
+ dbopen(DBG_SUBDIR_SERVER);
+
/* Don't die when child closes pipe */
signal(SIGPIPE, SIG_IGN);
while( (opt = getopt(argc, argv, "b:cCd:rphf:l:")) != -1) {
switch(opt) {
case 'b':
- rst_flags->blocksize = strtol(optarg, &e, 10);
+ tmplong = strtol(optarg, &e, 10);
+ rst_flags->blocksize = (ssize_t)tmplong;
if(*e == 'k' || *e == 'K') {
rst_flags->blocksize *= 1024;
} else if(*e == 'm' || *e == 'M') {
rst_flags->blocksize *= 1024 * 1024;
} else if(*e != '\0') {
error("invalid rst_flags->blocksize value \"%s\"", optarg);
+ /*NOTREACHED*/
}
if(rst_flags->blocksize < DISK_BLOCK_BYTES) {
error("minimum block size is %dk", DISK_BLOCK_BYTES / 1024);
+ /*NOTREACHED*/
+ }
+ if(rst_flags->blocksize > MAX_TAPE_BLOCK_KB * 1024) {
+ fprintf(stderr,"maximum block size is %dk, using it\n",
+ MAX_TAPE_BLOCK_KB);
+ rst_flags->blocksize = MAX_TAPE_BLOCK_KB * 1024;
+ /*NOTREACHED*/
}
break;
case 'c': rst_flags->compress = 1; break;
case 'p': rst_flags->pipe_to_fd = fileno(stdout); break;
case 'h': rst_flags->headers = 1; break;
case 'f':
- filefsf = strtol(optarg, &e, 10);
+ filefsf = (off_t)strtoll(optarg, &e, 10);
+ /*@ignore@*/
if(*e != '\0') {
error("invalid fileno value \"%s\"", optarg);
+ /*NOTREACHED*/
}
+ /*@end@*/
break;
case 'l':
label = stralloc(optarg);
}
if(rst_flags->compress && rst_flags->raw) {
- fprintf(stderr,
+ fprintf(stderr,
"Cannot specify both -r (raw) and -c (compressed) output.\n");
usage();
}
/*
* This is a new host/disk/date triple, so allocate a match_list.
*/
- me = alloc(sizeof(*me));
+ me = alloc(SIZEOF(*me));
me->hostname = argv[optind++];
me->diskname = "";
me->datestamp = "";
}
}
if(match_list == NULL) {
- match_list = alloc(sizeof(*match_list));
+ match_list = alloc(SIZEOF(*match_list));
match_list->hostname = "";
match_list->diskname = "";
match_list->datestamp = "";
if(tape_stat(tapename,&stat_tape)!=0) {
error("could not stat %s: %s", tapename, strerror(errno));
+ /*NOTREACHED*/
}
isafile=S_ISREG((stat_tape.st_mode));
else {
if((err = tape_rewind(tapename)) != NULL) {
error("Could not rewind device '%s': %s", tapename, err);
+ /*NOTREACHED*/
}
if ((tapedev = tape_open(tapename, 0)) == -1) {;
error("Could not open device '%s': %s", tapename, err);
+ /*NOTREACHED*/
}
read_file_header(&file, tapedev, isafile, rst_flags);
if(file.type != F_TAPESTART) {
tapefd_close(tapedev);
if((err = tape_rewind(tapename)) != NULL) {
error("Could not rewind device '%s': %s", tapename, err);
+ /*NOTREACHED*/
}
}
}
- file_number = 0;
- if(filefsf != -1) {
+ file_number = (off_t)0;
+ if(filefsf != (off_t)-1) {
if(isafile) {
fprintf(stderr,"%s: ignoring -f flag when restoring from a file.\n",
get_pname());
else {
if((err = tape_rewind(tapename)) != NULL) {
error("Could not rewind device '%s': %s", tapename, err);
+ /*NOTREACHED*/
}
- if((err = tape_fsf(tapename,filefsf)) != NULL) {
+ if((err = tape_fsf(tapename, filefsf)) != NULL) {
error("Could not fsf device '%s': %s", tapename, err);
+ /*NOTREACHED*/
}
file_number = filefsf;
}
}
if(tapedev < 0) {
error("could not open %s: %s", tapename, strerror(errno));
+ /*NOTREACHED*/
}
- read_file_header(&file, tapedev, isafile, rst_flags);
-
- if(file.type != F_TAPESTART && !isafile && filefsf == -1) {
+ read_result = read_file_header(&file, tapedev, isafile, rst_flags);
+ if(file.type != F_TAPESTART && !isafile && filefsf == (off_t)-1) {
fprintf(stderr, "%s: WARNING: not at start of tape, file numbers will be offset\n",
get_pname());
}
- count_error=0;
- read_result = 0;
+ count_error = 0;
while(count_error < 10) {
if(file.type == F_TAPEEND) break;
found_match = 0;
break;
}
}
- fprintf(stderr, "%s: %3d: %s ",
+ fprintf(stderr, "%s: " OFF_T_FMT ": %s ",
get_pname(),
- file_number,
+ (OFF_T_FMT_TYPE)file_number,
found_match ? "restoring" : "skipping");
if(file.type != F_DUMPFILE && file.type != F_SPLIT_DUMPFILE) {
print_header(stderr, &file);
tapefd_close(tapedev);
if((tapedev = tape_open(tapename, 0)) < 0) {
error("could not open %s: %s", tapename, strerror(errno));
+ /*NOTREACHED*/
}
count_error++;
} else {
* If the last read got something (even an error), we can
* do an fsf to get to the next file.
*/
- if(tapefd_fsf(tapedev, 1) < 0) {
+ if(tapefd_fsf(tapedev, (off_t)1) < 0) {
error("could not fsf %s: %s", tapename, strerror(errno));
+ /*NOTREACHED*/
}
count_error=0;
}
file_number++;
- read_file_header(&file, tapedev, isafile, rst_flags);
+ read_result = read_file_header(&file, tapedev, isafile, rst_flags);
}
if(isafile) {
close(tapedev);
tapefd_close(tapedev);
if((tapedev = tape_open(tapename, 0)) < 0) {
error("could not open %s: %s", tapename, strerror(errno));
+ /*NOTREACHED*/
}
} else {
- if(tapefd_fsf(tapedev, 1) < 0) {
+ if(tapefd_fsf(tapedev, (off_t)1) < 0) {
error("could not fsf %s: %s", tapename, strerror(errno));
+ /*NOTREACHED*/
}
}
tapefd_close(tapedev);
}
if((read_result <= 0 || file.type == F_TAPEEND) && !isafile) {
- fprintf(stderr, "%s: %3d: reached ", get_pname(), file_number);
+ fprintf(stderr, "%s: " OFF_T_FMT ": reached ",
+ get_pname(), (OFF_T_FMT_TYPE)file_number);
if(read_result <= 0) {
fprintf(stderr, "end of information\n");
} else {
* file named AUTHORS, in the root directory of this distribution.
*/
/*
- * $Id: restore.c,v 1.28 2006/03/14 13:12:01 martinea Exp $
+ * $Id: restore.c,v 1.52 2006/08/23 11:41:54 martinea Exp $
*
* retrieves files from an amanda tape
*/
#include "changer.h"
#include "logfile.h"
#include "fileheader.h"
+#include "arglist.h"
#include <signal.h>
+#define LOAD_STOP -1
+#define LOAD_CHANGER -2
+
int file_number;
/* stuff we're stuck having global */
-static long blocksize = -1;
+static size_t blocksize = (size_t)SSIZE_MAX;
static char *cur_tapedev = NULL;
static char *searchlabel = NULL;
static int backwards;
static int exitassemble = 0;
-static int tapefd, nslots;
+static int tapefd;
char *rst_conf_logdir = NULL;
char *rst_conf_logfile = NULL;
int outfd;
} open_output_t;
-
typedef struct dumplist_s {
struct dumplist_s *next;
dumpfile_t *file;
} dumplist_t;
+typedef struct seentapes_s {
+ struct seentapes_s *next;
+ char *slotstr;
+ char *label;
+ dumplist_t *files;
+} seentapes_t;
+
static open_output_t *open_outputs = NULL;
static dumplist_t *alldumps_list = NULL;
-static ssize_t get_block P((int tapefd, char *buffer, int isafile));
-static void append_file_to_fd P((char *filename, int fd));
-static int headers_equal P((dumpfile_t *file1, dumpfile_t *file2, int ignore_partnums));
-static int already_have_dump P((dumpfile_t *file));
-
/* local functions */
-static void handle_sigint(sig)
-int sig;
+static ssize_t get_block(int tapefd, char *buffer, int isafile);
+static void append_file_to_fd(char *filename, int fd);
+static int headers_equal(dumpfile_t *file1, dumpfile_t *file2, int ignore_partnums);
+static int already_have_dump(dumpfile_t *file);
+static void handle_sigint(int sig);
+static int scan_init(void *ud, int rc, int ns, int bk, int s);
+int loadlabel_slot(void *ud, int rc, char *slotstr, char *device);
+void drain_file(int tapefd, rst_flags_t *flags);
+char *label_of_current_slot(char *cur_tapedev, FILE *prompt_out,
+ int *tapefd, dumpfile_t *file, rst_flags_t *flags,
+ am_feature_t *their_features,
+ ssize_t *read_result, tapelist_t *desired_tape);
+
+int load_next_tape(char **cur_tapedev, FILE *prompt_out, int backwards,
+ rst_flags_t *flags, am_feature_t *their_features,
+ tapelist_t *desired_tape);
+int load_manual_tape(char **cur_tapedev, FILE *prompt_out,
+ rst_flags_t *flags, am_feature_t *their_features,
+ tapelist_t *desired_tape);
+void search_a_tape(char *cur_tapedev, FILE *prompt_out, rst_flags_t *flags,
+ am_feature_t *their_features, tapelist_t *desired_tape,
+ int isafile, match_list_t *match_list,
+ seentapes_t *tape_seen, dumpfile_t *file,
+ dumpfile_t *prev_rst_file, dumpfile_t *tapestart,
+ int slot_num, ssize_t *read_result);
+
/*
* We might want to flush any open dumps and unmerged splits before exiting
* on SIGINT, so do so.
*/
+static void
+handle_sigint(
+ int sig)
{
+ (void)sig; /* Quiet unused parameter warning */
+
flush_open_outputs(exitassemble, NULL);
if(rst_conf_logfile) unlink(rst_conf_logfile);
exit(0);
}
-int lock_logfile()
+int
+lock_logfile(void)
{
rst_conf_logdir = getconf_str(CNF_LOGDIR);
if (*rst_conf_logdir == '/') {
}
rst_conf_logfile = vstralloc(rst_conf_logdir, "/log", NULL);
if (access(rst_conf_logfile, F_OK) == 0) {
- error("%s exists: amdump or amflush is already running, or you must run amcleanup", rst_conf_logfile);
+ dbprintf(("%s exists: amdump or amflush is already running, "
+ "or you must run amcleanup\n", rst_conf_logfile));
+ return 0;
}
log_add(L_INFO, get_pname());
return 1;
* number, and datestamp, and 0 if not. The part number can be optionally
* ignored.
*/
-int headers_equal (file1, file2, ignore_partnums)
-dumpfile_t *file1, *file2;
-int ignore_partnums;
+int
+headers_equal(
+ dumpfile_t *file1,
+ dumpfile_t *file2,
+ int ignore_partnums)
{
if(!file1 || !file2) return(0);
* See whether we're already pulled an exact copy of the given file (chunk
* number and all). Returns 0 if not, 1 if so.
*/
-int already_have_dump(file)
-dumpfile_t *file;
+int
+already_have_dump(
+ dumpfile_t *file)
{
dumplist_t *fileentry = NULL;
* Open the named file and append its contents to the (hopefully open) file
* descriptor supplies.
*/
-static void append_file_to_fd(filename, fd)
-char *filename;
-int fd;
+static void
+append_file_to_fd(
+ char * filename,
+ int fd)
{
ssize_t bytes_read;
ssize_t s;
- off_t wc = 0;
+ off_t wc = (off_t)0;
char *buffer;
- if(blocksize == -1)
+ if(blocksize == SIZE_MAX)
blocksize = DISK_BLOCK_BYTES;
buffer = alloc(blocksize);
if((tapefd = open(filename, O_RDONLY)) == -1) {
error("can't open %s: %s", filename, strerror(errno));
- /* NOTREACHED */
+ /*NOTREACHED*/
}
for (;;) {
bytes_read = get_block(tapefd, buffer, 1); /* same as isafile = 1 */
if(bytes_read < 0) {
error("read error: %s", strerror(errno));
- /* NOTREACHED */
+ /*NOTREACHED*/
}
if (bytes_read == 0)
break;
- s = fullwrite(fd, buffer, bytes_read);
+ s = fullwrite(fd, buffer, (size_t)bytes_read);
if (s < bytes_read) {
- fprintf(stderr,"Error %d (%s) offset " OFF_T_FMT "+" AM64_FMT ", wrote " AM64_FMT "\n",
- errno, strerror(errno), wc, (am64_t)bytes_read, (am64_t)s);
+ fprintf(stderr,"Error (%s) offset " OFF_T_FMT "+" OFF_T_FMT ", wrote " OFF_T_FMT "\n",
+ strerror(errno), (OFF_T_FMT_TYPE)wc,
+ (OFF_T_FMT_TYPE)bytes_read, (OFF_T_FMT_TYPE)s);
if (s < 0) {
if((errno == EPIPE) || (errno == ECONNRESET)) {
- error("%s: pipe reader has quit in middle of file.\n",
+ error("%s: pipe reader has quit in middle of file.",
get_pname());
- /* NOTREACHED */
+ /*NOTREACHED*/
}
error("restore: write error = %s", strerror(errno));
- /* NOTREACHED */
+ /*NOTREACHED*/
}
- error("Short write: wrote %d bytes expected %d\n", s, bytes_read);
- /* NOTREACHCED */
+ error("Short write: wrote %d bytes expected %d.", s, bytes_read);
+ /*NOTREACHCED*/
}
- wc += bytes_read;
+ wc += (off_t)bytes_read;
}
amfree(buffer);
* Tape changer support routines, stolen brazenly from amtape
*/
static int
-scan_init(ud, rc, ns, bk, s)
- void * ud;
- int rc, ns, bk, s;
+scan_init(
+ void * ud,
+ int rc,
+ int ns,
+ int bk,
+ int s)
{
- if(rc)
- error("could not get changer info: %s", changer_resultstr);
+ (void)ud; /* Quiet unused parameter warning */
+ (void)ns; /* Quiet unused parameter warning */
+ (void)s; /* Quiet unused parameter warning */
- nslots = ns;
+ if(rc) {
+ error("could not get changer info: %s", changer_resultstr);
+ /*NOTREACHED*/
+ }
backwards = bk;
return 0;
}
-int loadlabel_slot(ud, rc, slotstr, device)
- void *ud;
-int rc;
-char *slotstr;
-char *device;
+
+int
+loadlabel_slot(
+ void * ud,
+ int rc,
+ char * slotstr,
+ char * device)
{
char *errstr;
char *datestamp = NULL;
char *label = NULL;
+ (void)ud; /* Quiet unused parameter warning */
- if(rc > 1)
+ if(rc > 1) {
error("could not load slot %s: %s", slotstr, changer_resultstr);
- else if(rc == 1)
+ /*NOTREACHED*/
+ } else if(rc == 1) {
fprintf(stderr, "%s: slot %s: %s\n",
get_pname(), slotstr, changer_resultstr);
- else if((errstr = tape_rdlabel(device, &datestamp, &label)) != NULL)
+ } else if((errstr = tape_rdlabel(device, &datestamp, &label)) != NULL) {
fprintf(stderr, "%s: slot %s: %s\n", get_pname(), slotstr, errstr);
- else {
- fprintf(stderr, "%s: slot %s: date %-8s label %s",
- get_pname(), slotstr, datestamp, label);
+ } else {
+ if(strlen(datestamp)>8)
+ fprintf(stderr, "%s: slot %s: date %-14s label %s",
+ get_pname(), slotstr, datestamp, label);
+ else
+ fprintf(stderr, "%s: slot %s: date %-8s label %s",
+ get_pname(), slotstr, datestamp, label);
if(strcmp(label, FAKE_LABEL) != 0
&& strcmp(label, searchlabel) != 0)
fprintf(stderr, " (wrong tape)\n");
amfree(errstr);
}
amfree(cur_tapedev);
- curslot = stralloc(slotstr);
+ curslot = newstralloc(curslot, slotstr);
amfree(datestamp);
amfree(label);
if(device)
amfree(datestamp);
amfree(label);
- if(cur_tapedev) amfree(cur_tapedev);
- curslot = stralloc(slotstr);
+ amfree(cur_tapedev);
+ curslot = newstralloc(curslot, slotstr);
if(!device) return(1);
cur_tapedev = stralloc(device);
* Check whether we've read all of the preceding parts of a given split dump,
* generally used to see if we're done and can close the thing.
*/
-int have_all_parts (file, upto)
-dumpfile_t *file;
-int upto;
+int
+have_all_parts (
+ dumpfile_t *file,
+ int upto)
{
int c;
int *foundparts = NULL;
if(upto < 1) upto = file->totalparts;
- foundparts = alloc(sizeof(int) * upto);
+ foundparts = alloc(SIZEOF(*foundparts) * upto);
for(c = 0 ; c< upto; c++) foundparts[c] = 0;
for(fileentry=alldumps_list;fileentry; fileentry=fileentry->next){
* string them together. If given an optional file header argument, flush
* only that dump and do not flush/free any others.
*/
-void flush_open_outputs(reassemble, only_file)
-int reassemble;
-dumpfile_t *only_file;
+void
+flush_open_outputs(
+ int reassemble,
+ dumpfile_t *only_file)
{
open_output_t *cur_out = NULL, *prev = NULL;
find_result_t *sorted_files = NULL;
if(only_file && !headers_equal(cur_file, only_file, 1)){
continue;
}
- cur_find_res = alloc(sizeof(find_result_t));
- memset(cur_find_res, '\0', sizeof(find_result_t));
- cur_find_res->datestamp = atoi(cur_file->datestamp);
+ cur_find_res = alloc(SIZEOF(find_result_t));
+ memset(cur_find_res, '\0', SIZEOF(find_result_t));
+ cur_find_res->timestamp = stralloc(cur_file->datestamp);
cur_find_res->hostname = stralloc(cur_file->name);
cur_find_res->diskname = stralloc(cur_file->disk);
cur_find_res->level = cur_file->dumplevel;
if(cur_file->partnum < 1) cur_find_res->partnum = stralloc("--");
else{
char part_str[NUM_STR_SIZE];
- snprintf(part_str, sizeof(part_str), "%d", cur_file->partnum);
+ snprintf(part_str, SIZEOF(part_str), "%d", cur_file->partnum);
cur_find_res->partnum = stralloc(part_str);
}
cur_find_res->user_ptr = (void*)cur_out;
/* is it a continuation of one we've been writing? */
if(main_file && cur_file->partnum > lastpartnum &&
headers_equal(cur_file, main_file, 1)){
+ char *cur_filename;
+ char *main_filename;
/* effectively changing filehandles */
aclose(cur_out->outfd);
cur_out->outfd = outfd;
+ cur_filename = make_filename(cur_file);
+ main_filename = make_filename(main_file);
fprintf(stderr, "Merging %s with %s\n",
- make_filename(cur_file), make_filename(main_file));
- append_file_to_fd(make_filename(cur_file), outfd);
- if(unlink(make_filename(cur_file)) < 0){
+ cur_filename, main_filename);
+ append_file_to_fd(cur_filename, outfd);
+ if(unlink(cur_filename) < 0){
fprintf(stderr, "Failed to unlink %s: %s\n",
- make_filename(cur_file), strerror(errno));
+ cur_filename, strerror(errno));
}
+ amfree(cur_filename);
+ amfree(main_filename);
}
/* or a new file? */
- else{
+ else {
if(outfd >= 0) aclose(outfd);
- if(main_file) amfree(main_file);
- main_file = alloc(sizeof(dumpfile_t));
- memcpy(main_file, cur_file, sizeof(dumpfile_t));
+ amfree(main_file);
+ main_file = alloc(SIZEOF(dumpfile_t));
+ memcpy(main_file, cur_file, SIZEOF(dumpfile_t));
outfd = cur_out->outfd;
- if(outfd < 0){
- if((outfd = open(make_filename(cur_file), O_RDWR|O_APPEND)) < 0){
- error("Couldn't open %s for appending: %s\n",
- make_filename(cur_file), strerror(errno));
+ if(outfd < 0) {
+ char *cur_filename = make_filename(cur_file);
+ open(cur_filename, O_RDWR|O_APPEND);
+ if (outfd < 0) {
+ error("Couldn't open %s for appending: %s",
+ cur_filename, strerror(errno));
+ /*NOTREACHED*/
}
+ amfree(cur_filename);
}
}
lastpartnum = cur_file->partnum;
*/
for(cur_out=open_outputs; cur_out; cur_out=cur_out->next){
dumpfile_t *cur_file = NULL;
- if(prev) amfree(prev);
+ amfree(prev);
cur_file = cur_out->file;
/* if we requested a particular file, do only that one */
if(only_file && !headers_equal(cur_file, only_file, 1)){
/*
* Turn a fileheader into a string suited for use on the filesystem.
*/
-char *make_filename(file)
-dumpfile_t *file;
+char *
+make_filename(
+ dumpfile_t *file)
{
char number[NUM_STR_SIZE];
char part[NUM_STR_SIZE];
char *sfn = NULL;
char *fn = NULL;
char *pad = NULL;
- int padlen = 0;
+ size_t padlen = 0;
- snprintf(number, sizeof(number), "%d", file->dumplevel);
- snprintf(part, sizeof(part), "%d", file->partnum);
+ snprintf(number, SIZEOF(number), "%d", file->dumplevel);
+ snprintf(part, SIZEOF(part), "%d", file->partnum);
- if(file->totalparts < 0){
- snprintf(totalparts, sizeof(totalparts), "UNKNOWN");
+ if(file->totalparts < 0) {
+ snprintf(totalparts, SIZEOF(totalparts), "UNKNOWN");
}
- else{
- snprintf(totalparts, sizeof(totalparts), "%d", file->totalparts);
+ else {
+ snprintf(totalparts, SIZEOF(totalparts), "%d", file->totalparts);
}
padlen = strlen(totalparts) + 1 - strlen(part);
pad = alloc(padlen);
memset(pad, '0', padlen);
pad[padlen - 1] = '\0';
- snprintf(part, sizeof(part), "%s%d", pad, file->partnum);
+ snprintf(part, SIZEOF(part), "%s%d", pad, file->partnum);
sfn = sanitise_filename(file->disk);
fn = vstralloc(file->name,
".",
number,
NULL);
- if(file->partnum > 0){
- fn = vstralloc(fn, ".", part, NULL);
+ if (file->partnum > 0) {
+ vstrextend(&fn, ".", part, NULL);
}
amfree(sfn);
amfree(pad);
/*
-XXX Making this thing a lib functiong broke a lot of assumptions everywhere,
-but I think I've found them all. Maybe. Damn globals all over the place.
-*/
-static ssize_t get_block(tapefd, buffer, isafile)
-int tapefd, isafile;
-char *buffer;
+ * XXX Making this thing a lib functiong broke a lot of assumptions everywhere,
+ * but I think I've found them all. Maybe. Damn globals all over the place.
+ */
+
+static ssize_t
+get_block(
+ int tapefd,
+ char * buffer,
+ int isafile)
{
if(isafile)
return (fullread(tapefd, buffer, blocksize));
return(tapefd_read(tapefd, buffer, blocksize));
}
-int disk_match(file, datestamp, hostname, diskname, level)
-dumpfile_t *file;
-char *datestamp, *hostname, *diskname, *level;
/*
* Returns 1 if the current dump file matches the hostname and diskname
* regular expressions given on the command line, 0 otherwise. As a
* special case, empty regexs are considered equivalent to ".*": they
* match everything.
*/
+
+int
+disk_match(
+ dumpfile_t *file,
+ char * datestamp,
+ char * hostname,
+ char * diskname,
+ char * level)
{
char level_str[NUM_STR_SIZE];
- snprintf(level_str, sizeof(level_str), "%d", file->dumplevel);
+ snprintf(level_str, SIZEOF(level_str), "%d", file->dumplevel);
if(file->type != F_DUMPFILE && file->type != F_SPLIT_DUMPFILE) return 0;
}
-void read_file_header(file, tapefd, isafile, flags)
-dumpfile_t *file;
-int tapefd;
-int isafile;
-rst_flags_t *flags;
/*
* Reads the first block of a tape file.
*/
+
+ssize_t
+read_file_header(
+ dumpfile_t * file,
+ int tapefd,
+ int isafile,
+ rst_flags_t * flags)
{
ssize_t bytes_read;
char *buffer;
if(flags->blocksize > 0)
- blocksize = flags->blocksize;
- else if(blocksize == -1)
+ blocksize = (size_t)flags->blocksize;
+ else if(blocksize == (size_t)SSIZE_MAX)
blocksize = DISK_BLOCK_BYTES;
buffer = alloc(blocksize);
bytes_read = get_block(tapefd, buffer, isafile);
if(bytes_read < 0) {
- error("error reading file header: %s", strerror(errno));
- /* NOTREACHED */
- }
-
- if(bytes_read < blocksize) {
+ fprintf(stderr, "%s: error reading file header: %s\n",
+ get_pname(), strerror(errno));
+ file->type = F_UNKNOWN;
+ } else if((size_t)bytes_read < blocksize) {
if(bytes_read == 0) {
fprintf(stderr, "%s: missing file header block\n", get_pname());
} else {
- fprintf(stderr, "%s: short file header block: " AM64_FMT " byte%s\n",
- get_pname(), (am64_t)bytes_read, (bytes_read == 1) ? "" : "s");
+ fprintf(stderr, "%s: short file header block: " OFF_T_FMT " byte%s\n",
+ get_pname(), (OFF_T_FMT_TYPE)bytes_read, (bytes_read == 1) ? "" : "s");
}
file->type = F_UNKNOWN;
} else {
- parse_file_header(buffer, file, bytes_read);
+ parse_file_header(buffer, file, (size_t)bytes_read);
}
amfree(buffer);
+ return bytes_read;
}
-void drain_file(tapefd, flags)
-int tapefd;
-rst_flags_t *flags;
+void
+drain_file(
+ int tapefd,
+ rst_flags_t * flags)
{
ssize_t bytes_read;
char *buffer;
if(flags->blocksize)
- blocksize = flags->blocksize;
- else if(blocksize == -1)
+ blocksize = (size_t)flags->blocksize;
+ else if(blocksize == (size_t)SSIZE_MAX)
blocksize = DISK_BLOCK_BYTES;
buffer = alloc(blocksize);
bytes_read = get_block(tapefd, buffer, 0);
if(bytes_read < 0) {
error("drain read error: %s", strerror(errno));
+ /*NOTREACHED*/
}
} while (bytes_read > 0);
amfree(buffer);
}
-ssize_t restore(file, filename, tapefd, isafile, flags)
-dumpfile_t *file;
-char *filename;
-int tapefd;
-int isafile;
-rst_flags_t *flags;
/*
* Restore the current file from tape. Depending on the settings of
* the command line flags, the file might need to be compressed or
* but with the -p flag the output goes to stdout (and presumably is
* piped to restore).
*/
+
+ssize_t
+restore(
+ dumpfile_t * file,
+ char * filename,
+ int tapefd,
+ int isafile,
+ rst_flags_t * flags)
{
int dest = -1, out;
ssize_t s;
int pipe[2];
} pipes[3];
+ memset(pipes, -1, SIZEOF(pipes));
if(flags->blocksize)
- blocksize = flags->blocksize;
- else if(blocksize == -1)
+ blocksize = (size_t)flags->blocksize;
+ else if(blocksize == (size_t)SSIZE_MAX)
blocksize = DISK_BLOCK_BYTES;
if(already_have_dump(file)){
- fprintf(stderr, " *** Duplicate file %s, one is probably an aborted write\n", make_filename(file));
+ char *filename = make_filename(file);
+ fprintf(stderr, " *** Duplicate file %s, one is probably an aborted write\n", filename);
+ amfree(filename);
check_for_aborted = 1;
}
/* store a shorthand record of this dump */
- tempdump = alloc(sizeof(dumplist_t));
- tempdump->file = alloc(sizeof(dumpfile_t));
+ tempdump = alloc(SIZEOF(dumplist_t));
+ tempdump->file = alloc(SIZEOF(dumpfile_t));
tempdump->next = NULL;
- memcpy(tempdump->file, file, sizeof(dumpfile_t));
+ memcpy(tempdump->file, file, SIZEOF(dumpfile_t));
/*
* If we're appending chunked files to one another, and if this is a
flags->leave_comp = 1;
}
if(myout == NULL){
- myout = alloc(sizeof(open_output_t));
- memset(myout, 0, sizeof(open_output_t));
+ myout = alloc(SIZEOF(open_output_t));
+ memset(myout, 0, SIZEOF(open_output_t));
}
}
else{
- myout = alloc(sizeof(open_output_t));
- memset(myout, 0, sizeof(open_output_t));
+ myout = alloc(SIZEOF(open_output_t));
+ memset(myout, 0, SIZEOF(open_output_t));
}
if(is_continuation && flags->pipe_to_fd == -1){
+ char *filename;
+ filename = make_filename(myout->file);
fprintf(stderr, "%s: appending to %s\n", get_pname(),
- make_filename(myout->file));
+ filename);
+ amfree(filename);
}
/* adjust compression flag */
}
final_filename = stralloc(tmp_filename);
tmp_filename = newvstralloc(tmp_filename, ".tmp", NULL);
- if((dest = creat(tmp_filename, CREAT_MODE)) < 0) {
+ if((dest = open(tmp_filename, (O_CREAT | O_RDWR | O_TRUNC),
+ CREAT_MODE)) < 0) {
error("could not create output file %s: %s",
- tmp_filename, strerror(errno));
- /*NOTREACHED*/
+ tmp_filename, strerror(errno));
+ /*NOTREACHED*/
}
amfree(filename_ext);
}
* it has a fixed size.
*/
if(flags->raw || (flags->headers && !is_continuation)) {
- int w;
- char *cont_filename;
+ ssize_t w;
dumpfile_t tmp_hdr;
if(flags->compress && !file_is_compressed) {
file->compressed = 1;
- snprintf(file->uncompress_cmd, sizeof(file->uncompress_cmd),
+ snprintf(file->uncompress_cmd, SIZEOF(file->uncompress_cmd),
" %s %s |", UNCOMPRESS_PATH,
#ifdef UNCOMPRESS_OPT
UNCOMPRESS_OPT
);
strncpy(file->comp_suffix,
COMPRESS_SUFFIX,
- sizeof(file->comp_suffix)-1);
- file->comp_suffix[sizeof(file->comp_suffix)-1] = '\0';
+ SIZEOF(file->comp_suffix)-1);
+ file->comp_suffix[SIZEOF(file->comp_suffix)-1] = '\0';
}
- memcpy(&tmp_hdr, file, sizeof(dumpfile_t));
+ memcpy(&tmp_hdr, file, SIZEOF(dumpfile_t));
/* remove CONT_FILENAME from header */
- cont_filename = stralloc(file->cont_filename);
- memset(file->cont_filename,'\0',sizeof(file->cont_filename));
+ memset(file->cont_filename,'\0',SIZEOF(file->cont_filename));
file->blocksize = DISK_BLOCK_BYTES;
/*
if((w = fullwrite(out, buffer, DISK_BLOCK_BYTES)) != DISK_BLOCK_BYTES) {
if(w < 0) {
error("write error: %s", strerror(errno));
+ /*NOTREACHED*/
} else {
error("write error: %d instead of %d", w, DISK_BLOCK_BYTES);
+ /*NOTREACHED*/
}
}
amfree(buffer);
- /* add CONT_FILENAME to header */
-#if 0
-// strncpy(file->cont_filename, cont_filename, sizeof(file->cont_filename));
-#endif
- amfree(cont_filename);
- memcpy(file, &tmp_hdr, sizeof(dumpfile_t));
+
+ memcpy(file, &tmp_hdr, SIZEOF(dumpfile_t));
}
/* find out if compression or uncompression is needed here */
/* Setup pipes for decryption / compression / uncompression */
stage = 0;
if (need_decrypt) {
- if (pipe(&pipes[stage].pipe[0]) < 0)
+ if (pipe(&pipes[stage].pipe[0]) < 0) {
error("error [pipe[%d]: %s]", stage, strerror(errno));
+ /*NOTREACHED*/
+ }
stage++;
}
if (need_compress || need_uncompress) {
- if (pipe(&pipes[stage].pipe[0]) < 0)
+ if (pipe(&pipes[stage].pipe[0]) < 0) {
error("error [pipe[%d]: %s]", stage, strerror(errno));
+ /*NOTREACHED*/
+ }
stage++;
}
pipes[stage].pipe[0] = -1;
switch(myout->comp_enc_pid = fork()) {
case -1:
error("could not fork for decrypt: %s", strerror(errno));
+ /*NOTREACHED*/
+
default:
aclose(pipes[stage].pipe[0]);
aclose(pipes[stage+1].pipe[1]);
stage++;
break;
+
case 0:
- if(dup2(pipes[stage].pipe[0], 0) == -1)
+ if(dup2(pipes[stage].pipe[0], 0) == -1) {
error("error decrypt stdin [dup2 %d %d: %s]", stage,
pipes[stage].pipe[0], strerror(errno));
+ /*NOTREACHED*/
+ }
- if(dup2(pipes[stage+1].pipe[1], 1) == -1)
+ if(dup2(pipes[stage+1].pipe[1], 1) == -1) {
error("error decrypt stdout [dup2 %d %d: %s]", stage + 1,
pipes[stage+1].pipe[1], strerror(errno));
+ /*NOTREACHED*/
+ }
safe_fd(-1, 0);
if (*file->srv_encrypt) {
(void) execlp(file->srv_encrypt, file->srv_encrypt,
- file->srv_decrypt_opt, NULL);
+ file->srv_decrypt_opt, (char *)NULL);
error("could not exec %s: %s", file->srv_encrypt, strerror(errno));
+ /*NOTREACHED*/
} else if (*file->clnt_encrypt) {
(void) execlp(file->clnt_encrypt, file->clnt_encrypt,
- file->clnt_decrypt_opt, NULL);
+ file->clnt_decrypt_opt, (char *)NULL);
error("could not exec %s: %s", file->clnt_encrypt, strerror(errno));
+ /*NOTREACHED*/
}
}
}
* Insert a compress pipe
*/
switch(myout->comp_enc_pid = fork()) {
- case -1: error("could not fork for %s: %s",
- COMPRESS_PATH, strerror(errno));
+ case -1:
+ error("could not fork for %s: %s", COMPRESS_PATH, strerror(errno));
+ /*NOTREACHED*/
+
default:
aclose(pipes[stage].pipe[0]);
aclose(pipes[stage+1].pipe[1]);
stage++;
break;
+
case 0:
- if(dup2(pipes[stage].pipe[0], 0) == -1)
+ if(dup2(pipes[stage].pipe[0], 0) == -1) {
error("error compress stdin [dup2 %d %d: %s]", stage,
pipes[stage].pipe[0], strerror(errno));
+ /*NOTREACHED*/
+ }
- if(dup2(pipes[stage+1].pipe[1], 1) == -1)
+ if(dup2(pipes[stage+1].pipe[1], 1) == -1) {
error("error compress stdout [dup2 %d %d: %s]", stage + 1,
pipes[stage+1].pipe[1], strerror(errno));
-
+ /*NOTREACHED*/
+ }
if (*flags->comp_type == '\0') {
flags->comp_type = NULL;
}
safe_fd(-1, 0);
(void) execlp(COMPRESS_PATH, COMPRESS_PATH, flags->comp_type, (char *)0);
error("could not exec %s: %s", COMPRESS_PATH, strerror(errno));
+ /*NOTREACHED*/
}
} else if(need_uncompress) {
/*
case -1:
error("could not fork for %s: %s",
UNCOMPRESS_PATH, strerror(errno));
+ /*NOTREACHED*/
+
default:
aclose(pipes[stage].pipe[0]);
aclose(pipes[stage+1].pipe[1]);
stage++;
break;
+
case 0:
- if(dup2(pipes[stage].pipe[0], 0) == -1)
+ if(dup2(pipes[stage].pipe[0], 0) == -1) {
error("error uncompress stdin [dup2 %d %d: %s]", stage,
pipes[stage].pipe[0], strerror(errno));
+ /*NOTREACHED*/
+ }
- if(dup2(pipes[stage+1].pipe[1], 1) == -1)
+ if(dup2(pipes[stage+1].pipe[1], 1) == -1) {
error("error uncompress stdout [dup2 %d %d: %s]", stage + 1,
pipes[stage+1].pipe[1], strerror(errno));
+ /*NOTREACHED*/
+ }
safe_fd(-1, 0);
if (*file->srvcompprog) {
- (void) execlp(file->srvcompprog, file->srvcompprog, "-d", NULL);
- error("could not exec %s: %s", file->srvcompprog, strerror(errno));
+ (void) execlp(file->srvcompprog, file->srvcompprog, "-d",
+ (char *)NULL);
+ error("could not exec %s: %s", file->srvcompprog,
+ strerror(errno));
+ /*NOTREACHED*/
} else if (*file->clntcompprog) {
- (void) execlp(file->clntcompprog, file->clntcompprog, "-d", NULL);
- error("could not exec %s: %s", file->clntcompprog, strerror(errno));
+ (void) execlp(file->clntcompprog, file->clntcompprog, "-d",
+ (char *)NULL);
+ error("could not exec %s: %s", file->clntcompprog,
+ strerror(errno));
+ /*NOTREACHED*/
} else {
(void) execlp(UNCOMPRESS_PATH, UNCOMPRESS_PATH,
#ifdef UNCOMPRESS_OPT
UNCOMPRESS_OPT,
#endif
- (char *)0);
+ (char *)NULL);
error("could not exec %s: %s", UNCOMPRESS_PATH, strerror(errno));
+ /*NOTREACHED*/
}
}
}
/* copy the rest of the file from tape to the output */
if(flags->blocksize > 0)
- blocksize = flags->blocksize;
- else if(blocksize == -1)
+ blocksize = (size_t)flags->blocksize;
+ else if(blocksize == SIZE_MAX)
blocksize = DISK_BLOCK_BYTES;
buffer = alloc(blocksize);
bytes_read = get_block(tapefd, buffer, isafile);
if(bytes_read < 0) {
error("restore read error: %s", strerror(errno));
- /* NOTREACHED */
+ /*NOTREACHED*/
}
if(bytes_read > 0) {
- if((s = fullwrite(pipes[0].pipe[1], buffer, bytes_read)) < 0) {
+ if((s = fullwrite(pipes[0].pipe[1], buffer, (size_t)bytes_read)) < 0) {
if ((errno == EPIPE) || (errno == ECONNRESET)) {
/*
* reading program has ended early
*/
break;
}
- perror("restore: write error");
- exit(2);
+ error("restore: write error: %s", strerror(errno));
+ /* NOTREACHED */
+ } else if (s < bytes_read) {
+ error("restore: wrote %d of %d bytes: %s",
+ s, bytes_read, strerror(errno));
+ /* NOTREACHED */
}
}
else if(isafile) {
if((tapefd = open(cont_filename,O_RDONLY)) == -1) {
error("can't open %s: %s", file->cont_filename,
strerror(errno));
+ /*NOTREACHED*/
}
else {
fprintf(stderr, "cannot open %s: %s\n",
else {
error("can't open %s: %s", file->cont_filename,
strerror(errno));
+ /*NOTREACHED*/
}
}
- read_file_header(file, tapefd, isafile, flags);
+ bytes_read = read_file_header(file, tapefd, isafile, flags);
if(file->type != F_DUMPFILE && file->type != F_CONT_DUMPFILE
&& file->type != F_SPLIT_DUMPFILE) {
fprintf(stderr, "unexpected header type: ");
}
if(!is_continuation){
if(tmp_filename && stat(tmp_filename, &statinfo) < 0){
- error("Can't stat the file I just created (%s)!\n", tmp_filename);
+ error("Can't stat the file I just created (%s)!", tmp_filename);
+ /*NOTREACHED*/
+ } else {
+ statinfo.st_size = (off_t)0;
}
- if(check_for_aborted){
+ if (check_for_aborted && final_filename) {
char *old_dump = final_filename;
struct stat oldstat;
if(stat(old_dump, &oldstat) >= 0){
}
else{
fprintf(stderr, "Older restore is larger, using that\n");
- unlink(tmp_filename);
+ if (tmp_filename)
+ unlink(tmp_filename);
amfree(tempdump->file);
amfree(tempdump);
amfree(tmp_filename);
}
}
if(tmp_filename && final_filename &&
- rename(tmp_filename, final_filename) < 0){
- error("Can't rename %s to %s: %s\n", tmp_filename, final_filename,
- strerror(errno));
+ rename(tmp_filename, final_filename) < 0) {
+ error("Can't rename %s to %s: %s",
+ tmp_filename, final_filename, strerror(errno));
+ /*NOTREACHED*/
}
}
- if(tmp_filename) amfree(tmp_filename);
- if(final_filename) amfree(final_filename);
+ amfree(tmp_filename);
+ amfree(final_filename);
/*
* structures (we waited in case we needed to give up)
*/
if(!is_continuation){
- oldout = alloc(sizeof(open_output_t));
- oldout->file = alloc(sizeof(dumpfile_t));
- memcpy(oldout->file, file, sizeof(dumpfile_t));
+ oldout = alloc(SIZEOF(open_output_t));
+ oldout->file = alloc(SIZEOF(dumpfile_t));
+ memcpy(oldout->file, file, SIZEOF(dumpfile_t));
if(flags->inline_assemble) oldout->outfd = pipes[0].pipe[1];
else oldout->outfd = -1;
oldout->comp_enc_pid = -1;
open_outputs = oldout;
}
if(alldumps_list){
- for(fileentry=alldumps_list;fileentry->next;fileentry=fileentry->next);
+ fileentry = alldumps_list;
+ while (fileentry->next != NULL)
+ fileentry=fileentry->next;
fileentry->next = tempdump;
}
else {
return (bytes_read);
}
+/* return NULL if the label is not the expected one */
+/* return the label if it is the expected one, and set *tapefd to a */
+/* file descriptor to the tapedev */
+char *
+label_of_current_slot(
+ char *cur_tapedev,
+ FILE *prompt_out,
+ int *tapefd,
+ dumpfile_t *file,
+ rst_flags_t *flags,
+ am_feature_t *their_features,
+ ssize_t *read_result,
+ tapelist_t *desired_tape)
+{
+ struct stat stat_tape;
+ char *label = NULL;
+ int wrongtape = 0;
+ char *err;
+ if (!cur_tapedev) {
+ send_message(prompt_out, flags, their_features,
+ "no tapedev specified");
+ } else if (tape_stat(cur_tapedev, &stat_tape) !=0 ) {
+ send_message(prompt_out, flags, their_features,
+ "could not stat '%s': %s",
+ cur_tapedev, strerror(errno));
+ wrongtape = 1;
+ } else if((err = tape_rewind(cur_tapedev)) != NULL) {
+ send_message(prompt_out, flags, their_features,
+ "Could not rewind device '%s': %s",
+ cur_tapedev, err);
+ wrongtape = 1;
+ /* err should not be freed */
+ } else if((*tapefd = tape_open(cur_tapedev, 0)) < 0){
+ send_message(prompt_out, flags, their_features,
+ "could not open tape device %s: %s",
+ cur_tapedev, strerror(errno));
+ wrongtape = 1;
+ }
+
+ if (!wrongtape) {
+ *read_result = read_file_header(file, *tapefd, 0, flags);
+ if (file->type != F_TAPESTART) {
+ send_message(prompt_out, flags, their_features,
+ "Not an amanda tape");
+ tapefd_close(*tapefd);
+ } else {
+ if (flags->check_labels && desired_tape &&
+ strcmp(file->name, desired_tape->label) != 0) {
+ send_message(prompt_out, flags, their_features,
+ "Label mismatch, got %s and expected %s",
+ file->name, desired_tape->label);
+ tapefd_close(*tapefd);
+ }
+ else {
+ label = stralloc(file->name);
+ }
+ }
+ }
+ return label;
+}
+
+/* return >0 the number of slot move */
+/* return LOAD_STOP if the search must be stopped */
+/* return LOAD_CHANGER if the changer search the library */
+int
+load_next_tape(
+ char **cur_tapedev,
+ FILE *prompt_out,
+ int backwards,
+ rst_flags_t *flags,
+ am_feature_t *their_features,
+ tapelist_t *desired_tape)
+{
+ int ret = -1;
+
+ if (desired_tape) {
+ send_message(prompt_out, flags, their_features,
+ "Looking for tape %s...",
+ desired_tape->label);
+ if (backwards) {
+ searchlabel = desired_tape->label;
+ changer_find(NULL, scan_init, loadlabel_slot,
+ desired_tape->label);
+ ret = LOAD_CHANGER;
+ } else {
+ amfree(curslot);
+ changer_loadslot("next", &curslot,
+ cur_tapedev);
+ ret = 1;
+ }
+ } else {
+ assert(!flags->amidxtaped);
+ amfree(curslot);
+ changer_loadslot("next", &curslot, cur_tapedev);
+ ret = 1;
+ }
+ return ret;
+}
+
+
+/* return 0 a new tape is loaded */
+/* return -1 no new tape */
+int
+load_manual_tape(
+ char **cur_tapedev,
+ FILE *prompt_out,
+ rst_flags_t *flags,
+ am_feature_t *their_features,
+ tapelist_t *desired_tape)
+{
+ int ret = 0;
+ char *input = NULL;
+
+ if (flags->amidxtaped) {
+ if (their_features &&
+ am_has_feature(their_features,
+ fe_amrecover_FEEDME)) {
+ fprintf(prompt_out, "FEEDME %s\r\n",
+ desired_tape->label);
+ fflush(prompt_out);
+ input = agets(stdin);/* Strips \n but not \r */
+ if(!input) {
+ error("Connection lost with amrecover");
+ /*NOTREACHED*/
+ } else if (strcmp("OK\r", input) == 0) {
+ } else if (strncmp("TAPE ", input, 5) == 0) {
+ amfree(*cur_tapedev);
+ *cur_tapedev = alloc(1025);
+ if (sscanf(input, "TAPE %1024s\r", *cur_tapedev) != 1) {
+ error("Got bad response from amrecover: %s", input);
+ /*NOTREACHED*/
+ }
+ } else {
+ send_message(prompt_out, flags, their_features,
+ "Got bad response from amrecover: %s", input);
+ error("Got bad response from amrecover: %s", input);
+ /*NOTREACHED*/
+ }
+ } else {
+ send_message(prompt_out, flags, their_features,
+ "Client doesn't support fe_amrecover_FEEDME");
+ error("Client doesn't support fe_amrecover_FEEDME");
+ /*NOTREACHED*/
+ }
+ }
+ else {
+ if (desired_tape) {
+ fprintf(prompt_out,
+ "Insert tape labeled %s in device %s \n"
+ "and press enter, ^D to finish reading tapes\n",
+ desired_tape->label, *cur_tapedev);
+ } else {
+ fprintf(prompt_out,"Insert a tape to search and press "
+ "enter, ^D to finish reading tapes\n");
+ }
+ fflush(prompt_out);
+ if((input = agets(stdin)) == NULL)
+ ret = -1;
+ }
+
+ amfree(input);
+ return ret;
+}
+
+
+void
+search_a_tape(
+ char *cur_tapedev,
+ FILE *prompt_out,
+ rst_flags_t *flags,
+ am_feature_t *their_features,
+ tapelist_t *desired_tape,
+ int isafile,
+ match_list_t *match_list,
+ seentapes_t *tape_seen,
+ dumpfile_t *file,
+ dumpfile_t *prev_rst_file,
+ dumpfile_t *tapestart,
+ int slot_num,
+ ssize_t *read_result)
+{
+ off_t filenum;
+ dumplist_t *fileentry = NULL;
+ int tapefile_idx = -1;
+ int i;
+ char *logline = NULL;
+ FILE *logstream = NULL;
+ off_t fsf_by;
+
+ filenum = (off_t)0;
+ if(desired_tape && desired_tape->numfiles > 0)
+ tapefile_idx = 0;
+
+ if (desired_tape) {
+ dbprintf(("search_a_tape: desired_tape=%p label=%s\n",
+ desired_tape, desired_tape->label));
+ dbprintf(("tape: numfiles = %d\n", desired_tape->numfiles));
+ for (i=0; i < desired_tape->numfiles; i++) {
+ dbprintf(("tape: files[%d] = " OFF_T_FMT "\n",
+ i, (OFF_T_FMT_TYPE)desired_tape->files[i]));
+ }
+ } else {
+ dbprintf(("search_a_tape: no desired_tape\n"));
+ }
+ dbprintf(("current tapefile_idx = %d\n", tapefile_idx));
+
+ /* if we know where we're going, fastforward there */
+ if(flags->fsf && !isafile){
+ /* If we have a tapelist entry, filenums will be store there */
+ if(tapefile_idx >= 0) {
+ fsf_by = desired_tape->files[tapefile_idx];
+ } else {
+ /*
+ * older semantics assume we're restoring one file, with the fsf
+ * flag being the filenum on tape for said file
+ */
+ fsf_by = (flags->fsf == 0) ? (off_t)0 : (off_t)1;
+ }
+ if(fsf_by > (off_t)0){
+ if(tapefd_rewind(tapefd) < 0) {
+ send_message(prompt_out, flags, their_features,
+ "Could not rewind device %s: %s",
+ cur_tapedev, strerror(errno));
+ error("Could not rewind device %s: %s",
+ cur_tapedev, strerror(errno));
+ /*NOTREACHED*/
+ }
+
+ if(tapefd_fsf(tapefd, fsf_by) < 0) {
+ send_message(prompt_out, flags, their_features,
+ "Could not fsf device %s by " OFF_T_FMT ": %s",
+ cur_tapedev, (OFF_T_FMT_TYPE)fsf_by,
+ strerror(errno));
+ error("Could not fsf device %s by " OFF_T_FMT ": %s",
+ cur_tapedev, (OFF_T_FMT_TYPE)fsf_by,
+ strerror(errno));
+ /*NOTREACHED*/
+ }
+ else {
+ filenum = fsf_by;
+ }
+ *read_result = read_file_header(file, tapefd, isafile, flags);
+ }
+ }
+
+ while((file->type == F_TAPESTART || file->type == F_DUMPFILE ||
+ file->type == F_SPLIT_DUMPFILE) &&
+ (tapefile_idx < 0 || tapefile_idx < desired_tape->numfiles)) {
+ int found_match = 0;
+ match_list_t *me;
+ dumplist_t *tempdump = NULL;
+
+ /* store record of this dump for inventorying purposes */
+ tempdump = alloc(SIZEOF(dumplist_t));
+ tempdump->file = alloc(SIZEOF(dumpfile_t));
+ tempdump->next = NULL;
+ memcpy(tempdump->file, &file, SIZEOF(dumpfile_t));
+ if(tape_seen->files){
+ fileentry = tape_seen->files;
+ while (fileentry->next != NULL)
+ fileentry = fileentry->next;
+ fileentry->next = tempdump;
+ }
+ else {
+ tape_seen->files = tempdump;
+ }
+
+ /* see if we need to restore the thing */
+ if(isafile)
+ found_match = 1;
+ else if(tapefile_idx >= 0){ /* do it by explicit file #s */
+ if(filenum == desired_tape->files[tapefile_idx]){
+ found_match = 1;
+ tapefile_idx++;
+ }
+ }
+ else{ /* search and match headers */
+ for(me = match_list; me; me = me->next) {
+ if(disk_match(file, me->datestamp, me->hostname,
+ me->diskname, me->level) != 0){
+ found_match = 1;
+ break;
+ }
+ }
+ }
+
+ if(found_match){
+ char *filename = make_filename(file);
+
+ fprintf(stderr, "%s: " OFF_T_FMT ": restoring ",
+ get_pname(), (OFF_T_FMT_TYPE)filenum);
+ print_header(stderr, file);
+ *read_result = restore(file, filename, tapefd, isafile, flags);
+ filenum++;
+ amfree(filename);
+ }
+
+ /* advance to the next file, fast-forwarding where reasonable */
+ if (!isafile) {
+ if (*read_result == 0) {
+ tapefd_close(tapefd);
+ if((tapefd = tape_open(cur_tapedev, 0)) < 0) {
+ send_message(prompt_out, flags, their_features,
+ "could not open %s: %s",
+ cur_tapedev, strerror(errno));
+ error("could not open %s: %s",
+ cur_tapedev, strerror(errno));
+ /*NOTREACHED*/
+ }
+ /* if the file is not what we're looking for fsf to next one */
+ }
+ else if (!found_match) {
+ if (tapefd_fsf(tapefd, (off_t)1) < 0) {
+ send_message(prompt_out, flags, their_features,
+ "Could not fsf device %s: %s",
+ cur_tapedev, strerror(errno));
+ error("Could not fsf device %s: %s",
+ cur_tapedev, strerror(errno));
+ /*NOTREACHED*/
+ }
+ filenum ++;
+ }
+ else if (flags->fsf && (tapefile_idx >= 0) &&
+ (tapefile_idx < desired_tape->numfiles)) {
+ fsf_by = desired_tape->files[tapefile_idx] - filenum;
+ if (fsf_by > (off_t)0) {
+ if(tapefd_fsf(tapefd, fsf_by) < 0) {
+ send_message(prompt_out, flags, their_features,
+ "Could not fsf device %s by "
+ OFF_T_FMT ": %s",
+ cur_tapedev, (OFF_T_FMT_TYPE)fsf_by,
+ strerror(errno));
+ error("Could not fsf device %s by " OFF_T_FMT ": %s",
+ cur_tapedev, (OFF_T_FMT_TYPE)fsf_by,
+ strerror(errno));
+ /*NOTREACHED*/
+ }
+ filenum = desired_tape->files[tapefile_idx];
+ }
+ }
+ } /* !isafile */
+
+ memcpy(prev_rst_file, file, SIZEOF(dumpfile_t));
+
+ if(isafile)
+ break;
+ *read_result = read_file_header(file, tapefd, isafile, flags);
+
+ /* only restore a single dump, if piping to stdout */
+ if (!headers_equal(prev_rst_file, file, 1) &&
+ (flags->pipe_to_fd == fileno(stdout)) && found_match) {
+ break;
+ }
+ } /* while we keep seeing headers */
+
+ if (!isafile) {
+ if (file->type == F_EMPTY) {
+ aclose(tapefd);
+ if((tapefd = tape_open(cur_tapedev, 0)) < 0) {
+ send_message(prompt_out, flags, their_features,
+ "could not open %s: %s",
+ cur_tapedev, strerror(errno));
+ error("could not open %s: %s",
+ cur_tapedev, strerror(errno));
+ /*NOTREACHED*/
+ }
+ } else {
+ if (tapefd_fsf(tapefd, (off_t)1) < 0) {
+ send_message(prompt_out, flags, their_features,
+ "could not fsf %s: %s",
+ cur_tapedev, strerror(errno));;
+ error("could not fsf %s: %s",
+ cur_tapedev, strerror(errno));
+ /*NOTREACHED*/
+ }
+ }
+ }
+ tapefd_close(tapefd);
+
+ /* spit out our accumulated list of dumps, if we're inventorying */
+ if (logstream) {
+ logline = log_genstring(L_START, "taper",
+ "datestamp %s label %s tape %d",
+ tapestart->datestamp, tapestart->name,
+ slot_num);
+ fprintf(logstream, "%s", logline);
+ for(fileentry=tape_seen->files; fileentry; fileentry=fileentry->next){
+ logline = NULL;
+ switch (fileentry->file->type) {
+ case F_DUMPFILE:
+ logline = log_genstring(L_SUCCESS, "taper",
+ "%s %s %s %d [faked log entry]",
+ fileentry->file->name,
+ fileentry->file->disk,
+ fileentry->file->datestamp,
+ fileentry->file->dumplevel);
+ break;
+ case F_SPLIT_DUMPFILE:
+ logline = log_genstring(L_CHUNK, "taper",
+ "%s %s %s %d %d [faked log entry]",
+ fileentry->file->name,
+ fileentry->file->disk,
+ fileentry->file->datestamp,
+ fileentry->file->partnum,
+ fileentry->file->dumplevel);
+ break;
+ default:
+ break;
+ }
+ if(logline){
+ fprintf(logstream, "%s", logline);
+ amfree(logline);
+ fflush(logstream);
+ }
+ }
+ }
+}
/*
* Take a pattern of dumps and restore it blind, a la amrestore. In addition,
* tapes to search (rather than "everything I can find"), which in turn can
* optionally list specific files to restore.
*/
-void search_tapes(prompt_out, use_changer, tapelist, match_list, flags, their_features)
-FILE *prompt_out;
-int use_changer;
-tapelist_t *tapelist;
-match_list_t *match_list;
-rst_flags_t *flags;
-am_feature_t *their_features;
+void
+search_tapes(
+ FILE * prompt_out,
+ int use_changer,
+ tapelist_t * tapelist,
+ match_list_t * match_list,
+ rst_flags_t * flags,
+ am_feature_t * their_features)
{
- struct stat stat_tape;
- char *err;
int have_changer = 1;
int slot_num = -1;
int slots = -1;
- int filenum;
FILE *logstream = NULL;
- dumplist_t *fileentry = NULL;
tapelist_t *desired_tape = NULL;
struct sigaction act, oact;
- int newtape = 1;
- ssize_t bytes_read = 0;
+ ssize_t read_result;
+ int slot;
+ char *label = NULL;
+ seentapes_t *seentapes = NULL;
+ int ret;
- struct seentapes{
- struct seentapes *next;
- char *slotstr;
- char *label;
- dumplist_t *files;
- } *seentapes = NULL;
+ dbprintf(("search_tapes(prompt=%p, use_changer=%d, tapelist=%p, "
+ "match_list=%p, flags=%p, features=%p)\n",
+ prompt_out, use_changer, tapelist, match_list,
+ flags, their_features));
if(!prompt_out) prompt_out = stderr;
- if(flags->blocksize) blocksize = flags->blocksize;
- else if(blocksize == -1) blocksize = DISK_BLOCK_BYTES;
+ if(flags->blocksize)
+ blocksize = (size_t)flags->blocksize;
+ else if(blocksize == (size_t)SSIZE_MAX)
+ blocksize = DISK_BLOCK_BYTES;
/* Don't die when child closes pipe */
signal(SIGPIPE, SIG_IGN);
act.sa_flags = 0;
if(sigaction(SIGINT, &act, &oact) != 0){
error("error setting SIGINT handler: %s", strerror(errno));
+ /*NOTREACHED*/
}
if(flags->delay_assemble || flags->inline_assemble) exitassemble = 1;
else exitassemble = 0;
/* if given a log file, print an inventory of stuff found */
- if(flags->inventory_log){
+ if(flags->inventory_log) {
if(!strcmp(flags->inventory_log, "-")) logstream = stdout;
- else if((logstream = fopen(flags->inventory_log, "w+")) == NULL){
- error("Couldn't open log file %s for writing: %s\n",
+ else if((logstream = fopen(flags->inventory_log, "w+")) == NULL) {
+ error("Couldn't open log file %s for writing: %s",
flags->inventory_log, strerror(errno));
+ /*NOTREACHED*/
}
}
have_changer = 0;
} else if (have_changer != 1) {
error("changer initialization failed: %s", strerror(errno));
+ /*NOTREACHED*/
}
else{ /* good, the changer works, see what it can do */
+ amfree(curslot);
changer_info(&slots, &curslot, &backwards);
}
what to load
*/
fprintf(prompt_out, "The following tapes are needed:");
- for(desired_tape = tapelist;
- desired_tape != NULL;
+ for(desired_tape = tapelist; desired_tape != NULL;
desired_tape = desired_tape->next){
fprintf(prompt_out, " %s", desired_tape->label);
}
}
desired_tape = tapelist;
+ if(use_changer && !cur_tapedev) { /* load current slot */
+ amfree(curslot);
+ changer_loadslot("current", &curslot, &cur_tapedev);
+ }
+
/*
* If we're not given a tapelist, iterate over everything our changer can
* find. If there's no changer, we'll prompt to be handfed tapes.
*
* (obnoxious, isn't this?)
*/
- slot_num = 0;
- curslot = stralloc("<none>");
- while(desired_tape || ((slot_num < slots || !have_changer) && !tapelist)){
- char *label = NULL;
- struct seentapes *tape_seen = NULL;
+
+ do { /* all desired tape */
+ seentapes_t *tape_seen = NULL;
dumpfile_t file, tapestart, prev_rst_file;
- char *logline = NULL;
- int tapefile_idx = -1;
- int wrongtape = 0;
int isafile = 0;
+ read_result = 0;
- /*
- * Deal with instances where we're being asked to restore from a file
- */
- if(desired_tape && desired_tape->isafile){
+ slot_num = 0;
+
+ memset(&file, 0, SIZEOF(file));
+
+ if (desired_tape && desired_tape->isafile) {
isafile = 1;
- if ((tapefd = open(desired_tape->label, 0)) == -1){
- fprintf(stderr, "could not open %s: %s\n",
- desired_tape->label, strerror(errno));
- continue;
+ if ((tapefd = open(desired_tape->label, 0)) == -1) {
+ send_message(prompt_out, flags, their_features,
+ "could not open %s: %s",
+ desired_tape->label, strerror(errno));
+ continue;
}
- fprintf(stderr, "Reading %s to fd %d\n", desired_tape->label, tapefd);
+ fprintf(stderr, "Reading %s to fd %d\n",
+ desired_tape->label, tapefd);
- read_file_header(&file, tapefd, 1, flags);
+ read_result = read_file_header(&file, tapefd, 1, flags);
label = stralloc(desired_tape->label);
- }
- /*
- * Make sure we can read whatever tape is loaded, then grab the label.
- */
- else if(cur_tapedev && newtape){
- if(tape_stat(cur_tapedev,&stat_tape)!=0) {
- error("could not stat %s: %s", cur_tapedev, strerror(errno));
+ } else {
+ /* check current_slot */
+ label = label_of_current_slot(cur_tapedev, prompt_out,
+ &tapefd, &file, flags,
+ their_features, &read_result,
+ desired_tape);
+ while (label==NULL && slot_num < slots &&
+ use_changer) {
+ /*
+ * If we have an incorrect tape loaded, go try to find
+ * the right one
+ * (or just see what the next available one is).
+ */
+ slot = load_next_tape(&cur_tapedev, prompt_out,
+ backwards, flags,
+ their_features, desired_tape);
+ if(slot == LOAD_STOP) {
+ slot_num = slots;
+ amfree(label);
+ } else {
+ if (slot == LOAD_CHANGER)
+ slot_num = slots;
+ else /* slot > 0 */
+ slot_num += slot;
+
+ /* check current_slot */
+ label = label_of_current_slot(cur_tapedev, prompt_out,
+ &tapefd, &file, flags,
+ their_features, &read_result,
+ desired_tape);
+ }
}
- if((err = tape_rewind(cur_tapedev)) != NULL) {
- fprintf(stderr, "Could not rewind device '%s': %s\n",
- cur_tapedev, err);
- wrongtape = 1;
- }
- if((tapefd = tape_open(cur_tapedev, 0)) < 0){
- fprintf(stderr, "could not open tape device %s: %s\n",
- cur_tapedev, strerror(errno));
- wrongtape = 1;
+ if (label == NULL) {
+ ret = load_manual_tape(&cur_tapedev, prompt_out,
+ flags,
+ their_features, desired_tape);
+ if (ret == 0) {
+ label = label_of_current_slot(cur_tapedev, prompt_out,
+ &tapefd, &file, flags,
+ their_features, &read_result,
+ desired_tape);
+ }
}
- if (!wrongtape) {
- read_file_header(&file, tapefd, 0, flags);
- if (file.type != F_TAPESTART) {
- fprintf(stderr, "Not an amanda tape\n");
- tapefd_close(tapefd);
- wrongtape = 1;
- } else {
- memcpy(&tapestart, &file, sizeof(dumpfile_t));
- label = stralloc(file.name);
- }
- }
- } else if(newtape) {
- wrongtape = 1; /* nothing loaded */
- bytes_read = -1;
+ if (label)
+ memcpy(&tapestart, &file, SIZEOF(dumpfile_t));
}
+
+ if (!label)
+ continue;
/*
* Skip this tape if we did it already. Note that this would let
* duplicate labels through, so long as they were in the same slot.
* I'm over it, are you?
*/
- if(label && newtape && !isafile && !wrongtape){
- for(tape_seen = seentapes; tape_seen; tape_seen = tape_seen->next){
- if(!strcmp(tape_seen->label, label) &&
- !strcmp(tape_seen->slotstr, curslot)){
- fprintf(stderr, "Saw repeat tape %s in slot %s\n", label, curslot);
- wrongtape = 1;
+ if (!isafile) {
+ for (tape_seen = seentapes; tape_seen;
+ tape_seen = tape_seen->next) {
+ if (!strcmp(tape_seen->label, label) &&
+ !strcmp(tape_seen->slotstr, curslot)){
+ send_message(prompt_out, flags, their_features,
+ "Saw repeat tape %s in slot %s",
+ label, curslot);
amfree(label);
break;
}
}
}
- /*
- * See if we've got the tape we were looking for, if we were looking
- * for something specific.
- */
- if((desired_tape || !cur_tapedev) && newtape && !isafile && !wrongtape){
- if(!label || (flags->check_labels &&
- desired_tape && strcmp(label, desired_tape->label) != 0)){
- if(label){
- fprintf(stderr, "Label mismatch, got %s and expected %s\n", label, desired_tape->label);
- if(have_changer && !backwards){
- fprintf(stderr, "Changer can't go backwards, restoring anyway\n");
- }
- else wrongtape = 1;
- }
- else fprintf(stderr, "No tape device initialized yet\n");
- }
- }
-
-
- /*
- * If we have an incorrect tape loaded, go try to find the right one
- * (or just see what the next available one is).
- */
- if((wrongtape || !newtape) && !isafile){
- if(desired_tape){
- tapefd_close(tapefd);
- if(have_changer){
- fprintf(stderr,"Looking for tape %s...\n", desired_tape->label);
- if(backwards){
- searchlabel = desired_tape->label;
- changer_find(NULL, scan_init, loadlabel_slot, desired_tape->label);
- }
- else{
- changer_loadslot("next", &curslot, &cur_tapedev);
- }
- while(have_changer && !cur_tapedev){
- fprintf(stderr, "Changer did not set the tape device (slot empty or changer misconfigured?)\n");
- changer_loadslot("next", &curslot, &cur_tapedev);
- }
- }
- else {
- char *input = NULL;
-
- if (!flags->amidxtaped) {
- fprintf(prompt_out,
- "Insert tape labeled %s in device %s "
- "and press return\n",
- desired_tape->label, cur_tapedev);
- fflush(prompt_out);
- input = agets(stdin);
- amfree(input);
- } else if (their_features &&
- am_has_feature(their_features,
- fe_amrecover_FEEDME)) {
- fprintf(prompt_out, "FEEDME %s\n",
- desired_tape->label);
- fflush(prompt_out);
- input = agets(stdin); /* Strips \n but not \r */
- if (strcmp("OK\r", input) != 0) {
- error("Got bad response from amrecover: %s",
- input);
- }
- amfree(input);
- } else {
- error("Client doesn't support fe_amrecover_FEEDME");
- }
- }
- }
- else{
- assert(!flags->amidxtaped);
- if(have_changer){
- if(slot_num == 0)
- changer_loadslot("first", &curslot, &cur_tapedev);
- else
- changer_loadslot("next", &curslot, &cur_tapedev);
- if(have_changer && !cur_tapedev)
- error("Changer did not set the tape device, probably misconfigured");
- }
- else {
- /* XXX need a condition for ending processing? */
- char *input = NULL;
- fprintf(prompt_out,"Insert a tape to search and press enter, ^D to finish reading tapes\n");
- fflush(prompt_out);
- if((input = agets(stdin)) == NULL) break;
- amfree(input);
- }
- }
- newtape = 1;
- amfree(label);
+ if(!label)
continue;
- }
- newtape = 0;
-
- slot_num++;
+ if(!curslot)
+ curslot = stralloc("<none>");
if(!isafile){
fprintf(stderr, "Scanning %s (slot %s)\n", label, curslot);
fflush(stderr);
}
- tape_seen = alloc(sizeof(struct seentapes));
- memset(tape_seen, '\0', sizeof(struct seentapes));
+ tape_seen = alloc(SIZEOF(seentapes_t));
+ memset(tape_seen, '\0', SIZEOF(seentapes_t));
tape_seen->label = label;
tape_seen->slotstr = stralloc(curslot);
* have one) contains a list of files to restore, obey that instead
* of checking for matching headers on all files.
*/
- filenum = 0;
- if(desired_tape && desired_tape->numfiles > 0) tapefile_idx = 0;
-
- /* if we know where we're going, fastforward there */
- if(flags->fsf && !isafile){
- int fsf_by = 0;
- /* If we have a tapelist entry, filenums will be store there */
- if(tapefile_idx >= 0)
- fsf_by = desired_tape->files[tapefile_idx];
- /*
- * older semantics assume we're restoring one file, with the fsf
- * flag being the filenum on tape for said file
- */
- else fsf_by = flags->fsf;
-
- if(fsf_by > 0){
- if(tapefd_rewind(tapefd) < 0) {
- error("Could not rewind device %s: %s", cur_tapedev,
- strerror(errno));
- }
-
- if(tapefd_fsf(tapefd, fsf_by) < 0) {
- error("Could not fsf device %s by %d: %s", cur_tapedev, fsf_by,
- strerror(errno));
- }
- else {
- filenum = fsf_by;
- }
- read_file_header(&file, tapefd, isafile, flags);
- }
- }
+ search_a_tape(cur_tapedev, prompt_out, flags, their_features,
+ desired_tape, isafile, match_list, tape_seen,
+ &file, &prev_rst_file, &tapestart, slot_num,
+ &read_result);
- while((file.type == F_TAPESTART || file.type == F_DUMPFILE ||
- file.type == F_SPLIT_DUMPFILE) &&
- (tapefile_idx < 0 || tapefile_idx < desired_tape->numfiles)) {
- int found_match = 0;
- match_list_t *me;
- dumplist_t *tempdump = NULL;
-
- /* store record of this dump for inventorying purposes */
- tempdump = alloc(sizeof(dumplist_t));
- tempdump->file = alloc(sizeof(dumpfile_t));
- tempdump->next = NULL;
- memcpy(tempdump->file, &file, sizeof(dumpfile_t));
- if(tape_seen->files){
- for(fileentry=tape_seen->files;
- fileentry->next;
- fileentry=fileentry->next);
- fileentry->next = tempdump;
- }
- else tape_seen->files = tempdump;
-
- /* see if we need to restore the thing */
- if(isafile) found_match = 1;
- else if(tapefile_idx >= 0){ /* do it by explicit file #s */
- if(filenum == desired_tape->files[tapefile_idx]){
- found_match = 1;
- tapefile_idx++;
- }
- }
- else{ /* search and match headers */
- for(me = match_list; me; me = me->next) {
- if(disk_match(&file, me->datestamp, me->hostname,
- me->diskname, me->level) != 0){
- found_match = 1;
- break;
- }
- }
- }
-
- if(found_match){
- char *filename = make_filename(&file);
- fprintf(stderr, "%s: %3d: restoring ", get_pname(), filenum);
- print_header(stderr, &file);
- bytes_read = restore(&file, filename, tapefd, isafile, flags);
- filenum ++;
- amfree(filename);
- }
-
- /* advance to the next file, fast-forwarding where reasonable */
- if(bytes_read == 0 && !isafile) {
- tapefd_close(tapefd);
- if((tapefd = tape_open(cur_tapedev, 0)) < 0) {
- error("could not open %s: %s",
- cur_tapedev, strerror(errno));
- }
- } else if(!isafile){
- /* cheat and jump ahead to where we're going if we can */
- if (!found_match && flags->fsf) {
- drain_file(tapefd, flags);
- filenum ++;
- } else if(tapefile_idx >= 0 &&
- tapefile_idx < desired_tape->numfiles &&
- flags->fsf){
- int fsf_by = desired_tape->files[tapefile_idx] - filenum;
- if(fsf_by > 0){
- if(tapefd_fsf(tapefd, fsf_by) < 0) {
- error("Could not fsf device %s by %d: %s", cur_tapedev, fsf_by,
- strerror(errno));
- }
- else filenum = desired_tape->files[tapefile_idx];
- }
- } else if (!found_match && flags->fsf) {
- /* ... or fsf by 1, whatever */
- if(tapefd_fsf(tapefd, 1) < 0) {
- error("could not fsf device %s: %s",
- cur_tapedev, strerror(errno));
- } else {
- filenum ++;
- }
- }
- }
-
-
- memcpy(&prev_rst_file, &file, sizeof(dumpfile_t));
-
-
- if(isafile)
- break;
- read_file_header(&file, tapefd, isafile, flags);
-
- /* only restore a single dump, if piping to stdout */
- if(!headers_equal(&prev_rst_file, &file, 1) &&
- flags->pipe_to_fd == fileno(stdout)) break;
- } /* while we keep seeing headers */
-
- if(!isafile){
- if(bytes_read == 0) {
- /* XXX is this dain-bramaged? */
- aclose(tapefd);
- if((tapefd = tape_open(cur_tapedev, 0)) < 0) {
- error("could not open %s: %s",
- cur_tapedev, strerror(errno));
- }
- } else{
- if(tapefd_fsf(tapefd, 1) < 0) {
- error("could not fsf %s: %s",
- cur_tapedev, strerror(errno));
- }
- }
- }
- tapefd_close(tapefd);
-
- /* spit out our accumulated list of dumps, if we're inventorying */
- if(logstream){
- logline = log_genstring(L_START, "taper",
- "datestamp %s label %s tape %d",
- tapestart.datestamp, tapestart.name, slot_num);
- fprintf(logstream, logline);
- for(fileentry=tape_seen->files; fileentry; fileentry=fileentry->next){
- logline = NULL;
- switch(fileentry->file->type){
- case F_DUMPFILE:
- logline = log_genstring(L_SUCCESS, "taper",
- "%s %s %s %d [faked log entry]",
- fileentry->file->name,
- fileentry->file->disk,
- fileentry->file->datestamp,
- fileentry->file->dumplevel);
- break;
- case F_SPLIT_DUMPFILE:
- logline = log_genstring(L_CHUNK, "taper",
- "%s %s %s %d %d [faked log entry]",
- fileentry->file->name,
- fileentry->file->disk,
- fileentry->file->datestamp,
- fileentry->file->partnum,
- fileentry->file->dumplevel);
- break;
- default:
- break;
- }
- if(logline){
- fprintf(logstream, logline);
- amfree(logline);
- fflush(logstream);
- }
- }
- }
fprintf(stderr, "%s: Search of %s complete\n",
get_pname(), tape_seen->label);
- if(desired_tape) desired_tape = desired_tape->next;
+ if (desired_tape) desired_tape = desired_tape->next;
/* only restore a single dump, if piping to stdout */
- if(!headers_equal(&prev_rst_file, &file, 1) &&
- flags->pipe_to_fd == fileno(stdout)) break;
- }
+ if (!headers_equal(&prev_rst_file, &file, 1) &&
+ flags->pipe_to_fd == fileno(stdout))
+ break;
+
+ } while (desired_tape);
- while(seentapes != NULL) {
- struct seentapes *tape_seen = seentapes;
+ while (seentapes != NULL) {
+ seentapes_t *tape_seen = seentapes;
seentapes = seentapes->next;
while(tape_seen->files != NULL) {
dumplist_t *temp_dump = tape_seen->files;
/*
* Create a new, clean set of restore flags with some sane default values.
*/
-rst_flags_t *new_rst_flags()
+rst_flags_t *
+new_rst_flags(void)
{
- rst_flags_t *flags = alloc(sizeof(rst_flags_t));
+ rst_flags_t *flags = alloc(SIZEOF(rst_flags_t));
- memset(flags, 0, sizeof(rst_flags_t));
+ memset(flags, 0, SIZEOF(rst_flags_t));
flags->fsf = 1;
flags->comp_type = COMPRESS_FAST_OPT;
* Make sure the set of restore options given is sane. Print errors for
* things that're odd, and return -1 for fatal errors.
*/
-int check_rst_flags(rst_flags_t *flags)
+int
+check_rst_flags(
+ rst_flags_t * flags)
{
int ret = 0;
/*
* Clean up after a rst_flags_t
*/
-void free_rst_flags(flags)
-rst_flags_t *flags;
+void
+free_rst_flags(
+ rst_flags_t * flags)
{
if(!flags) return;
- if(flags->restore_dir) amfree(flags->restore_dir);
- if(flags->alt_tapedev) amfree(flags->alt_tapedev);
- if(flags->inventory_log) amfree(flags->inventory_log);
+ amfree(flags->restore_dir);
+ amfree(flags->alt_tapedev);
+ amfree(flags->inventory_log);
amfree(flags);
}
/*
* Clean up after a match_list_t
*/
-void free_match_list(match_list)
-match_list_t *match_list;
+void
+free_match_list(
+ match_list_t * match_list)
{
match_list_t *me;
match_list_t *prev = NULL;
for(me = match_list; me; me = me->next){
/* XXX freeing these is broken? can't work out why */
-/* if(me->hostname) amfree(me->hostname);
- if(me->diskname) amfree(me->diskname);
- if(me->datestamp) amfree(me->datestamp);
- if(me->level) amfree(me->level); */
- if(prev) amfree(prev);
+/* amfree(me->hostname);
+ amfree(me->diskname);
+ amfree(me->datestamp);
+ amfree(me->level); */
+ amfree(prev);
prev = me;
}
- if(prev) amfree(prev);
+ amfree(prev);
}
+
+
+printf_arglist_function3(
+ void send_message,
+ FILE *, prompt_out,
+ rst_flags_t *, flags,
+ am_feature_t *, their_features,
+ char *, format)
+{
+ va_list argp;
+ char linebuf[STR_SIZE];
+
+ arglist_start(argp, format);
+ vsnprintf(linebuf, SIZEOF(linebuf)-1, format, argp);
+ arglist_end(argp);
+
+ fprintf(stderr,"%s\n", linebuf);
+ if (flags->amidxtaped && their_features &&
+ am_has_feature(their_features, fe_amrecover_message)) {
+ fprintf(prompt_out, "MESSAGE %s\r\n", linebuf);
+ fflush(prompt_out);
+ }
+}
+
* file named AUTHORS, in the root directory of this distribution.
*/
/*
- * $Id: restore.h,v 1.5 2006/03/14 13:12:01 martinea Exp $
+ * $Id: restore.h,v 1.8 2006/06/22 17:16:39 martinea Exp $
*
*
*/
unsigned int amidxtaped:1; /* for client-daemon use */
unsigned int check_labels:1;
unsigned int mask_splits:1;
- unsigned int fsf;
- long blocksize;
+ off_t fsf;
+ ssize_t blocksize;
int pipe_to_fd;
char *restore_dir;
char *comp_type;
char *inventory_log;
} rst_flags_t;
-char *make_filename P((dumpfile_t *file));
-int disk_match P((dumpfile_t *file, char *datestamp,
- char *hostname, char *diskname, char *level));
-void read_file_header P((dumpfile_t *file, int tapefd, int isafile,
- rst_flags_t *flags));
-ssize_t restore P((dumpfile_t *file, char *filename, int tapefd, int isafile,
- rst_flags_t *flags));
-void flush_open_outputs P((int reassemble, dumpfile_t *only_file));
-void search_tapes P((FILE *prompt_out, int use_changer, tapelist_t *tapelist,
+char *make_filename(dumpfile_t *file);
+int disk_match(dumpfile_t *file, char *datestamp,
+ char *hostname, char *diskname, char *level);
+ssize_t read_file_header(dumpfile_t *file, int tapefd, int isafile,
+ rst_flags_t *flags);
+ssize_t restore(dumpfile_t *file, char *filename, int tapefd, int isafile,
+ rst_flags_t *flags);
+void flush_open_outputs(int reassemble, dumpfile_t *only_file);
+void search_tapes(FILE *prompt_out, int use_changer, tapelist_t *tapelist,
match_list_t *restorethese, rst_flags_t *flags,
- am_feature_t *their_features));
-int have_all_parts P((dumpfile_t *file, int upto));
-rst_flags_t *new_rst_flags P((void));
-int check_rst_flags P((rst_flags_t *flags));
-void free_rst_flags P((rst_flags_t *flags));
-void free_match_list P((match_list_t *match_list));
-int lock_logfile P(());
+ am_feature_t *their_features);
+int have_all_parts(dumpfile_t *file, int upto);
+rst_flags_t *new_rst_flags(void);
+int check_rst_flags(rst_flags_t *flags);
+void free_rst_flags(rst_flags_t *flags);
+void free_match_list(match_list_t *match_list);
+int lock_logfile(void);
+void send_message(FILE *prompt_out, rst_flags_t *flags,
+ am_feature_t *their_features, char * format, ...);
+ /* __attribute__ ((format (printf, 4, 5))); */
+
#endif /* RESTORE_H */
INCLUDES = -I$(top_builddir)/common-src \
-I$(top_srcdir)/common-src \
-I$(top_srcdir)/restore-src \
- -I$(top_srcdir)/tape-src
+ -I$(top_srcdir)/tape-src \
+ -I$(top_srcdir)/amandad-src
+
+LINT=@AMLINT@
+LINTFLAGS=@AMLINTFLAGS@
lib_LTLIBRARIES = libamserver.la
LIB_EXTENSION = la
sbin_SCRIPTS = amcheckdb amcleanup amdump \
amoverview amrmtape amtoc \
amverify amverifyrun amstatus \
- amcrypt amaespipe
+ amcrypt amaespipe amcrypt-ossl \
+ amcrypt-ossl-asym
libamserver_la_SOURCES= amindex.c changer.c \
conffile.c diskfile.c driverio.c \
###
LDADD = ../common-src/libamanda.$(LIB_EXTENSION) \
+ libamserver.$(LIB_EXTENSION) \
+ ../tape-src/libamtape.$(LIB_EXTENSION) \
+ ../common-src/libamanda.$(LIB_EXTENSION) \
+ ../tape-src/libamtape.$(LIB_EXTENSION) \
+ ../common-src/libamanda.$(LIB_EXTENSION) \
+ $(READLINE_LIBS)
+
+amindexd_LDADD = ../common-src/libamanda.$(LIB_EXTENSION) \
libamserver.$(LIB_EXTENSION) \
+ ../amandad-src/libamandad.$(LIB_EXTENSION) \
../tape-src/libamtape.$(LIB_EXTENSION) \
../common-src/libamanda.$(LIB_EXTENSION) \
../tape-src/libamtape.$(LIB_EXTENSION) \
CLEANFILES = *.test.c $(sbin_SCRIPTS)
-amindexd_SOURCES = amindexd.c \
- disk_history.c disk_history.h \
- list_dir.c list_dir.h
+amindexd_CSRC = amindexd.c disk_history.c list_dir.c
+amindexd_SOURCES = disk_history.h list_dir.h $(amindexd_CSRC)
amreport_SOURCES = reporter.c
else true; \
fi; \
done
-if !WANT_SSH_SECURITY
+## ##
+## enterprise version will install dumper/planner suid ##
+## ##
+
@list="dumper planner"; \
for p in $$list; do \
if echo "$(libexec_PROGRAMS)" | grep $$p >/dev/null 2>&1; then \
else true; \
fi; \
done
-endif
+
+lint:
+ @ for p in $(libexec_PROGRAMS) $(sbin_PROGRAMS); do \
+ if [ $$p = "amindexd" ]; then \
+ s="$(amindexd_CSRC)"; \
+ elif [ $$p = "amreport" ]; then \
+ s="$(amreport_SOURCES)"; \
+ elif [ $$p = "amgetconf" ]; then \
+ s="$(getconf_SOURCES)"; \
+ else \
+ s=$$p.c; \
+ fi; \
+ f="$$s $(libamserver_la_SOURCES)"; \
+ (cd ../common-src; make listlibsrc); \
+ f="$$f "`cat ../common-src/listlibsrc.output`; \
+ (cd ../tape-src; make listlibsrc); \
+ f="$$f "`cat ../tape-src/listlibsrc.output`; \
+ echo $(LINT) $$f; \
+ $(LINT) $(LINTFLAGS) $(CPPFLAGS) $(DEFS) -I. -I../config \
+ $(INCLUDES) $$f; \
+ if [ $$? -ne 0 ]; then \
+ exit 1; \
+ fi; \
+ done; \
+ exit 0
+
+listlibsrc:
+ @ for p in $(libamserver_la_SOURCES); do \
+ listlibsrcs="$$listlibsrcs `pwd`/$$p"; \
+ done; \
+ echo $$listlibsrcs >listlibsrc.output
+
diskfile_SOURCES = diskfile.test.c
conffile_SOURCES = conffile.test.c
DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \
$(srcdir)/Makefile.in $(srcdir)/amaespipe.sh.in \
$(srcdir)/amcheckdb.sh.in $(srcdir)/amcleanup.sh.in \
+ $(srcdir)/amcrypt-ossl-asym.sh.in $(srcdir)/amcrypt-ossl.sh.in \
$(srcdir)/amcrypt.sh.in $(srcdir)/amdump.sh.in \
$(srcdir)/amfreetapes.sh.in $(srcdir)/amoverview.pl.in \
$(srcdir)/amrmtape.sh.in $(srcdir)/amstatus.pl.in \
CONFIG_HEADER = $(top_builddir)/config/config.h
CONFIG_CLEAN_FILES = amcheckdb.sh amcleanup.sh amdump.sh \
amfreetapes.sh amoverview.pl amrmtape.sh amtoc.pl amverify.sh \
- amstatus.pl amverifyrun.sh amcrypt.sh amaespipe.sh
+ amstatus.pl amverifyrun.sh amcrypt.sh amaespipe.sh \
+ amcrypt-ossl.sh amcrypt-ossl-asym.sh
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
am__vpath_adj = case $$p in \
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
amadmin_SOURCES = amadmin.c
amadmin_OBJECTS = amadmin.$(OBJEXT)
amadmin_LDADD = $(LDADD)
+am__DEPENDENCIES_1 =
amadmin_DEPENDENCIES = ../common-src/libamanda.$(LIB_EXTENSION) \
libamserver.$(LIB_EXTENSION) \
../tape-src/libamtape.$(LIB_EXTENSION) \
../common-src/libamanda.$(LIB_EXTENSION) \
../tape-src/libamtape.$(LIB_EXTENSION) \
- ../common-src/libamanda.$(LIB_EXTENSION)
+ ../common-src/libamanda.$(LIB_EXTENSION) $(am__DEPENDENCIES_1)
amcheck_SOURCES = amcheck.c
amcheck_OBJECTS = amcheck.$(OBJEXT)
amcheck_LDADD = $(LDADD)
../tape-src/libamtape.$(LIB_EXTENSION) \
../common-src/libamanda.$(LIB_EXTENSION) \
../tape-src/libamtape.$(LIB_EXTENSION) \
- ../common-src/libamanda.$(LIB_EXTENSION)
+ ../common-src/libamanda.$(LIB_EXTENSION) $(am__DEPENDENCIES_1)
amcleanupdisk_SOURCES = amcleanupdisk.c
amcleanupdisk_OBJECTS = amcleanupdisk.$(OBJEXT)
amcleanupdisk_LDADD = $(LDADD)
../tape-src/libamtape.$(LIB_EXTENSION) \
../common-src/libamanda.$(LIB_EXTENSION) \
../tape-src/libamtape.$(LIB_EXTENSION) \
- ../common-src/libamanda.$(LIB_EXTENSION)
+ ../common-src/libamanda.$(LIB_EXTENSION) $(am__DEPENDENCIES_1)
amflush_SOURCES = amflush.c
amflush_OBJECTS = amflush.$(OBJEXT)
amflush_LDADD = $(LDADD)
../tape-src/libamtape.$(LIB_EXTENSION) \
../common-src/libamanda.$(LIB_EXTENSION) \
../tape-src/libamtape.$(LIB_EXTENSION) \
- ../common-src/libamanda.$(LIB_EXTENSION)
+ ../common-src/libamanda.$(LIB_EXTENSION) $(am__DEPENDENCIES_1)
am_amgetconf_OBJECTS = getconf.$(OBJEXT)
amgetconf_OBJECTS = $(am_amgetconf_OBJECTS)
amgetconf_LDADD = $(LDADD)
../tape-src/libamtape.$(LIB_EXTENSION) \
../common-src/libamanda.$(LIB_EXTENSION) \
../tape-src/libamtape.$(LIB_EXTENSION) \
- ../common-src/libamanda.$(LIB_EXTENSION)
-am_amindexd_OBJECTS = amindexd.$(OBJEXT) disk_history.$(OBJEXT) \
+ ../common-src/libamanda.$(LIB_EXTENSION) $(am__DEPENDENCIES_1)
+am__objects_1 = amindexd.$(OBJEXT) disk_history.$(OBJEXT) \
list_dir.$(OBJEXT)
+am_amindexd_OBJECTS = $(am__objects_1)
amindexd_OBJECTS = $(am_amindexd_OBJECTS)
-amindexd_LDADD = $(LDADD)
amindexd_DEPENDENCIES = ../common-src/libamanda.$(LIB_EXTENSION) \
libamserver.$(LIB_EXTENSION) \
+ ../amandad-src/libamandad.$(LIB_EXTENSION) \
../tape-src/libamtape.$(LIB_EXTENSION) \
../common-src/libamanda.$(LIB_EXTENSION) \
../tape-src/libamtape.$(LIB_EXTENSION) \
../tape-src/libamtape.$(LIB_EXTENSION) \
../common-src/libamanda.$(LIB_EXTENSION) \
../tape-src/libamtape.$(LIB_EXTENSION) \
- ../common-src/libamanda.$(LIB_EXTENSION)
+ ../common-src/libamanda.$(LIB_EXTENSION) $(am__DEPENDENCIES_1)
amlogroll_SOURCES = amlogroll.c
amlogroll_OBJECTS = amlogroll.$(OBJEXT)
amlogroll_LDADD = $(LDADD)
../tape-src/libamtape.$(LIB_EXTENSION) \
../common-src/libamanda.$(LIB_EXTENSION) \
../tape-src/libamtape.$(LIB_EXTENSION) \
- ../common-src/libamanda.$(LIB_EXTENSION)
+ ../common-src/libamanda.$(LIB_EXTENSION) $(am__DEPENDENCIES_1)
am_amreport_OBJECTS = reporter.$(OBJEXT)
amreport_OBJECTS = $(am_amreport_OBJECTS)
amreport_LDADD = $(LDADD)
../tape-src/libamtape.$(LIB_EXTENSION) \
../common-src/libamanda.$(LIB_EXTENSION) \
../tape-src/libamtape.$(LIB_EXTENSION) \
- ../common-src/libamanda.$(LIB_EXTENSION)
+ ../common-src/libamanda.$(LIB_EXTENSION) $(am__DEPENDENCIES_1)
amtape_SOURCES = amtape.c
amtape_OBJECTS = amtape.$(OBJEXT)
amtape_LDADD = $(LDADD)
../tape-src/libamtape.$(LIB_EXTENSION) \
../common-src/libamanda.$(LIB_EXTENSION) \
../tape-src/libamtape.$(LIB_EXTENSION) \
- ../common-src/libamanda.$(LIB_EXTENSION)
+ ../common-src/libamanda.$(LIB_EXTENSION) $(am__DEPENDENCIES_1)
amtrmidx_SOURCES = amtrmidx.c
amtrmidx_OBJECTS = amtrmidx.$(OBJEXT)
amtrmidx_LDADD = $(LDADD)
../tape-src/libamtape.$(LIB_EXTENSION) \
../common-src/libamanda.$(LIB_EXTENSION) \
../tape-src/libamtape.$(LIB_EXTENSION) \
- ../common-src/libamanda.$(LIB_EXTENSION)
+ ../common-src/libamanda.$(LIB_EXTENSION) $(am__DEPENDENCIES_1)
amtrmlog_SOURCES = amtrmlog.c
amtrmlog_OBJECTS = amtrmlog.$(OBJEXT)
amtrmlog_LDADD = $(LDADD)
../tape-src/libamtape.$(LIB_EXTENSION) \
../common-src/libamanda.$(LIB_EXTENSION) \
../tape-src/libamtape.$(LIB_EXTENSION) \
- ../common-src/libamanda.$(LIB_EXTENSION)
+ ../common-src/libamanda.$(LIB_EXTENSION) $(am__DEPENDENCIES_1)
chunker_SOURCES = chunker.c
chunker_OBJECTS = chunker.$(OBJEXT)
chunker_LDADD = $(LDADD)
../tape-src/libamtape.$(LIB_EXTENSION) \
../common-src/libamanda.$(LIB_EXTENSION) \
../tape-src/libamtape.$(LIB_EXTENSION) \
- ../common-src/libamanda.$(LIB_EXTENSION)
+ ../common-src/libamanda.$(LIB_EXTENSION) $(am__DEPENDENCIES_1)
am_conffile_OBJECTS = conffile.test.$(OBJEXT)
conffile_OBJECTS = $(am_conffile_OBJECTS)
conffile_LDADD = $(LDADD)
../tape-src/libamtape.$(LIB_EXTENSION) \
../common-src/libamanda.$(LIB_EXTENSION) \
../tape-src/libamtape.$(LIB_EXTENSION) \
- ../common-src/libamanda.$(LIB_EXTENSION)
+ ../common-src/libamanda.$(LIB_EXTENSION) $(am__DEPENDENCIES_1)
am_diskfile_OBJECTS = diskfile.test.$(OBJEXT)
diskfile_OBJECTS = $(am_diskfile_OBJECTS)
diskfile_LDADD = $(LDADD)
../tape-src/libamtape.$(LIB_EXTENSION) \
../common-src/libamanda.$(LIB_EXTENSION) \
../tape-src/libamtape.$(LIB_EXTENSION) \
- ../common-src/libamanda.$(LIB_EXTENSION)
+ ../common-src/libamanda.$(LIB_EXTENSION) $(am__DEPENDENCIES_1)
driver_SOURCES = driver.c
driver_OBJECTS = driver.$(OBJEXT)
driver_LDADD = $(LDADD)
../tape-src/libamtape.$(LIB_EXTENSION) \
../common-src/libamanda.$(LIB_EXTENSION) \
../tape-src/libamtape.$(LIB_EXTENSION) \
- ../common-src/libamanda.$(LIB_EXTENSION)
+ ../common-src/libamanda.$(LIB_EXTENSION) $(am__DEPENDENCIES_1)
dumper_SOURCES = dumper.c
dumper_OBJECTS = dumper.$(OBJEXT)
dumper_LDADD = $(LDADD)
../tape-src/libamtape.$(LIB_EXTENSION) \
../common-src/libamanda.$(LIB_EXTENSION) \
../tape-src/libamtape.$(LIB_EXTENSION) \
- ../common-src/libamanda.$(LIB_EXTENSION)
+ ../common-src/libamanda.$(LIB_EXTENSION) $(am__DEPENDENCIES_1)
am_infofile_OBJECTS = infofile.test.$(OBJEXT)
infofile_OBJECTS = $(am_infofile_OBJECTS)
infofile_LDADD = $(LDADD)
../tape-src/libamtape.$(LIB_EXTENSION) \
../common-src/libamanda.$(LIB_EXTENSION) \
../tape-src/libamtape.$(LIB_EXTENSION) \
- ../common-src/libamanda.$(LIB_EXTENSION)
+ ../common-src/libamanda.$(LIB_EXTENSION) $(am__DEPENDENCIES_1)
planner_SOURCES = planner.c
planner_OBJECTS = planner.$(OBJEXT)
planner_LDADD = $(LDADD)
../tape-src/libamtape.$(LIB_EXTENSION) \
../common-src/libamanda.$(LIB_EXTENSION) \
../tape-src/libamtape.$(LIB_EXTENSION) \
- ../common-src/libamanda.$(LIB_EXTENSION)
+ ../common-src/libamanda.$(LIB_EXTENSION) $(am__DEPENDENCIES_1)
taper_SOURCES = taper.c
taper_OBJECTS = taper.$(OBJEXT)
taper_LDADD = $(LDADD)
../tape-src/libamtape.$(LIB_EXTENSION) \
../common-src/libamanda.$(LIB_EXTENSION) \
../tape-src/libamtape.$(LIB_EXTENSION) \
- ../common-src/libamanda.$(LIB_EXTENSION)
+ ../common-src/libamanda.$(LIB_EXTENSION) $(am__DEPENDENCIES_1)
sbinSCRIPT_INSTALL = $(INSTALL_SCRIPT)
SCRIPTS = $(sbin_SCRIPTS)
DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)/config
AMANDA_TMPDIR = @AMANDA_TMPDIR@
AMDEP_FALSE = @AMDEP_FALSE@
AMDEP_TRUE = @AMDEP_TRUE@
+AMLINT = @AMLINT@
+AMLINTFLAGS = @AMLINTFLAGS@
AMPLOT_CAT_COMPRESS = @AMPLOT_CAT_COMPRESS@
AMPLOT_CAT_GZIP = @AMPLOT_CAT_GZIP@
AMPLOT_CAT_PACK = @AMPLOT_CAT_PACK@
AMPLOT_COMPRESS = @AMPLOT_COMPRESS@
AMTAR = @AMTAR@
+AM_CFLAGS = @AM_CFLAGS@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AWK = @AWK@
AWK_VAR_ASSIGNMENT_OPT = @AWK_VAR_ASSIGNMENT_OPT@
BINARY_OWNER = @BINARY_OWNER@
+BUILD_MAN_PAGES_FALSE = @BUILD_MAN_PAGES_FALSE@
+BUILD_MAN_PAGES_TRUE = @BUILD_MAN_PAGES_TRUE@
CAT = @CAT@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
INCLUDES = -I$(top_builddir)/common-src \
-I$(top_srcdir)/common-src \
-I$(top_srcdir)/restore-src \
- -I$(top_srcdir)/tape-src
+ -I$(top_srcdir)/tape-src \
+ -I$(top_srcdir)/amandad-src
+LINT = @AMLINT@
+LINTFLAGS = @AMLINTFLAGS@
lib_LTLIBRARIES = libamserver.la
LIB_EXTENSION = la
sbin_SCRIPTS = amcheckdb amcleanup amdump \
amoverview amrmtape amtoc \
amverify amverifyrun amstatus \
- amcrypt amaespipe
+ amcrypt amaespipe amcrypt-ossl \
+ amcrypt-ossl-asym
libamserver_la_SOURCES = amindex.c changer.c \
conffile.c diskfile.c driverio.c \
# routines, and second to pick up any references in the other libraries.
###
LDADD = ../common-src/libamanda.$(LIB_EXTENSION) \
+ libamserver.$(LIB_EXTENSION) \
+ ../tape-src/libamtape.$(LIB_EXTENSION) \
+ ../common-src/libamanda.$(LIB_EXTENSION) \
+ ../tape-src/libamtape.$(LIB_EXTENSION) \
+ ../common-src/libamanda.$(LIB_EXTENSION) \
+ $(READLINE_LIBS)
+
+amindexd_LDADD = ../common-src/libamanda.$(LIB_EXTENSION) \
libamserver.$(LIB_EXTENSION) \
+ ../amandad-src/libamandad.$(LIB_EXTENSION) \
../tape-src/libamtape.$(LIB_EXTENSION) \
../common-src/libamanda.$(LIB_EXTENSION) \
../tape-src/libamtape.$(LIB_EXTENSION) \
# there are used for testing only:
TEST_PROGS = diskfile conffile infofile
CLEANFILES = *.test.c $(sbin_SCRIPTS)
-amindexd_SOURCES = amindexd.c \
- disk_history.c disk_history.h \
- list_dir.c list_dir.h
-
+amindexd_CSRC = amindexd.c disk_history.c list_dir.c
+amindexd_SOURCES = disk_history.h list_dir.h $(amindexd_CSRC)
amreport_SOURCES = reporter.c
amgetconf_SOURCES = getconf.c
noinst_HEADERS = amindex.h changer.h \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
amaespipe.sh: $(top_builddir)/config.status $(srcdir)/amaespipe.sh.in
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+amcrypt-ossl.sh: $(top_builddir)/config.status $(srcdir)/amcrypt-ossl.sh.in
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+amcrypt-ossl-asym.sh: $(top_builddir)/config.status $(srcdir)/amcrypt-ossl-asym.sh.in
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
install-libLTLIBRARIES: $(lib_LTLIBRARIES)
@$(NORMAL_INSTALL)
test -z "$(libdir)" || $(mkdir_p) "$(DESTDIR)$(libdir)"
else true; \
fi; \
done
-@WANT_SSH_SECURITY_FALSE@ @list="dumper planner"; \
-@WANT_SSH_SECURITY_FALSE@ for p in $$list; do \
-@WANT_SSH_SECURITY_FALSE@ if echo "$(libexec_PROGRAMS)" | grep $$p >/dev/null 2>&1; then \
-@WANT_SSH_SECURITY_FALSE@ pa=$(DESTDIR)$(libexecdir)/`echo $$p|sed '$(transform)'`; \
-@WANT_SSH_SECURITY_FALSE@ echo chown root $$pa; \
-@WANT_SSH_SECURITY_FALSE@ chown root $$pa; \
-@WANT_SSH_SECURITY_FALSE@ echo chmod u+s,o-rwx $$pa; \
-@WANT_SSH_SECURITY_FALSE@ chmod u+s,o-rwx $$pa; \
-@WANT_SSH_SECURITY_FALSE@ else true; \
-@WANT_SSH_SECURITY_FALSE@ fi; \
-@WANT_SSH_SECURITY_FALSE@ done
+
+ @list="dumper planner"; \
+ for p in $$list; do \
+ if echo "$(libexec_PROGRAMS)" | grep $$p >/dev/null 2>&1; then \
+ pa=$(DESTDIR)$(libexecdir)/`echo $$p|sed '$(transform)'`; \
+ echo chown root $$pa; \
+ chown root $$pa; \
+ echo chmod u+s,o-rwx $$pa; \
+ chmod u+s,o-rwx $$pa; \
+ else true; \
+ fi; \
+ done
+
+lint:
+ @ for p in $(libexec_PROGRAMS) $(sbin_PROGRAMS); do \
+ if [ $$p = "amindexd" ]; then \
+ s="$(amindexd_CSRC)"; \
+ elif [ $$p = "amreport" ]; then \
+ s="$(amreport_SOURCES)"; \
+ elif [ $$p = "amgetconf" ]; then \
+ s="$(getconf_SOURCES)"; \
+ else \
+ s=$$p.c; \
+ fi; \
+ f="$$s $(libamserver_la_SOURCES)"; \
+ (cd ../common-src; make listlibsrc); \
+ f="$$f "`cat ../common-src/listlibsrc.output`; \
+ (cd ../tape-src; make listlibsrc); \
+ f="$$f "`cat ../tape-src/listlibsrc.output`; \
+ echo $(LINT) $$f; \
+ $(LINT) $(LINTFLAGS) $(CPPFLAGS) $(DEFS) -I. -I../config \
+ $(INCLUDES) $$f; \
+ if [ $$? -ne 0 ]; then \
+ exit 1; \
+ fi; \
+ done; \
+ exit 0
+
+listlibsrc:
+ @ for p in $(libamserver_la_SOURCES); do \
+ listlibsrcs="$$listlibsrcs `pwd`/$$p"; \
+ done; \
+ echo $$listlibsrcs >listlibsrc.output
%.test.c: $(srcdir)/%.c
echo '#define TEST' >$@
* University of Maryland at College Park
*/
/*
- * $Id: amadmin.c,v 1.105 2006/02/03 17:29:28 vectro Exp $
+ * $Id: amadmin.c,v 1.124 2006/07/26 15:17:37 martinea Exp $
*
* controlling process for the Amanda backup system
*/
disklist_t diskq;
-int main P((int argc, char **argv));
-void usage P((void));
-void force P((int argc, char **argv));
-void force_one P((disk_t *dp));
-void unforce P((int argc, char **argv));
-void unforce_one P((disk_t *dp));
-void force_bump P((int argc, char **argv));
-void force_bump_one P((disk_t *dp));
-void force_no_bump P((int argc, char **argv));
-void force_no_bump_one P((disk_t *dp));
-void unforce_bump P((int argc, char **argv));
-void unforce_bump_one P((disk_t *dp));
-void reuse P((int argc, char **argv));
-void noreuse P((int argc, char **argv));
-void info P((int argc, char **argv));
-void info_one P((disk_t *dp));
-void due P((int argc, char **argv));
-void due_one P((disk_t *dp));
-void find P((int argc, char **argv));
-void delete P((int argc, char **argv));
-void delete_one P((disk_t *dp));
-void balance P((int argc, char **argv));
-void tape P((int argc, char **argv));
-void bumpsize P((int argc, char **argv));
-void diskloop P((int argc, char **argv, char *cmdname,
- void (*func) P((disk_t *dp))));
-char *seqdatestr P((int seq));
-static int next_level0 P((disk_t *dp, info_t *info));
-int bump_thresh P((int level));
-void export_db P((int argc, char **argv));
-void import_db P((int argc, char **argv));
-void disklist P((int argc, char **argv));
-void disklist_one P((disk_t *dp));
-void show_version P((int argc, char **argv));
-static void check_dumpuser P((void));
+int main(int argc, char **argv);
+void usage(void);
+void force(int argc, char **argv);
+void force_one(disk_t *dp);
+void unforce(int argc, char **argv);
+void unforce_one(disk_t *dp);
+void force_bump(int argc, char **argv);
+void force_bump_one(disk_t *dp);
+void force_no_bump(int argc, char **argv);
+void force_no_bump_one(disk_t *dp);
+void unforce_bump(int argc, char **argv);
+void unforce_bump_one(disk_t *dp);
+void reuse(int argc, char **argv);
+void noreuse(int argc, char **argv);
+void info(int argc, char **argv);
+void info_one(disk_t *dp);
+void due(int argc, char **argv);
+void due_one(disk_t *dp);
+void find(int argc, char **argv);
+void delete(int argc, char **argv);
+void delete_one(disk_t *dp);
+void balance(int argc, char **argv);
+void tape(int argc, char **argv);
+void bumpsize(int argc, char **argv);
+void diskloop(int argc, char **argv, char *cmdname, void (*func)(disk_t *dp));
+char *seqdatestr(int seq);
+static int next_level0(disk_t *dp, info_t *info);
+int bump_thresh(int level);
+void export_db(int argc, char **argv);
+void import_db(int argc, char **argv);
+void disklist(int argc, char **argv);
+void disklist_one(disk_t *dp);
+void show_version(int argc, char **argv);
+static void show_config(int argc, char **argv);
+static void check_dumpuser(void);
static char *conf_tapelist = NULL;
static char *displayunit;
static const struct {
const char *name;
- void (*fn) P((int, char **));
+ void (*fn)(int, char **);
const char *usage;
} cmdtab[] = {
{ "version", show_version,
- "\t\t\t\t# Show version info." },
+ "\t\t\t\t\t# Show version info." },
+ { "config", show_config,
+ "\t\t\t\t\t# Show configuration." },
{ "force", force,
- " [<hostname> [<disks>]* ]+\t# Force level 0 at next run." },
+ " [<hostname> [<disks>]* ]+\t\t# Force level 0 at next run." },
{ "unforce", unforce,
" [<hostname> [<disks>]* ]+\t# Clear force command." },
{ "force-bump", force_bump,
" [<hostname> [<disks>]* ]+\t# Force no-bump at next run." },
{ "unforce-bump", unforce_bump,
" [<hostname> [<disks>]* ]+\t# Clear bump command." },
+ { "disklist", disklist,
+ " [<hostname> [<disks>]* ]*\t# Debug disklist entries." },
{ "reuse", reuse,
- " <tapelabel> ...\t\t# re-use this tape." },
+ " <tapelabel> ...\t\t # re-use this tape." },
{ "no-reuse", noreuse,
- " <tapelabel> ...\t# never re-use this tape." },
+ " <tapelabel> ...\t # never re-use this tape." },
{ "find", find,
- " [<hostname> [<disks>]* ]*\t# Show which tapes these dumps are on." },
+ " [<hostname> [<disks>]* ]*\t # Show which tapes these dumps are on." },
{ "delete", delete,
- " [<hostname> [<disks>]* ]+\t# Delete from database." },
+ " [<hostname> [<disks>]* ]+ # Delete from database." },
{ "info", info,
- " [<hostname> [<disks>]* ]*\t# Show current info records." },
+ " [<hostname> [<disks>]* ]*\t # Show current info records." },
{ "due", due,
- " [<hostname> [<disks>]* ]*\t# Show due date." },
+ " [<hostname> [<disks>]* ]*\t # Show due date." },
{ "balance", balance,
- " [-days <num>]\t\t# Show nightly dump size balance." },
+ " [-days <num>]\t\t # Show nightly dump size balance." },
{ "tape", tape,
- " [-days <num>]\t\t\t# Show which tape is due next." },
+ " [-days <num>]\t\t # Show which tape is due next." },
{ "bumpsize", bumpsize,
- "\t\t\t# Show current bump thresholds." },
+ "\t\t\t # Show current bump thresholds." },
{ "export", export_db,
- " [<hostname> [<disks>]* ]*\t# Export curinfo database to stdout." },
+ " [<hostname> [<disks>]* ]* # Export curinfo database to stdout." },
{ "import", import_db,
- "\t\t\t\t# Import curinfo database from stdin." },
- { "disklist", disklist,
- " [<hostname> [<disks>]* ]*\t# Debug disklist entries." },
+ "\t\t\t\t # Import curinfo database from stdin." },
};
-#define NCMDS (sizeof(cmdtab) / sizeof(cmdtab[0]))
+#define NCMDS (int)(sizeof(cmdtab) / sizeof(cmdtab[0]))
-int main(argc, argv)
- int argc;
- char **argv;
+static char *conffile;
+
+int
+main(
+ int argc,
+ char ** argv)
{
int i;
char *conf_diskfile;
char *conf_infofile;
- char *conffile;
unsigned long malloc_hist_1, malloc_size_1;
unsigned long malloc_hist_2, malloc_size_2;
+ int new_argc;
+ char **new_argv;
safe_fd(-1, 0);
safe_cd();
set_pname("amadmin");
+ dbopen(DBG_SUBDIR_SERVER);
+
/* Don't die when child closes pipe */
signal(SIGPIPE, SIG_IGN);
erroutput_type = ERR_INTERACTIVE;
- if(argc < 3) usage();
+ parse_server_conf(argc, argv, &new_argc, &new_argv);
+
+ if(new_argc < 3) usage();
- if(strcmp(argv[2],"version") == 0) {
- show_version(argc, argv);
+ if(strcmp(new_argv[2],"version") == 0) {
+ show_version(new_argc, new_argv);
goto done;
}
- config_name = argv[1];
+ config_name = new_argv[1];
+
config_dir = vstralloc(CONFIG_DIR, "/", config_name, "/", NULL);
conffile = stralloc2(config_dir, CONFFILE_NAME);
- if(read_conffile(conffile))
+ if(read_conffile(conffile)) {
error("errors processing config file \"%s\"", conffile);
- amfree(conffile);
+ /*NOTREACHED*/
+ }
+
+ dbrename(config_name, DBG_SUBDIR_SERVER);
+
+ report_bad_conf_arg();
check_dumpuser();
} else {
conf_diskfile = stralloc2(config_dir, conf_diskfile);
}
- if (read_diskfile(conf_diskfile, &diskq) < 0)
+ if (read_diskfile(conf_diskfile, &diskq) < 0) {
error("could not load disklist \"%s\"", conf_diskfile);
+ /*NOTREACHED*/
+ }
amfree(conf_diskfile);
conf_tapelist = getconf_str(CNF_TAPELIST);
} else {
conf_tapelist = stralloc2(config_dir, conf_tapelist);
}
- if(read_tapelist(conf_tapelist))
+ if(read_tapelist(conf_tapelist)) {
error("could not load tapelist \"%s\"", conf_tapelist);
-
+ /*NOTREACHED*/
+ }
conf_infofile = getconf_str(CNF_INFOFILE);
if (*conf_infofile == '/') {
conf_infofile = stralloc(conf_infofile);
} else {
conf_infofile = stralloc2(config_dir, conf_infofile);
}
- if(open_infofile(conf_infofile))
+ if(open_infofile(conf_infofile)) {
error("could not open info db \"%s\"", conf_infofile);
+ /*NOTREACHED*/
+ }
amfree(conf_infofile);
displayunit = getconf_str(CNF_DISPLAYUNIT);
unitdivisor = getconf_unit_divisor();
for (i = 0; i < NCMDS; i++)
- if (strcmp(argv[2], cmdtab[i].name) == 0) {
- (*cmdtab[i].fn)(argc, argv);
+ if (strcmp(new_argv[2], cmdtab[i].name) == 0) {
+ (*cmdtab[i].fn)(new_argc, new_argv);
break;
}
if (i == NCMDS) {
- fprintf(stderr, "%s: unknown command \"%s\"\n", argv[0], argv[2]);
+ fprintf(stderr, "%s: unknown command \"%s\"\n", new_argv[0], new_argv[2]);
usage();
}
+ free_new_argv(new_argc, new_argv);
+
close_infofile();
clear_tapelist();
amfree(conf_tapelist);
malloc_list(fileno(stderr), malloc_hist_1, malloc_hist_2);
}
+ amfree(conffile);
+ free_disklist(&diskq);
+ free_server_config();
+ dbclose();
return 0;
}
-void usage P((void))
+void
+usage(void)
{
int i;
- fprintf(stderr, "\nUsage: %s%s <conf> <command> {<args>} ...\n",
+ fprintf(stderr, "\nUsage: %s%s <conf> <command> {<args>} [-o configoption]* ...\n",
get_pname(), versionsuffix());
fprintf(stderr, " Valid <command>s are:\n");
for (i = 0; i < NCMDS; i++)
#define SECS_PER_DAY (24*60*60)
time_t today;
-char *seqdatestr(seq)
-int seq;
+char *
+seqdatestr(
+ int seq)
{
static char str[16];
static char *dow[7] = {"Sun","Mon","Tue","Wed","Thu","Fri","Sat"};
tm = localtime(&t);
- snprintf(str, sizeof(str),
- "%2d/%02d %3s", tm->tm_mon+1, tm->tm_mday, dow[tm->tm_wday]);
+ if (tm)
+ snprintf(str, SIZEOF(str),
+ "%2d/%02d %3s", tm->tm_mon+1, tm->tm_mday, dow[tm->tm_wday]);
+ else
+ strcpy(str, "BAD DATE");
+
return str;
}
#undef days_diff
-#define days_diff(a, b) (((b) - (a) + SECS_PER_DAY) / SECS_PER_DAY)
+#define days_diff(a, b) (int)(((b) - (a) + SECS_PER_DAY) / SECS_PER_DAY)
/* when is next level 0 due? 0 = tonight, 1 = tommorrow, etc*/
-static int next_level0(dp, info)
-disk_t *dp;
-info_t *info;
+static int
+next_level0(
+ disk_t * dp,
+ info_t * info)
{
if(dp->strategy == DS_NOFULL)
return 1; /* fake it */
return dp->dumpcycle - days_diff(info->inf[0].date, today);
}
-static void check_dumpuser()
+static void
+check_dumpuser(void)
{
static int been_here = 0;
uid_t uid_me;
if ((pw = getpwnam(dumpuser)) == NULL) {
error("cannot look up dump user \"%s\"", dumpuser);
- /* NOTREACHED */
+ /*NOTREACHED*/
}
uid_dumpuser = pw->pw_uid;
if ((pw = getpwuid(uid_me)) == NULL) {
error("cannot look up my own uid %ld", (long)uid_me);
- /* NOTREACHED */
+ /*NOTREACHED*/
}
if (uid_me != uid_dumpuser) {
error("ERROR: running as user \"%s\" instead of \"%s\"",
pw->pw_name, dumpuser);
+ /*NOTREACHED*/
}
been_here = 1;
return;
/* ----------------------------------------------- */
-void diskloop(argc, argv, cmdname, func)
-int argc;
-char **argv;
-char *cmdname;
-void (*func) P((disk_t *dp));
+void
+diskloop(
+ int argc,
+ char ** argv,
+ char * cmdname,
+ void (*func)(disk_t *dp))
{
disk_t *dp;
int count = 0;
+ char *errstr;
if(argc < 4) {
fprintf(stderr,"%s: expecting \"%s [<hostname> [<disks>]* ]+\"\n",
usage();
}
- match_disklist(&diskq, argc-3, argv+3);
+ errstr = match_disklist(&diskq, argc-3, argv+3);
+ if (errstr) {
+ printf("%s", errstr);
+ amfree(errstr);
+ }
for(dp = diskq.head; dp != NULL; dp = dp->next) {
if(dp->todo) {
/* ----------------------------------------------- */
-void force_one(dp)
-disk_t *dp;
+void
+force_one(
+ disk_t * dp)
{
char *hostname = dp->host->hostname;
char *diskname = dp->name;
}
-void force(argc, argv)
-int argc;
-char **argv;
+void
+force(
+ int argc,
+ char ** argv)
{
diskloop(argc, argv, "force", force_one);
}
/* ----------------------------------------------- */
-void unforce_one(dp)
-disk_t *dp;
+void
+unforce_one(
+ disk_t * dp)
{
char *hostname = dp->host->hostname;
char *diskname = dp->name;
}
}
-void unforce(argc, argv)
-int argc;
-char **argv;
+void
+unforce(
+ int argc,
+ char ** argv)
{
diskloop(argc, argv, "unforce", unforce_one);
}
/* ----------------------------------------------- */
-void force_bump_one(dp)
-disk_t *dp;
+void
+force_bump_one(
+ disk_t * dp)
{
char *hostname = dp->host->hostname;
char *diskname = dp->name;
}
-void force_bump(argc, argv)
-int argc;
-char **argv;
+void
+force_bump(
+ int argc,
+ char ** argv)
{
diskloop(argc, argv, "force-bump", force_bump_one);
}
/* ----------------------------------------------- */
-void force_no_bump_one(dp)
-disk_t *dp;
+void
+force_no_bump_one(
+ disk_t * dp)
{
char *hostname = dp->host->hostname;
char *diskname = dp->name;
}
-void force_no_bump(argc, argv)
-int argc;
-char **argv;
+void
+force_no_bump(
+ int argc,
+ char ** argv)
{
diskloop(argc, argv, "force-no-bump", force_no_bump_one);
}
/* ----------------------------------------------- */
-void unforce_bump_one(dp)
-disk_t *dp;
+void
+unforce_bump_one(
+ disk_t * dp)
{
char *hostname = dp->host->hostname;
char *diskname = dp->name;
}
-void unforce_bump(argc, argv)
-int argc;
-char **argv;
+void
+unforce_bump(
+ int argc,
+ char ** argv)
{
diskloop(argc, argv, "unforce-bump", unforce_bump_one);
}
/* ----------------------------------------------- */
-void reuse(argc, argv)
-int argc;
-char **argv;
+void
+reuse(
+ int argc,
+ char ** argv)
{
tape_t *tp;
int count;
if(write_tapelist(conf_tapelist)) {
error("could not write tapelist \"%s\"", conf_tapelist);
+ /*NOTREACHED*/
}
}
-void noreuse(argc, argv)
-int argc;
-char **argv;
+void
+noreuse(
+ int argc,
+ char ** argv)
{
tape_t *tp;
int count;
if(write_tapelist(conf_tapelist)) {
error("could not write tapelist \"%s\"", conf_tapelist);
+ /*NOTREACHED*/
}
}
static int deleted;
-void delete_one(dp)
-disk_t *dp;
+void
+delete_one(
+ disk_t * dp)
{
char *hostname = dp->host->hostname;
char *diskname = dp->name;
}
deleted++;
- if(del_info(hostname, diskname))
+ if(del_info(hostname, diskname)) {
error("couldn't delete %s:%s from database: %s",
hostname, diskname, strerror(errno));
- else
+ /*NOTREACHED*/
+ } else {
printf("%s: %s:%s deleted from curinfo database.\n",
get_pname(), hostname, diskname);
+ }
}
-void delete(argc, argv)
-int argc;
-char **argv;
+void
+delete(
+ int argc,
+ char ** argv)
{
deleted = 0;
diskloop(argc, argv, "delete", delete_one);
/* ----------------------------------------------- */
-void info_one(dp)
-disk_t *dp;
+void
+info_one(
+ disk_t * dp)
{
info_t info;
int lev;
printf(" (Forcing bump at next run)\n");
if (ISSET(info.command, FORCE_NO_BUMP))
printf(" (Forcing no-bump at next run)\n");
- printf(" Stats: dump rates (kps), Full: %5.1f, %5.1f, %5.1f\n",
+ printf(" Stats: dump rates (kps), Full: %5.1lf, %5.1lf, %5.1lf\n",
info.full.rate[0], info.full.rate[1], info.full.rate[2]);
- printf(" Incremental: %5.1f, %5.1f, %5.1f\n",
+ printf(" Incremental: %5.1lf, %5.1lf, %5.1lf\n",
info.incr.rate[0], info.incr.rate[1], info.incr.rate[2]);
- printf(" compressed size, Full: %5.1f%%,%5.1f%%,%5.1f%%\n",
+ printf(" compressed size, Full: %5.1lf%%,%5.1lf%%,%5.1lf%%\n",
info.full.comp[0]*100, info.full.comp[1]*100, info.full.comp[2]*100);
- printf(" Incremental: %5.1f%%,%5.1f%%,%5.1f%%\n",
+ printf(" Incremental: %5.1lf%%,%5.1lf%%,%5.1lf%%\n",
info.incr.comp[0]*100, info.incr.comp[1]*100, info.incr.comp[2]*100);
printf(" Dumps: lev datestmp tape file origK compK secs\n");
for(lev = 0, sp = &info.inf[0]; lev < 9; lev++, sp++) {
if(sp->date < (time_t)0 && sp->label[0] == '\0') continue;
tm = localtime(&sp->date);
- printf(" %d %04d%02d%02d %-15s %4d %7ld %7ld %4ld\n",
- lev, tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday,
- sp->label, sp->filenum, sp->size, sp->csize, sp->secs);
+ if (tm) {
+ printf(" %d %04d%02d%02d %-15s "
+ OFF_T_FMT " " OFF_T_FMT " " OFF_T_FMT " " TIME_T_FMT "\n",
+ lev, tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday,
+ sp->label,
+ (OFF_T_FMT_TYPE)sp->filenum,
+ (OFF_T_FMT_TYPE)sp->size,
+ (OFF_T_FMT_TYPE)sp->csize,
+ (TIME_T_FMT_TYPE)sp->secs);
+ } else {
+ printf(" %d BAD-DATE %-15s "
+ OFF_T_FMT " " OFF_T_FMT " " OFF_T_FMT " " TIME_T_FMT "\n",
+ lev,
+ sp->label,
+ (OFF_T_FMT_TYPE)sp->filenum,
+ (OFF_T_FMT_TYPE)sp->size,
+ (OFF_T_FMT_TYPE)sp->csize,
+ (TIME_T_FMT_TYPE)sp->secs);
+ }
}
}
-void info(argc, argv)
-int argc;
-char **argv;
+void
+info(
+ int argc,
+ char ** argv)
{
disk_t *dp;
/* ----------------------------------------------- */
-void due_one(dp)
-disk_t *dp;
+void
+due_one(
+ disk_t * dp)
{
am_host_t *hp;
int days;
}
}
-void due(argc, argv)
-int argc;
-char **argv;
+void
+due(
+ int argc,
+ char ** argv)
{
disk_t *dp;
/* ----------------------------------------------- */
-void tape(argc, argv)
-int argc;
-char **argv;
+void
+tape(
+ int argc,
+ char ** argv)
{
tape_t *tp, *lasttp;
int runtapes, i, j;
printf("days must be an integer bigger than 0\n");
return;
}
+ if (nb_days > 10000)
+ nb_days = 10000;
}
runtapes = getconf_int(CNF_RUNTAPES);
printf("The next Amanda run should go onto ");
else
printf(" ");
- if(tp != NULL)
- printf("tape %s or ", tp->label);
- printf("a new tape.\n");
+ if(tp != NULL) {
+ printf("tape %s or a new tape.\n", tp->label);
+ } else {
+ if (runtapes - i == 1)
+ printf("1 new tape.\n");
+ else
+ printf("%d new tapes.\n", runtapes - i);
+ i = runtapes;
+ }
tp = lookup_last_reusable_tape(i + 1);
}
}
lasttp = lookup_tapepos(lookup_nb_tape());
i = runtapes;
- if(lasttp && i > 0 && lasttp->datestamp == 0) {
+ if(lasttp && i > 0 && strcmp(lasttp->datestamp,"0") == 0) {
int c = 0;
- while(lasttp && i > 0 && lasttp->datestamp == 0) {
+ while(lasttp && i > 0 && strcmp(lasttp->datestamp,"0") == 0) {
c++;
lasttp = lasttp->prev;
i--;
lasttp->label);
lasttp = lasttp->prev;
c--;
- while(lasttp && c > 0 && lasttp->datestamp == 0) {
+ while(lasttp && c > 0 && strcmp(lasttp->datestamp,"0") == 0) {
printf(", %s", lasttp->label);
lasttp = lasttp->prev;
c--;
/* ----------------------------------------------- */
-void balance(argc, argv)
-int argc;
-char **argv;
+void
+balance(
+ int argc,
+ char ** argv)
{
disk_t *dp;
struct balance_stats {
int disks;
- long origsize, outsize;
+ off_t origsize, outsize;
} *sp;
int conf_runspercycle, conf_dumpcycle;
int seq, runs_per_cycle, overdue, max_overdue;
int later, total, balance, distinct;
- float fseq, disk_dumpcycle;
+ double fseq, disk_dumpcycle;
info_t info;
- long int total_balanced, balanced;
+ off_t total_balanced, balanced;
int empty_day;
time(&today);
conf_dumpcycle = getconf_int(CNF_DUMPCYCLE);
conf_runspercycle = getconf_int(CNF_RUNSPERCYCLE);
later = conf_dumpcycle;
- if(later > 10000) later = 10000;
overdue = 0;
max_overdue = 0;
later = atoi(argv[4]);
if(later < 0) later = conf_dumpcycle;
}
+ if(later > 10000) later = 10000;
if(conf_runspercycle == 0) {
runs_per_cycle = conf_dumpcycle;
distinct = later + 3;
sp = (struct balance_stats *)
- alloc(sizeof(struct balance_stats) * (distinct+1));
+ alloc(SIZEOF(struct balance_stats) * (distinct+1));
- for(seq=0; seq <= distinct; seq++)
- sp[seq].disks = sp[seq].origsize = sp[seq].outsize = 0;
+ for(seq=0; seq <= distinct; seq++) {
+ sp[seq].disks = 0;
+ sp[seq].origsize = sp[seq].outsize = (off_t)0;
+ }
for(dp = diskq.head; dp != NULL; dp = dp->next) {
if(get_info(dp->host->hostname, dp->name, &info)) {
continue;
}
sp[distinct].disks++;
- sp[distinct].origsize += info.inf[0].size/unitdivisor;
- sp[distinct].outsize += info.inf[0].csize/unitdivisor;
+ sp[distinct].origsize += info.inf[0].size/(off_t)unitdivisor;
+ sp[distinct].outsize += info.inf[0].csize/(off_t)unitdivisor;
sp[balance].disks++;
if(dp->dumpcycle == 0) {
- sp[balance].origsize += (info.inf[0].size/unitdivisor) * runs_per_cycle;
- sp[balance].outsize += (info.inf[0].csize/unitdivisor) * runs_per_cycle;
+ sp[balance].origsize += (info.inf[0].size/(off_t)unitdivisor) * (off_t)runs_per_cycle;
+ sp[balance].outsize += (info.inf[0].csize/(off_t)unitdivisor) * (off_t)runs_per_cycle;
}
else {
- sp[balance].origsize += (info.inf[0].size/unitdivisor) *
- (conf_dumpcycle / dp->dumpcycle);
- sp[balance].outsize += (info.inf[0].csize/unitdivisor) *
- (conf_dumpcycle / dp->dumpcycle);
+ sp[balance].origsize += (info.inf[0].size/(off_t)unitdivisor) *
+ (off_t)(conf_dumpcycle / dp->dumpcycle);
+ sp[balance].outsize += (info.inf[0].csize/(off_t)unitdivisor) *
+ (off_t)(conf_dumpcycle / dp->dumpcycle);
}
- disk_dumpcycle = dp->dumpcycle;
+ disk_dumpcycle = (double)dp->dumpcycle;
if(dp->dumpcycle <= 0)
- disk_dumpcycle = ((float)conf_dumpcycle) / ((float)runs_per_cycle);
+ disk_dumpcycle = ((double)conf_dumpcycle) / ((double)runs_per_cycle);
seq = next_level0(dp, &info);
fseq = seq + 0.0001;
}
sp[seq].disks++;
- sp[seq].origsize += info.inf[0].size/unitdivisor;
- sp[seq].outsize += info.inf[0].csize/unitdivisor;
+ sp[seq].origsize += info.inf[0].size/(off_t)unitdivisor;
+ sp[seq].outsize += info.inf[0].csize/(off_t)unitdivisor;
if(seq < later) {
sp[total].disks++;
- sp[total].origsize += info.inf[0].size/unitdivisor;
- sp[total].outsize += info.inf[0].csize/unitdivisor;
+ sp[total].origsize += info.inf[0].size/(off_t)unitdivisor;
+ sp[total].outsize += info.inf[0].csize/(off_t)unitdivisor;
}
/* See, if there's another run in this dumpcycle */
fseq += disk_dumpcycle;
- seq = fseq;
+ seq = (int)fseq;
} while (seq < later);
}
- if(sp[total].outsize == 0 && sp[later].outsize == 0) {
+ if(sp[total].outsize == (off_t)0 && sp[later].outsize == (off_t)0) {
printf("\nNo data to report on yet.\n");
amfree(sp);
return;
}
- balanced = sp[balance].outsize / runs_per_cycle;
+ balanced = sp[balance].outsize / (off_t)runs_per_cycle;
if(conf_dumpcycle == later) {
- total_balanced = sp[total].outsize / runs_per_cycle;
+ total_balanced = sp[total].outsize / (off_t)runs_per_cycle;
}
else {
- total_balanced = 1024*(((sp[total].outsize/1024) * conf_dumpcycle)
- / (runs_per_cycle * later));
+ total_balanced = (((sp[total].outsize/(off_t)1024) * (off_t)conf_dumpcycle)
+ / (off_t)(runs_per_cycle * later)) * (off_t)1024;
}
empty_day = 0;
printf("\n");
empty_day = 0;
}
- printf("%-9.9s %3d %10ld %10ld ",
+ printf("%-9.9s %3d " OFF_T_FMT " " OFF_T_FMT " ",
seqdatestr(seq), sp[seq].disks,
- sp[seq].origsize, sp[seq].outsize);
+ (OFF_T_FMT_TYPE)sp[seq].origsize,
+ (OFF_T_FMT_TYPE)sp[seq].outsize);
if(!sp[seq].outsize) printf(" --- \n");
- else printf("%+8.1f%%\n",
- (sp[seq].outsize-balanced)*100.0/(double)balanced);
+ else printf("%+8.1lf%%\n",
+ (((double)sp[seq].outsize - (double)balanced) * 100.0 /
+ (double)balanced));
}
}
if(sp[later].disks != 0) {
- printf("later %3d %10ld %10ld ",
+ printf("later %3d " OFF_T_FMT " " OFF_T_FMT " ",
sp[later].disks,
- sp[later].origsize, sp[later].outsize);
+ (OFF_T_FMT_TYPE)sp[later].origsize,
+ (OFF_T_FMT_TYPE)sp[later].outsize);
if(!sp[later].outsize) printf(" --- \n");
- else printf("%+8.1f%%\n",
- (sp[later].outsize-balanced)*100.0/(double)balanced);
+ else printf("%+8.1lf%%\n",
+ (((double)sp[later].outsize - (double)balanced) * 100.0 /
+ (double)balanced));
}
printf("----------------------------------------------\n");
- printf("TOTAL %3d %10ld %10ld %9ld\n", sp[total].disks,
- sp[total].origsize, sp[total].outsize, total_balanced);
+ printf("TOTAL %3d " OFF_T_FMT " " OFF_T_FMT " " OFF_T_FMT "\n",
+ sp[total].disks,
+ (OFF_T_FMT_TYPE)sp[total].origsize,
+ (OFF_T_FMT_TYPE)sp[total].outsize,
+ (OFF_T_FMT_TYPE)total_balanced);
if (sp[balance].origsize != sp[total].origsize ||
sp[balance].outsize != sp[total].outsize ||
balanced != total_balanced) {
- printf("BALANCED %10ld %10ld %9ld\n",
- sp[balance].origsize, sp[balance].outsize, balanced);
+ printf("BALANCED " OFF_T_FMT " " OFF_T_FMT " " OFF_T_FMT "\n",
+ (OFF_T_FMT_TYPE)sp[balance].origsize,
+ (OFF_T_FMT_TYPE)sp[balance].outsize,
+ (OFF_T_FMT_TYPE)balanced);
}
if (sp[distinct].disks != sp[total].disks) {
- printf("DISTINCT %3d %10ld %10ld\n", sp[distinct].disks,
- sp[distinct].origsize, sp[distinct].outsize);
+ printf("DISTINCT %3d " OFF_T_FMT " " OFF_T_FMT "\n",
+ sp[distinct].disks,
+ (OFF_T_FMT_TYPE)sp[distinct].origsize,
+ (OFF_T_FMT_TYPE)sp[distinct].outsize);
}
printf(" (estimated %d run%s per dumpcycle)\n",
runs_per_cycle, (runs_per_cycle == 1) ? "" : "s");
/* ----------------------------------------------- */
-void find(argc, argv)
-int argc;
-char **argv;
+void
+find(
+ int argc,
+ char ** argv)
{
int start_argc;
char *sort_order = NULL;
find_result_t *output_find;
+ char *errstr;
if(argc < 3) {
fprintf(stderr,
sort_order = newstralloc(sort_order, DEFAULT_SORT_ORDER);
if(argc > 4 && strcmp(argv[3],"--sort") == 0) {
- int i, valid_sort=1;
+ size_t i, valid_sort=1;
- for(i=strlen(argv[4])-1;i>=0;i--) {
- switch (argv[4][i]) {
+ for(i = strlen(argv[4]); i > 0; i--) {
+ switch (argv[4][i - 1]) {
case 'h':
case 'H':
case 'k':
case 'D':
case 'l':
case 'L':
+ case 'p':
+ case 'P':
case 'b':
case 'B':
break;
} else {
start_argc=4;
}
- match_disklist(&diskq, argc-(start_argc-1), argv+(start_argc-1));
+ errstr = match_disklist(&diskq, argc-(start_argc-1), argv+(start_argc-1));
+ if (errstr) {
+ printf("%s", errstr);
+ amfree(errstr);
+ }
+
output_find = find_dump(1, &diskq);
if(argc-(start_argc-1) > 0) {
free_find_result(&output_find);
- match_disklist(&diskq, argc-(start_argc-1), argv+(start_argc-1));
+ errstr = match_disklist(&diskq, argc-(start_argc-1),
+ argv+(start_argc-1));
+ if (errstr) {
+ printf("%s", errstr);
+ amfree(errstr);
+ }
output_find = find_dump(0, NULL);
}
/* shared code with planner.c */
-int bump_thresh(level)
-int level;
+int
+bump_thresh(
+ int level)
{
int bump = getconf_int(CNF_BUMPSIZE);
double mult = getconf_real(CNF_BUMPMULT);
- while(--level) bump = (int) bump * mult;
+ while(--level)
+ bump = (int)((double)bump * mult);
return bump;
}
-void bumpsize(argc, argv)
-int argc;
-char **argv;
+void
+bumpsize(
+ int argc,
+ char ** argv)
{
int l;
int conf_bumppercent = getconf_int(CNF_BUMPPERCENT);
double conf_bumpmult = getconf_real(CNF_BUMPMULT);
+ (void)argc; /* Quiet unused parameter warning */
+ (void)argv; /* Quiet unused parameter warning */
+
printf("Current bump parameters:\n");
if(conf_bumppercent == 0) {
printf(" bumpsize %5d KB\t- minimum savings (threshold) to bump level 1 -> 2\n",
getconf_int(CNF_BUMPSIZE));
printf(" bumpdays %5d\t- minimum days at each level\n",
getconf_int(CNF_BUMPDAYS));
- printf(" bumpmult %5.5g\t- threshold = bumpsize * bumpmult**(level-1)\n\n",
+ printf(" bumpmult %5.5lg\t- threshold = bumpsize * bumpmult**(level-1)\n\n",
conf_bumpmult);
printf(" Bump -> To Threshold\n");
putchar('\n');
}
else {
- double bumppercent = conf_bumppercent;
+ double bumppercent = (double)conf_bumppercent;
printf(" bumppercent %3d %%\t- minimum savings (threshold) to bump level 1 -> 2\n",
conf_bumppercent);
printf(" bumpdays %5d\t- minimum days at each level\n",
getconf_int(CNF_BUMPDAYS));
- printf(" bumpmult %5.5g\t- threshold = disk_size * bumppercent * bumpmult**(level-1)\n\n",
+ printf(" bumpmult %5.5lg\t- threshold = disk_size * bumppercent * bumpmult**(level-1)\n\n",
conf_bumpmult);
printf(" Bump -> To Threshold\n");
for(l = 1; l < 9; l++) {
- printf("\t%d -> %d %7.2f %%\n", l, l+1, bumppercent);
+ printf("\t%d -> %d %7.2lf %%\n", l, l+1, bumppercent);
bumppercent *= conf_bumpmult;
if(bumppercent >= 100.000) { bumppercent = 100.0;}
}
/* ----------------------------------------------- */
-void export_one P((disk_t *dp));
+void export_one(disk_t *dp);
-void export_db(argc, argv)
-int argc;
-char **argv;
+void
+export_db(
+ int argc,
+ char ** argv)
{
disk_t *dp;
time_t curtime;
printf("CURINFO Version %s CONF %s\n", version(), getconf_str(CNF_ORG));
curtime = time(0);
- if(gethostname(hostname, sizeof(hostname)-1) == -1)
+ if(gethostname(hostname, SIZEOF(hostname)-1) == -1) {
error("could not determine host name: %s\n", strerror(errno));
- hostname[sizeof(hostname)-1] = '\0';
+ /*NOTREACHED*/
+ }
+ hostname[SIZEOF(hostname)-1] = '\0';
printf("# Generated by:\n# host: %s\n# date: %s",
hostname, ctime(&curtime));
export_one(dp);
}
-void export_one(dp)
-disk_t *dp;
+void
+export_one(
+ disk_t * dp)
{
info_t info;
int i,l;
return;
}
printf("host: %s\ndisk: %s\n", dp->host->hostname, dp->name);
- printf("command: %d\n", info.command);
+ printf("command: %u\n", info.command);
printf("last_level: %d\n",info.last_level);
printf("consecutive_runs: %d\n",info.consecutive_runs);
printf("full-rate:");
- for(i=0;i<AVG_COUNT;i++) printf(" %f", info.full.rate[i]);
+ for(i=0;i<AVG_COUNT;i++) printf(" %lf", info.full.rate[i]);
printf("\nfull-comp:");
- for(i=0;i<AVG_COUNT;i++) printf(" %f", info.full.comp[i]);
+ for(i=0;i<AVG_COUNT;i++) printf(" %lf", info.full.comp[i]);
printf("\nincr-rate:");
- for(i=0;i<AVG_COUNT;i++) printf(" %f", info.incr.rate[i]);
+ for(i=0;i<AVG_COUNT;i++) printf(" %lf", info.incr.rate[i]);
printf("\nincr-comp:");
- for(i=0;i<AVG_COUNT;i++) printf(" %f", info.incr.comp[i]);
+ for(i=0;i<AVG_COUNT;i++) printf(" %lf", info.incr.comp[i]);
printf("\n");
for(l=0;l<DUMP_LEVELS;l++) {
if(info.inf[l].date < (time_t)0 && info.inf[l].label[0] == '\0') continue;
- printf("stats: %d %ld %ld %ld %ld %d %s\n", l,
- info.inf[l].size, info.inf[l].csize, info.inf[l].secs,
- (long)info.inf[l].date, info.inf[l].filenum,
+ printf("stats: %d " OFF_T_FMT " " OFF_T_FMT " " TIME_T_FMT " " TIME_T_FMT " " OFF_T_FMT " %s\n", l,
+ (OFF_T_FMT_TYPE)info.inf[l].size,
+ (OFF_T_FMT_TYPE)info.inf[l].csize,
+ (TIME_T_FMT_TYPE)info.inf[l].secs,
+ (TIME_T_FMT_TYPE)info.inf[l].date,
+ (OFF_T_FMT_TYPE)info.inf[l].filenum,
info.inf[l].label);
}
for(l=0;info.history[l].level > -1;l++) {
- printf("history: %d %ld %ld %ld\n",info.history[l].level,
- info.history[l].size, info.history[l].csize,
- info.history[l].date);
+ printf("history: %d " OFF_T_FMT " " OFF_T_FMT " " TIME_T_FMT "\n",
+ info.history[l].level,
+ (OFF_T_FMT_TYPE)info.history[l].size,
+ (OFF_T_FMT_TYPE)info.history[l].csize,
+ (TIME_T_FMT_TYPE)info.history[l].date);
}
printf("//\n");
}
/* ----------------------------------------------- */
-int import_one P((void));
-char *impget_line P((void));
+int import_one(void);
+char *impget_line(void);
-void import_db(argc, argv)
-int argc;
-char **argv;
+void
+import_db(
+ int argc,
+ char ** argv)
{
- int vers_maj, vers_min, vers_patch, newer;
+ int vers_maj;
+ int vers_min;
+ int vers_patch;
+ int newer;
char *org;
char *line = NULL;
char *hdr;
char *s;
+ int rc;
int ch;
+ (void)argc; /* Quiet unused parameter warning */
+ (void)argv; /* Quiet unused parameter warning */
+
/* process header line */
if((line = agets(stdin)) == NULL) {
hdr = "version";
#define sc "CURINFO Version"
- if(strncmp(s - 1, sc, sizeof(sc)-1) != 0) {
+ if(strncmp(s - 1, sc, SIZEOF(sc)-1) != 0) {
goto bad_header;
}
- s += sizeof(sc)-1;
+ s += SIZEOF(sc)-1;
ch = *s++;
#undef sc
skip_whitespace(s, ch);
hdr = "CONF";
skip_whitespace(s, ch); /* find the org keyword */
#define sc "CONF"
- if(ch == '\0' || strncmp(s - 1, sc, sizeof(sc)-1) != 0) {
+ if(ch == '\0' || strncmp(s - 1, sc, SIZEOF(sc)-1) != 0) {
goto bad_header;
}
- s += sizeof(sc)-1;
+ s += SIZEOF(sc)-1;
ch = *s++;
#undef sc
}
org = s - 1;
+ /*@ignore@*/
newer = (vers_maj != VERSION_MAJOR)? vers_maj > VERSION_MAJOR :
(vers_min != VERSION_MINOR)? vers_min > VERSION_MINOR :
vers_patch > VERSION_PATCH;
fprintf(stderr,
"%s: WARNING: input is from newer Amanda version: %d.%d.%d.\n",
get_pname(), vers_maj, vers_min, vers_patch);
+ /*@end@*/
if(strcmp(org, getconf_str(CNF_ORG)) != 0) {
fprintf(stderr, "%s: WARNING: input is from different org: %s\n",
get_pname(), org);
}
- while(import_one());
+ do {
+ rc = import_one();
+ } while (rc);
amfree(line);
return;
bad_header:
- amfree(line);
+ /*@i@*/ amfree(line);
fprintf(stderr, "%s: bad CURINFO header line in input: %s.\n",
get_pname(), hdr);
fprintf(stderr, " Was the input in \"amadmin export\" format?\n");
}
-int import_one P((void))
+int
+import_one(void)
{
info_t info;
stats_t onestat;
int rc, level;
- long onedate;
+ time_t onedate;
+ time_t *onedate_p = &onedate;
char *line = NULL;
char *s, *fp;
int ch;
int nb_history, i;
char *hostname = NULL;
char *diskname = NULL;
+ time_t *secs_p;
#if TEXTDB
check_dumpuser();
#endif
- memset(&info, 0, sizeof(info_t));
+ memset(&info, 0, SIZEOF(info_t));
for(level = 0; level < DUMP_LEVELS; level++) {
info.inf[level].date = (time_t)-1;
skip_whitespace(s, ch);
#define sc "host:"
- if(ch == '\0' || strncmp(s - 1, sc, sizeof(sc)-1) != 0) goto parse_err;
- s += sizeof(sc)-1;
+ if(ch == '\0' || strncmp(s - 1, sc, SIZEOF(sc)-1) != 0) goto parse_err;
+ s += SIZEOF(sc)-1;
ch = s[-1];
#undef sc
skip_whitespace(s, ch);
skip_non_whitespace(s, ch);
s[-1] = '\0';
hostname = stralloc(fp);
- s[-1] = ch;
+ s[-1] = (char)ch;
skip_whitespace(s, ch);
while (ch == 0) {
skip_whitespace(s, ch);
}
#define sc "disk:"
- if(strncmp(s - 1, sc, sizeof(sc)-1) != 0) goto parse_err;
- s += sizeof(sc)-1;
+ if(strncmp(s - 1, sc, SIZEOF(sc)-1) != 0) goto parse_err;
+ s += SIZEOF(sc)-1;
ch = s[-1];
#undef sc
skip_whitespace(s, ch);
skip_non_whitespace(s, ch);
s[-1] = '\0';
diskname = stralloc(fp);
- s[-1] = ch;
+ s[-1] = (char)ch;
amfree(line);
if((line = impget_line()) == NULL) goto shortfile_err;
- if(sscanf(line, "command: %d", &info.command) != 1) goto parse_err;
+ if(sscanf(line, "command: %u", &info.command) != 1) goto parse_err;
/* get last_level and consecutive_runs */
/* get rate: and comp: lines for full dumps */
- rc = sscanf(line, "full-rate: %f %f %f",
+ rc = sscanf(line, "full-rate: %lf %lf %lf",
&info.full.rate[0], &info.full.rate[1], &info.full.rate[2]);
if(rc != 3) goto parse_err;
amfree(line);
if((line = impget_line()) == NULL) goto shortfile_err;
- rc = sscanf(line, "full-comp: %f %f %f",
+ rc = sscanf(line, "full-comp: %lf %lf %lf",
&info.full.comp[0], &info.full.comp[1], &info.full.comp[2]);
if(rc != 3) goto parse_err;
amfree(line);
if((line = impget_line()) == NULL) goto shortfile_err;
- rc = sscanf(line, "incr-rate: %f %f %f",
+ rc = sscanf(line, "incr-rate: %lf %lf %lf",
&info.incr.rate[0], &info.incr.rate[1], &info.incr.rate[2]);
if(rc != 3) goto parse_err;
amfree(line);
if((line = impget_line()) == NULL) goto shortfile_err;
- rc = sscanf(line, "incr-comp: %f %f %f",
+ rc = sscanf(line, "incr-comp: %lf %lf %lf",
&info.incr.comp[0], &info.incr.comp[1], &info.incr.comp[2]);
if(rc != 3) goto parse_err;
/* end of record */
break;
}
- memset(&onestat, 0, sizeof(onestat));
+ memset(&onestat, 0, SIZEOF(onestat));
s = line;
ch = *s++;
skip_whitespace(s, ch);
#define sc "stats:"
- if(ch == '\0' || strncmp(s - 1, sc, sizeof(sc)-1) != 0) {
+ if(ch == '\0' || strncmp(s - 1, sc, SIZEOF(sc)-1) != 0) {
goto parse_err;
}
- s += sizeof(sc)-1;
+ s += SIZEOF(sc)-1;
ch = s[-1];
#undef sc
skip_integer(s, ch);
skip_whitespace(s, ch);
- if(ch == '\0' || sscanf(s - 1, "%ld", &onestat.size) != 1) {
+ if(ch == '\0' || sscanf(s - 1, OFF_T_FMT,
+ (OFF_T_FMT_TYPE *)&onestat.size) != 1) {
goto parse_err;
}
skip_integer(s, ch);
skip_whitespace(s, ch);
- if(ch == '\0' || sscanf(s - 1, "%ld", &onestat.csize) != 1) {
+ if(ch == '\0' || sscanf(s - 1, OFF_T_FMT,
+ (OFF_T_FMT_TYPE *)&onestat.csize) != 1) {
goto parse_err;
}
skip_integer(s, ch);
skip_whitespace(s, ch);
- if(ch == '\0' || sscanf(s - 1, "%ld", &onestat.secs) != 1) {
+ secs_p = &onestat.secs;
+ if(ch == '\0' || sscanf(s - 1, TIME_T_FMT,
+ (TIME_T_FMT_TYPE *)secs_p) != 1) {
goto parse_err;
}
skip_integer(s, ch);
skip_whitespace(s, ch);
- if(ch == '\0' || sscanf(s - 1, "%ld", &onedate) != 1) {
+ if(ch == '\0' || sscanf(s - 1, TIME_T_FMT,
+ (TIME_T_FMT_TYPE *)onedate_p) != 1) {
goto parse_err;
}
skip_integer(s, ch);
skip_whitespace(s, ch);
if(ch != '\0') {
- if(sscanf(s - 1, "%d", &onestat.filenum) != 1) {
+ if(sscanf(s - 1, OFF_T_FMT, (OFF_T_FMT_TYPE *)&onestat.filenum) != 1) {
goto parse_err;
}
skip_integer(s, ch);
goto parse_err;
onestat.label[0] = '\0';
} else {
- strncpy(onestat.label, s - 1, sizeof(onestat.label)-1);
- onestat.label[sizeof(onestat.label)-1] = '\0';
+ strncpy(onestat.label, s - 1, SIZEOF(onestat.label)-1);
+ onestat.label[SIZEOF(onestat.label)-1] = '\0';
}
}
/* time_t not guarranteed to be long */
- onestat.date = onedate;
+ /*@i1@*/ onestat.date = onedate;
if(level < 0 || level > 9) goto parse_err;
info.inf[level] = onestat;
}
while(1) {
history_t onehistory;
- long date;
+ time_t date;
+ time_t *date_p = &date;
if(line[0] == '/' && line[1] == '/') {
info.history[nb_history].level = -2;
rc = 0;
break;
}
- memset(&onehistory, 0, sizeof(onehistory));
+ memset(&onehistory, 0, SIZEOF(onehistory));
s = line;
ch = *s++;
#define sc "history:"
- if(strncmp(line, sc, sizeof(sc)-1) != 0) {
+ if(strncmp(line, sc, SIZEOF(sc)-1) != 0) {
break;
}
- s += sizeof(sc)-1;
+ s += SIZEOF(sc)-1;
ch = s[-1];
#undef sc
skip_whitespace(s, ch);
skip_integer(s, ch);
skip_whitespace(s, ch);
- if(ch == '\0' || sscanf((s - 1), "%ld", &onehistory.size) != 1) {
+ if(ch == '\0' || sscanf((s - 1), OFF_T_FMT,
+ (OFF_T_FMT_TYPE *)&onehistory.size) != 1) {
break;
}
skip_integer(s, ch);
skip_whitespace(s, ch);
- if(ch == '\0' || sscanf((s - 1), "%ld", &onehistory.csize) != 1) {
+ if(ch == '\0' || sscanf((s - 1), OFF_T_FMT,
+ (OFF_T_FMT_TYPE *)&onehistory.csize) != 1) {
break;
}
skip_integer(s, ch);
skip_whitespace(s, ch);
- if(ch == '\0' || sscanf((s - 1), "%ld", &date) != 1) {
+ if((ch == '\0') || (sscanf((s - 1), TIME_T_FMT,
+ (TIME_T_FMT_TYPE *)date_p) != 1)) {
break;
}
skip_integer(s, ch);
- onehistory.date = date; /* time_t not guarranteed to be long */
+ /*@i1@*/onehistory.date = date; /* time_t not guarranteed to be long */
info.history[nb_history++] = onehistory;
amfree(line);
if((line = impget_line()) == NULL) goto shortfile_err;
}
- amfree(line);
+ /*@i@*/ amfree(line);
/* got a full record, now write it out to the database */
return 1;
parse_err:
- amfree(line);
+ /*@i@*/ amfree(line);
amfree(hostname);
amfree(diskname);
fprintf(stderr, "%s: parse error reading import record.\n", get_pname());
return 0;
shortfile_err:
- amfree(line);
+ /*@i@*/ amfree(line);
amfree(hostname);
amfree(diskname);
fprintf(stderr, "%s: short file reading import record.\n", get_pname());
}
char *
-impget_line ()
+impget_line(void)
{
char *line;
char *s;
/* ----------------------------------------------- */
-void disklist_one(dp)
-disk_t *dp;
+void
+disklist_one(
+ disk_t * dp)
{
am_host_t *hp;
interface_t *ip;
printf(" host %s:\n", hp->hostname);
printf(" interface %s\n",
ip->name[0] ? ip->name : "default");
-
printf(" disk %s:\n", dp->name);
if(dp->device) printf(" device %s\n", dp->device);
}
printf("\n");
}
- printf(" priority %ld\n", dp->priority);
- printf(" dumpcycle %ld\n", dp->dumpcycle);
+ printf(" priority %d\n", dp->priority);
+ printf(" dumpcycle %d\n", dp->dumpcycle);
printf(" maxdumps %d\n", dp->maxdumps);
printf(" maxpromoteday %d\n", dp->maxpromoteday);
if(dp->bumppercent > 0) {
printf(" bumppercent %d\n", dp->bumppercent);
}
else {
- printf(" bumpsize %d\n", dp->bumpsize);
+ printf(" bumpsize " OFF_T_FMT "\n",
+ (OFF_T_FMT_TYPE)dp->bumpsize);
}
printf(" bumpdays %d\n", dp->bumpdays);
- printf(" bumpmult %f\n", dp->bumpmult);
+ printf(" bumpmult %lf\n", dp->bumpmult);
printf(" strategy ");
switch(dp->strategy) {
break;
}
if(dp->compress != COMP_NONE) {
- printf(" comprate %.2f %.2f\n",
+ printf(" comprate %.2lf %.2lf\n",
dp->comprate[0], dp->comprate[1]);
}
printf(" auth %s\n", dp->security_driver);
printf(" kencrypt %s\n", (dp->kencrypt? "YES" : "NO"));
- printf(" holdingdisk %s\n", (!dp->no_hold? "YES" : "NO"));
+ printf(" amandad_path %s\n", dp->amandad_path);
+ printf(" client_username %s\n", dp->client_username);
+ printf(" ssh_keys %s\n", dp->ssh_keys);
+
+ printf(" holdingdisk ");
+ switch(dp->to_holdingdisk) {
+ case HOLD_NEVER:
+ printf("NEVER\n");
+ break;
+ case HOLD_AUTO:
+ printf("AUTO\n");
+ break;
+ case HOLD_REQUIRED:
+ printf("REQUIRED\n");
+ break;
+ }
+
printf(" record %s\n", (dp->record? "YES" : "NO"));
printf(" index %s\n", (dp->index? "YES" : "NO"));
st = dp->start_t;
if(st) {
stm = localtime(&st);
- printf(" starttime %d:%02d:%02d\n",
- stm->tm_hour, stm->tm_min, stm->tm_sec);
+ if (stm)
+ printf(" starttime %d:%02d:%02d\n",
+ stm->tm_hour, stm->tm_min, stm->tm_sec);
+ else
+ printf(" starttime BAD DATE\n");
}
- if(dp->tape_splitsize > 0) {
- printf(" tape_splitsize %ld\n", dp->tape_splitsize);
+ if(dp->tape_splitsize > (off_t)0) {
+ printf(" tape_splitsize " OFF_T_FMT "\n",
+ (OFF_T_FMT_TYPE)dp->tape_splitsize);
}
if(dp->split_diskbuffer) {
printf(" split_diskbuffer %s\n", dp->split_diskbuffer);
}
- if(dp->fallback_splitsize > 0) {
- printf(" fallback_splitsize %ldMb\n", (dp->fallback_splitsize / 1024));
+ if(dp->fallback_splitsize > (off_t)0) {
+ printf(" fallback_splitsize " OFF_T_FMT "Mb\n",
+ (OFF_T_FMT_TYPE)(dp->fallback_splitsize / (off_t)1024));
}
printf(" skip-incr %s\n", (dp->skip_incr? "YES" : "NO"));
printf(" skip-full %s\n", (dp->skip_full? "YES" : "NO"));
+ printf(" spindle %d\n", dp->spindle);
printf("\n");
}
-void disklist(argc, argv)
-int argc;
-char **argv;
+void
+disklist(
+ int argc,
+ char ** argv)
{
disk_t *dp;
disklist_one(dp);
}
-void show_version(argc, argv)
-int argc;
-char **argv;
+void
+show_version(
+ int argc,
+ char ** argv)
{
int i;
+ (void)argc; /* Quiet unused parameter warning */
+ (void)argv; /* Quiet unused parameter warning */
+
for(i = 0; version_info[i] != NULL; i++)
printf("%s", version_info[i]);
}
+
+
+void show_config(
+ int argc,
+ char **argv)
+{
+ argc = argc;
+ argv = argv;
+ dump_configuration(conffile);
+}
+
-#! /bin/sh
+#! @SHELL@
#
# Copyright (c) 2005 Zmanda Inc. All Rights Reserved.
#
* file named AUTHORS, in the root directory of this distribution.
*/
/*
- * $Id: amcheck.c,v 1.121 2006/02/06 22:17:09 ktill Exp $
+ * $Id: amcheck.c,v 1.149 2006/08/24 01:57:16 paddy_s Exp $
*
* checks for common problems in server and clients
*/
#define BUFFER_SIZE 32768
-static int conf_ctimeout;
+static time_t conf_ctimeout;
static int overwrite;
static disklist_t origq;
/* local functions */
-void usage P((void));
-int start_client_checks P((int fd));
-int start_server_check P((int fd, int do_localchk, int do_tapechk));
-int main P((int argc, char **argv));
-int test_server_pgm P((FILE *outf, char *dir, char *pgm,
- int suid, uid_t dumpuid));
+void usage(void);
+pid_t start_client_checks(int fd);
+pid_t start_server_check(int fd, int do_localchk, int do_tapechk);
+int main(int argc, char **argv);
+int test_server_pgm(FILE *outf, char *dir, char *pgm, int suid, uid_t dumpuid);
-void usage()
+void
+usage(void)
{
- error("Usage: amcheck%s [-M <username>] [-mawsclt] <conf> [host [disk]* ]*", versionsuffix());
+ error("Usage: amcheck%s [-am] [-w] [-sclt] [-M <address>] <conf> [host [disk]* ]* [-o configoption]*", versionsuffix());
+ /*NOTREACHED*/
}
static unsigned long malloc_hist_1, malloc_size_1;
static char *displayunit;
static long int unitdivisor;
-int main(argc, argv)
-int argc;
-char **argv;
+int
+main(
+ int argc,
+ char ** argv)
{
char buffer[BUFFER_SIZE];
char *version_string;
char *mainfname = NULL;
char pid_str[NUM_STR_SIZE];
- int do_clientchk, clientchk_pid, client_probs;
- int do_localchk, do_tapechk, serverchk_pid, server_probs;
- int chk_flag;
- int opt, size, tempfd, mainfd;
+ int do_clientchk, client_probs;
+ int do_localchk, do_tapechk, server_probs;
+ pid_t clientchk_pid, serverchk_pid;
+ int opt, tempfd, mainfd;
+ ssize_t size;
amwait_t retstat;
pid_t pid;
extern int optind;
char *dumpuser;
struct passwd *pw;
uid_t uid_me;
+ int new_argc, my_argc;
+ char **new_argv, **my_argv;
+ char *errstr;
safe_fd(-1, 0);
safe_cd();
/* Don't die when child closes pipe */
signal(SIGPIPE, SIG_IGN);
- dbopen();
+ dbopen(DBG_SUBDIR_SERVER);
+ memset(buffer, 0, sizeof(buffer));
malloc_size_1 = malloc_inuse(&malloc_hist_1);
- snprintf(pid_str, sizeof(pid_str), "%ld", (long)getpid());
+ snprintf(pid_str, SIZEOF(pid_str), "%ld", (long)getpid());
erroutput_type = ERR_INTERACTIVE;
alwaysmail = mailout = overwrite = 0;
do_localchk = do_tapechk = do_clientchk = 0;
- chk_flag = 0;
server_probs = client_probs = 0;
tempfd = mainfd = -1;
+ parse_server_conf(argc, argv, &new_argc, &new_argv);
+ my_argc = new_argc;
+ my_argv = new_argv;
+
/* process arguments */
- while((opt = getopt(argc, argv, "M:mawsclt")) != EOF) {
+ while((opt = getopt(my_argc, my_argv, "M:mawsclt")) != EOF) {
switch(opt) {
case 'M': mailto=stralloc(optarg);
+ if(!validate_mailto(mailto)){
+ printf("Invalid characters in mail address\n");
+ exit(1);
+ }
+ /*FALLTHROUGH*/
case 'm':
#ifdef MAILER
mailout = 1;
exit(1);
#endif
break;
- case 's': do_localchk = 1; do_tapechk = 1;
- chk_flag = 1;
+ case 's': do_localchk = do_clientchk = do_tapechk = 1;
break;
case 'c': do_clientchk = 1;
- chk_flag = 1;
break;
case 'l': do_localchk = 1;
- chk_flag = 1;
break;
- case 'w': do_tapechk = 1; overwrite = 1;
- chk_flag = 1;
+ case 'w': overwrite = 1;
break;
case 't': do_tapechk = 1;
- chk_flag = 1;
break;
case '?':
default:
usage();
}
}
- argc -= optind, argv += optind;
- if(! chk_flag) {
+ my_argc -= optind, my_argv += optind;
+ if(my_argc < 1) usage();
+
+
+ if ((do_localchk | do_clientchk | do_tapechk) == 0) {
+ /* Check everything if individual checks were not asked for */
do_localchk = do_clientchk = do_tapechk = 1;
}
- if(argc < 1) usage();
+ if(overwrite)
+ do_tapechk = 1;
- config_name = stralloc(*argv);
+ config_name = stralloc(*my_argv);
config_dir = vstralloc(CONFIG_DIR, "/", config_name, "/", NULL);
conffile = stralloc2(config_dir, CONFFILE_NAME);
if(read_conffile(conffile)) {
error("errors processing config file \"%s\"", conffile);
+ /*NOTREACHED*/
}
+
+ dbrename(config_name, DBG_SUBDIR_SERVER);
+
+ report_bad_conf_arg();
+
amfree(conffile);
+ if(mailout && !mailto &&
+ (getconf_seen(CNF_MAILTO)==0 || strlen(getconf_str(CNF_MAILTO)) == 0)) {
+ printf("\nNo mail address configured in amanda.conf\n");
+ if(alwaysmail)
+ printf("When using -a option please specify -Maddress also\n\n");
+ else
+ printf("Use -Maddress instead of -m\n\n");
+ exit(1);
+ }
+ if(mailout && !mailto)
+ {
+ if(getconf_seen(CNF_MAILTO) &&
+ strlen(getconf_str(CNF_MAILTO)) > 0) {
+ if(!validate_mailto(getconf_str(CNF_MAILTO))){
+ printf("\nMail address in amanda.conf has invalid characters");
+ printf("\nNo email will be sent\n");
+ mailout = 0;
+ }
+ }
+ else {
+ printf("\nNo mail address configured in amanda.conf\n");
+ if(alwaysmail)
+ printf("When using -a option please specify -Maddress also\n\n");
+ else
+ printf("Use -Maddress instead of -m\n\n");
+ exit(1);
+ }
+ }
- conf_ctimeout = getconf_int(CNF_CTIMEOUT);
+ conf_ctimeout = getconf_time(CNF_CTIMEOUT);
conf_diskfile = getconf_str(CNF_DISKFILE);
if (*conf_diskfile == '/') {
}
if(read_diskfile(conf_diskfile, &origq) < 0) {
error("could not load disklist %s", conf_diskfile);
+ /*NOTREACHED*/
+ }
+ errstr = match_disklist(&origq, my_argc-1, my_argv+1);
+ if (errstr) {
+ printf("%s",errstr);
+ amfree(errstr);
}
- match_disklist(&origq, argc-1, argv+1);
amfree(conf_diskfile);
/*
dumpuser = getconf_str(CNF_DUMPUSER);
if ((pw = getpwnam(dumpuser)) == NULL) {
error("cannot look up dump user \"%s\"", dumpuser);
+ /*NOTREACHED*/
}
uid_dumpuser = pw->pw_uid;
if ((pw = getpwuid(uid_me)) == NULL) {
error("cannot look up my own uid (%ld)", (long)uid_me);
+ /*NOTREACHED*/
}
if (uid_me != uid_dumpuser) {
error("running as user \"%s\" instead of \"%s\"",
- pw->pw_name,
- dumpuser);
+ pw->pw_name, dumpuser);
+ /*NOTREACHED*/
}
displayunit = getconf_str(CNF_DISPLAYUNIT);
if(do_clientchk && (do_localchk || do_tapechk)) {
/* we need the temp file */
tempfname = vstralloc(AMANDA_TMPDIR, "/amcheck.temp.", pid_str, NULL);
- if((tempfd = open(tempfname, O_RDWR|O_CREAT|O_TRUNC, 0600)) == -1)
+ if((tempfd = open(tempfname, O_RDWR|O_CREAT|O_TRUNC, 0600)) == -1) {
error("could not open %s: %s", tempfname, strerror(errno));
+ /*NOTREACHED*/
+ }
unlink(tempfname); /* so it goes away on close */
amfree(tempfname);
}
if(mailout) {
/* the main fd is a file too */
mainfname = vstralloc(AMANDA_TMPDIR, "/amcheck.main.", pid_str, NULL);
- if((mainfd = open(mainfname, O_RDWR|O_CREAT|O_TRUNC, 0600)) == -1)
+ if((mainfd = open(mainfname, O_RDWR|O_CREAT|O_TRUNC, 0600)) == -1) {
error("could not open %s: %s", mainfname, strerror(errno));
+ /*NOTREACHED*/
+ }
unlink(mainfname); /* so it goes away on close */
amfree(mainfname);
}
char number[NUM_STR_SIZE];
char *wait_msg = NULL;
- snprintf(number, sizeof(number), "%ld", (long)pid);
+ snprintf(number, SIZEOF(number), "%ld", (long)pid);
wait_msg = vstralloc("parent: reaped bogus pid ", number, "\n",
NULL);
- if (fullwrite(mainfd, wait_msg, strlen(wait_msg)) < 0)
+ if (fullwrite(mainfd, wait_msg, strlen(wait_msg)) < 0) {
error("write main file: %s", strerror(errno));
+ /*NOTREACHED*/
+ }
amfree(wait_msg);
}
}
/* copy temp output to main output and write tagline */
if(do_clientchk && (do_localchk || do_tapechk)) {
- if(lseek(tempfd, 0, 0) == -1)
+ if(lseek(tempfd, (off_t)0, 0) == (off_t)-1) {
error("seek temp file: %s", strerror(errno));
+ /*NOTREACHED*/
+ }
- while((size=fullread(tempfd, buffer, sizeof(buffer))) > 0) {
- if (fullwrite(mainfd, buffer, size) < 0)
+ while((size = fullread(tempfd, buffer, SIZEOF(buffer))) > 0) {
+ if (fullwrite(mainfd, buffer, (size_t)size) < 0) {
error("write main file: %s", strerror(errno));
+ /*NOTREACHED*/
+ }
}
- if(size < 0)
+ if(size < 0) {
error("read temp file: %s", strerror(errno));
+ /*NOTREACHED*/
+ }
aclose(tempfd);
}
version_string = vstralloc("\n",
"(brought to you by Amanda ", version(), ")\n",
NULL);
- if (fullwrite(mainfd, version_string, strlen(version_string)) < 0)
+ if (fullwrite(mainfd, version_string, strlen(version_string)) < 0) {
error("write main file: %s", strerror(errno));
+ /*NOTREACHED*/
+ }
amfree(version_string);
amfree(config_dir);
amfree(config_name);
char *subject;
char **a;
amwait_t retstat;
- pid_t mailpid;
- pid_t wpid;
- int r;
- int w;
+ ssize_t r;
+ ssize_t w;
char *err = NULL;
char *extra_info = NULL;
char *line = NULL;
char number[NUM_STR_SIZE];
fflush(stdout);
- if(lseek(mainfd, (off_t)0, SEEK_SET) == -1) {
+ if(lseek(mainfd, (off_t)0, SEEK_SET) == (off_t)-1) {
error("lseek main file: %s", strerror(errno));
+ /*NOTREACHED*/
}
if(alwaysmail && !(server_probs || client_probs)) {
subject = stralloc2(getconf_str(CNF_ORG),
* Remember that split() returns the original input string in
* argv[0], so we have to skip over that.
*/
- a = (char **) alloc((MAILTO_LIMIT + 1) * sizeof(char *));
- memset(a, 0, (MAILTO_LIMIT + 1) * sizeof(char *));
+ a = (char **) alloc((MAILTO_LIMIT + 1) * SIZEOF(char *));
+ memset(a, 0, (MAILTO_LIMIT + 1) * SIZEOF(char *));
if(mailto) {
a[1] = mailto;
a[2] = NULL;
} else {
- r = split(getconf_str(CNF_MAILTO), a, MAILTO_LIMIT, " ");
+ r = (ssize_t)split(getconf_str(CNF_MAILTO), a, MAILTO_LIMIT, " ");
a[r + 1] = NULL;
}
if((nullfd = open("/dev/null", O_RDWR)) < 0) {
error("nullfd: /dev/null: %s", strerror(errno));
+ /*NOTREACHED*/
}
- mailpid = pipespawn(MAILER, STDIN_PIPE | STDERR_PIPE,
+ pipespawn(MAILER, STDIN_PIPE | STDERR_PIPE,
&mailfd, &nullfd, &errfd,
MAILER,
"-s", subject,
* cases, the pipe will break and we will exit out of the loop.
*/
signal(SIGPIPE, SIG_IGN);
- while((r = fullread(mainfd, buffer, sizeof(buffer))) > 0) {
- if((w = fullwrite(mailfd, buffer, r)) != r) {
+ while((r = fullread(mainfd, buffer, SIZEOF(buffer))) > 0) {
+ if((w = fullwrite(mailfd, buffer, (size_t)r)) != (ssize_t)r) {
if(w < 0 && errno == EPIPE) {
strappend(extra_info, "EPIPE writing to mail process\n");
break;
} else if(w < 0) {
error("mailfd write: %s", strerror(errno));
+ /*NOTREACHED*/
} else {
error("mailfd write: wrote %d instead of %d", w, r);
+ /*NOTREACHED*/
}
}
}
aclose(mailfd);
ferr = fdopen(errfd, "r");
+ if (!ferr) {
+ error("Can't fdopen: %s", strerror(errno));
+ /*NOTREACHED*/
+ }
for(; (line = agets(ferr)) != NULL; free(line)) {
+ if (line[0] == '\0')
+ continue;
strappend(extra_info, line);
strappend(extra_info, "\n");
}
afclose(ferr);
errfd = -1;
rc = 0;
- while ((wpid = wait(&retstat)) != -1) {
+ while (wait(&retstat) != -1) {
if (WIFSIGNALED(retstat)) {
ret = 0;
rc = sig = WTERMSIG(retstat);
} else {
strappend(err, "returned ");
}
- snprintf(number, sizeof(number), "%d", ret);
+ snprintf(number, SIZEOF(number), "%d", ret);
strappend(err, number);
}
}
amfree(extra_info);
}
error("error running mailer %s: %s", MAILER, err);
+ /*NOTREACHED*/
}
}
#endif
+ free_new_argv(new_argc, new_argv);
+ free_server_config();
+
dbclose();
return (server_probs || client_probs);
}
char *label;
char *searchlabel, *labelstr;
tape_t *tp;
-FILE *errf;
-
-int test_server_pgm(outf, dir, pgm, suid, dumpuid)
-FILE *outf;
-char *dir;
-char *pgm;
-int suid;
-uid_t dumpuid;
+FILE *errf = NULL;
+
+int
+test_server_pgm(
+ FILE * outf,
+ char * dir,
+ char * pgm,
+ int suid,
+ uid_t dumpuid)
{
struct stat statbuf;
int pgmbad = 0;
+ char *quoted;
pgm = vstralloc(dir, "/", pgm, versionsuffix(), NULL);
+ quoted = quote_string(pgm);
if(stat(pgm, &statbuf) == -1) {
fprintf(outf, "ERROR: program %s: does not exist\n",
- pgm);
+ quoted);
pgmbad = 1;
} else if (!S_ISREG(statbuf.st_mode)) {
fprintf(outf, "ERROR: program %s: not a file\n",
- pgm);
+ quoted);
pgmbad = 1;
} else if (access(pgm, X_OK) == -1) {
fprintf(outf, "ERROR: program %s: not executable\n",
- pgm);
+ quoted);
pgmbad = 1;
} else if (suid \
&& dumpuid != 0
&& (statbuf.st_uid != 0 || (statbuf.st_mode & 04000) == 0)) {
- fprintf(outf, "WARNING: program %s: not setuid-root\n",
- pgm);
+ fprintf(outf, "ERROR: program %s: not setuid-root\n",
+ quoted);
+ pgmbad = 1;
}
+ amfree(quoted);
amfree(pgm);
return pgmbad;
}
-int start_server_check(fd, do_localchk, do_tapechk)
- int fd;
- int do_localchk, do_tapechk;
+pid_t
+start_server_check(
+ int fd,
+ int do_localchk,
+ int do_tapechk)
{
char *tapename;
generic_fs_stats_t fs;
- FILE *outf;
+ FILE *outf = NULL;
holdingdisk_t *hdp;
- int pid;
+ pid_t pid;
int confbad = 0, tapebad = 0, disklow = 0, logbad = 0;
int userbad = 0, infobad = 0, indexbad = 0, pgmbad = 0;
int testtape = do_tapechk;
tapetype_t *tp = NULL;
+ char *quoted;
switch(pid = fork()) {
- case -1: error("could not fork server check: %s", strerror(errno));
- case 0: break;
+ case -1:
+ error("could not fork server check: %s", strerror(errno));
+ /*NOTREACHED*/
+
+ case 0:
+ break;
+
default:
return pid;
}
startclock();
- if((outf = fdopen(fd, "w")) == NULL)
+ if((outf = fdopen(fd, "w")) == NULL) {
error("fdopen %d: %s", fd, strerror(errno));
+ /*NOTREACHED*/
+ }
errf = outf;
fprintf(outf, "Amanda Tape Server Host Check\n");
amfree(errstr);
confbad = 1;
}
- lbl_templ = tp->lbl_templ;
+ lbl_templ = tapetype_get_lbl_templ(tp);
if(strcmp(lbl_templ, "") != 0) {
if(strchr(lbl_templ, '/') == NULL) {
lbl_templ = stralloc2(config_dir, lbl_templ);
confbad = 1;
#endif
}
+
+ /* check that localhost is resolvable */
+ if ((gethostbyname("localhost")) == NULL) {
+ fprintf(outf, "ERROR: Cannot resolve `localhost'.\n");
+ }
}
/*
* Look up the programs used on the server side.
*/
if(do_localchk) {
- int suid_check=1;
-#ifdef SSH_SECURITY
- suid_check=0;
-#endif
+ /*
+ * entreprise version will do planner/dumper suid check
+ */
if(access(libexecdir, X_OK) == -1) {
+ quoted = quote_string(libexecdir);
fprintf(outf, "ERROR: program dir %s: not accessible\n",
- libexecdir);
+ quoted);
pgmbad = 1;
+ amfree(quoted);
} else {
- pgmbad = pgmbad \
- || test_server_pgm(outf, libexecdir, "planner",
- suid_check, uid_dumpuser);
- pgmbad = pgmbad \
- || test_server_pgm(outf, libexecdir, "dumper",
- suid_check, uid_dumpuser);
- pgmbad = pgmbad \
- || test_server_pgm(outf, libexecdir, "driver",
- 0, uid_dumpuser);
- pgmbad = pgmbad \
- || test_server_pgm(outf, libexecdir, "taper",
- 0, uid_dumpuser);
- pgmbad = pgmbad \
- || test_server_pgm(outf, libexecdir, "amtrmidx",
- 0, uid_dumpuser);
- pgmbad = pgmbad \
- || test_server_pgm(outf, libexecdir, "amlogroll",
- 0, uid_dumpuser);
+ if(test_server_pgm(outf, libexecdir, "planner", 1, uid_dumpuser))
+ pgmbad = 1;
+ if(test_server_pgm(outf, libexecdir, "dumper", 1, uid_dumpuser))
+ pgmbad = 1;
+ if(test_server_pgm(outf, libexecdir, "driver", 0, uid_dumpuser))
+ pgmbad = 1;
+ if(test_server_pgm(outf, libexecdir, "taper", 0, uid_dumpuser))
+ pgmbad = 1;
+ if(test_server_pgm(outf, libexecdir, "amtrmidx", 0, uid_dumpuser))
+ pgmbad = 1;
+ if(test_server_pgm(outf, libexecdir, "amlogroll", 0, uid_dumpuser))
+ pgmbad = 1;
}
if(access(sbindir, X_OK) == -1) {
+ quoted = quote_string(sbindir);
fprintf(outf, "ERROR: program dir %s: not accessible\n",
sbindir);
pgmbad = 1;
+ amfree(quoted);
} else {
- pgmbad = pgmbad \
- || test_server_pgm(outf, sbindir, "amgetconf",
- 0, uid_dumpuser);
- pgmbad = pgmbad \
- || test_server_pgm(outf, sbindir, "amcheck",
- 1, uid_dumpuser);
- pgmbad = pgmbad \
- || test_server_pgm(outf, sbindir, "amdump",
- 0, uid_dumpuser);
- pgmbad = pgmbad \
- || test_server_pgm(outf, sbindir, "amreport",
- 0, uid_dumpuser);
+ if(test_server_pgm(outf, sbindir, "amgetconf", 0, uid_dumpuser))
+ pgmbad = 1;
+ if(test_server_pgm(outf, sbindir, "amcheck", 1, uid_dumpuser))
+ pgmbad = 1;
+ if(test_server_pgm(outf, sbindir, "amdump", 0, uid_dumpuser))
+ pgmbad = 1;
+ if(test_server_pgm(outf, sbindir, "amreport", 0, uid_dumpuser))
+ pgmbad = 1;
}
if(access(COMPRESS_PATH, X_OK) == -1) {
+ quoted = quote_string(COMPRESS_PATH);
fprintf(outf, "WARNING: %s is not executable, server-compression and indexing will not work\n",
- COMPRESS_PATH);
+ quoted);
+ amfree(quoted);
}
}
*/
}
if(access(tape_dir, W_OK) == -1) {
- fprintf(outf, "ERROR: tapelist dir %s: not writable.\n", tape_dir);
+ quoted = quote_string(tape_dir);
+ fprintf(outf, "ERROR: tapelist dir %s: not writable.\n", quoted);
tapebad = 1;
+ amfree(quoted);
}
else if(stat(tapefile, &statbuf) == -1) {
- fprintf(outf, "ERROR: tapefile %s: %s, you must create an empty file.\n",
- tapefile, strerror(errno));
+ quoted = quote_string(tape_dir);
+ fprintf(outf, "ERROR: tapefile %s (%s), "
+ "you must create an empty file.\n",
+ quoted, strerror(errno));
tapebad = 1;
+ amfree(quoted);
}
else if(!S_ISREG(statbuf.st_mode)) {
- fprintf(outf, "ERROR: tapefile %s: should be a regular file.\n", tapefile);
+ quoted = quote_string(tapefile);
+ fprintf(outf, "ERROR: tapefile %s: should be a regular file.\n",
+ quoted);
tapebad = 1;
+ amfree(quoted);
}
else if(access(tapefile, F_OK) != 0) {
- fprintf(outf, "ERROR: can't access tape list %s\n", tapefile);
+ quoted = quote_string(tapefile);
+ fprintf(outf, "ERROR: can't access tape list %s\n", quoted);
tapebad = 1;
+ amfree(quoted);
} else if(access(tapefile, F_OK) == 0 && access(tapefile, W_OK) != 0) {
- fprintf(outf, "ERROR: tape list %s: not writable\n", tapefile);
+ quoted = quote_string(tapefile);
+ fprintf(outf, "ERROR: tape list %s: not writable\n", quoted);
tapebad = 1;
+ amfree(quoted);
} else if(read_tapelist(tapefile)) {
- fprintf(outf, "ERROR: tape list %s: parse error\n", tapefile);
+ quoted = quote_string(tapefile);
+ fprintf(outf, "ERROR: tape list %s: parse error\n", quoted);
tapebad = 1;
+ amfree(quoted);
}
holdfile = vstralloc(config_dir, "/", "hold", NULL);
if(access(holdfile, F_OK) != -1) {
+ quoted = quote_string(holdfile);
fprintf(outf, "WARNING: hold file %s exists\n", holdfile);
+ amfree(quoted);
}
amfree(tapefile);
amfree(tape_dir);
if(do_localchk) {
for(hdp = holdingdisks; hdp != NULL; hdp = hdp->next) {
- if(get_fs_stats(hdp->diskdir, &fs) == -1) {
- fprintf(outf, "ERROR: holding dir %s: %s, you must create a directory.\n",
- hdp->diskdir, strerror(errno));
+ quoted = quote_string(holdingdisk_get_diskdir(hdp));
+ if(get_fs_stats(holdingdisk_get_diskdir(hdp), &fs) == -1) {
+ fprintf(outf, "ERROR: holding dir %s (%s), "
+ "you must create a directory.\n",
+ quoted, strerror(errno));
disklow = 1;
}
- else if(access(hdp->diskdir, W_OK) == -1) {
+ else if(access(holdingdisk_get_diskdir(hdp), W_OK) == -1) {
fprintf(outf, "ERROR: holding disk %s: not writable: %s.\n",
- hdp->diskdir, strerror(errno));
+ quoted, strerror(errno));
+ disklow = 1;
+ }
+ else if(access(holdingdisk_get_diskdir(hdp), X_OK) == -1) {
+ fprintf(outf, "ERROR: holding disk %s: not searcheable: %s.\n",
+ quoted, strerror(errno));
disklow = 1;
}
- else if(fs.avail == -1) {
+ else if(fs.avail == (off_t)-1) {
fprintf(outf,
- "WARNING: holding disk %s: available space unknown (%ld KB requested)\n",
- hdp->diskdir, (long)hdp->disksize);
+ "WARNING: holding disk %s: "
+ "available space unknown (" OFF_T_FMT" KB requested)\n",
+ quoted, (OFF_T_FMT_TYPE)holdingdisk_get_disksize(hdp));
disklow = 1;
}
- else if(hdp->disksize > 0) {
- if(fs.avail < hdp->disksize) {
+ else if(holdingdisk_get_disksize(hdp) > (off_t)0) {
+ if(fs.avail < holdingdisk_get_disksize(hdp)) {
fprintf(outf,
- "WARNING: holding disk %s: only %ld %sB free (%ld %sB requested)\n",
- hdp->diskdir, (long)fs.avail/unitdivisor, displayunit,
- (long)hdp->disksize/unitdivisor, displayunit);
+ "WARNING: holding disk %s: "
+ "only " OFF_T_FMT " %sB free ("
+ OFF_T_FMT " %sB requested)\n", quoted,
+ (OFF_T_FMT_TYPE)(fs.avail / (off_t)unitdivisor),
+ displayunit,
+ (OFF_T_FMT_TYPE)(holdingdisk_get_disksize(hdp)/(off_t)unitdivisor),
+ displayunit);
disklow = 1;
}
- else
+ else {
fprintf(outf,
- "Holding disk %s: %ld %sB disk space available, that's plenty\n",
- hdp->diskdir, fs.avail/unitdivisor, displayunit);
+ "Holding disk %s: " OFF_T_FMT
+ " %sB disk space available, that's plenty\n",
+ quoted, (OFF_T_FMT_TYPE)(fs.avail/(off_t)unitdivisor),
+ displayunit);
+ }
}
else {
- if(fs.avail < -hdp->disksize) {
+ assert(holdingdisk_get_disksize(hdp) < (off_t)0);
+ if((fs.avail + holdingdisk_get_disksize(hdp)) <= (off_t)0) {
fprintf(outf,
- "WARNING: holding disk %s: only %ld %sB free, using nothing\n",
- hdp->diskdir, fs.avail/unitdivisor, displayunit);
+ "WARNING: holding disk %s: "
+ "only " OFF_T_FMT " %sB free, using nothing\n",
+ quoted, (OFF_T_FMT_TYPE)(fs.avail/(off_t)unitdivisor),
+ displayunit);
disklow = 1;
}
- else
+ else {
fprintf(outf,
- "Holding disk %s: %ld %sB disk space available, using %ld %sB\n",
- hdp->diskdir, fs.avail/unitdivisor, displayunit,
- (fs.avail + hdp->disksize)/unitdivisor, displayunit);
+ "Holding disk %s: "
+ OFF_T_FMT " %sB disk space available, using "
+ OFF_T_FMT " %sB\n",
+ quoted,
+ (OFF_T_FMT_TYPE)(fs.avail/(off_t)unitdivisor),
+ displayunit,
+ (OFF_T_FMT_TYPE)(fs.avail + holdingdisk_get_disksize(hdp) / (off_t)unitdivisor),
+ displayunit);
+ }
}
+ amfree(quoted);
}
}
}
logfile = vstralloc(conf_logdir, "/log", NULL);
+ quoted = quote_string(conf_logdir);
if(stat(conf_logdir, &statbuf) == -1) {
- fprintf(outf, "ERROR: logdir %s: %s, you must create a directory.\n",
- conf_logdir, strerror(errno));
+ fprintf(outf, "ERROR: logdir %s (%s), you must create directory.\n",
+ quoted, strerror(errno));
disklow = 1;
}
else if(access(conf_logdir, W_OK) == -1) {
- fprintf(outf, "ERROR: log dir %s: not writable\n", conf_logdir);
+ fprintf(outf, "ERROR: log dir %s: not writable\n", quoted);
logbad = 1;
}
+ amfree(quoted);
if(access(logfile, F_OK) == 0) {
testtape = 0;
logbad = 1;
- if(access(logfile, W_OK) != 0)
- fprintf(outf, "ERROR: log file %s: not writable\n",
- logfile);
+ if(access(logfile, W_OK) != 0) {
+ quoted = quote_string(logfile);
+ fprintf(outf, "ERROR: log file %s: not writable\n", quoted);
+ amfree(quoted);
+ }
}
olddir = vstralloc(conf_logdir, "/oldlog", NULL);
+ quoted = quote_string(olddir);
if (stat(olddir,&stat_old) == 0) { /* oldlog exist */
if(!(S_ISDIR(stat_old.st_mode))) {
- fprintf(outf, "ERROR: oldlog directory \"%s\" is not a directory\n", olddir);
+ fprintf(outf, "ERROR: oldlog directory %s is not a directory\n",
+ quoted);
}
if(access(olddir, W_OK) == -1) {
- fprintf(outf, "ERROR: oldlog dir %s: not writable\n", olddir);
+ fprintf(outf, "ERROR: oldlog dir %s: not writable\n", quoted);
}
}
else if(lstat(olddir,&stat_old) == 0) {
- fprintf(outf, "ERROR: oldlog directory \"%s\" is not a directory\n", olddir);
+ fprintf(outf, "ERROR: oldlog directory %s is not a directory\n",
+ quoted);
}
+ amfree(quoted);
if (testtape) {
logfile = newvstralloc(logfile, conf_logdir, "/amdump", NULL);
}
}
+ amfree(olddir);
amfree(logfile);
amfree(conf_logdir);
}
if (testtape) {
/* check that the tape is a valid amanda tape */
- char *error_msg;
int tape_status;
tapedays = getconf_int(CNF_TAPECYCLE);
"WARNING: if a tape changer is not available, runtapes must be set to 1\n");
}
- tape_status = taper_scan(NULL, &label, &datestamp, &error_msg,
- &tapename);
- fprintf(outf, "%s\n", error_msg);
- amfree(error_msg);
+ tape_status = taper_scan(NULL, &label, &datestamp, &tapename,
+ FILE_taperscan_output_callback, outf);
if (tape_status < 0) {
tape_t *exptape = lookup_last_reusable_tape(0);
fprintf(outf, " (expecting ");
if(exptape != NULL) fprintf(outf, "tape %s or ", exptape->label);
fprintf(outf, "a new tape)\n");
+ tapebad = 1;
} else {
if (overwrite) {
char *wrlabel_status;
wrlabel_status = tape_wrlabel(tapename, "X", label,
- tp->blocksize * 1024);
+ (unsigned)(tapetype_get_blocksize(tp) * 1024));
if (wrlabel_status != NULL) {
if (tape_status == 3) {
fprintf(outf,
}
}
}
+ amfree(tapename);
} else if (do_tapechk) {
fprintf(outf, "WARNING: skipping tape test because amdump or amflush seem to be running\n");
fprintf(outf, "WARNING: if they are not, you must run amcleanup\n");
}
#if TEXTDB
+ quoted = quote_string(conf_infofile);
if(stat(conf_infofile, &statbuf) == -1) {
- fprintf(outf, "NOTE: info dir %s: does not exist\n", conf_infofile);
- fprintf(outf, "NOTE: it will be created on the next run.\n");
+ if (errno == ENOENT) {
+ fprintf(outf, "NOTE: conf info dir %s does not exist\n",
+ quoted);
+ fprintf(outf, "NOTE: it will be created on the next run.\n");
+ } else {
+ fprintf(outf, "ERROR: conf info dir %s (%s)\n",
+ quoted, strerror(errno));
+ }
amfree(conf_infofile);
} else if (!S_ISDIR(statbuf.st_mode)) {
- fprintf(outf, "ERROR: info dir %s: not a directory\n", conf_infofile);
+ fprintf(outf, "ERROR: info dir %s: not a directory\n", quoted);
amfree(conf_infofile);
infobad = 1;
} else if (access(conf_infofile, W_OK) == -1) {
- fprintf(outf, "ERROR: info dir %s: not writable\n", conf_infofile);
+ fprintf(outf, "ERROR: info dir %s: not writable\n", quoted);
amfree(conf_infofile);
infobad = 1;
} else {
strappend(conf_infofile, "/");
}
+ amfree(quoted);
#endif
while(!empty(origq)) {
#if TEXTDB
if(conf_infofile) {
hostinfodir = newstralloc2(hostinfodir, conf_infofile, host);
+ quoted = quote_string(hostinfodir);
if(stat(hostinfodir, &statbuf) == -1) {
- fprintf(outf, "NOTE: info dir %s: does not exist\n",
- hostinfodir);
- fprintf(outf, "NOTE: it will be created on the next run.\n");
+ if (errno == ENOENT) {
+ fprintf(outf, "NOTE: host info dir %s does not exist\n",
+ quoted);
+ fprintf(outf,
+ "NOTE: it will be created on the next run.\n");
+ } else {
+ fprintf(outf, "ERROR: host info dir %s (%s)\n",
+ quoted, strerror(errno));
+ }
amfree(hostinfodir);
} else if (!S_ISDIR(statbuf.st_mode)) {
fprintf(outf, "ERROR: info dir %s: not a directory\n",
- hostinfodir);
+ quoted);
amfree(hostinfodir);
infobad = 1;
} else if (access(hostinfodir, W_OK) == -1) {
- fprintf(outf, "ERROR: info dir %s: not writable\n",
- hostinfodir);
+ fprintf(outf, "ERROR: info dir %s: not writable\n", quoted);
amfree(hostinfodir);
infobad = 1;
} else {
strappend(hostinfodir, "/");
}
+ amfree(quoted);
}
#endif
for(dp = hostp->disks; dp != NULL; dp = dp->hostnext) {
disk = sanitise_filename(dp->name);
#if TEXTDB
if(hostinfodir) {
+ char *quotedif;
+
diskdir = newstralloc2(diskdir, hostinfodir, disk);
infofile = vstralloc(diskdir, "/", "info", NULL);
+ quoted = quote_string(diskdir);
+ quotedif = quote_string(infofile);
if(stat(diskdir, &statbuf) == -1) {
- fprintf(outf, "NOTE: info dir %s: does not exist\n",
- diskdir);
- fprintf(outf, "NOTE: it will be created on the next run.\n");
+ if (errno == ENOENT) {
+ fprintf(outf, "NOTE: info dir %s does not exist\n",
+ quoted);
+ fprintf(outf,
+ "NOTE: it will be created on the next run.\n");
+ } else {
+ fprintf(outf, "ERROR: info dir %s (%s)\n",
+ quoted, strerror(errno));
+ }
} else if (!S_ISDIR(statbuf.st_mode)) {
fprintf(outf, "ERROR: info dir %s: not a directory\n",
- diskdir);
+ quoted);
infobad = 1;
} else if (access(diskdir, W_OK) == -1) {
fprintf(outf, "ERROR: info dir %s: not writable\n",
- diskdir);
+ quoted);
infobad = 1;
} else if(stat(infofile, &statbuf) == -1) {
- fprintf(outf, "WARNING: info file %s: does not exist\n",
- infofile);
- fprintf(outf, "NOTE: it will be created on the next run.\n");
+ if (errno == ENOENT) {
+ fprintf(outf, "NOTE: info file %s does not exist\n",
+ quotedif);
+ fprintf(outf, "NOTE: it will be created on the next run.\n");
+ } else {
+ fprintf(outf, "ERROR: info dir %s (%s)\n",
+ quoted, strerror(errno));
+ }
} else if (!S_ISREG(statbuf.st_mode)) {
fprintf(outf, "ERROR: info file %s: not a file\n",
- infofile);
+ quotedif);
infobad = 1;
} else if (access(infofile, R_OK) == -1) {
fprintf(outf, "ERROR: info file %s: not readable\n",
- infofile);
+ quotedif);
infobad = 1;
}
+ amfree(quotedif);
+ amfree(quoted);
amfree(infofile);
}
#endif
if(dp->index) {
if(! indexdir_checked) {
+ quoted = quote_string(conf_indexdir);
if(stat(conf_indexdir, &statbuf) == -1) {
- fprintf(outf, "NOTE: index dir %s: does not exist\n",
- conf_indexdir);
- fprintf(outf, "NOTE: it will be created on the next run.\n");
+ if (errno == ENOENT) {
+ fprintf(outf, "NOTE: index dir %s does not exist\n",
+ quoted);
+ fprintf(outf, "NOTE: it will be created on the next run.\n");
+ } else {
+ fprintf(outf, "ERROR: index dir %s (%s)\n",
+ quoted, strerror(errno));
+ }
amfree(conf_indexdir);
} else if (!S_ISDIR(statbuf.st_mode)) {
fprintf(outf, "ERROR: index dir %s: not a directory\n",
- conf_indexdir);
+ quoted);
amfree(conf_indexdir);
indexbad = 1;
} else if (access(conf_indexdir, W_OK) == -1) {
fprintf(outf, "ERROR: index dir %s: not writable\n",
- conf_indexdir);
+ quoted);
amfree(conf_indexdir);
indexbad = 1;
} else {
strappend(conf_indexdir, "/");
}
indexdir_checked = 1;
+ amfree(quoted);
}
if(conf_indexdir) {
if(! hostindexdir_checked) {
hostindexdir = stralloc2(conf_indexdir, host);
+ quoted = quote_string(hostindexdir);
if(stat(hostindexdir, &statbuf) == -1) {
- fprintf(outf, "NOTE: index dir %s: does not exist\n",
- hostindexdir);
- fprintf(outf, "NOTE: it will be created on the next run.\n");
+ if (errno == ENOENT) {
+ fprintf(outf, "NOTE: index dir %s does not exist\n",
+ quoted);
+ fprintf(outf, "NOTE: it will be created on the next run.\n");
+ } else {
+ fprintf(outf, "ERROR: index dir %s (%s)\n",
+ quoted, strerror(errno));
+ }
amfree(hostindexdir);
} else if (!S_ISDIR(statbuf.st_mode)) {
fprintf(outf, "ERROR: index dir %s: not a directory\n",
- hostindexdir);
+ quoted);
amfree(hostindexdir);
indexbad = 1;
} else if (access(hostindexdir, W_OK) == -1) {
fprintf(outf, "ERROR: index dir %s: not writable\n",
- hostindexdir);
+ quoted);
amfree(hostindexdir);
indexbad = 1;
} else {
strappend(hostindexdir, "/");
}
hostindexdir_checked = 1;
+ amfree(quoted);
}
if(hostindexdir) {
diskdir = newstralloc2(diskdir, hostindexdir, disk);
+ quoted = quote_string(diskdir);
if(stat(diskdir, &statbuf) == -1) {
- fprintf(outf, "NOTE: index dir %s: does not exist\n",
- diskdir);
- fprintf(outf, "NOTE: it will be created on the next run.\n");
+ if (errno == ENOENT) {
+ fprintf(outf, "NOTE: index dir %s does not exist\n",
+ quoted);
+ fprintf(outf, "NOTE: it will be created on the next run.\n");
+ } else {
+ fprintf(outf, "ERROR: index dir %s (%s)\n",
+ quoted, strerror(errno));
+ }
} else if (!S_ISDIR(statbuf.st_mode)) {
fprintf(outf, "ERROR: index dir %s: not a directory\n",
- diskdir);
+ quoted);
indexbad = 1;
} else if (access(diskdir, W_OK) == -1) {
fprintf(outf, "ERROR: index dir %s: is not writable\n",
- diskdir);
+ quoted);
indexbad = 1;
}
+ amfree(quoted);
}
}
}
- if ( dp->encrypt == ENCRYPT_SERV_CUST && dp->srv_encrypt ) {
- if(access(dp->srv_encrypt, X_OK) == -1) {
+ if ( dp->encrypt == ENCRYPT_SERV_CUST ) {
+ if ( dp->srv_encrypt[0] == '\0' ) {
+ fprintf(outf, "ERROR: server encryption program not specified\n");
+ pgmbad = 1;
+ }
+ else if(access(dp->srv_encrypt, X_OK) == -1) {
fprintf(outf, "ERROR: %s is not executable, server encryption will not work\n",
dp->srv_encrypt );
pgmbad = 1;
}
}
- if ( dp->compress == COMP_SERV_CUST && dp->srvcompprog ) {
- if(access(dp->srvcompprog, X_OK) == -1) {
+ if ( dp->compress == COMP_SERV_CUST ) {
+ if ( dp->srvcompprog[0] == '\0' ) {
+ fprintf(outf, "ERROR: server custom compression program not specified\n");
+ pgmbad = 1;
+ }
+ else if(access(dp->srvcompprog, X_OK) == -1) {
+ quoted = quote_string(dp->srvcompprog);
+
fprintf(outf, "ERROR: %s is not executable, server custom compression will not work\n",
- dp->srvcompprog );
+ quoted);
+ amfree(quoted);
pgmbad = 1;
}
}
|| infobad \
|| indexbad \
|| pgmbad);
- /* NOTREACHED */
+ /*NOTREACHED*/
return 0;
}
int remote_errors;
FILE *outf;
-static void handle_result P((void *, pkt_t *, security_handle_t *));
+static void handle_result(void *, pkt_t *, security_handle_t *);
+void start_host(am_host_t *hostp);
#define HOST_READY ((void *)0) /* must be 0 */
#define HOST_ACTIVE ((void *)1)
#define DISK_ACTIVE ((void *)1)
#define DISK_DONE ((void *)2)
-void start_host(hostp)
- am_host_t *hostp;
+void
+start_host(
+ am_host_t *hostp)
{
disk_t *dp;
char *req = NULL;
- int req_len = 0;
+ size_t req_len = 0;
int disk_count;
const security_driver_t *secdrv;
char number[NUM_STR_SIZE];
fe_req_options_hostname);
int has_maxdumps = am_has_feature(hostp->features,
fe_req_options_maxdumps);
+ int has_config = am_has_feature(hostp->features,
+ fe_req_options_config);
if(!am_has_feature(hostp->features, fe_selfcheck_req) &&
!am_has_feature(hostp->features, fe_selfcheck_req_device)) {
hostp->hostname);
}
- snprintf(number, sizeof(number), "%d", hostp->maxdumps);
+ snprintf(number, SIZEOF(number), "%d", hostp->maxdumps);
req = vstralloc("SERVICE ", "selfcheck", "\n",
"OPTIONS ",
has_features ? "features=" : "",
has_hostname ? "hostname=" : "",
has_hostname ? hostp->hostname : "",
has_hostname ? ";" : "",
+ has_config ? "config=" : "",
+ has_config ? config_name : "",
+ has_config ? ";" : "",
"\n",
NULL);
req_len += 256; /* room for non-disk answers */
for(dp = hostp->disks; dp != NULL; dp = dp->hostnext) {
char *l;
- int l_len;
+ size_t l_len;
char *o;
- char* calcsize;
+ char *calcsize;
+ char *qname;
+ char *qdevice;
if(dp->up != DISK_READY || dp->todo != 1) {
continue;
}
o = optionstr(dp, hostp->features, outf);
+ if (o == NULL) {
+ remote_errors++;
+ continue;
+ }
+ qname = quote_string(dp->name);
+ qdevice = quote_string(dp->device);
+ if ((dp->name && qname[0] == '"') ||
+ (dp->device && qdevice[0] == '"')) {
+ if(!am_has_feature(hostp->features, fe_interface_quoted_text)) {
+ fprintf(outf,
+ "WARNING: %s:%s:%s host does not support quoted text\n",
+ hostp->hostname, qname, qdevice);
+ }
+ }
if(dp->device) {
if(!am_has_feature(hostp->features, fe_selfcheck_req_device)) {
fprintf(outf,
"ERROR: %s:%s (%s): selfcheck does not support device.\n",
- hostp->hostname, dp->name, dp->device);
+ hostp->hostname, qname, dp->device);
}
if(!am_has_feature(hostp->features, fe_sendsize_req_device)) {
fprintf(outf,
"ERROR: %s:%s (%s): sendsize does not support device.\n",
- hostp->hostname, dp->name, dp->device);
+ hostp->hostname, qname, dp->device);
}
if(!am_has_feature(hostp->features, fe_sendbackup_req_device)) {
fprintf(outf,
"ERROR: %s:%s (%s): sendbackup does not support device.\n",
- hostp->hostname, dp->name, dp->device);
+ hostp->hostname, qname, dp->device);
}
}
if(strncmp(dp->program,"DUMP",4) == 0 ||
if(strcmp(dp->program, "DUMP") == 0 &&
!am_has_feature(hostp->features, fe_program_dump)) {
fprintf(outf, "ERROR: %s:%s does not support DUMP.\n",
- hostp->hostname, dp->name);
+ hostp->hostname, qname);
}
if(strcmp(dp->program, "GNUTAR") == 0 &&
!am_has_feature(hostp->features, fe_program_gnutar)) {
fprintf(outf, "ERROR: %s:%s does not support GNUTAR.\n",
- hostp->hostname, dp->name);
+ hostp->hostname, qname);
}
if(dp->estimate == ES_CALCSIZE &&
!am_has_feature(hostp->features, fe_calcsize_estimate)) {
fprintf(outf, "ERROR: %s:%s does not support CALCSIZE for estimate, using CLIENT.\n",
- hostp->hostname, dp->name);
+ hostp->hostname, qname);
dp->estimate = ES_CLIENT;
}
if(dp->estimate == ES_CALCSIZE &&
if(dp->device) {
l = vstralloc(calcsize,
dp->program, " ",
- dp->name, " ",
+ qname, " ",
dp->device,
" 0 OPTIONS |",
o,
else {
l = vstralloc(calcsize,
dp->program, " ",
- dp->name,
+ qname,
" 0 OPTIONS |",
o,
"\n",
} else {
if(!am_has_feature(hostp->features, fe_program_dumper_api)) {
fprintf(outf, "ERROR: %s:%s does not support DUMPER-API.\n",
- hostp->hostname, dp->name);
+ hostp->hostname, qname);
}
l = vstralloc("DUMPER ",
dp->program,
" ",
- dp->name,
+ qname,
" ",
dp->device,
" 0 OPTIONS |",
"\n",
NULL);
}
+ amfree(qname);
+ amfree(qdevice);
l_len = strlen(l);
amfree(o);
- /*
- * Allow 2X for err response.
- */
- if(req_len + l_len > MAX_PACKET / 2) {
- amfree(l);
- break;
- }
+
strappend(req, l);
req_len += l_len;
amfree(l);
if (secdrv == NULL) {
error("could not find security driver '%s' for host '%s'",
hostp->disks->security_driver, hostp->hostname);
+ /*NOTREACHED*/
}
- protocol_sendreq(hostp->hostname, secdrv, generic_get_security_conf,
+ protocol_sendreq(hostp->hostname, secdrv, amhost_get_security_conf,
req, conf_ctimeout, handle_result, hostp);
amfree(req);
hostp->up = HOST_ACTIVE;
}
-int start_client_checks(fd)
-int fd;
+pid_t
+start_client_checks(
+ int fd)
{
am_host_t *hostp;
disk_t *dp;
- int hostcount, pid;
+ int hostcount;
+ pid_t pid;
int userbad = 0;
switch(pid = fork()) {
- case -1: error("could not fork client check: %s", strerror(errno));
- case 0: break;
+ case -1:
+ error("could not fork client check: %s", strerror(errno));
+ /*NOTREACHED*/
+
+ case 0:
+ break;
+
default:
return pid;
}
startclock();
- if((outf = fdopen(fd, "w")) == NULL)
+ if((outf = fdopen(fd, "w")) == NULL) {
error("fdopen %d: %s", fd, strerror(errno));
+ /*NOTREACHED*/
+ }
errf = outf;
fprintf(outf, "\nAmanda Backup Client Hosts Check\n");
for(dp = origq.head; dp != NULL; dp = dp->next) {
hostp = dp->host;
- if(hostp->up == HOST_READY) {
+ if(hostp->up == HOST_READY && dp->todo == 1) {
start_host(hostp);
hostcount++;
protocol_check();
}
exit(userbad || remote_errors > 0);
- /* NOTREACHED */
+ /*NOTREACHED*/
return 0;
}
-static void handle_result(datap, pkt, sech)
-void *datap;
-pkt_t *pkt;
-security_handle_t *sech;
+static void
+handle_result(
+ void * datap,
+ pkt_t * pkt,
+ security_handle_t * sech)
{
am_host_t *hostp;
disk_t *dp;
ch = *s++;
while(ch) {
line = s - 1;
- skip_line(s, ch);
+ skip_quoted_line(s, ch);
if (s[-2] == '\n') {
s[-2] = '\0';
}
#define sc "OPTIONS "
- if(strncmp(line, sc, sizeof(sc)-1) == 0) {
+ if(strncmp(line, sc, SIZEOF(sc)-1) == 0) {
#undef sc
#define sc "features="
t = strstr(line, sc);
if(t != NULL && (isspace((int)t[-1]) || t[-1] == ';')) {
- t += sizeof(sc)-1;
+ t += SIZEOF(sc)-1;
#undef sc
am_release_feature_set(hostp->features);
if((hostp->features = am_string_to_feature(t)) == NULL) {
}
#define sc "OK "
- if(strncmp(line, sc, sizeof(sc)-1) == 0) {
+ if(strncmp(line, sc, SIZEOF(sc)-1) == 0) {
continue;
#undef sc
}
#define sc "ERROR "
- if(strncmp(line, sc, sizeof(sc)-1) == 0) {
- t = line + sizeof(sc) - 1;
+ if(strncmp(line, sc, SIZEOF(sc)-1) == 0) {
+ t = line + SIZEOF(sc) - 1;
tch = t[-1];
#undef sc
* just means the client is "old" (does not support the service).
* We can ignore this.
*/
- if(hostp->features == NULL
- && pkt->type == P_NAK
- && (strcmp(t - 1, "unknown service: noop") == 0
- || strcmp(t - 1, "noop: invalid service") == 0)) {
- } else {
+ if(!((hostp->features == NULL) && (pkt->type == P_NAK)
+ && ((strcmp(t - 1, "unknown service: noop") == 0)
+ || (strcmp(t - 1, "noop: invalid service") == 0)))) {
fprintf(outf, "ERROR: %s%s: %s\n",
(pkt->type == P_NAK) ? "NAK " : "",
hostp->hostname,
}
}
start_host(hostp);
+ if(hostp->up == HOST_DONE)
+ security_close_connection(sech, hostp->hostname);
}
-#! /bin/sh
+#! @SHELL@
#
# check tapelist against database and vice versa
#
log "usage: ${Program} <config>"
exit 1
fi
+shift;
#
# Check if the configuration directory exists. Make sure that the
# Get the location and name of the tapelist filename. If tapelist is not
# specified in the amanda.conf file, then use tapelist in the config
# directory.
-TapeList=`amgetconf${SUF} tapelist`
+TapeList=`amgetconf${SUF} $Config tapelist "@$"`
if [ ! "$TapeList" ]; then
TapeList="$ConfigDir/$Config/tapelist"
fi
&& echo "$Amadmin not found or not executable" >&2 \
&& exit 1
-$Amadmin $Config export \
+$Amadmin $Config export "$@"\
| grep "^stats: " \
| while read LINE; do
[ "$LINE" = "" ] && continue
-#!/bin/sh
+#!@SHELL@
#
# Amanda, The Advanced Maryland Automatic Network Disk Archiver
# Copyright (c) 1991-1998 University of Maryland at College Park
SUF=
fi
-if [ $# -ne 1 ]
-then
- echo "Usage: amcleanup conf"
- exit 1
+if test -h /proc/1/exe ; then
+ if test $# -eq 1 ; then
+ KILL_ENABLE=0
+ conf=$1
+ shift;
+ elif test $# -eq 2 && test "$1" == "-k" ; then
+ KILL_ENABLE=1
+ conf=$2
+ shift
+ shift
+ else
+ echo "Usage: amcleanup [-k] conf"
+ exit 1
+ fi
+else
+ if test $# -ne 1 ; then
+ echo "Usage: amcleanup conf"
+ exit 1
+ else
+ conf=$1
+ KILL_ENABLE=0
+ fi
fi
-conf=$1
-if [ ! -d $confdir/$conf ]; then
- echo "amcleanup: could not cd into $confdir/$conf"
- exit 1
+if test ! -d $confdir/$conf ; then
+ echo "amcleanup: could not cd into $confdir/$conf"
+ exit 1
fi
cd $confdir/$conf
-logdir=`amgetconf$SUF logdir`
-[ $? -ne 0 ] && exit 1
+logdir=`amgetconf$SUF $conf logdir "$@"`
+rc=$?
+if test $rc -ne 0 ; then
+ echo "amcleanup: 'amgetconf$SUF logdir' exited with status: $rc" 1>&2
+ exit 1
+fi
logfile=$logdir/log
errfile=$logdir/amdump
erramflush=$logdir/amflush
-tapecycle=`amgetconf$SUF tapecycle`
+tapecycle=`amgetconf$SUF $conf tapecycle "$@"`
+rc=$?
+if test $rc -ne 0 ; then
+ echo "amcleanup: 'amgetconf$SUF tapecycle' exited with status: $rc " 1>&2
+ exit 1
+fi
+dumpuser=`amgetconf$SUF $conf dumpuser "$@"`
+rc=$?
+if test $rc -ne 0 ; then
+ echo "amcleanup: 'amgetconf$SUF $conf dumpuser' exited with status: $rc" 1>&2
+ exit 1
+fi
+
+# Check for running processes which should not be
+# running right now.
+if test ${KILL_ENABLE} -eq 1 ; then
+ if test -h /proc/1/exe ; then
+ USER_PROCESS_NAMES="\
+ @libexecdir@/amandad \
+ @libexecdir@/amcleanupdisk \
+ @libexecdir@/amidxtaped \
+ @libexecdir@/amindexd \
+ @libexecdir@/amlogroll \
+ @libexecdir@/amtrmidx \
+ @libexecdir@/amtrmlog \
+ @libexecdir@/chg-chio \
+ @libexecdir@/chg-chs \
+ @libexecdir@/chg-disk \
+ @libexecdir@/chg-iomega \
+ @libexecdir@/chg-juke \
+ @libexecdir@/chg-manual \
+ @libexecdir@/chg-mcutil \
+ @libexecdir@/chg-mtx \
+ @libexecdir@/chg-multi \
+ @libexecdir@/chg-null \
+ @libexecdir@/chg-rait \
+ @libexecdir@/chg-rth \
+ @libexecdir@/chg-scsi \
+ @libexecdir@/chg-zd-mtx \
+ @libexecdir@/chunker \
+ @libexecdir@/driver \
+ @libexecdir@/generic-dumper \
+ @libexecdir@/gnutar \
+ @libexecdir@/noop \
+ @libexecdir@/patch-system \
+ @libexecdir@/selfcheck \
+ @libexecdir@/sendbackup \
+ @libexecdir@/sendsize \
+ @libexecdir@/star \
+ @libexecdir@/taper \
+ @libexecdir@/versionsuffix \
+ @sbindir@/amaddclient \
+ @sbindir@/amadmin \
+ @sbindir@/amaespipe \
+ @sbindir@/amcheckdb \
+ @sbindir@/amcrypt \
+ @sbindir@/amcryptsimple \
+ @sbindir@/amdd \
+ @sbindir@/amdump \
+ @sbindir@/amfetchdump \
+ @sbindir@/amflush \
+ @sbindir@/amgetconf \
+ @sbindir@/amgpgcrypt \
+ @sbindir@/amlabel \
+ @sbindir@/ammt \
+ @sbindir@/amoverview \
+ @sbindir@/amplot \
+ @sbindir@/amrecover \
+ @sbindir@/amreport \
+ @sbindir@/amrestore \
+ @sbindir@/amrmtape \
+ @sbindir@/amserverconfig \
+ @sbindir@/amstatus \
+ @sbindir@/amtape \
+ @sbindir@/amtapetype \
+ @sbindir@/amtoc \
+ @sbindir@/amverify \
+ @sbindir@/amverifyrun"
-if [ -f $logfile ]; then
- lognotfound=0
+ ROOT_PROCESS_NAMES="\
+ @libexecdir@/calcsize \
+ @libexecdir@/killpgrp \
+ @libexecdir@/rundump \
+ @libexecdir@/runtar \
+ @libexecdir@/dumper \
+ @libexecdir@/planner \
+ @sbindir@/amcheck"
+ PREVIOUS_DIR="`pwd`"
+ cd /proc
+ PIDS_FOUND=0
+ KEEP_CHECKING=1
+ while test ${KEEP_CHECKING} -ne 0 ; do
+ PIDS_THIS_PASS=0
+ for search_user in ${dumpuser} root ; do
+ if test "${search_user}" == "${dumpuser}" ; then
+ PROCESS_NAMES=${USER_PROCESS_NAMES}
+ elif test "${search_user}" == "root" ; then
+ PROCESS_NAMES=${ROOT_PROCESS_NAMES}
+ fi
+ for search_pid in [0-9]* ; do
+ for search_name in ${PROCESS_NAMES} ; do
+ ls -l /proc/${search_pid}/exe 2>/dev/null | grep ${search_name} >/dev/null
+ match_name=$?
+ pid_uid="`cat /proc/${search_pid}/status 2>/dev/null | grep Uid | awk '//{split($_,i); print i[2]}'`"
+ if test ${match_name} -eq 0 && test "${pid_uid}" == "${search_user}" ; then
+ echo "amcleanup: Process ${search_name} found running at pid #${search_pid}."
+ kill_pid=${search_pid}
+ kill_name=${search_name}
+ PIDS_FOUND=`expr ${PIDS} + 1`
+ PIDS_THIS_PASS=1
+ break
+ else
+ kill_pid=""
+ continue
+ fi
+ done
+ if test ! -z "${kill_pid}" ; then
+ if test -d /proc/${kill_pid} ; then
+ echo "amcleanup: Sending process ${kill_pid} the TERM signal."
+ kill -15 -- ${kill_pid}
+ sleep 5
+ if test -d /proc/${kill_pid} ; then
+ echo "amcleanup: Sending process ${kill_pid} the KILL signal."
+ kill -9 -- ${kill_pid}
+ fi
+ sleep 5
+ if test -d /proc/${kill_pid} ; then
+ echo "amcleanup: Process ${kill_pid} did not respond to the KILL signal (and may be hung)!" 1>&2
+ KILL_FAILURES=`expr ${KILL_FAILURES} + 1`
+ fi
+ else
+ echo "amcleanup: Process ${kill_pid} no longer running. Skipping..."
+ fi
+ fi
+ done
+ done
+ if test ${PIDS_THIS_PASS} -eq 0 ; then
+ KEEP_CHECKING=0
+ else
+ KEEP_CHECKING=1
+ fi
+ done
+ if test ${PIDS_FOUND} -gt 0 ; then
+ echo "amcleanup: ${PIDS_FOUND} Amanda processes were found running."
+ echo "amcleanup: ${KILL_FAILURES} processes failed to terminate."
+ else
+ echo "amcleanup: No Amanda processes were found running."
+ fi
+ cd "${PREVIOUS_DIR}"
+ fi
+fi
+
+retstatus=0
+if test -f $logfile ; then
echo "amcleanup: processing outstanding log file."
exec </dev/null >/dev/null 2>&1
- amreport$SUF $conf
+ amreport$SUF $conf "$@"
+ rc=$?
+ if test $rc -ne 0 ; then
+ echo "amcleanup: amreport exited with status: $rc" 1>&2
+ retstatus=`expr $retstatus + 1`
+ fi
# Roll the log file to its datestamped name.
- amlogroll$SUF $conf
+ amlogroll$SUF $conf "$@"
+ rc=$?
+ if test $rc -ne 0 ; then
+ echo "acmleanup: amlogroll exited with status: $rc" 1>&2
+ retstatus=`expr $retstatus + 2`
+ fi
# Trim the index file to those for dumps that still exist.
- amtrmidx$SUF $conf
+ amtrmidx$SUF $conf "$@"
+ rc=$?
+ if test $rc -ne 0 ; then
+ echo "amcleanup: amtrmidx exited with status: $rc" 1>&2
+ retstatus=`expr $retstatus + 4`
+ fi
else
echo "amcleanup: no unprocessed logfile to clean up."
-
- lognotfound=1
fi
-if [ -f $errfile ]; then
+if test -f $errfile ; then
# if log was found, this will have been directed to /dev/null,
# which is fine.
echo "amcleanup: $errfile exists, renaming it."
days=1
# First, find out the last existing errfile,
# to avoid ``infinite'' loops if tapecycle is infinite
- while [ $days -lt $maxdays ] && [ -f $errfile.$days ]; do
+ while test $days -lt $maxdays && test -f $errfile.$days ; do
days=`expr $days + 1`
done
# Now, renumber the existing log files
- while [ $days -ge 2 ]; do
+ while test $days -ge 2 ; do
ndays=`expr $days - 1`
mv $errfile.$ndays $errfile.$days
days=$ndays
mv $errfile $errfile.1
fi
-if [ -f $erramflush ]; then
+if test -f $erramflush ; then
# if log was found, this will have been directed to /dev/null,
# which is fine.
echo "amcleanup: $erramflush exists, renaming it."
days=1
# First, find out the last existing erramflush,
# to avoid ``infinite'' loops if tapecycle is infinite
- while [ $days -lt $maxdays ] && [ -f $erramflush.$days ]; do
+ while test $days -lt $maxdays && test -f $erramflush.$days ; do
days=`expr $days + 1`
done
# Now, renumber the existing log files
- while [ $days -ge 2 ]; do
+ while test $days -ge 2 ; do
ndays=`expr $days - 1`
mv $erramflush.$ndays $erramflush.$days
days=$ndays
mv $erramflush $erramflush.1
fi
-$libexecdir/amcleanupdisk $conf
+$libexecdir/amcleanupdisk $conf "$@"
+rc=$?
+if test $rc -ne 0 ; then
+ echo "amcleanup: amcleanupdisk exited with status: $rc" 1>&2
+ retstatus=`expr $retstatus + 8`
+fi
-exit $lognotfound
+exit $retstatus
* file named AUTHORS, in the root directory of this distribution.
*/
/*
- * $Id: amcleanupdisk.c,v 1.16 2006/01/14 04:37:19 paddy_s Exp $
+ * $Id: amcleanupdisk.c,v 1.22 2006/07/25 18:27:57 martinea Exp $
*/
#include "amanda.h"
char *datestamp;
/* local functions */
-int main P((int argc, char **argv));
-void check_holdingdisk P((char *diskdir, char *datestamp));
-void check_disks P((void));
-
-int main(main_argc, main_argv)
-int main_argc;
-char **main_argv;
+int main(int argc, char **argv);
+void check_holdingdisk(char *diskdir, char *datestamp);
+void check_disks(void);
+
+int
+main(
+ int main_argc,
+ char ** main_argv)
{
struct passwd *pw;
char *dumpuser;
set_pname("amcleanupdisk");
+ dbopen(DBG_SUBDIR_SERVER);
+
/* Don't die when child closes pipe */
signal(SIGPIPE, SIG_IGN);
- if(main_argc != 2)
+ if(main_argc != 2) {
error("Usage: amcleanupdisk%s <confdir>", versionsuffix());
+ /*NOTREACHED*/
+ }
config_name = main_argv[1];
config_dir = vstralloc(CONFIG_DIR, "/", config_name, "/", NULL);
conffile = stralloc2(config_dir, CONFFILE_NAME);
- if(read_conffile(conffile))
+ if(read_conffile(conffile)) {
error("errors processing config file \"%s\"", conffile);
+ /*NOTREACHED*/
+ }
amfree(conffile);
+ dbrename(config_name, DBG_SUBDIR_SERVER);
+
conf_diskfile = getconf_str(CNF_DISKFILE);
if (*conf_diskfile == '/') {
conf_diskfile = stralloc(conf_diskfile);
} else {
conf_diskfile = stralloc2(config_dir, conf_diskfile);
}
- if (read_diskfile(conf_diskfile, &diskq) < 0)
+ if (read_diskfile(conf_diskfile, &diskq) < 0) {
error("could not load disklist %s", conf_diskfile);
+ /*NOTREACHED*/
+ }
amfree(conf_diskfile);
conf_infofile = getconf_str(CNF_INFOFILE);
} else {
conf_infofile = stralloc2(config_dir, conf_infofile);
}
- if (open_infofile(conf_infofile) < 0)
+ if (open_infofile(conf_infofile) < 0) {
error("could not open info db \"%s\"", conf_infofile);
+ /*NOTREACHED*/
+ }
amfree(conf_infofile);
datestamp = construct_datestamp(NULL);
dumpuser = getconf_str(CNF_DUMPUSER);
- if((pw = getpwnam(dumpuser)) == NULL)
+ if((pw = getpwnam(dumpuser)) == NULL) {
error("dumpuser %s not found in password file", dumpuser);
- if(pw->pw_uid != getuid())
+ /*NOTREACHED*/
+ }
+
+ if(pw->pw_uid != getuid()) {
error("must run amcleanupdisk as user %s", dumpuser);
+ /*NOTREACHED*/
+ }
holding_list = pick_all_datestamp(1);
}
-void check_holdingdisk(diskdir, datestamp)
-char *diskdir, *datestamp;
+void
+check_holdingdisk(
+ char * diskdir,
+ char * datestamp)
{
DIR *workdir;
struct dirent *entry;
filetype_t filetype;
info_t info;
int level;
- int dl, l;
+ size_t dl, l;
dirname = vstralloc(diskdir, "/", datestamp, NULL);
dl = strlen(dirname);
amfree(hostname);
amfree(diskname);
filetype = get_amanda_names(tmpname, &hostname, &diskname, &level);
+ amfree(tmpname);
if(filetype != F_DUMPFILE) {
continue;
}
if(put_info(dp->host->hostname, dp->name, &info)) {
error("could not put info record for %s:%s: %s",
dp->host->hostname, dp->name, strerror(errno));
+ /*NOTREACHED*/
}
} else {
fprintf(stderr,"rename_tmp_holding(%s) failed\n", destname);
}
-void check_disks()
+void
+check_disks(void)
{
holdingdisk_t *hdisk;
sle_t *dir;
for(dir = holding_list->first; dir !=NULL; dir = dir->next) {
for(hdisk = getconf_holdingdisks(); hdisk != NULL; hdisk = hdisk->next)
- check_holdingdisk(hdisk->diskdir, dir->name);
+ check_holdingdisk(holdingdisk_get_diskdir(hdisk), dir->name);
}
}
--- /dev/null
+#!@SHELL@
+#
+# amcrypt-ossl-asym.sh - asymmetric crypto helper using OpenSSL
+# Usage: amcrypt-ossl-asym.sh [-d]
+#
+# Copyright © 2006 Ben Slusky <sluskyb@paranoiacs.org>
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+#
+# Keys can be generated with the standard OpenSSL commands, e.g.:
+#
+# $ openssl genrsa -aes128 -out backup-privkey.pem 1024
+# Generating RSA private key, 1024 bit long modulus
+# [...]
+# Enter pass phrase for backup-privkey.pem: <ENTER YOUR PASS PHRASE>
+# Verifying - Enter pass phrase for backup-privkey.pem: <ENTER YOUR PASS PHRASE>
+#
+# $ openssl rsa -in backup-privkey.pem -pubout -out backup-pubkey.pem
+# Enter pass phrase for backup-privkey.pem: <ENTER YOUR PASS PHRASE>
+# Writing RSA key
+#
+
+# change these as needed
+OPENSSL= # whatever's in $PATH
+CIPHER=aes-256-cbc # see `openssl help` for more ciphers
+AMANDA_HOME=~amandabackup
+RANDFILE=$AMANDA_HOME/.rnd
+export RANDFILE
+PASSPHRASE=$AMANDA_HOME/.am_passphrase # optional
+PRIVKEY=$AMANDA_HOME/backup-privkey.pem
+PUBKEY=$AMANDA_HOME/backup-pubkey.pem
+
+# where might openssl be?
+PATH=/bin:/usr/bin:/usr/local/bin:/usr/ssl/bin:/usr/local/ssl/bin
+export PATH
+MAGIC='AmAnDa+OpEnSsL'
+ME=`basename "$0"`
+WORKDIR="/tmp/.${ME}.$$"
+
+# first things first
+if [ -z "${OPENSSL:=`which openssl`}" ]; then
+ echo "${ME}: openssl not found" >&2
+ exit 1
+elif [ ! -x "${OPENSSL}" ]; then
+ echo "${ME}: can't execute openssl (${OPENSSL})" >&2
+ exit 1
+fi
+
+if [ -n "${PASSPHRASE}" ]; then
+ # check the openssl version. if it's too old, we have to handle
+ # the pass phrase differently.
+ OSSL_VERSION=`eval \"${OPENSSL}\" version |cut -d\ -f2`
+ case "${OSSL_VERSION}" in
+ ''|0.[0-8].*|0.9.[0-6]*|0.9.7|0.9.7[a-c]*)
+ echo "${ME}: ${OPENSSL} is version ${OSSL_VERSION}" >&2
+ echo "${ME}: Using pass phrase kluge for OpenSSL version >=0.9.7d" >&2
+ PASS_FROM_STDIN=yes
+ ;;
+ esac
+fi
+
+mkdir -m 700 "${WORKDIR}"
+if [ $? -ne 0 ]; then
+ echo "${ME}: failed to create temp directory" >&2
+ exit 1
+fi
+# ignore SIGINT
+trap "" 2
+trap "rm -rf \"${WORKDIR}\"" 0 1 3 15
+
+# we'll need to pad the datastream to a multiple of the cipher block size
+# prior to encryption and decryption. 96 bytes (= 768 bits) should be good
+# for any cipher.
+pad() {
+ perl -pe 'BEGIN { $bs = 96; $/ = \8192 } $nbytes = ($nbytes + length) % $bs; END { print "\0" x ($bs - $nbytes) }'
+}
+
+encrypt() {
+ # generate a random printable cipher key (on one line)
+ echo `"${OPENSSL}" rand -base64 80` >"${WORKDIR}/pass"
+
+ # encrypt the cipher key using the RSA public key
+ "${OPENSSL}" rsautl -encrypt -in "${WORKDIR}/pass" -out "${WORKDIR}/pass.ciphertext" -pubin -inkey "${PUBKEY}" -pkcs
+ [ $? -eq 0 ] || return 1
+
+ # print magic
+ printf %s "${MAGIC}"
+
+ # print the encrypted cipher key, preceded by size
+ ls -l "${WORKDIR}/pass.ciphertext" | awk '{ printf("%-10d", $5) }'
+ cat "${WORKDIR}/pass.ciphertext"
+
+ # encrypt data using the cipher key and print
+ pad | "${OPENSSL}" enc "-${CIPHER}" -nopad -e -pass "file:${WORKDIR}/pass" -nosalt
+ [ $? -eq 0 ] || return 1
+}
+
+decrypt() {
+ # read magic
+ magicsize=`printf %s "${MAGIC}" | wc -c | sed 's/^ *//'`
+ magic=`dd bs=$magicsize count=1 2>/dev/null`
+ if [ "$magic" != "${MAGIC}" ]; then
+ echo "${ME}: bad magic" >&2
+ return 1
+ fi
+
+ # read size of encrypted cipher key
+ n=`dd bs=10 count=1 2>/dev/null`
+ [ $n -gt 0 ] 2>/dev/null
+ if [ $? -ne 0 ]; then
+ echo "${ME}: bad header" >&2
+ return 1
+ fi
+
+ # read the encrypted cipher key
+ dd "of=${WORKDIR}/pass.ciphertext" bs=$n count=1 2>/dev/null
+
+ # decrypt the cipher key using the RSA private key
+ if [ "${PASS_FROM_STDIN}" = yes ]; then
+ "${OPENSSL}" rsautl -decrypt -in "${WORKDIR}/pass.ciphertext" -out "${WORKDIR}/pass" -inkey "${PRIVKEY}" -pkcs < "${PASSPHRASE}"
+ else
+ "${OPENSSL}" rsautl -decrypt -in "${WORKDIR}/pass.ciphertext" -out "${WORKDIR}/pass" -inkey "${PRIVKEY}" ${PASSARG} -pkcs 3< "${PASSPHRASE}"
+ fi
+ [ $? -eq 0 ] || return 1
+
+ # use the cipher key to decrypt data
+ pad | "${OPENSSL}" enc "-${CIPHER}" -nopad -d -pass "file:${WORKDIR}/pass" -nosalt
+
+ # N.B.: in the likely event that we're piping to gzip, the above command
+ # may return a spurious error if gzip closes the output stream early.
+ return 0
+}
+
+if [ "$1" = -d ]; then
+ if [ -z "${PRIVKEY}" ]; then
+ echo "${ME}: must specify private key for decryption" >&2
+ exit 1
+ elif [ ! -r "${PRIVKEY}" ]; then
+ echo "${ME}: can't read private key from ${PRIVKEY}" >&2
+ exit 1
+ fi
+
+ if [ -n "${PASSPHRASE}" -a -e "${PASSPHRASE}" -a -r "${PASSPHRASE}" ]; then
+ PASSARG='-passin fd:3'
+ else
+ PASSPHRASE=/dev/null
+ fi
+
+ decrypt
+ if [ $? -ne 0 ]; then
+ echo "${ME}: decryption failed" >&2
+ exit 1
+ fi
+else
+ if [ -z "${PUBKEY}" ]; then
+ echo "${ME}: must specify public key for encryption" >&2
+ exit 1
+ elif [ ! -r "${PUBKEY}" ]; then
+ echo "${ME}: can't read public key from ${PUBKEY}" >&2
+ exit 1
+ fi
+
+ encrypt
+ if [ $? -ne 0 ]; then
+ echo "${ME}: encryption failed" >&2
+ exit 1
+ fi
+fi
--- /dev/null
+#!@SHELL@
+#
+# amcrypt-ossl.sh - crypto helper using OpenSSL
+# Usage: amcrypt-ossl.sh [-d]
+#
+
+# change these as needed
+OPENSSL= # whatever's in $PATH
+CIPHER=aes-256-cbc # see `openssl help` for more ciphers
+AMANDA_HOME=~amandabackup
+RANDFILE=$AMANDA_HOME/.rnd
+export RANDFILE
+PASSPHRASE=$AMANDA_HOME/.am_passphrase # required
+
+# where might openssl be?
+PATH=/bin:/usr/bin:/usr/local/bin:/usr/ssl/bin:/usr/local/ssl/bin
+export PATH
+ME=`basename "$0"`
+
+if [ -z "${OPENSSL:=`which openssl`}" ]; then
+ echo "${ME}: openssl not found" >&2
+ exit 1
+elif [ ! -x "${OPENSSL}" ]; then
+ echo "${ME}: can't execute openssl (${OPENSSL})" >&2
+ exit 1
+fi
+
+# we'll need to pad the datastream to a multiple of the cipher block size prior
+# to encryption. 96 bytes (= 768 bits) should be good for any cipher.
+pad() {
+ perl -pe 'BEGIN { $bs = 96; $/ = \8192 } $nbytes = ($nbytes + length) % $bs; END { print "\0" x ($bs - $nbytes) }'
+}
+
+if [ "$1" = -d ]; then
+ # decrypt
+ "${OPENSSL}" enc -d "-${CIPHER}" -nopad -salt -pass fd:3 3< "${PASSPHRASE}"
+else
+ # encrypt
+ pad | "${OPENSSL}" enc -e "-${CIPHER}" -nopad -salt -pass fd:3 3< "${PASSPHRASE}"
+fi
+
-#!/bin/sh
+#!@SHELL@
#
# Original wrapper by Paul Bijnens
#
-#!/bin/sh
+#!@SHELL@
#
# Amanda, The Advanced Maryland Automatic Network Disk Archiver
# Copyright (c) 1991-1998 University of Maryland at College Park
SUF=
fi
+if [ $# -lt 1 ]
+then
+ echo "Usage: amdump config [host [disk...]...]" 1>&2
+ exit 1
+fi
+
+
conf=$1
if [ ! -d $confdir/$conf ]; then
- echo "amdump$SUF: could not find directory $confdir/$conf"
+ echo "amdump$SUF: could not find directory $confdir/$conf" 1>&2
exit 1
fi
+shift
cd $confdir/$conf || exit 1
-logdir=`amgetconf$SUF $conf logdir`
+logdir=`amgetconf$SUF $conf logdir "$@"`
[ $? -ne 0 ] && exit 1
errfile=$logdir/amdump
-tapecycle=`amgetconf$SUF $conf tapecycle`
+tapecycle=`amgetconf$SUF $conf tapecycle "$@"`
[ $? -ne 0 ] && exit 1
-dumpuser=`amgetconf$SUF $conf dumpuser`
+dumpuser=`amgetconf$SUF $conf dumpuser "$@"`
[ $? -ne 0 ] && exit 1
runuser=`{ whoami ; } 2>/dev/null`
fi
fi
-if [ $runuser != $dumpuser ]; then
- echo "amdump: must be run as user $dumpuser, not $runuser"
- exit 1
-fi
+#if [ $runuser != $dumpuser ]; then
+# echo "amdump: must be run as user $dumpuser, not $runuser" 1>&2
+# exit 1
+#fi
if test -f hold; then
- echo "amdump: waiting for hold file to be removed" >&2
+ echo "amdump: waiting for hold file to be removed" 1>&2
while test -f hold; do
sleep 60
done
fi
if test -f $errfile || test -f $logdir/log; then
- echo "amdump: amdump or amflush is already running, or you must run amcleanup" >&2
+ echo "amdump: amdump or amflush is already running, or you must run amcleanup" 1>&2
exit 1
fi
exec </dev/null 2>>$errfile 1>&2
echo "amdump: start at `date`"
echo "amdump: datestamp `date +%Y%m%d`"
-$libexecdir/planner$SUF "$@" | $libexecdir/driver$SUF $conf
+$libexecdir/planner$SUF $conf "$@" | $libexecdir/driver$SUF $conf "$@"
echo "amdump: end at `date`"
# Send out a report on the dumps.
-$sbindir/amreport$SUF $conf
+$sbindir/amreport$SUF $conf "$@"
# Roll the log file to its datestamped name.
-$libexecdir/amlogroll$SUF $conf
+$libexecdir/amlogroll$SUF $conf "$@"
# Trim the log file to those for dumps that still exist.
-$libexecdir/amtrmlog$SUF $conf
+$libexecdir/amtrmlog$SUF $conf "$@"
# Trim the index file to those for dumps that still exist.
-$libexecdir/amtrmidx$SUF $conf
+$libexecdir/amtrmidx$SUF $conf "$@"
# Keep a debug log through the tapecycle plus a couple of days.
maxdays=`expr $tapecycle + 2`
* file named AUTHORS, in the root directory of this distribution.
*/
/*
- * $Id: amflush.c,v 1.80 2006/01/14 04:37:19 paddy_s Exp $
+ * $Id: amflush.c,v 1.95 2006/07/25 21:41:24 martinea Exp $
*
* write files from work directory onto tape
*/
char *reporter_program;
char *logroll_program;
char *datestamp;
+char *amflush_timestamp;
+char *amflush_datestamp;
sl_t *datestamp_list;
/* local functions */
-int main P((int main_argc, char **main_argv));
-void flush_holdingdisk P((char *diskdir, char *datestamp));
-void confirm P((void));
-void redirect_stderr P((void));
-void detach P((void));
-void run_dumps P((void));
-static int get_letter_from_user P((void));
-
-int main(main_argc, main_argv)
-int main_argc;
-char **main_argv;
+int main(int main_argc, char **main_argv);
+void flush_holdingdisk(char *diskdir, char *datestamp);
+void confirm(void);
+void redirect_stderr(void);
+void detach(void);
+void run_dumps(void);
+static int get_letter_from_user(void);
+
+int
+main(
+ int main_argc,
+ char ** main_argv)
{
int foreground;
int batch;
char *conf_diskfile;
char *conf_tapelist;
char *conf_logfile;
+ int conf_usetimestamps;
disklist_t diskq;
disk_t *dp;
pid_t pid;
int driver_pipe[2];
char date_string[100];
time_t today;
+ int new_argc, my_argc;
+ char **new_argv, **my_argv;
+ char *errstr;
+ struct tm *tm;
safe_fd(-1, 0);
safe_cd();
set_pname("amflush");
+ dbopen(DBG_SUBDIR_SERVER);
+
/* Don't die when child closes pipe */
signal(SIGPIPE, SIG_IGN);
/* process arguments */
- while((opt = getopt(main_argc, main_argv, "bfsD:")) != EOF) {
+ parse_server_conf(main_argc, main_argv, &new_argc, &new_argv);
+ my_argc = new_argc;
+ my_argv = new_argv;
+
+ while((opt = getopt(my_argc, my_argv, "bfsD:")) != EOF) {
switch(opt) {
case 'b': batch = 1;
break;
case 's': redirect = 0;
break;
case 'D': if (datearg == NULL)
- datearg = alloc(21*sizeof(char *));
+ datearg = alloc(21*SIZEOF(char *));
if(nb_datearg == 20) {
fprintf(stderr,"maximum of 20 -D arguments.\n");
exit(1);
exit(1);
}
- main_argc -= optind, main_argv += optind;
+ my_argc -= optind, my_argv += optind;
- if(main_argc < 1) {
- error("Usage: amflush%s [-b] [-f] [-s] [-D date]* <confdir> [host [disk]* ]*", versionsuffix());
+ if(my_argc < 1) {
+ error("Usage: amflush%s [-b] [-f] [-s] [-D date]* <confdir> [host [disk]* ]* [-o configoption]*", versionsuffix());
+ /*NOTREACHED*/
}
- config_name = main_argv[0];
+ config_name = my_argv[0];
config_dir = vstralloc(CONFIG_DIR, "/", config_name, "/", NULL);
conffile = stralloc2(config_dir, CONFFILE_NAME);
- if(read_conffile(conffile))
+ if(read_conffile(conffile)) {
error("errors processing config file \"%s\"", conffile);
+ /*NOTREACHED*/
+ }
amfree(conffile);
+ dbrename(config_name, DBG_SUBDIR_SERVER);
+
+ report_bad_conf_arg();
+
conf_diskfile = getconf_str(CNF_DISKFILE);
if (*conf_diskfile == '/') {
conf_diskfile = stralloc(conf_diskfile);
} else {
conf_diskfile = stralloc2(config_dir, conf_diskfile);
}
- if (read_diskfile(conf_diskfile, &diskq) < 0)
+ if (read_diskfile(conf_diskfile, &diskq) < 0) {
error("could not read disklist file \"%s\"", conf_diskfile);
- match_disklist(&diskq, main_argc-1, main_argv+1);
+ /*NOTREACHED*/
+ }
+ errstr = match_disklist(&diskq, my_argc-1, my_argv+1);
+ if (errstr) {
+ printf("%s",errstr);
+ amfree(errstr);
+ }
amfree(conf_diskfile);
conf_tapelist = getconf_str(CNF_TAPELIST);
} else {
conf_tapelist = stralloc2(config_dir, conf_tapelist);
}
- if(read_tapelist(conf_tapelist))
+ if(read_tapelist(conf_tapelist)) {
error("could not load tapelist \"%s\"", conf_tapelist);
+ /*NOTREACHED*/
+ }
amfree(conf_tapelist);
- datestamp = construct_datestamp(NULL);
+ conf_usetimestamps = getconf_boolean(CNF_USETIMESTAMPS);
+
+ amflush_datestamp = construct_datestamp(NULL);
+ if(conf_usetimestamps == 0) {
+ amflush_timestamp = stralloc(amflush_datestamp);
+ }
+ else {
+ amflush_timestamp = construct_timestamp(NULL);
+ }
dumpuser = getconf_str(CNF_DUMPUSER);
- if((pw = getpwnam(dumpuser)) == NULL)
+ if((pw = getpwnam(dumpuser)) == NULL) {
error("dumpuser %s not found in password file", dumpuser);
- if(pw->pw_uid != getuid())
+ /*NOTREACHED*/
+ }
+ if(pw->pw_uid != getuid()) {
error("must run amflush as user %s", dumpuser);
+ /*NOTREACHED*/
+ }
conf_logdir = getconf_str(CNF_LOGDIR);
if (*conf_logdir == '/') {
conf_logdir = stralloc2(config_dir, conf_logdir);
}
conf_logfile = vstralloc(conf_logdir, "/log", NULL);
- if (access(conf_logfile, F_OK) == 0)
+ if (access(conf_logfile, F_OK) == 0) {
error("%s exists: amdump or amflush is already running, or you must run amcleanup", conf_logfile);
+ /*NOTREACHED*/
+ }
amfree(conf_logfile);
driver_program = vstralloc(libexecdir, "/", "driver", versionsuffix(),
erroutput_type = (ERR_AMANDALOG|ERR_INTERACTIVE);
set_logerror(logerror);
today = time(NULL);
- strftime(date_string, 100, "%a %b %e %H:%M:%S %Z %Y", localtime (&today));
+ tm = localtime(&today);
+ if (tm)
+ strftime(date_string, 100, "%a %b %e %H:%M:%S %Z %Y", tm);
+ else
+ error("BAD DATE"); /* should never happen */
fprintf(stderr, "amflush: start at %s\n", date_string);
- fprintf(stderr, "amflush: datestamp %s\n", datestamp);
- log_add(L_START, "date %s", datestamp);
+ fprintf(stderr, "amflush: datestamp %s\n", amflush_timestamp);
+ log_add(L_START, "date %s", amflush_timestamp);
/* START DRIVER */
if(pipe(driver_pipe) == -1) {
error("error [opening pipe to driver: %s]", strerror(errno));
+ /*NOTREACHED*/
}
if((driver_pid = fork()) == 0) {
/*
"driver", config_name, "nodump", (char *)0,
safe_env());
error("cannot exec %s: %s", driver_program, strerror(errno));
+ /*NOTREACHED*/
} else if(driver_pid == -1) {
error("cannot fork for %s: %s", driver_program, strerror(errno));
+ /*NOTREACHED*/
}
driver_stream = fdopen(driver_pipe[1], "w");
+ if (!driver_stream) {
+ error("Can't fdopen: %s", strerror(errno));
+ /*NOTREACHED*/
+ }
+ fprintf(driver_stream, "DATE %s\n", amflush_timestamp);
for(holding_file=holding_list->first; holding_file != NULL;
holding_file = holding_file->next) {
get_dumpfile(holding_file->name, &file);
dp = lookup_disk(file.name, file.disk);
+ if (!dp) {
+ error("dp == NULL");
+ /*NOTREACHED*/
+ }
if (dp->todo == 0) continue;
fprintf(stderr,
continue;
} else {
error("wait for %s: %s", driver_program, strerror(errno));
+ /*NOTREACHED*/
}
} else if (pid == driver_pid) {
break;
if (rename(errfilex, nerrfilex) != 0) {
error("cannot rename \"%s\" to \"%s\": %s",
errfilex, nerrfilex, strerror(errno));
+ /*NOTREACHED*/
}
}
errfilex = newvstralloc(errfilex, errfile, ".1", NULL);
if (rename(errfile,errfilex) != 0) {
error("cannot rename \"%s\" to \"%s\": %s",
errfilex, nerrfilex, strerror(errno));
+ /*NOTREACHED*/
}
amfree(errfile);
amfree(errfilex);
"amreport", config_name, (char *)0,
safe_env());
error("cannot exec %s: %s", reporter_program, strerror(errno));
+ /*NOTREACHED*/
} else if(reporter_pid == -1) {
error("cannot fork for %s: %s", reporter_program, strerror(errno));
+ /*NOTREACHED*/
}
while(1) {
if((pid = wait(&exitcode)) == -1) {
continue;
} else {
error("wait for %s: %s", reporter_program, strerror(errno));
+ /*NOTREACHED*/
}
} else if (pid == reporter_pid) {
break;
* Call amlogroll to rename the log file to its datestamped version.
* Since we exec at this point, our exit code will be that of amlogroll.
*/
-
execle(logroll_program,
"amlogroll", config_name, (char *)0,
safe_env());
error("cannot exec %s: %s", logroll_program, strerror(errno));
+ /*NOTREACHED*/
return 0; /* keep the compiler happy */
}
-static int get_letter_from_user()
+static int
+get_letter_from_user(void)
{
int r, ch;
fflush(stdout); fflush(stderr);
- while((ch = getchar()) != EOF && ch != '\n' && isspace(ch)) {}
+ while((ch = getchar()) != EOF && ch != '\n' && isspace(ch)) {
+ (void)ch; /* Quite lint */
+ }
if(ch == '\n') {
r = '\0';
} else if (ch != EOF) {
r = ch;
if(islower(r)) r = toupper(r);
- while((ch = getchar()) != EOF && ch != '\n') {}
+ while((ch = getchar()) != EOF && ch != '\n') {
+ (void)ch; /* Quite lint */
+ }
} else {
r = ch;
clearerr(stdin);
}
-void confirm()
-/* confirm before detaching and running */
+/*
+ * confirm before detaching and running
+ */
+
+void
+confirm(void)
{
tape_t *tp;
char *tpchanger;
int ch;
char *extra;
- printf("\nToday is: %s\n",datestamp);
+ printf("\nToday is: %s\n",amflush_datestamp);
printf("Flushing dumps in");
extra = "";
for(dir = datestamp_list->first; dir != NULL; dir = dir->next) {
exit(1);
}
-void redirect_stderr()
+void
+redirect_stderr(void)
{
int fderr;
char *errfile;
fflush(stdout); fflush(stderr);
errfile = vstralloc(conf_logdir, "/amflush", NULL);
- if((fderr = open(errfile, O_WRONLY| O_CREAT | O_TRUNC, 0600)) == -1)
+ if((fderr = open(errfile, O_WRONLY| O_CREAT | O_TRUNC, 0600)) == -1) {
error("could not open %s: %s", errfile, strerror(errno));
+ /*NOTREACHED*/
+ }
dup2(fderr,1);
dup2(fderr,2);
aclose(fderr);
amfree(errfile);
}
-void detach()
+void
+detach(void)
{
int fd;
fflush(stdout); fflush(stderr);
- if((fd = open("/dev/null", O_RDWR, 0666)) == -1)
+ if((fd = open("/dev/null", O_RDWR, 0666)) == -1) {
error("could not open /dev/null: %s", strerror(errno));
+ /*NOTREACHED*/
+ }
dup2(fd,0);
aclose(fd);
switch(fork()) {
- case -1: error("could not fork: %s", strerror(errno));
+ case -1:
+ error("could not fork: %s", strerror(errno));
+ /*NOTREACHED*/
+
case 0:
setsid();
return;
exit(0);
}
-
-
-#! /bin/sh
+#! @SHELL@
#
# ICEM internal :-)
#
* University of Maryland at College Park
*/
/*
- * $Id: amindex.c,v 1.13 2001/09/01 03:36:24 jrjackson Exp $
+ * $Id: amindex.c,v 1.15 2006/05/25 01:47:19 johnfranks Exp $
*
* index control
*/
+#include "amanda.h"
#include "conffile.h"
#include "amindex.h"
-char *getindexfname(host, disk, date, level)
-char *host, *disk, *date;
-int level;
+char *
+getindexfname(
+ char * host,
+ char * disk,
+ char * date,
+ int level)
{
char *conf_indexdir;
char *buf;
char level_str[NUM_STR_SIZE];
- char datebuf[8 + 1];
+ char datebuf[14 + 1];
char *dc = NULL;
char *pc;
int ch;
if (date != NULL) {
dc = date;
pc = datebuf;
- while (pc < datebuf + sizeof (datebuf)) {
- if ((*pc++ = ch = *dc++) == '\0') {
+ while (pc < datebuf + SIZEOF(datebuf)) {
+ ch = *dc++;
+ *pc++ = (char)ch;
+ if (ch == '\0') {
break;
} else if (! isdigit (ch)) {
pc--;
}
}
- datebuf[sizeof(datebuf)-1] = '\0';
+ datebuf[SIZEOF(datebuf)-1] = '\0';
dc = datebuf;
- snprintf(level_str, sizeof(level_str), "%d", level);
+ snprintf(level_str, SIZEOF(level_str), "%d", level);
}
host = sanitise_filename(host);
* University of Maryland at College Park
*/
/*
- * $Id: amindex.h,v 1.7 1999/09/15 00:32:27 jrj Exp $
+ * $Id: amindex.h,v 1.8 2006/05/25 01:47:19 johnfranks Exp $
*
* headers for index control
*/
#include "amanda.h"
#include "conffile.h"
-char *getindexfname P((char *host, char *disk, char *date, int level));
+char *getindexfname(char *host, char *disk, char *date, int level);
#endif /* AMINDEX_H */
* file named AUTHORS, in the root directory of this distribution.
*/
/*
- * $Id: amindexd.c,v 1.86 2006/03/09 16:51:41 martinea Exp $
+ * $Id: amindexd.c,v 1.106 2006/07/25 18:27:57 martinea Exp $
*
* This is the server daemon part of the index client/server system.
* It is assumed that this is launched from inetd instead of being
#include "token.h"
#include "find.h"
#include "tapefile.h"
-
-#ifdef HAVE_NETINET_IN_SYSTM_H
-#include <netinet/in_systm.h>
-#endif
-
-#ifdef HAVE_NETINET_IP_H
-#include <netinet/ip.h>
-#endif
+#include "util.h"
+#include "amandad.h"
#include <grp.h>
} REMOVE_ITEM;
/* state */
-char local_hostname[MAX_HOSTNAME_LENGTH+1]; /* me! */
-char *remote_hostname = NULL; /* the client */
-char *dump_hostname = NULL; /* machine we are restoring */
-char *disk_name; /* disk we are restoring */
-char *target_date = NULL;
-disklist_t disk_list; /* all disks in cur config */
-find_result_t *output_find = NULL;
+static int from_amandad;
+static char local_hostname[MAX_HOSTNAME_LENGTH+1]; /* me! */
+static char *remote_hostname = NULL; /* the client */
+static char *dump_hostname = NULL; /* machine we are restoring */
+static char *disk_name; /* disk we are restoring */
+char *qdisk_name = NULL; /* disk we are restoring */
+static char *target_date = NULL;
+static disklist_t disk_list; /* all disks in cur config */
+static find_result_t *output_find = NULL;
+static g_option_t *g_options = NULL;
+static int cmdfdin, cmdfdout;
static int amindexd_debug = 0;
static am_feature_t *our_features = NULL;
static am_feature_t *their_features = NULL;
-static REMOVE_ITEM *remove_files P((REMOVE_ITEM *));
-static char *uncompress_file P((char *, char **));
-static int process_ls_dump P((char *, DUMP_ITEM *, int, char **));
+static REMOVE_ITEM *remove_files(REMOVE_ITEM *);
+static char *uncompress_file(char *, char **);
+static int process_ls_dump(char *, DUMP_ITEM *, int, char **);
- /* XXX this is a hack to make sure the printf-ish output buffer
- for lreply and friends is big enough for long label strings.
- Should go away if someone institutes a more fundamental fix
- for that problem. */
- static int str_buffer_size = STR_SIZE;
+static size_t reply_buffer_size = 1;
+static char *reply_buffer = NULL;
+static char *amandad_auth = NULL;
-static void reply P((int, char *, ...))
+static void reply(int, char *, ...)
__attribute__ ((format (printf, 2, 3)));
-static void lreply P((int, char *, ...))
+static void lreply(int, char *, ...)
__attribute__ ((format (printf, 2, 3)));
-static void fast_lreply P((int, char *, ...))
+static void fast_lreply(int, char *, ...)
__attribute__ ((format (printf, 2, 3)));
-static int is_dump_host_valid P((char *));
-static int is_disk_valid P((char *));
-static int is_config_valid P((char *));
-static int build_disk_table P((void));
-static int disk_history_list P((void));
-static int is_dir_valid_opaque P((char *));
-static int opaque_ls P((char *, int));
-static int tapedev_is P((void));
-static int are_dumps_compressed P((void));
-int main P((int, char **));
-
-static REMOVE_ITEM *remove_files(remove)
-REMOVE_ITEM *remove;
+static int is_dump_host_valid(char *);
+static int is_disk_valid(char *);
+static int is_config_valid(char *);
+static int build_disk_table(void);
+static int disk_history_list(void);
+static int is_dir_valid_opaque(char *);
+static int opaque_ls(char *, int);
+static void opaque_ls_one (DIR_ITEM *dir_item, am_feature_e marshall_feature,
+ int recursive);
+static int tapedev_is(void);
+static int are_dumps_compressed(void);
+static char *amindexd_nicedate (char *datestamp);
+static int cmp_date (const char *date1, const char *date2);
+int main(int, char **);
+
+static REMOVE_ITEM *
+remove_files(
+ REMOVE_ITEM *remove)
{
REMOVE_ITEM *prev;
return remove;
}
-static char *uncompress_file(filename_gz, emsg)
-char *filename_gz;
-char **emsg;
+static char *
+uncompress_file(
+ char * filename_gz,
+ char ** emsg)
{
char *cmd = NULL;
char *filename = NULL;
struct stat stat_filename;
int result;
- int len;
+ size_t len;
filename = stralloc(filename_gz);
len = strlen(filename);
/* uncompress the file */
result=stat(filename,&stat_filename);
if(result==-1 && errno==ENOENT) { /* file does not exist */
+ struct stat statbuf;
REMOVE_ITEM *remove_file;
+
+ /*
+ * Check that compressed file exists manually.
+ */
+ if (stat(filename_gz, &statbuf) < 0) {
+ *emsg = newvstralloc(*emsg, "Compressed file '",
+ filename_gz,
+ "' is inaccessable: ",
+ strerror(errno),
+ NULL);
+ dbprintf(("%s\n",*emsg));
+ amfree(filename);
+ return NULL;
+ }
+
cmd = vstralloc(UNCOMPRESS_PATH,
#ifdef UNCOMPRESS_OPT
" ", UNCOMPRESS_OPT,
#endif
" \'", filename_gz, "\'",
" 2>/dev/null",
- " | sort",
+ " | (LC_ALL=C; export LC_ALL ; sort) ",
" > ", "\'", filename, "\'",
NULL);
dbprintf(("%s: uncompress command: %s\n",
debug_prefix_time(NULL), cmd));
- if (system(cmd)!=0) {
- amfree(*emsg);
- *emsg = vstralloc("\"", cmd, "\" failed", NULL);
+ if (system(cmd) != 0) {
+ *emsg = newvstralloc(*emsg, "\"", cmd, "\" failed", NULL);
unlink(filename);
errno = -1;
amfree(filename);
}
/* add at beginning */
- remove_file = (REMOVE_ITEM *)alloc(sizeof(REMOVE_ITEM));
+ remove_file = (REMOVE_ITEM *)alloc(SIZEOF(REMOVE_ITEM));
remove_file->filename = stralloc(filename);
remove_file->next = uncompress_remove;
uncompress_remove = remove_file;
amfree(filename);
amfree(cmd);
return NULL;
- } else {
- /* already uncompressed */
}
amfree(cmd);
return filename;
/* find all matching entries in a dump listing */
/* return -1 if error */
-static int process_ls_dump(dir, dump_item, recursive, emsg)
-char *dir;
-DUMP_ITEM *dump_item;
-int recursive;
-char **emsg;
+static int
+process_ls_dump(
+ char * dir,
+ DUMP_ITEM * dump_item,
+ int recursive,
+ char ** emsg)
{
char *line = NULL;
char *old_line = NULL;
FILE *fp;
char *s;
int ch;
- int len_dir_slash;
+ size_t len_dir_slash;
if (strcmp(dir, "/") == 0) {
dir_slash = stralloc(dir);
len_dir_slash=strlen(dir_slash);
- for(; (line = agets(fp)) != NULL; free(line)) {
- if(strncmp(dir_slash, line, len_dir_slash) == 0) {
- if(!recursive) {
- s = line + len_dir_slash;
- ch = *s++;
- while(ch && ch != '/') ch = *s++;/* find end of the file name */
- if(ch == '/') {
+ while ((line = agets(fp)) != NULL) {
+ if (line[0] != '\0') {
+ if(strncmp(dir_slash, line, len_dir_slash) == 0) {
+ if(!recursive) {
+ s = line + len_dir_slash;
ch = *s++;
+ while(ch && ch != '/')
+ ch = *s++;/* find end of the file name */
+ if(ch == '/') {
+ ch = *s++;
+ }
+ s[-1] = '\0';
+ }
+ if(old_line == NULL || strcmp(line, old_line) != 0) {
+ add_dir_list_item(dump_item, line);
+ amfree(old_line);
+ old_line = line;
+ line = NULL;
}
- s[-1] = '\0';
- }
- if(old_line == NULL || strcmp(line, old_line) != 0) {
- add_dir_list_item(dump_item, line);
- amfree(old_line);
- old_line = line;
- line = NULL;
}
}
+ /*@i@*/ amfree(line);
}
afclose(fp);
- amfree(old_line);
- amfree(line);
+ /*@i@*/ amfree(old_line);
amfree(filename);
amfree(dir_slash);
return 0;
printf_arglist_function1(static void reply, int, n, char *, fmt)
{
va_list args;
- char *buf;
+ int len;
- buf = alloc(str_buffer_size);
+ if(!reply_buffer)
+ reply_buffer = alloc(reply_buffer_size);
- arglist_start(args, fmt);
- snprintf(buf, str_buffer_size, "%03d ", n);
- vsnprintf(buf+4, str_buffer_size-4, fmt, args);
- arglist_end(args);
+ while(1) {
+ arglist_start(args, fmt);
+ len = vsnprintf(reply_buffer, reply_buffer_size, fmt, args);
+ arglist_end(args);
- if (printf("%s\r\n", buf) < 0)
+ if (len > -1 && (size_t)len < reply_buffer_size)
+ break;
+
+ reply_buffer_size *= 2;
+ amfree(reply_buffer);
+ reply_buffer = alloc(reply_buffer_size);
+ }
+
+ if (printf("%03d %s\r\n", n, reply_buffer) < 0)
{
dbprintf(("%s: ! error %d (%s) in printf\n",
debug_prefix_time(NULL), errno, strerror(errno)));
uncompress_remove = remove_files(uncompress_remove);
exit(1);
}
- dbprintf(("%s: < %s\n", debug_prefix_time(NULL), buf));
- amfree(buf);
+ dbprintf(("%s: < %03d %s\n", debug_prefix_time(NULL), n, reply_buffer));
}
-static void lreply_backend(int flush, int n, char *fmt, va_list args) {
- char *buf;
+/* send one line of a multi-line response */
+printf_arglist_function1(static void lreply, int, n, char *, fmt)
+{
+ va_list args;
+ int len;
+
+ if(!reply_buffer)
+ reply_buffer = alloc(reply_buffer_size);
- buf = alloc(str_buffer_size);
+ while(1) {
+ arglist_start(args, fmt);
+ len = vsnprintf(reply_buffer, reply_buffer_size, fmt, args);
+ arglist_end(args);
- snprintf(buf, str_buffer_size, "%03d-", n);
- vsnprintf(buf+4, str_buffer_size-4, fmt, args);
+ if (len > -1 && (size_t)len < reply_buffer_size)
+ break;
- if (printf("%s\r\n", buf) < 0)
+ reply_buffer_size *= 2;
+ amfree(reply_buffer);
+ reply_buffer = alloc(reply_buffer_size);
+ }
+
+ if (printf("%03d-%s\r\n", n, reply_buffer) < 0)
{
dbprintf(("%s: ! error %d (%s) in printf\n",
debug_prefix_time(NULL), errno, strerror(errno)));
uncompress_remove = remove_files(uncompress_remove);
exit(1);
}
- if (flush && fflush(stdout) != 0)
+ if (fflush(stdout) != 0)
{
dbprintf(("%s: ! error %d (%s) in fflush\n",
debug_prefix_time(NULL), errno, strerror(errno)));
exit(1);
}
- dbprintf(("%s: < %s\n", debug_prefix_time(NULL), buf));
- amfree(buf);
+ dbprintf(("%s: < %03d-%s\n", debug_prefix_time(NULL), n, reply_buffer));
+
}
/* send one line of a multi-line response */
-printf_arglist_function1(static void lreply, int, n, char *, fmt)
+printf_arglist_function1(static void fast_lreply, int, n, char *, fmt)
{
va_list args;
+ int len;
- arglist_start(args, fmt);
- lreply_backend(1, n, fmt, args);
- arglist_end(args);
+ if(!reply_buffer)
+ reply_buffer = alloc(reply_buffer_size);
-}
+ while(1) {
+ arglist_start(args, fmt);
+ len = vsnprintf(reply_buffer, reply_buffer_size, fmt, args);
+ arglist_end(args);
-/* send one line of a multi-line response */
-printf_arglist_function1(static void fast_lreply, int, n, char *, fmt)
-{
- va_list args;
+ if (len > -1 && (size_t)len < reply_buffer_size)
+ break;
- arglist_start(args, fmt);
- lreply_backend(0, n, fmt, args);
- arglist_end(args);
+ reply_buffer_size *= 2;
+ amfree(reply_buffer);
+ reply_buffer = alloc(reply_buffer_size);
+ }
+ if (printf("%03d-%s\r\n", n, reply_buffer) < 0)
+ {
+ dbprintf(("%s: ! error %d (%s) in printf\n",
+ debug_prefix_time(NULL), errno, strerror(errno)));
+ uncompress_remove = remove_files(uncompress_remove);
+ exit(1);
+ }
+
+ dbprintf(("%s: < %03d-%s\n", debug_prefix_time(NULL), n, reply_buffer));
}
/* see if hostname is valid */
/* also do a security check on the requested dump hostname */
/* to restrict access to index records if required */
/* return -1 if not okay */
-static int is_dump_host_valid(host)
-char *host;
+static int
+is_dump_host_valid(
+ char * host)
{
struct stat dir_stat;
char *fn;
}
-static int is_disk_valid(disk)
-char *disk;
+static int
+is_disk_valid(
+ char *disk)
{
char *fn;
struct stat dir_stat;
disk_t *idisk;
+ char *qdisk;
- if (config_name == NULL || dump_hostname == NULL) {
+ if (config_name == NULL) {
reply(501, "Must set config,host before setting disk.");
return -1;
}
+ else if (dump_hostname == NULL) {
+ reply(501, "Must set host before setting disk.");
+ return -1;
+ }
/* check that the config actually handles that disk */
idisk = lookup_disk(dump_hostname, disk);
if(idisk == NULL) {
- reply(501, "Disk %s:%s is not in your disklist.", dump_hostname, disk);
+ qdisk = quote_string(disk);
+ reply(501, "Disk %s:%s is not in your disklist.", dump_hostname, qdisk);
+ amfree(qdisk);
return -1;
}
/* assume an index dir already */
fn = getindexfname(dump_hostname, disk, NULL, 0);
if (stat (fn, &dir_stat) != 0 || !S_ISDIR(dir_stat.st_mode)) {
- reply(501, "No index records for disk: %s. Invalid?", disk);
+ qdisk = quote_string(disk);
+ reply(501, "No index records for disk: %s. Invalid?", qdisk);
amfree(fn);
+ amfree(qdisk);
return -1;
}
}
-static int is_config_valid(config)
-char *config;
+static int
+is_config_valid(
+ char * config)
{
char *conffile;
char *conf_diskfile;
}
amfree(conf_tapelist);
+ dbrename(config, DBG_SUBDIR_SERVER);
+
output_find = find_dump(1, &disk_list);
sort_find_result("DLKHpB", &output_find);
}
-static int build_disk_table()
+static int
+build_disk_table(void)
{
- char date[3 * NUM_STR_SIZE + 2 + 1];
- long last_datestamp;
- int last_filenum;
+ char *date;
+ char *last_timestamp;
+ off_t last_filenum;
int last_level;
int last_partnum;
find_result_t *find_output;
- if (config_name == NULL || dump_hostname == NULL || disk_name == NULL) {
+ if (config_name == NULL) {
reply(590, "Must set config,host,disk before building disk table");
return -1;
}
+ else if (dump_hostname == NULL) {
+ reply(590, "Must set host,disk before building disk table");
+ return -1;
+ }
+ else if (disk_name == NULL) {
+ reply(590, "Must set disk before building disk table");
+ return -1;
+ }
clear_list();
- last_datestamp = -1;
- last_filenum = -1;
+ last_timestamp = NULL;
+ last_filenum = (off_t)-1;
last_level = -1;
last_partnum = -1;
for(find_output = output_find;
* for the same datestamp after we see a holding disk entry
* (as indicated by a filenum of zero).
*/
- if(find_output->datestamp == last_datestamp &&
+ if(last_timestamp &&
+ strcmp(find_output->timestamp, last_timestamp) == 0 &&
find_output->level == last_level &&
partnum == last_partnum && last_filenum == 0) {
continue;
}
- last_datestamp = find_output->datestamp;
+ last_timestamp = find_output->timestamp;
last_filenum = find_output->filenum;
last_level = find_output->level;
last_partnum = partnum;
- snprintf(date, sizeof(date), "%04d-%02d-%02d",
- find_output->datestamp/10000,
- (find_output->datestamp/100) %100,
- find_output->datestamp %100);
+ date = amindexd_nicedate(find_output->timestamp);
add_dump(date, find_output->level, find_output->label,
find_output->filenum, partnum);
- dbprintf(("%s: - %s %d %s %d %d\n",
+ dbprintf(("%s: - %s %d %s " OFF_T_FMT " %d\n",
debug_prefix_time(NULL), date, find_output->level,
- find_output->label, find_output->filenum, partnum));
+ find_output->label,
+ (OFF_T_FMT_TYPE)find_output->filenum,
+ partnum));
}
}
return 0;
}
-static int disk_history_list()
+static int
+disk_history_list(void)
{
DUMP_ITEM *item;
+ char date[20];
- if (config_name == NULL || dump_hostname == NULL || disk_name == NULL) {
+ if (config_name == NULL) {
reply(502, "Must set config,host,disk before listing history");
return -1;
}
+ else if (dump_hostname == NULL) {
+ reply(502, "Must set host,disk before listing history");
+ return -1;
+ }
+ else if (disk_name == NULL) {
+ reply(502, "Must set disk before listing history");
+ return -1;
+ }
- lreply(200, " Dump history for config \"%s\" host \"%s\" disk \"%s\"",
- config_name, dump_hostname, disk_name);
+ lreply(200, " Dump history for config \"%s\" host \"%s\" disk %s",
+ config_name, dump_hostname, qdisk_name);
for (item=first_dump(); item!=NULL; item=next_dump(item)){
char *tapelist_str = marshal_tapelist(item->tapes, 1);
+ strncpy(date, item->date, 20);
+ date[19] = '\0';
+ if(!am_has_feature(their_features,fe_amrecover_timestamp))
+ date[10] = '\0';
+
if(am_has_feature(their_features, fe_amindexd_marshall_in_DHST)){
- str_buffer_size = strlen(item->date) + NUM_STR_SIZE +
- strlen(tapelist_str) + 9;
- lreply(201, " %s %d %s", item->date, item->level, tapelist_str);
+ lreply(201, " %s %d %s", date, item->level, tapelist_str);
}
else{
- str_buffer_size = strlen(item->date) + NUM_STR_SIZE +
- strlen(tapelist_str) + NUM_STR_SIZE + 9;
- lreply(201, " %s %d %s %d", item->date, item->level, tapelist_str,
- item->file);
+ lreply(201, " %s %d %s " OFF_T_FMT, date, item->level,
+ tapelist_str, (OFF_T_FMT_TYPE)item->file);
}
- str_buffer_size = STR_SIZE;
+ amfree(tapelist_str);
}
- reply(200, "Dump history for config \"%s\" host \"%s\" disk \"%s\"",
- config_name, dump_hostname, disk_name);
+ reply(200, "Dump history for config \"%s\" host \"%s\" disk %s",
+ config_name, dump_hostname, qdisk_name);
return 0;
}
-/* is the directory dir backed up - dir assumed complete relative to
- disk mount point */
+/*
+ * is the directory dir backed up - dir assumed complete relative to
+ * disk mount point
+ */
/* opaque version of command */
-static int is_dir_valid_opaque(dir)
-char *dir;
+static int
+is_dir_valid_opaque(
+ char *dir)
{
DUMP_ITEM *item;
char *line = NULL;
char *ldir = NULL;
char *filename_gz = NULL;
char *filename = NULL;
- int ldir_len;
+ size_t ldir_len;
static char *emsg = NULL;
if (config_name == NULL || dump_hostname == NULL || disk_name == NULL) {
reply(502, "Must set config,host,disk before asking about directories");
return -1;
}
- if (target_date == NULL) {
+ else if (dump_hostname == NULL) {
+ reply(502, "Must set host,disk before asking about directories");
+ return -1;
+ }
+ else if (disk_name == NULL) {
+ reply(502, "Must set disk before asking about directories");
+ return -1;
+ }
+ else if (target_date == NULL) {
reply(502, "Must set date before asking about directories");
return -1;
}
/* scan through till we find first dump on or before date */
for (item=first_dump(); item!=NULL; item=next_dump(item))
- if (strcmp(item->date, target_date) <= 0)
+ if (cmp_date(item->date, target_date) <= 0)
break;
if (item == NULL)
return -1;
}
for(; (line = agets(fp)) != NULL; free(line)) {
+ if (line[0] == '\0')
+ continue;
if (strncmp(line, ldir, ldir_len) != 0) {
continue; /* not found yet */
}
return -1;
}
-static int opaque_ls(dir,recursive)
-char *dir;
-int recursive;
+static int
+opaque_ls(
+ char * dir,
+ int recursive)
{
DUMP_ITEM *dump_item;
DIR_ITEM *dir_item;
- int last_level;
+ int level, last_level;
static char *emsg = NULL;
am_feature_e marshall_feature;
clear_dir_list();
- if (config_name == NULL || dump_hostname == NULL || disk_name == NULL) {
+ if (config_name == NULL) {
reply(502, "Must set config,host,disk before listing a directory");
return -1;
}
- if (target_date == NULL) {
+ else if (dump_hostname == NULL) {
+ reply(502, "Must set host,disk before listing a directory");
+ return -1;
+ }
+ else if (disk_name == NULL) {
+ reply(502, "Must set disk before listing a directory");
+ return -1;
+ }
+ else if (target_date == NULL) {
reply(502, "Must set date before listing a directory");
return -1;
}
/* scan through till we find first dump on or before date */
for (dump_item=first_dump(); dump_item!=NULL; dump_item=next_dump(dump_item))
- if (strcmp(dump_item->date, target_date) <= 0)
+ if (cmp_date(dump_item->date, target_date) <= 0)
break;
if (dump_item == NULL)
/* return the information to the caller */
lreply(200, " Opaque list of %s", dir);
- for (dir_item = get_dir_list(); dir_item != NULL;
- dir_item = dir_item->next) {
- char *tapelist_str;
-
- if (!am_has_feature(their_features, marshall_feature) &&
- (num_entries(dir_item->dump->tapes) > 1 ||
- dir_item->dump->tapes->numfiles > 1)) {
- fast_lreply(501, " ERROR: Split dumps not supported"
- " with old version of amrecover.");
- break;
- } else {
- if (am_has_feature(their_features, marshall_feature)) {
- tapelist_str = marshal_tapelist(dir_item->dump->tapes, 1);
- } else {
- tapelist_str = dir_item->dump->tapes->label;
- }
-
- if((!recursive && am_has_feature(their_features,
- fe_amindexd_fileno_in_OLSD))
- ||
- (recursive && am_has_feature(their_features,
- fe_amindexd_fileno_in_ORLD))) {
- str_buffer_size = strlen(dir_item->dump->date) +
- NUM_STR_SIZE + strlen(tapelist_str) +
- strlen(dir_item->path) + NUM_STR_SIZE + 9;
- fast_lreply(201, " %s %d %s %d %s",
- dir_item->dump->date, dir_item->dump->level,
- tapelist_str, dir_item->dump->file,
- dir_item->path);
- }
- else {
- str_buffer_size = strlen(dir_item->dump->date) +
- NUM_STR_SIZE + strlen(tapelist_str) +
- strlen(dir_item->path) + 9;
- fast_lreply(201, " %s %d %s %s",
- dir_item->dump->date, dir_item->dump->level,
- tapelist_str, dir_item->path);
- }
- if(am_has_feature(their_features, marshall_feature)) {
- amfree(tapelist_str);
+ for(level=0; level<=9; level++) {
+ for (dir_item = get_dir_list(); dir_item != NULL;
+ dir_item = dir_item->next) {
+
+ if(dir_item->dump->level == level) {
+ if (!am_has_feature(their_features, marshall_feature) &&
+ (num_entries(dir_item->dump->tapes) > 1 ||
+ dir_item->dump->tapes->numfiles > 1)) {
+ fast_lreply(501, " ERROR: Split dumps not supported"
+ " with old version of amrecover.");
+ break;
}
- str_buffer_size = STR_SIZE;
- }
+ else {
+ opaque_ls_one(dir_item, marshall_feature, recursive);
+ }
+ }
+ }
}
reply(200, " Opaque list of %s", dir);
return 0;
}
+void opaque_ls_one(
+ DIR_ITEM * dir_item,
+ am_feature_e marshall_feature,
+ int recursive)
+{
+ char date[20];
+ char *tapelist_str;
+ char *qpath;
-/* returns the value of changer or tapedev from the amanda.conf file if set,
- otherwise reports an error */
-static int tapedev_is()
+ if (am_has_feature(their_features, marshall_feature)) {
+ tapelist_str = marshal_tapelist(dir_item->dump->tapes, 1);
+ } else {
+ tapelist_str = dir_item->dump->tapes->label;
+ }
+
+ strncpy(date, dir_item->dump->date, 20);
+ date[19] = '\0';
+ if(!am_has_feature(their_features,fe_amrecover_timestamp))
+ date[10] = '\0';
+
+ qpath = quote_string(dir_item->path);
+ if((!recursive && am_has_feature(their_features,
+ fe_amindexd_fileno_in_OLSD)) ||
+ (recursive && am_has_feature(their_features,
+ fe_amindexd_fileno_in_ORLD))) {
+ fast_lreply(201, " %s %d %s " OFF_T_FMT " %s",
+ date,
+ dir_item->dump->level,
+ tapelist_str,
+ (OFF_T_FMT_TYPE)dir_item->dump->file,
+ qpath);
+ }
+ else {
+
+ fast_lreply(201, " %s %d %s %s",
+ date, dir_item->dump->level,
+ tapelist_str, qpath);
+ }
+ amfree(qpath);
+ if(am_has_feature(their_features, marshall_feature)) {
+ amfree(tapelist_str);
+ }
+}
+
+/*
+ * returns the value of changer or tapedev from the amanda.conf file if set,
+ * otherwise reports an error
+ */
+
+static int
+tapedev_is(void)
{
char *result;
/* returns YES if dumps for disk are compressed, NO if not */
-static int are_dumps_compressed()
+static int
+are_dumps_compressed(void)
{
disk_t *diskp;
/* check state okay to do this */
- if (config_name == NULL || dump_hostname == NULL || disk_name == NULL) {
+ if (config_name == NULL) {
reply(501, "Must set config,host,disk name before asking about dumps.");
return -1;
}
+ else if (dump_hostname == NULL) {
+ reply(501, "Must set host,disk name before asking about dumps.");
+ return -1;
+ }
+ else if (disk_name == NULL) {
+ reply(501, "Must set disk name before asking about dumps.");
+ return -1;
+ }
/* now go through the list of disks and find which have indexes */
- for (diskp = disk_list.head; diskp != NULL; diskp = diskp->next)
+ for (diskp = disk_list.head; diskp != NULL; diskp = diskp->next) {
if ((strcasecmp(diskp->host->hostname, dump_hostname) == 0)
- && (strcmp(diskp->name, disk_name) == 0))
+ && (strcmp(diskp->name, disk_name) == 0)) {
break;
+ }
+ }
- if (diskp == NULL)
- {
+ if (diskp == NULL) {
reply(501, "Couldn't find host/disk in disk file.");
return -1;
}
return 0;
}
-int main(argc, argv)
-int argc;
-char **argv;
+int
+main(
+ int argc,
+ char ** argv)
{
char *line = NULL, *part = NULL;
char *s, *fp;
socklen_t socklen;
struct sockaddr_in his_addr;
struct hostent *his_name;
- char *arg;
+ char *arg = NULL;
char *cmd;
- int len;
+ size_t len;
int user_validated = 0;
char *errstr = NULL;
- char *pgm = "amindexd"; /* in case argv[0] is not set */
+ char *pgm = "amindexd"; /* in case argv[0] is not set */
- safe_fd(-1, 0);
+ safe_fd(DATA_FD_OFFSET, 2);
safe_cd();
/*
if(geteuid() == 0) {
if(client_uid == (uid_t) -1) {
error("error [cannot find user %s in passwd file]\n", CLIENT_LOGIN);
+ /*NOTREACHED*/
}
+ /*@ignore@*/
initgroups(CLIENT_LOGIN, client_gid);
+ /*@end@*/
setgid(client_gid);
setuid(client_uid);
}
#endif /* FORCE_USERID */
- dbopen();
+ dbopen(DBG_SUBDIR_SERVER);
dbprintf(("%s: version %s\n", get_pname(), version()));
if(argv == NULL) {
argv++;
}
+ if(argc > 0 && strcmp(*argv, "amandad") == 0) {
+ from_amandad = 1;
+ argc--;
+ argv++;
+ if(argc > 0) {
+ amandad_auth = *argv;
+ argc--;
+ argv++;
+ }
+ }
+ else {
+ from_amandad = 0;
+ safe_fd(-1, 0);
+ }
+
if (argc > 0) {
config_name = stralloc(*argv);
config_dir = vstralloc(CONFIG_DIR, "/", config_name, "/", NULL);
argv++;
}
- if(gethostname(local_hostname, sizeof(local_hostname)-1) == -1)
+ if(gethostname(local_hostname, SIZEOF(local_hostname)-1) == -1) {
error("gethostname: %s", strerror(errno));
- local_hostname[sizeof(local_hostname)-1] = '\0';
+ /*NOTREACHED*/
+ }
+ local_hostname[SIZEOF(local_hostname)-1] = '\0';
/* now trim domain off name */
s = local_hostname;
while(ch && ch != '.') ch = *s++;
s[-1] = '\0';
- if(amindexd_debug) {
- /*
- * Fake the remote address as the local address enough to get
- * through the security check.
- */
- his_name = gethostbyname(local_hostname);
- if(his_name == NULL) {
- error("gethostbyname(%s) failed\n", local_hostname);
+
+ if(from_amandad == 0) {
+ if(amindexd_debug) {
+ /*
+ * Fake the remote address as the local address enough to get
+ * through the security check.
+ */
+ his_name = gethostbyname(local_hostname);
+ if(his_name == NULL) {
+ error("gethostbyname(%s) failed\n", local_hostname);
+ /*NOTREACHED*/
+ }
+ assert((sa_family_t)his_name->h_addrtype == (sa_family_t)AF_INET);
+ his_addr.sin_family = (sa_family_t)his_name->h_addrtype;
+ his_addr.sin_port = (in_port_t)htons(0);
+ memcpy((void *)&his_addr.sin_addr.s_addr,
+ (void *)his_name->h_addr_list[0],
+ (size_t)his_name->h_length);
+ } else {
+ /* who are we talking to? */
+ socklen = sizeof (his_addr);
+ if (getpeername(0, (struct sockaddr *)&his_addr, &socklen) == -1)
+ error("getpeername: %s", strerror(errno));
}
- assert(his_name->h_addrtype == AF_INET);
- his_addr.sin_family = his_name->h_addrtype;
- his_addr.sin_port = htons(0);
- memcpy((char *)&his_addr.sin_addr.s_addr,
- (char *)his_name->h_addr_list[0], his_name->h_length);
- } else {
- /* who are we talking to? */
- socklen = sizeof (his_addr);
- if (getpeername(0, (struct sockaddr *)&his_addr, &socklen) == -1)
- error("getpeername: %s", strerror(errno));
- }
- if (his_addr.sin_family != AF_INET || ntohs(his_addr.sin_port) == 20)
- {
- error("connection rejected from %s family %d port %d",
- inet_ntoa(his_addr.sin_addr), his_addr.sin_family,
- htons(his_addr.sin_port));
+ if ((his_addr.sin_family != (sa_family_t)AF_INET)
+ || (ntohs(his_addr.sin_port) == 20)) {
+ error("connection rejected from %s family %d port %d",
+ inet_ntoa(his_addr.sin_addr), his_addr.sin_family,
+ htons(his_addr.sin_port));
+ /*NOTREACHED*/
+ }
+ if ((his_name = gethostbyaddr((char *)&(his_addr.sin_addr),
+ sizeof(his_addr.sin_addr),
+ AF_INET)) == NULL) {
+ error("gethostbyaddr(%s): hostname lookup failed",
+ inet_ntoa(his_addr.sin_addr));
+ /*NOTREACHED*/
+ }
+ fp = s = stralloc(his_name->h_name);
+ ch = *s++;
+ while(ch && ch != '.') ch = *s++;
+ s[-1] = '\0';
+ remote_hostname = newstralloc(remote_hostname, fp);
+ s[-1] = (char)ch;
+ amfree(fp);
}
- if ((his_name = gethostbyaddr((char *)&(his_addr.sin_addr),
- sizeof(his_addr.sin_addr),
- AF_INET)) == NULL) {
- error("gethostbyaddr(%s): hostname lookup failed",
- inet_ntoa(his_addr.sin_addr));
+ else {
+ cmdfdout = DATA_FD_OFFSET + 0;
+ cmdfdin = DATA_FD_OFFSET + 1;
+
+ /* read the REQ packet */
+ for(; (line = agets(stdin)) != NULL; free(line)) {
+#define sc "OPTIONS "
+ if(strncmp(line, sc, sizeof(sc)-1) == 0) {
+#undef sc
+ g_options = parse_g_options(line+8, 1);
+ if(!g_options->hostname) {
+ g_options->hostname = alloc(MAX_HOSTNAME_LENGTH+1);
+ gethostname(g_options->hostname, MAX_HOSTNAME_LENGTH);
+ g_options->hostname[MAX_HOSTNAME_LENGTH] = '\0';
+ }
+ }
+ }
+ amfree(line);
+
+ if(amandad_auth && g_options->auth) {
+ if(strcasecmp(amandad_auth, g_options->auth) != 0) {
+ printf("ERROR recover program ask for auth=%s while amindexd is configured for '%s'\n",
+ g_options->auth, amandad_auth);
+ error("amindexd: ERROR recover program ask for auth=%s while amindexd is configured for '%s'",
+ g_options->auth, amandad_auth);
+ /*NOTREACHED*/
+ }
+ }
+ /* send the REP packet */
+ printf("CONNECT MESG %d\n", DATA_FD_OFFSET);
+ printf("\n");
+ fflush(stdin);
+ fflush(stdout);
+ if ((dup2(cmdfdout, fileno(stdout)) < 0)
+ || (dup2(cmdfdin, fileno(stdin)) < 0)) {
+ error("amandad: Failed to setup stdin or stdout");
+ /*NOTREACHED*/
+ }
}
- fp = s = his_name->h_name;
- ch = *s++;
- while(ch && ch != '.') ch = *s++;
- s[-1] = '\0';
- remote_hostname = newstralloc(remote_hostname, fp);
- s[-1] = ch;
/* clear these so we can detect when the have not been set by the client */
amfree(dump_hostname);
+ amfree(qdisk_name);
amfree(disk_name);
amfree(target_date);
reply(220, "%s AMANDA index server (%s) ready.", local_hostname,
version());
+ user_validated = from_amandad;
+
/* a real simple parser since there are only a few commands */
while (1)
{
/* get a line from the client */
- amfree(line);
while(1) {
if((part = agets(stdin)) == NULL) {
if(errno != 0) {
dbclose();
return 1; /* they hung up? */
}
- if(line) {
- strappend(line, part);
- amfree(part);
- } else {
- line = part;
- part = NULL;
- }
+ strappend(line, part); /* Macro: line can be null */
+ amfree(part);
+
if(amindexd_debug) {
break; /* we have a whole line */
}
dbprintf(("%s: > %s\n", debug_prefix_time(NULL), line));
- arg = NULL;
+ if (arg != NULL)
+ amfree(arg);
s = line;
ch = *s++;
skip_whitespace(s, ch);
if(ch == '\0') {
reply(500, "Command not recognised/incorrect: %s", line);
+ amfree(line);
continue;
}
cmd = s - 1;
skip_whitespace(s, ch); /* find the argument */
if (ch) {
arg = s-1;
- skip_non_whitespace(s, ch);
+ skip_quoted_string(s, ch);
+ arg = unquote_string(arg);
}
}
user_validated = check_security(&his_addr, arg, 0, &errstr);
if(user_validated) {
reply(200, "Access OK");
+ amfree(line);
continue;
}
}
}
if (strcmp(cmd, "QUIT") == 0) {
+ amfree(line);
break;
} else if (strcmp(cmd, "HOST") == 0 && arg) {
/* set host we are restoring */
{
dump_hostname = newstralloc(dump_hostname, arg);
reply(200, "Dump host set to %s.", dump_hostname);
+ amfree(qdisk_name); /* invalidate any value */
amfree(disk_name); /* invalidate any value */
}
- s[-1] = ch;
+ s[-1] = (char)ch;
+ } else if (strcmp(cmd, "LISTHOST") == 0) {
+ disk_t *disk,
+ *diskdup;
+ int nbhost = 0,
+ found = 0;
+ s[-1] = '\0';
+ if (config_name == NULL) {
+ reply(501, "Must set config before listhost");
+ }
+ else {
+ lreply(200, " List hosts for config %s", config_name);
+ for (disk = disk_list.head; disk!=NULL; disk = disk->next) {
+ found = 0;
+ for (diskdup = disk_list.head; diskdup!=disk; diskdup = diskdup->next) {
+ if(strcmp(diskdup->host->hostname, disk->host->hostname) == 0) {
+ found = 1;
+ break;
+ }
+ }
+ if(!found){
+ fast_lreply(201, " %s", disk->host->hostname);
+ nbhost++;
+ }
+ }
+ if(nbhost > 0) {
+ reply(200, " List hosts for config %s", config_name);
+ }
+ else {
+ reply(200, "No hosts for config %s", config_name);
+ }
+ }
+ s[-1] = (char)ch;
} else if (strcmp(cmd, "DISK") == 0 && arg) {
s[-1] = '\0';
if (is_disk_valid(arg) != -1) {
disk_name = newstralloc(disk_name, arg);
+ qdisk_name = quote_string(disk_name);
if (build_disk_table() != -1) {
- reply(200, "Disk set to %s.", disk_name);
+ reply(200, "Disk set to %s.", qdisk_name);
}
}
- s[-1] = ch;
+ s[-1] = (char)ch;
} else if (strcmp(cmd, "LISTDISK") == 0) {
+ char *qname;
disk_t *disk;
int nbdisk = 0;
s[-1] = '\0';
- if (config_name == NULL || dump_hostname == NULL) {
+ if (config_name == NULL) {
reply(501, "Must set config, host before listdisk");
}
+ else if (dump_hostname == NULL) {
+ reply(501, "Must set host before listdisk");
+ }
else if(arg) {
lreply(200, " List of disk for device %s on host %s", arg,
dump_hostname);
for (disk = disk_list.head; disk!=NULL; disk = disk->next) {
- if(strcmp(disk->host->hostname, dump_hostname) == 0 &&
- ((disk->device && strcmp(disk->device, arg) == 0) ||
- (!disk->device && strcmp(disk->name, arg) == 0))) {
- fast_lreply(201, " %s", disk->name);
+
+ if (strcmp(disk->host->hostname, dump_hostname) == 0 &&
+ ((disk->device && strcmp(disk->device, arg) == 0) ||
+ (!disk->device && strcmp(disk->name, arg) == 0))) {
+ qname = quote_string(disk->name);
+ fast_lreply(201, " %s", qname);
+ amfree(qname);
nbdisk++;
}
}
lreply(200, " List of disk for host %s", dump_hostname);
for (disk = disk_list.head; disk!=NULL; disk = disk->next) {
if(strcmp(disk->host->hostname, dump_hostname) == 0) {
- fast_lreply(201, " %s", disk->name);
+ qname = quote_string(disk->name);
+ fast_lreply(201, " %s", qname);
+ amfree(qname);
nbdisk++;
}
}
reply(200, "No disk for host %s", dump_hostname);
}
}
- s[-1] = ch;
+ s[-1] = (char)ch;
} else if (strcmp(cmd, "SCNF") == 0 && arg) {
s[-1] = '\0';
amfree(config_name);
config_dir = vstralloc(CONFIG_DIR, "/", config_name, "/", NULL);
if (is_config_valid(arg) != -1) {
amfree(dump_hostname); /* invalidate any value */
+ amfree(qdisk_name); /* invalidate any value */
amfree(disk_name); /* invalidate any value */
reply(200, "Config set to %s.", config_name);
} else {
amfree(config_name);
amfree(config_dir);
}
- s[-1] = ch;
+ s[-1] = (char)ch;
} else if (strcmp(cmd, "FEATURES") == 0 && arg) {
char *our_feature_string = NULL;
char *their_feature_string = NULL;
am_release_feature_set(their_features);
our_features = am_init_feature_set();
our_feature_string = am_feature_to_string(our_features);
- their_feature_string = newstralloc(target_date, arg);
+ their_feature_string = newstralloc(their_feature_string, arg);
their_features = am_string_to_feature(their_feature_string);
reply(200, "FEATURES %s", our_feature_string);
amfree(our_feature_string);
amfree(their_feature_string);
- s[-1] = ch;
+ s[-1] = (char)ch;
} else if (strcmp(cmd, "DATE") == 0 && arg) {
s[-1] = '\0';
target_date = newstralloc(target_date, arg);
reply(200, "Working date set to %s.", target_date);
- s[-1] = ch;
+ s[-1] = (char)ch;
} else if (strcmp(cmd, "DHST") == 0) {
(void)disk_history_list();
} else if (strcmp(cmd, "OISD") == 0 && arg) {
} else if (strcmp(cmd, "OLSD") == 0 && arg) {
(void)opaque_ls(arg,0);
} else if (strcmp(cmd, "ORLD") == 0 && arg) {
- (void)opaque_ls(arg,1);
+ (void)opaque_ls(arg, 1);
} else if (strcmp(cmd, "TAPE") == 0) {
(void)tapedev_is();
} else if (strcmp(cmd, "DCMP") == 0) {
*cmd_undo = cmd_undo_ch; /* restore the command line */
reply(500, "Command not recognised/incorrect: %s", cmd);
}
+ amfree(line);
}
- amfree(line);
-
+ amfree(arg);
+
uncompress_remove = remove_files(uncompress_remove);
free_find_result(&output_find);
reply(200, "Good bye.");
dbclose();
return 0;
}
+
+static char *
+amindexd_nicedate(
+ char * datestamp)
+{
+ static char nice[20];
+ int year, month, day;
+ int hours, minutes, seconds;
+ char date[9], atime[7];
+ int numdate, numtime;
+
+ strncpy(date, datestamp, 8);
+ date[8] = '\0';
+ numdate = atoi(date);
+ year = numdate / 10000;
+ month = (numdate / 100) % 100;
+ day = numdate % 100;
+
+ if(strlen(datestamp) <= 8) {
+ snprintf(nice, SIZEOF(nice), "%4d-%02d-%02d",
+ year, month, day);
+ }
+ else {
+ strncpy(atime, &(datestamp[8]), 6);
+ atime[6] = '\0';
+ numtime = atoi(atime);
+ hours = numtime / 10000;
+ minutes = (numtime / 100) % 100;
+ seconds = numtime % 100;
+
+ snprintf(nice, SIZEOF(nice), "%4d-%02d-%02d-%02d-%02d-%02d",
+ year, month, day, hours, minutes, seconds);
+ }
+
+ return nice;
+}
+
+static int
+cmp_date(
+ const char * date1,
+ const char * date2)
+{
+ return strncmp(date1, date2, strlen(date2));
+}
* file named AUTHORS, in the root directory of this distribution.
*/
/*
- * $Id: amlabel.c,v 1.43 2006/01/14 04:37:19 paddy_s Exp $
+ * $Id: amlabel.c,v 1.53 2006/07/25 18:27:57 martinea Exp $
*
* write an Amanda label on a tape
*/
/* local functions */
-int main P((int, char **));
-void usage P((char *argv0));
+int main(int argc, char **argv);
+void usage(void);
-void usage(argv0)
-char *argv0;
+void
+usage(void)
{
- fprintf(stderr, "Usage: %s [-f] <conf> <label> [slot <slot-number>]\n",
- argv0);
+ fprintf(stderr, "Usage: %s [-f] <conf> <label> [slot <slot-number>] [-o configoption]*\n",
+ get_pname());
exit(1);
}
-int main(argc, argv)
- int argc;
- char **argv;
+int
+main(
+ int argc,
+ char ** argv)
{
char *conffile;
char *conf_tapelist;
#endif /* HAVE_LINUX_ZFTAPE_H */
int have_changer;
int force, tape_ok;
- tape_t *tp;
tapetype_t *tape;
- long tt_blocksize_kb;
+ size_t tt_blocksize_kb;
int slotcommand;
uid_t uid_me;
uid_t uid_dumpuser;
char *dumpuser;
struct passwd *pw;
+ int new_argc;
+ char **new_argv;
#ifdef HAVE_LIBVTBLC
int vtbl_no = -1;
set_pname("amlabel");
+ dbopen(DBG_SUBDIR_SERVER);
+
/* Don't die when child closes pipe */
signal(SIGPIPE, SIG_IGN);
erroutput_type = ERR_INTERACTIVE;
- if(argc > 1 && strcmp(argv[1],"-f") == 0)
+ parse_server_conf(argc, argv, &new_argc, &new_argv);
+
+ if(new_argc > 1 && strcmp(new_argv[1],"-f") == 0)
force=1;
else force=0;
- if(argc != 3+force && argc != 5+force)
- usage(argv[0]);
+ if(new_argc != 3+force && new_argc != 5+force)
+ usage();
- config_name = argv[1+force];
- label = argv[2+force];
+ config_name = new_argv[1+force];
+ label = new_argv[2+force];
- if(argc == 5+force) {
- if(strcmp(argv[3+force], "slot"))
- usage(argv[0]);
- slotstr = argv[4+force];
+ if(new_argc == 5+force) {
+ if(strcmp(new_argv[3+force], "slot"))
+ usage();
+ slotstr = new_argv[4+force];
slotcommand = 1;
} else {
slotstr = "current";
conffile = stralloc2(config_dir, CONFFILE_NAME);
if (read_conffile(conffile)) {
error("errors processing config file \"%s\"", conffile);
+ /*NOTREACHED*/
}
+ dbrename(config_name, DBG_SUBDIR_SERVER);
+
+ report_bad_conf_arg();
+
conf_tapelist = getconf_str(CNF_TAPELIST);
if (*conf_tapelist == '/') {
conf_tapelist = stralloc(conf_tapelist);
}
if (read_tapelist(conf_tapelist)) {
error("could not load tapelist \"%s\"", conf_tapelist);
+ /*NOTREACHED*/
}
uid_me = getuid();
if ((pw = getpwnam(dumpuser)) == NULL) {
error("cannot look up dump user \"%s\"", dumpuser);
- /* NOTREACHED */
+ /*NOTREACHED*/
}
uid_dumpuser = pw->pw_uid;
if ((pw = getpwuid(uid_me)) == NULL) {
error("cannot look up my own uid %ld", (long)uid_me);
- /* NOTREACHED */
+ /*NOTREACHED*/
}
if (uid_me != uid_dumpuser) {
error("running as user \"%s\" instead of \"%s\"",
pw->pw_name, dumpuser);
- /* NOTREACHED */
+ /*NOTREACHED*/
}
labelstr = getconf_str(CNF_LABELSTR);
- if(!match(labelstr, label))
+ if(!match(labelstr, label)) {
error("label %s doesn't match labelstr \"%s\"", label, labelstr);
+ /*NOTREACHED*/
+ }
- if((tp = lookup_tapelabel(label))!=NULL) {
- if(!force)
+ if((lookup_tapelabel(label))!=NULL) {
+ if(!force) {
error("label %s already on a tape\n",label);
+ /*NOTREACHED*/
+ }
}
tape = lookup_tapetype(getconf_str(CNF_TAPETYPE));
- tt_blocksize_kb = tape->blocksize;
+ tt_blocksize_kb = (size_t)tapetype_get_blocksize(tape);
if((have_changer = changer_init()) == 0) {
if(slotcommand) {
fprintf(stderr,
"%s: no tpchanger specified in \"%s\", so slot command invalid\n",
- argv[0], conffile);
- usage(argv[0]);
+ new_argv[0], conffile);
+ usage();
}
tapename = stralloc(getconf_str(CNF_TAPEDEV));
#ifdef HAVE_LIBVTBLC
#endif /* HAVE_LIBVTBLC */
} else if(have_changer != 1) {
error("changer initialization failed: %s", strerror(errno));
+ /*NOTREACHED*/
} else {
if(changer_loadslot(slotstr, &outslot, &tapename)) {
error("could not load slot \"%s\": %s", slotstr, changer_resultstr);
+ /*NOTREACHED*/
}
printf("labeling tape in slot %s (%s):\n", outslot, tapename);
(errno == EACCES) ? "tape is write-protected"
: strerror(errno));
error(errstr);
+ /*NOTREACHED*/
}
}
#endif /* HAVE_LINUX_ZFTAPE_H */
if(tapefd_rewind(fd) == -1) {
putchar('\n');
error(strerror(errno));
+ /*NOTREACHED*/
}
}
else
if((errstr = tape_rewind(tapename)) != NULL) {
putchar('\n');
error(errstr);
+ /*NOTREACHED*/
}
tape_ok=1;
tape_ok=0;
}
else {
- if((tp = lookup_tapelabel(oldlabel)) != NULL) {
+ if((lookup_tapelabel(oldlabel)) != NULL) {
printf(", tape is active");
if(!force)
tape_ok=0;
if(tapefd_rewind(fd) == -1) {
putchar('\n');
error(strerror(errno));
+ /*NOTREACHED*/
}
}
else
if((errstr = tape_rewind(tapename)) != NULL) {
putchar('\n');
error(errstr);
+ /*NOTREACHED*/
}
if(tape_ok) {
#ifdef HAVE_LINUX_ZFTAPE_H
if (isa_zftape) {
- errstr = tapefd_wrlabel(fd, "X", label, tt_blocksize_kb * 1024);
+ errstr = tapefd_wrlabel(fd, "X", label,
+ (tt_blocksize_kb * 1024));
if(errstr != NULL) {
putchar('\n');
error(errstr);
+ /*NOTREACHED*/
}
}
else
#endif /* HAVE_LINUX_ZFTAPE_H */
- errstr = tape_wrlabel(tapename, "X", label, tt_blocksize_kb * 1024);
+ errstr = tape_wrlabel(tapename, "X", label,
+ (tt_blocksize_kb * 1024));
if(errstr != NULL) {
putchar('\n');
error(errstr);
+ /*NOTREACHED*/
}
#ifdef HAVE_LINUX_ZFTAPE_H
if (isa_zftape) {
- tapefd_weof(fd, 1);
+ tapefd_weof(fd, (off_t)1);
}
#endif /* HAVE_LINUX_ZFTAPE_H */
#ifdef HAVE_LINUX_ZFTAPE_H
if (isa_zftape) {
- errstr = tapefd_wrendmark(fd, "X", tt_blocksize_kb * 1024);
+ errstr = tapefd_wrendmark(fd, "X",
+ (tt_blocksize_kb * 1024));
if(errstr != NULL) {
putchar('\n');
error(errstr);
+ /*NOTREACHED*/
}
}
else
#endif /* HAVE_LINUX_ZFTAPE_H */
- errstr = tape_wrendmark(tapename, "X", tt_blocksize_kb * 1024);
+ errstr = tape_wrendmark(tapename, "X",
+ (tt_blocksize_kb * 1024));
if(errstr != NULL) {
putchar('\n');
error(errstr);
+ /*NOTREACHED*/
}
#ifdef HAVE_LINUX_ZFTAPE_H
if (isa_zftape) {
- tapefd_weof(fd, 1);
+ tapefd_weof(fd, (off_t)1);
printf(",\nrewinding"); fflush(stdout);
if(tapefd_rewind(fd) == -1) {
putchar('\n');
error(strerror(errno));
+ /*NOTREACHED*/
}
close(fd);
#ifdef HAVE_LIBVTBLC
}
putchar('\n');
error(errstr);
+ /*NOTREACHED*/
}
/* read volume table */
if ((num_volumes = read_vtbl(fd, volumes, vtbl_buffer,
"reading volume table: ", strerror(errno));
putchar('\n');
error(errstr);
+ /*NOTREACHED*/
}
/* set date and volume label for first entry */
vtbl_no = 0;
"setting date for entry 1: ", strerror(errno));
putchar('\n');
error(errstr);
+ /*NOTREACHED*/
}
if(set_label(label, volumes, num_volumes, vtbl_no)){
errstr = newstralloc2(errstr,
"setting label for entry 1: ", strerror(errno));
putchar('\n');
error(errstr);
+ /*NOTREACHED*/
}
/* set date and volume label for last entry */
vtbl_no = 1;
"setting date for entry 2: ", strerror(errno));
putchar('\n');
error(errstr);
+ /*NOTREACHED*/
}
if(set_label("AMANDA Tape End", volumes, num_volumes, vtbl_no)){
errstr = newstralloc2(errstr,
"setting label for entry 2: ", strerror(errno));
putchar('\n');
error(errstr);
+ /*NOTREACHED*/
}
/* write volume table back */
if (write_vtbl(fd, volumes, vtbl_buffer, num_volumes, first_seg,
"writing volume table: ", strerror(errno));
putchar('\n');
error(errstr);
+ /*NOTREACHED*/
}
close(fd);
#endif /* HAVE_LIBVTBLC */
if((errstr = tape_rdlabel(tapename, &olddatestamp, &oldlabel)) != NULL) {
putchar('\n');
- if (strcmp(errstr, "not an amanda tape") != 0)
+ if (strcmp(errstr, "not an amanda tape") != 0) {
error(errstr);
+ /*NOTREACHED*/
+ }
error("no label found, are you sure %s is non-rewinding?",
tapename);
+ /*NOTREACHED*/
}
if (strcmp("X", olddatestamp) != 0 ||
putchar('\n');
error("read label %s back, timestamp %s (expected X), what now?",
oldlabel, olddatestamp);
+ /*NOTREACHED*/
}
amfree(oldlabel);
amfree(olddatestamp);
conf_tapelist_old = stralloc2(conf_tapelist, ".amlabel");
if(write_tapelist(conf_tapelist_old)) {
error("couldn't write tapelist: %s", strerror(errno));
+ /*NOTREACHED*/
}
amfree(conf_tapelist_old);
/* XXX add cur_tape number to tape list structure */
remove_tapelabel(label);
- add_tapelabel(0, label);
+ add_tapelabel("0", label);
if(write_tapelist(conf_tapelist)) {
error("couldn't write tapelist: %s", strerror(errno));
+ /*NOTREACHED*/
}
} /* write tape list */
-
- if(have_changer) {
- /* Now we try to inform the changer, about the new label */
- /* changer_label(outslot,label); */
- }
printf(", done.\n");
} else {
printf("\ntape not labeled\n");
}
+ clear_tapelist();
+ free_new_argv(new_argc, new_argv);
+ free_server_config();
amfree(outslot);
amfree(tapename);
amfree(conffile);
amfree(conf_tapelist);
amfree(config_dir);
config_name=NULL;
+ dbclose();
malloc_size_2 = malloc_inuse(&malloc_hist_2);
* University of Maryland at College Park
*/
/*
- * $Id: amlogroll.c,v 1.7 2005/09/20 21:32:26 jrjackson Exp $
+ * $Id: amlogroll.c,v 1.14 2006/07/25 18:27:57 martinea Exp $
*
* rename a live log file to the datestamped name.
*/
char *datestamp;
-void handle_start P((void));
+void handle_start(void);
+int main(int argc, char **argv);
-int main(argc, argv)
-int argc;
-char **argv;
+int main(int argc, char **argv)
{
char *conffile;
char *logfname;
unsigned long malloc_hist_1, malloc_size_1;
unsigned long malloc_hist_2, malloc_size_2;
char my_cwd[STR_SIZE];
+ int new_argc, my_argc;
+ char **new_argv, **my_argv;
safe_fd(-1, 0);
set_pname("amlogroll");
+ dbopen(DBG_SUBDIR_SERVER);
+
malloc_size_1 = malloc_inuse(&malloc_hist_1);
/* Process options */
erroutput_type = ERR_INTERACTIVE;
- if (getcwd(my_cwd, sizeof(my_cwd)) == NULL) {
+ if (getcwd(my_cwd, SIZEOF(my_cwd)) == NULL) {
error("cannot determine current working directory");
+ /*NOTREACHED*/
}
- if (argc < 2) {
+ parse_server_conf(argc, argv, &new_argc, &new_argv);
+ my_argc = new_argc;
+ my_argv = new_argv;
+
+ if (my_argc < 2) {
config_dir = stralloc2(my_cwd, "/");
if ((config_name = strrchr(my_cwd, '/')) != NULL) {
config_name = stralloc(config_name + 1);
}
} else {
- config_name = stralloc(argv[1]);
+ config_name = stralloc(my_argv[1]);
config_dir = vstralloc(CONFIG_DIR, "/", config_name, "/", NULL);
}
conffile = stralloc2(config_dir, CONFFILE_NAME);
if(read_conffile(conffile)) {
error("errors processing config file \"%s\"", conffile);
+ /*NOTREACHED*/
}
amfree(conffile);
+ dbrename(config_name, DBG_SUBDIR_SERVER);
+
+ report_bad_conf_arg();
+
conf_logdir = getconf_str(CNF_LOGDIR);
if (*conf_logdir == '/') {
conf_logdir = stralloc(conf_logdir);
if((logfile = fopen(logfname, "r")) == NULL) {
error("could not open log %s: %s", logfname, strerror(errno));
+ /*NOTREACHED*/
}
amfree(logfname);
amfree(datestamp);
amfree(config_dir);
amfree(config_name);
+ free_new_argv(new_argc, new_argv);
+ free_server_config();
malloc_size_2 = malloc_inuse(&malloc_hist_2);
malloc_list(fileno(stderr), malloc_hist_1, malloc_hist_2);
}
+ dbclose();
+
return 0;
}
-void handle_start()
+void handle_start(void)
{
static int started = 0;
char *s, *fp;
skip_whitespace(s, ch);
#define sc "date"
- if(ch == '\0' || strncmp(s - 1, sc, sizeof(sc)-1) != 0) {
+ if(ch == '\0' || strncmp(s - 1, sc, SIZEOF(sc)-1) != 0) {
return; /* ignore bogus line */
}
- s += sizeof(sc)-1;
+ s += SIZEOF(sc) - 1;
ch = s[-1];
#undef sc
skip_whitespace(s, ch);
skip_non_whitespace(s, ch);
s[-1] = '\0';
datestamp = newstralloc(datestamp, fp);
- s[-1] = ch;
+ s[-1] = (char)ch;
started = 1;
}
use FileHandle;
use Getopt::Long;
+use Text::ParseWords;
use Carp;
use POSIX;
die "$0: error in opening `$amadmin $opt_config find' pipe: $!\n";
<$fh>;
while (<$fh>) {
+print "'$_'\n";
chomp;
next if /found Amanda directory/;
next if /skipping cruft directory/;
next if /skip-incr/;
- ($date, $host, $disk, $level, $tape, $file, $part, $status) = split ' ', $_;
+ ($date, $host, $disk, $level, $tape, $file, $part, $status) = quotewords(" ", 0, $_);
next if $date eq 'date';
next if $date eq 'Warning:';
next if $date eq 'Scanning';
-#!/bin/sh
+#!@SHELL@
#
# amrmtape.sh
# Time-stamp: <96/10/23 12:07:21 adrian>
push @datestamp, $gdatestamp;
}
}
+ elsif(/planner: timestamp (\S+)/) {
+ $gdatestamp = $1;
+ if(!defined $datestamp{$gdatestamp}) {
+ $datestamp{$gdatestamp} = 1;
+ push @datestamp, $gdatestamp;
+ }
+ }
elsif(/setup_estimate: ([_\-\d\.A-Za-z]*):(\S+): command .*, options: *(\S+) *last_level -?\d+ next_level0 -?\d+ level_days \d+ *getting estimates (-?\d) \(-2\) (-?\d) \(-2\) (-?\d) \(-2\)/) {
$host=$1;
$partition=$2;
}
$running_dumper{$2} = $hostpart;
$error{$hostpart}="";
+ $size{$hostpart} = 0;
$dumpers_active++;
if(! defined($dumpers_active[$dumpers_active])) {
$dumpers_active[$dumpers_active]=0;
}
$running_dumper{$2} = $hostpart;
$error{$hostpart}="";
+ $size{$hostpart} = 0;
$dumpers_active++;
if(! defined($dumpers_active[$dumpers_active])) {
$dumpers_active[$dumpers_active]=0;
}
$running_dumper{$2} = $hostpart;
$error{$hostpart}="";
+ $size{$hostpart} = 0;
$dumpers_active++;
if(! defined($dumpers_active[$dumpers_active])) {
$dumpers_active[$dumpers_active]=0;
$error{$hostpart}="driver: (aborted:$error)";
$dumpers_active--;
}
- elsif(/driver: result time (\S+) from (dumper\d+): (DONE|PARTIAL) (\d+-\d+) (\d+) (\d+) (\d+) \[.*\]/) {
+ elsif(/driver: result time (\S+) from (dumper\d+): (DONE|PARTIAL) (\d+-\d+) (\d+) (\d+) (\d+) "?\[.*\]"?/) {
$current_time=$1;
$serial=$4;
$origsize=$5 / $unitdivisor;
$dump_time{$hostpart}=$1;
$error{$hostpart}="";
$dumpers_active--;
- $partial{$hostpart}=1 if $3 eq "PARTIAL" ;
+ if ($3 eq "PARTIAL") {
+ $partial{$hostpart} = 1;
+ }
+ else {
+ $partial{$hostpart} = 0;
+ }
}
- elsif(/driver: result time (\S+) from (chunker\d+): (DONE|PARTIAL) (\d+-\d+) (\d+) \[.*\]/) {
+ elsif(/driver: result time (\S+) from (chunker\d+): (DONE|PARTIAL) (\d+-\d+) (\d+) "?\[.*\]"?/) {
$current_time=$1;
$serial=$4;
$outputsize=$5 / $unitdivisor;
$running_dumper{$2} = "0";
$dump_time{$hostpart}=$1;
$error{$hostpart}="";
- $partial{$hostpart}=1 if $3 eq "PARTIAL" ;
+ if ($3 eq "PARTIAL") {
+ $partial{$hostpart} = 1;
+ }
+ else {
+ $partial{$hostpart} = 0;
+ }
}
elsif(/driver: result time (\S+) from (dumper\d+): ABORT-FINISHED (\d+-\d+)/) {
$current_time=$1;
if(!defined $level{$hostpart}) {
$level{$hostpart} = $level;
}
- $serial{$serial}=$hostpart;
$taper_started{$hostpart}=1;
$taper_finished{$hostpart}=0;
$taper_time{$hostpart}=$1;
if(!defined $level{$hostpart}) {
$level{$hostpart} = $level;
}
- $serial{$serial}=$hostpart;
$taper_started{$hostpart}=1;
$taper_finished{$hostpart}=0;
$taper_time{$hostpart}=$1;
$taper_finished{$hostpart}=0;
$taper_time{$hostpart}=$1;
}
- elsif(/driver: result time (\S+) from taper: (DONE|PARTIAL) (\d+-\d+) (\S+) (\d+) \[sec (\S+) kb (\d+) kps/) {
+ elsif(/driver: result time (\S+) from taper: (DONE|PARTIAL) (\d+-\d+) (\S+) (\d+) "?\[sec (\S+) kb (\d+) kps/) {
$current_time=$1;
$serial=$3;
$label=$4;
else {
$ntesize{$nb_tape} += $size{$hostpart};
}
- $partial{$hostpart}=1 if $3 eq "PARTIAL" ;
+ if ($3 eq "PARTIAL") {
+ $partial{$hostpart} = 1;
+ }
+ else {
+ $partial{$hostpart} = 0;
+ }
}
elsif(/driver: result time (\S+) from taper: (TRY-AGAIN|TAPE-ERROR) (\d+-\d+) (.+)/) {
$current_time=$1;
$hostpart=&make_hostpart($host,$partition,$datestamp);
next if(!defined $estimate{$hostpart} && !defined $flush{$hostpart});
$nb_partition++;
- if( !defined $size{$hostpart} && defined $holding_file{$hostpart}) {
+ if( (!defined $size{$hostpart} || $size{$hostpart} == 0) &&
+ defined $holding_file{$hostpart}) {
$size{$hostpart} = &dump_size($holding_file{$hostpart}) / (1024 * $unitdivisor);
}
$in_flush=0;
if( defined $starttime ) {
print " (", &showtime($taper_time{$hostpart}), ")";
}
- print ", PARTIAL" if defined $partial{$hostpart};
+ print ", PARTIAL" if defined $partial{$hostpart} &&
+ $partial{$hostpart} == 1;
print "\n";
}
$tpartition++;
print " (", &showtime($dump_time{$hostpart}), ")";
}
print ", wait for writing to tape";
- print ", PARTIAL" if defined $partial{$hostpart};
+ print ", PARTIAL" if defined $partial{$hostpart} &&
+ $partial{$hostpart} == 1;;
print "\n";
}
$dpartition++;
printf "%-${maxnamelength}s%2d", "$host:$partition", $level{$hostpart};
printf "%9d$unit", $size{$hostpart};
print " waiting to flush";
- print ", PARTIAL" if defined $partial{$hostpart};
+ print ", PARTIAL" if defined $partial{$hostpart} &&
+ $partial{$hostpart} == 1;
print "\n";
}
$wfpartition++;
* file named AUTHORS, in the root directory of this distribution.
*/
/*
- * $Id: amtape.c,v 1.40.2.1 2006/04/14 11:32:07 martinea Exp $
+ * $Id: amtape.c,v 1.47 2006/07/25 18:27:57 martinea Exp $
*
* tape changer interface program
*/
#include "version.h"
/* local functions */
-void usage P((void));
-int main P((int argc, char **argv));
-void reset_changer P((int argc, char **argv));
-void eject_tape P((int argc, char **argv));
-void clean_tape P((int argc, char **argv));
-void load_slot P((int argc, char **argv));
-void load_label P((int argc, char **argv));
-void show_slots P((int argc, char **argv));
-void show_current P((int argc, char **argv));
-void update_labeldb P((int argc, char **argv));
-void amtape_taper_scan P((int argc, char **argv));
-void show_device P((int argc, char **argv));
-int update_one_slot P((void *ud, int rc, char *slotstr, char *device));
-int loadlabel_slot P((void *ud, int rc, char *slotstr, char *device));
-int show_init P((void *ud, int rc, int ns, int bk, int s));
-int show_init_all P((void *ud, int rc, int ns, int bk, int s));
-int show_init_current P((void *ud, int rc, int ns, int bk, int s));
-int show_slot P((void *ud, int rc, char *slotstr, char *device));
+void usage(void);
+int main(int argc, char **argv);
+void reset_changer(int argc, char **argv);
+void eject_tape(int argc, char **argv);
+void clean_tape(int argc, char **argv);
+void load_slot(int argc, char **argv);
+void load_label(int argc, char **argv);
+void show_slots(int argc, char **argv);
+void show_current(int argc, char **argv);
+void update_labeldb (int argc, char **argv);
+void amtape_taper_scan(int argc, char **argv);
+void show_device(int argc, char **argv);
+int update_one_slot (void *ud, int rc, char *slotstr, char *device);
+int loadlabel_slot(void *ud, int rc, char *slotstr, char *device);
+int show_init(void *ud, int rc, int ns, int bk, int s);
+int show_init_all(void *ud, int rc, int ns, int bk, int s);
+int show_init_current(void *ud, int rc, int ns, int bk, int s);
+int show_slot(void *ud, int rc, char *slotstr, char *device);
static const struct {
const char *name;
- void (*fn) P((int, char **));
+ void (*fn)(int, char **);
const char *usage;
} cmdtab[] = {
{ "reset", reset_changer,
{ "update", update_labeldb,
"update update the label matchingdatabase"},
};
-#define NCMDS (sizeof(cmdtab) / sizeof(cmdtab[0]))
+#define NCMDS (int)(sizeof(cmdtab) / sizeof(cmdtab[0]))
-void usage()
+void
+usage(void)
{
int i;
exit(1);
}
-int main(argc, argv)
-int argc;
-char **argv;
+int
+main(
+ int argc,
+ char ** argv)
{
char *conffile;
char *conf_tapelist;
/* Don't die when child closes pipe */
signal(SIGPIPE, SIG_IGN);
+ dbopen(DBG_SUBDIR_SERVER);
+
malloc_size_1 = malloc_inuse(&malloc_hist_1);
erroutput_type = ERR_INTERACTIVE;
conffile = stralloc2(config_dir, CONFFILE_NAME);
if (read_conffile(conffile)) {
error("errors processing config file \"%s\"", conffile);
+ /*NOTREACHED*/
}
+ dbrename(config_name, DBG_SUBDIR_SERVER);
+
conf_tapelist = getconf_str(CNF_TAPELIST);
if (*conf_tapelist == '/') {
conf_tapelist = stralloc(conf_tapelist);
}
if (read_tapelist(conf_tapelist)) {
error("could not load tapelist \"%s\"", conf_tapelist);
+ /*NOTREACHED*/
}
amfree(conf_tapelist);
if ((pw = getpwnam(dumpuser)) == NULL) {
error("cannot look up dump user \"%s\"", dumpuser);
- /* NOTREACHED */
+ /*NOTREACHED*/
}
uid_dumpuser = pw->pw_uid;
if ((pw = getpwuid(uid_me)) == NULL) {
error("cannot look up my own uid %ld", (long)uid_me);
- /* NOTREACHED */
+ /*NOTREACHED*/
}
if (uid_me != uid_dumpuser) {
error("running as user \"%s\" instead of \"%s\"",
pw->pw_name, dumpuser);
- /* NOTREACHED */
+ /*NOTREACHED*/
}
if((have_changer = changer_init()) == 0) {
error("no tpchanger specified in \"%s\"", conffile);
+ /*NOTREACHED*/
} else if (have_changer != 1) {
error("changer initialization failed: %s", strerror(errno));
+ /*NOTREACHED*/
}
/* switch on command name */
malloc_list(fileno(stderr), malloc_hist_1, malloc_hist_2);
}
+ dbclose();
return 0;
}
/* ---------------------------- */
-void reset_changer(argc, argv)
-int argc;
-char **argv;
+void
+reset_changer(
+ int argc,
+ char ** argv)
{
char *slotstr = NULL;
+ (void)argc; /* Quiet unused parameter warning */
+ (void)argv; /* Quiet unused parameter warning */
+
switch(changer_reset(&slotstr)) {
case 0:
fprintf(stderr, "%s: changer is reset, slot %s is loaded.\n",
break;
default:
error("could not reset changer: %s", changer_resultstr);
+ /*NOTREACHED*/
}
amfree(slotstr);
}
/* ---------------------------- */
-void clean_tape(argc, argv)
-int argc;
-char **argv;
+void
+clean_tape(
+ int argc,
+ char ** argv)
{
char *devstr = NULL;
+ (void)argc; /* Quiet unused parameter warning */
+ (void)argv; /* Quiet unused parameter warning */
+
if(changer_clean(&devstr) == 0) {
fprintf(stderr, "%s: device %s is clean.\n", get_pname(), devstr);
} else {
/* ---------------------------- */
-void eject_tape(argc, argv)
-int argc;
-char **argv;
+void
+eject_tape(
+ int argc,
+ char ** argv)
{
char *slotstr = NULL;
+ (void)argc; /* Quiet unused parameter warning */
+ (void)argv; /* Quiet unused parameter warning */
+
if(changer_eject(&slotstr) == 0) {
fprintf(stderr, "%s: slot %s is ejected.\n", get_pname(), slotstr);
} else {
/* ---------------------------- */
-void load_slot(argc, argv)
-int argc;
-char **argv;
+void
+load_slot(
+ int argc,
+ char ** argv)
{
char *slotstr = NULL, *devicename = NULL;
char *errstr;
is_advance = (strcmp(argv[1], "advance") == 0);
if(changer_loadslot(argv[1], &slotstr, &devicename)) {
error("could not load slot %s: %s", slotstr, changer_resultstr);
+ /*NOTREACHED*/
}
if(! is_advance && (errstr = tape_rewind(devicename)) != NULL) {
fprintf(stderr,
char *label = NULL, *first_match_label = NULL, *first_match = NULL;
char *searchlabel, *labelstr;
tape_t *tp;
+static int scan_init(void *ud, int rc, int ns, int bk, int s);
static int
-scan_init(ud, rc, ns, bk, s)
- void *ud;
- int rc, ns, bk, s;
+scan_init(
+ void * ud,
+ int rc,
+ int ns,
+ int bk,
+ int s)
{
- if(rc)
+ (void)ud; /* Quiet unused parameter warning */
+ (void)s; /* Quiet unused parameter warning */
+
+ if(rc) {
error("could not get changer info: %s", changer_resultstr);
+ /*NOTREACHED*/
+ }
nslots = ns;
backwards = bk;
return 0;
}
-int loadlabel_slot(ud, rc, slotstr, device)
- void *ud;
-int rc;
-char *slotstr;
-char *device;
+int
+loadlabel_slot(
+ void * ud,
+ int rc,
+ char * slotstr,
+ char * device)
{
char *errstr;
- if(rc > 1)
+ (void)ud; /* Quiet unused parameter warning */
+
+ if(rc > 1) {
error("could not load slot %s: %s", slotstr, changer_resultstr);
+ /*NOTREACHED*/
+ }
else if(rc == 1)
fprintf(stderr, "%s: slot %s: %s\n",
get_pname(), slotstr, changer_resultstr);
return 0;
}
-void load_label(argc, argv)
-int argc;
-char **argv;
+void
+load_label(
+ int argc,
+ char ** argv)
{
if(argc != 2)
usage();
/* ---------------------------- */
-int show_init(ud, rc, ns, bk, s)
- void *ud;
-int rc, ns, bk, s;
+int
+show_init(
+ void * ud,
+ int rc,
+ int ns,
+ int bk,
+ int s)
{
- if(rc)
+ (void)ud; /* Quiet unused parameter warning */
+ (void)s; /* Quiet unused parameter warning */
+
+ if(rc) {
error("could not get changer info: %s", changer_resultstr);
+ /*NOTREACHED*/
+ }
nslots = ns;
backwards = bk;
return 0;
}
-int show_init_all(ud, rc, ns, bk, s)
- void *ud;
-int rc, ns, bk, s;
+int
+show_init_all(
+ void * ud,
+ int rc,
+ int ns,
+ int bk,
+ int s)
{
int ret = show_init(NULL, rc, ns, bk, s);
+
+ (void)ud; /* Quiet unused parameter warning */
+
fprintf(stderr, "%s: scanning all %d slots in tape-changer rack:\n",
get_pname(), nslots);
return ret;
}
-int show_init_current(ud, rc, ns, bk, s)
- void *ud;
-int rc, ns, bk, s;
+int
+show_init_current(
+ void * ud,
+ int rc,
+ int ns,
+ int bk,
+ int s)
{
int ret = show_init(NULL, rc, ns, bk, s);
+
+ (void)ud; /* Quiet unused parameter warning */
+
fprintf(stderr, "%s: scanning current slot in tape-changer rack:\n",
get_pname());
return ret;
}
-int show_slot(ud, rc, slotstr, device)
- void *ud;
-int rc;
-char *slotstr, *device;
+int
+show_slot(
+ void * ud,
+ int rc,
+ char * slotstr,
+ char * device)
{
char *errstr;
- if(rc > 1)
+ (void)ud; /* Quiet unused parameter warning */
+
+ if(rc > 1) {
error("could not load slot %s: %s", slotstr, changer_resultstr);
- else if(rc == 1)
+ /*NOTREACHED*/
+ }
+ else if(rc == 1) {
fprintf(stderr, "slot %s: %s\n", slotstr, changer_resultstr);
- else if((errstr = tape_rdlabel(device, &datestamp, &label)) != NULL)
+ }
+ else if((errstr = tape_rdlabel(device, &datestamp, &label)) != NULL) {
fprintf(stderr, "slot %s: %s\n", slotstr, errstr);
- else {
+ amfree(errstr);
+ } else {
fprintf(stderr, "slot %s: date %-8s label %s\n",
slotstr, datestamp, label);
}
return 0;
}
-void show_current(argc, argv)
-int argc;
-char **argv;
+void
+show_current(
+ int argc,
+ char ** argv)
{
+ (void)argv; /* Quiet unused parameter warning */
+
if(argc != 1)
usage();
changer_current(NULL, show_init_current, show_slot);
}
-void show_slots(argc, argv)
-int argc;
-char **argv;
+void
+show_slots(
+ int argc,
+ char ** argv)
{
+ (void)argv; /* Quiet unused parameter warning */
+
if(argc != 1)
usage();
/* ---------------------------- */
-void amtape_taper_scan(argc, argv)
-int argc;
-char **argv;
+
+void
+amtape_taper_scan(
+ int argc,
+ char ** argv)
{
char *device = NULL;
- char *label = NULL, *errmsg = NULL;
+ char *label = NULL;
+
+ (void)argc; /* Quiet unused parameter warning */
+ (void)argv; /* Quiet unused parameter warning */
if((tp = lookup_last_reusable_tape(0)) == NULL)
searchlabel = NULL;
if(searchlabel) fprintf(stderr, "tape label %s or ", searchlabel);
fprintf(stderr, "a new tape.\n");
- if (taper_scan(searchlabel, &label, &datestamp, &errmsg, &device) <= 0) {
- fprintf(stderr, "%s\n", errmsg);
- }
+ taper_scan(searchlabel, &label, &datestamp,&device, FILE_taperscan_output_callback, stderr);
fprintf(stderr, "%s: label %s is now loaded.\n",
get_pname(), label);
amfree(label);
amfree(datestamp);
- amfree(errmsg);
amfree(device);
}
/* ---------------------------- */
-void show_device(argc, argv)
-int argc;
-char **argv;
+void
+show_device(
+ int argc,
+ char ** argv)
{
char *slot = NULL, *device = NULL;
- if(changer_loadslot("current", &slot, &device))
+ (void)argc; /* Quiet unused parameter warning */
+ (void)argv; /* Quiet unused parameter warning */
+
+ if(changer_loadslot("current", &slot, &device)) {
error("Could not load current slot.\n");
+ /*NOTREACHED*/
+ }
printf("%s\n", device);
amfree(slot);
/* ---------------------------- */
-int update_one_slot(ud, rc, slotstr, device)
- void *ud;
- int rc;
- char *slotstr;
- char *device;
+int
+update_one_slot(
+ void * ud,
+ int rc,
+ char * slotstr,
+ char * device)
{
char *errstr = NULL;
char *datestamp = NULL;
char *label = NULL;
+ (void)ud; /* Quiet unused parameter warning */
+
if(rc > 1)
error("could not load slot %s: %s", slotstr, changer_resultstr);
else if(rc == 1)
return 0;
}
-void update_labeldb(argc, argv)
-int argc;
-char **argv;
+void
+update_labeldb(
+ int argc,
+ char ** argv)
{
+ (void)argv; /* Quiet unused parameter warning */
+
if(argc != 1)
usage();
changer_find(NULL, show_init_all, update_one_slot, NULL);
}
-
* file named AUTHORS, in the root directory of this distribution.
*/
/*
- * $Id: amtrmidx.c,v 1.34 2006/01/14 04:37:19 paddy_s Exp $
+ * $Id: amtrmidx.c,v 1.42 2006/07/25 18:27:57 martinea Exp $
*
* trims number of index files to only those still in system. Well
* actually, it keeps a few extra, plus goes back to the last level 0
#include "tapefile.h"
#include "find.h"
#include "version.h"
+#include "util.h"
-static int sort_by_name_reversed(a, b)
- const void *a;
- const void *b;
+static int sort_by_name_reversed(const void *a, const void *b);
+
+int main(int argc, char **argv);
+
+static int sort_by_name_reversed(
+ const void *a,
+ const void *b)
{
char **ap = (char **) a;
char **bp = (char **) b;
return -1 * strcmp(*ap, *bp);
}
-int main P((int, char **));
-int main(argc, argv)
-int argc;
-char **argv;
+int main(int argc, char **argv)
{
disk_t *diskp;
disklist_t diskl;
- int i;
+ size_t i;
char *conffile;
char *conf_diskfile;
char *conf_tapelist;
find_result_t *output_find;
time_t tmp_time;
int amtrmidx_debug = 0;
+ int new_argc, my_argc;
+ char **new_argv, **my_argv;
safe_fd(-1, 0);
safe_cd();
/* Don't die when child closes pipe */
signal(SIGPIPE, SIG_IGN);
- dbopen();
+ dbopen(DBG_SUBDIR_SERVER);
dbprintf(("%s: version %s\n", argv[0], version()));
- if (argc > 1 && strcmp(argv[1], "-t") == 0) {
+ parse_server_conf(argc, argv, &new_argc, &new_argv);
+ my_argc = new_argc;
+ my_argv = new_argv;
+
+ if (my_argc > 1 && strcmp(my_argv[1], "-t") == 0) {
amtrmidx_debug = 1;
- argc--;
- argv++;
+ my_argc--;
+ my_argv++;
}
- if (argc < 2) {
- fprintf(stderr, "Usage: %s [-t] <config>\n", argv[0]);
+ if (my_argc < 2) {
+ fprintf(stderr, "Usage: %s [-t] <config> [-o configoption]*\n", my_argv[0]);
return 1;
}
- config_name = argv[1];
+ config_name = my_argv[1];
config_dir = vstralloc(CONFIG_DIR, "/", config_name, "/", NULL);
conffile = stralloc2(config_dir, CONFFILE_NAME);
- if (read_conffile(conffile))
+ if (read_conffile(conffile)) {
error("errors processing config file \"%s\"", conffile);
+ /*NOTREACHED*/
+ }
amfree(conffile);
+ dbrename(config_name, DBG_SUBDIR_SERVER);
+
+ report_bad_conf_arg();
+
conf_diskfile = getconf_str(CNF_DISKFILE);
if(*conf_diskfile == '/') {
conf_diskfile = stralloc(conf_diskfile);
} else {
conf_diskfile = stralloc2(config_dir, conf_diskfile);
}
- if (read_diskfile(conf_diskfile, &diskl) < 0)
+ if (read_diskfile(conf_diskfile, &diskl) < 0) {
error("could not load disklist \"%s\"", conf_diskfile);
+ /*NOTREACHED*/
+ }
amfree(conf_diskfile);
conf_tapelist = getconf_str(CNF_TAPELIST);
} else {
conf_tapelist = stralloc2(config_dir, conf_tapelist);
}
- if(read_tapelist(conf_tapelist))
+ if(read_tapelist(conf_tapelist)) {
error("could not load tapelist \"%s\"", conf_tapelist);
+ /*NOTREACHED*/
+ }
amfree(conf_tapelist);
output_find = find_dump(1, &diskl);
{
if (diskp->index)
{
- char *indexdir;
+ char *indexdir, *qindexdir;
DIR *d;
struct dirent *f;
char **names;
- int name_length;
- int name_count;
+ size_t name_length;
+ size_t name_count;
char *host;
- char *disk;
+ char *disk, *qdisk;
+ size_t len_date;
- dbprintf(("%s %s\n", diskp->host->hostname, diskp->name));
/* get listing of indices, newest first */
host = sanitise_filename(diskp->host->hostname);
disk = sanitise_filename(diskp->name);
+ qdisk = quote_string(diskp->name);
indexdir = vstralloc(conf_indexdir, "/",
host, "/",
disk, "/",
NULL);
+ qindexdir = quote_string(indexdir);
+
+ dbprintf(("%s %s -> %s\n", diskp->host->hostname,
+ qdisk, qindexdir));
amfree(host);
+ amfree(qdisk);
amfree(disk);
if ((d = opendir(indexdir)) == NULL) {
- dbprintf(("could not open index directory \"%s\"\n", indexdir));
+ dbprintf(("could not open index directory %s\n", qindexdir));
amfree(indexdir);
+ amfree(qindexdir);
continue;
}
name_length = 100;
- names = (char **)alloc(name_length * sizeof(char *));
+ names = (char **)alloc(name_length * SIZEOF(char *));
name_count = 0;
while ((f = readdir(d)) != NULL) {
- int l;
+ size_t l;
if(is_dot_or_dotdot(f->d_name)) {
continue;
}
- for(i = 0; i < sizeof("YYYYMMDD")-1; i++) {
+ for(i = 0; i < SIZEOF("YYYYMMDDHHMMSS")-1; i++) {
if(! isdigit((int)(f->d_name[i]))) {
break;
}
}
- if(i < sizeof("YYYYMMDD")-1
- || f->d_name[i] != '_'
- || ! isdigit((int)(f->d_name[i+1]))) {
+ len_date = i;
+ /* len_date=8 for YYYYMMDD */
+ /* len_date=14 for YYYYMMDDHHMMSS */
+ if((len_date != 8 && len_date != 14)
+ || f->d_name[len_date] != '_'
+ || ! isdigit((int)(f->d_name[len_date+1]))) {
continue; /* not an index file */
}
/*
* Clear out old index temp files.
*/
- l = strlen(f->d_name) - (sizeof(".tmp")-1);
- if(l > sizeof("YYYYMMDD_L")-1
- && strcmp (f->d_name + l, ".tmp") == 0) {
+ l = strlen(f->d_name) - (SIZEOF(".tmp")-1);
+ if ((l > (len_date + 1))
+ && (strcmp(f->d_name + l, ".tmp")==0)) {
struct stat sbuf;
- char *path;
+ char *path, *qpath;
path = stralloc2(indexdir, f->d_name);
+ qpath = quote_string(path);
if(lstat(path, &sbuf) != -1
- && (sbuf.st_mode & S_IFMT) == S_IFREG
- && sbuf.st_mtime < tmp_time) {
- dbprintf(("rm %s\n", path));
+ && ((sbuf.st_mode & S_IFMT) == S_IFREG)
+ && ((time_t)sbuf.st_mtime < tmp_time)) {
+ dbprintf(("rm %s\n", qpath));
if(amtrmidx_debug == 0 && unlink(path) == -1) {
- dbprintf(("Error removing \"%s\": %s\n",
- path, strerror(errno)));
+ dbprintf(("Error removing %s: %s\n",
+ qpath, strerror(errno)));
}
}
+ amfree(qpath);
amfree(path);
continue;
}
if(name_count >= name_length) {
char **new_names;
- new_names = alloc((name_length + 100) * sizeof(char *));
- memcpy(new_names, names, name_length * sizeof(char *));
- name_length += 100;
+ new_names = alloc((name_length * 2) * SIZEOF(char *));
+ memcpy(new_names, names, name_length * SIZEOF(char *));
amfree(names);
names = new_names;
+ name_length *= 2;
}
names[name_count++] = stralloc(f->d_name);
}
closedir(d);
- qsort(names, name_count, sizeof(char *), sort_by_name_reversed);
+ qsort(names, name_count, SIZEOF(char *), sort_by_name_reversed);
/*
* Search for the first full dump past the minimum number
* of index files to keep.
*/
for(i = 0; i < name_count; i++) {
- if(!dump_exist(output_find,
- diskp->host->hostname,diskp->name,
- atoi(names[i]),
- names[i][sizeof("YYYYMMDD_L")-1-1] - '0')) {
- char *path;
+ char *datestamp;
+ int level;
+ size_t len_date;
+
+ for(len_date = 0; len_date < SIZEOF("YYYYMMDDHHMMSS")-1; len_date++) {
+ if(! isdigit((int)(names[i][len_date]))) {
+ break;
+ }
+ }
+
+ datestamp = stralloc(names[i]);
+ datestamp[len_date] = '\0';
+ level = names[i][len_date+1] - '0';
+ if(!dump_exist(output_find, diskp->host->hostname,
+ diskp->name, datestamp, level)) {
+ char *path, *qpath;
path = stralloc2(indexdir, names[i]);
- dbprintf(("rm %s\n", path));
+ qpath = quote_string(path);
+ dbprintf(("rm %s\n", qpath));
if(amtrmidx_debug == 0 && unlink(path) == -1) {
- dbprintf(("Error removing \"%s\": %s\n",
- path, strerror(errno)));
+ dbprintf(("Error removing %s: %s\n",
+ qpath, strerror(errno)));
}
+ amfree(qpath);
amfree(path);
}
+ amfree(datestamp);
amfree(names[i]);
}
amfree(names);
amfree(indexdir);
+ amfree(qindexdir);
}
}
amfree(conf_indexdir);
amfree(config_dir);
free_find_result(&output_find);
+ clear_tapelist();
+ free_disklist(&diskl);
+ free_new_argv(new_argc, new_argv);
+ free_server_config();
dbclose();
* file named AUTHORS, in the root directory of this distribution.
*/
/*
- * $Id: amtrmlog.c,v 1.10 2006/01/14 04:37:19 paddy_s Exp $
+ * $Id: amtrmlog.c,v 1.17 2006/07/25 18:27:57 martinea Exp $
*
* trims number of index files to only those still in system. Well
* actually, it keeps a few extra, plus goes back to the last level 0
#include "find.h"
#include "version.h"
-int main P((int, char **));
+int amtrmidx_debug = 0;
-int main(argc, argv)
-int argc;
-char **argv;
+int main(int argc, char **argv);
+
+int
+main(
+ int argc,
+ char ** argv)
{
disklist_t diskl;
int no_keep; /* files per system to keep */
char *conf_diskfile;
char *conf_tapelist;
char *conf_logdir;
- int amtrmidx_debug = 0;
+ int dumpcycle;
+ int new_argc, my_argc;
+ char **new_argv, **my_argv;
safe_fd(-1, 0);
safe_cd();
/* Don't die when child closes pipe */
signal(SIGPIPE, SIG_IGN);
- if (argc > 1 && strcmp(argv[1], "-t") == 0) {
+ parse_server_conf(argc, argv, &new_argc, &new_argv);
+ my_argc = new_argc;
+ my_argv = new_argv;
+
+ if (my_argc > 1 && strcmp(my_argv[1], "-t") == 0) {
amtrmidx_debug = 1;
- argc--;
- argv++;
+ my_argc--;
+ my_argv++;
}
- if (argc < 2) {
- fprintf(stderr, "Usage: %s [-t] <config>\n", argv[0]);
+ if (my_argc < 2) {
+ fprintf(stderr, "Usage: %s [-t] <config> [-o configoption]*\n", my_argv[0]);
return 1;
}
- dbopen();
- dbprintf(("%s: version %s\n", argv[0], version()));
+ dbopen(DBG_SUBDIR_SERVER);
+ dbprintf(("%s: version %s\n", my_argv[0], version()));
- config_name = argv[1];
+ config_name = my_argv[1];
config_dir = vstralloc(CONFIG_DIR, "/", config_name, "/", NULL);
conffile = stralloc2(config_dir, CONFFILE_NAME);
- if (read_conffile(conffile))
+ if (read_conffile(conffile)) {
error("errors processing amanda config file \"%s\"", conffile);
+ /*NOTREACHED*/
+ }
amfree(conffile);
+ dbrename(config_name, DBG_SUBDIR_SERVER);
+
+ report_bad_conf_arg();
+
conf_diskfile = getconf_str(CNF_DISKFILE);
if (*conf_diskfile == '/') {
conf_diskfile = stralloc(conf_diskfile);
} else {
conf_diskfile = stralloc2(config_dir, conf_diskfile);
}
- if (read_diskfile(conf_diskfile, &diskl) < 0)
+ if (read_diskfile(conf_diskfile, &diskl) < 0) {
error("could not load disklist \"%s\"", conf_diskfile);
+ /*NOTREACHED*/
+ }
amfree(conf_diskfile);
conf_tapelist = getconf_str(CNF_TAPELIST);
} else {
conf_tapelist = stralloc2(config_dir, conf_tapelist);
}
- if (read_tapelist(conf_tapelist))
+ if (read_tapelist(conf_tapelist)) {
error("could not load tapelist \"%s\"", conf_tapelist);
+ /*NOTREACHED*/
+ }
amfree(conf_tapelist);
today = time((time_t *)NULL);
- date_keep = today - (getconf_int(CNF_DUMPCYCLE)*86400);
+ dumpcycle = getconf_int(CNF_DUMPCYCLE);
+ if(dumpcycle > 5000)
+ dumpcycle = 5000;
+ date_keep = today - (dumpcycle * 86400);
output_find_log = find_log();
conf_logdir = stralloc2(config_dir, conf_logdir);
}
olddir = vstralloc(conf_logdir, "/oldlog", NULL);
- if (mkpdir(olddir, 02700, (uid_t)-1, (gid_t)-1) != 0)
+ if (mkpdir(olddir, 02700, (uid_t)-1, (gid_t)-1) != 0) {
error("could not create parents of %s: %s", olddir, strerror(errno));
- if (mkdir(olddir, 02700) != 0 && errno != EEXIST)
+ /*NOTREACHED*/
+ }
+ if (mkdir(olddir, 02700) != 0 && errno != EEXIST) {
error("could not create %s: %s", olddir, strerror(errno));
+ /*NOTREACHED*/
+ }
if (stat(olddir,&stat_old) == -1) {
error("can't stat oldlog directory \"%s\": %s", olddir, strerror(errno));
+ /*NOTREACHED*/
}
if (!S_ISDIR(stat_old.st_mode)) {
error("Oldlog directory \"%s\" is not a directory", olddir);
+ /*NOTREACHED*/
}
- if ((dir = opendir(conf_logdir)) == NULL)
+ if ((dir = opendir(conf_logdir)) == NULL) {
error("could not open log directory \"%s\": %s", conf_logdir,strerror(errno));
+ /*NOTREACHED*/
+ }
while ((adir=readdir(dir)) != NULL) {
if(strncmp(adir->d_name,"log.",4)==0) {
useful=0;
for (name=output_find_log;*name !=NULL; name++) {
- if(strncmp(adir->d_name,*name,12)==0) {
+ if((strlen(adir->d_name) >= 13 &&
+ strlen(*name) >= 13 &&
+ adir->d_name[12] == '.' && (*name)[12] == '.' &&
+ strncmp(adir->d_name,*name,12)==0) ||
+ strncmp(adir->d_name,*name,18)==0) {
useful=1;
+ break;
}
}
logname=newvstralloc(logname,
conf_logdir, "/" ,adir->d_name, NULL);
if(stat(logname,&stat_log)==0) {
- if(stat_log.st_mtime > date_keep) {
+ if((time_t)stat_log.st_mtime > date_keep) {
useful = 1;
}
}
conf_logdir, "/", adir->d_name, NULL);
newfile = newvstralloc(newfile,
olddir, "/", adir->d_name, NULL);
- if (rename(oldfile,newfile) != 0)
+ if (rename(oldfile,newfile) != 0) {
error("could not rename \"%s\" to \"%s\": %s",
oldfile, newfile, strerror(errno));
+ /*NOTREACHED*/
+ }
}
}
}
amfree(olddir);
amfree(config_dir);
amfree(conf_logdir);
+ clear_tapelist();
+ free_disklist(&diskl);
+ free_new_argv(new_argc, new_argv);
+ free_server_config();
dbclose();
-#! /bin/sh
+#! @SHELL@
#
-# $Id: amverify.sh.in,v 1.35 2006/03/16 17:32:32 ktill Exp $
+# $Id: amverify.sh.in,v 1.38 2006/07/25 19:00:56 martinea Exp $
#
# (C) 1996 by ICEM Systems GmbH
# Author: Axel Zinser (fifi@icem.de)
}
getparm() {
- $AMGETCONF $CONFIG $1 2>/dev/null | grep -v BUGGY
+ $AMGETCONF $CONFIG $1 2>/dev/null
}
sendreport() {
-#!/bin/sh
+#!@SHELL@
#
prefix=@prefix@
fi
getparm() {
- $AMGETCONF $CONFIG $1 2>/dev/null | grep -v BUGGY
+ $AMGETCONF $CONFIG $1 2>/dev/null
}
CONFIG=$1
* file named AUTHORS, in the root directory of this distribution.
*/
/*
- * $Id: changer.c,v 1.29.2.1 2006/04/24 14:43:01 martinea Exp $
+ * $Id: changer.c,v 1.36 2006/08/24 01:57:16 paddy_s Exp $
*
* interface routines for tape changers
*/
static char *tapechanger = NULL;
/* local functions */
-static int changer_command P((char *cmd, char *arg));
+static int changer_command(char *cmd, char *arg);
+static int report_bad_resultstr(void);
+static int run_changer_command(char *cmd, char *arg, char **slotstr, char **rest);
-int changer_init()
+int
+changer_init(void)
{
tapechanger = getconf_str(CNF_TPCHANGER);
return strcmp(tapechanger, "") != 0;
}
-static int report_bad_resultstr()
+static int
+report_bad_resultstr(void)
{
char *s;
return 2;
}
-static int run_changer_command(cmd, arg, slotstr, rest)
-char *cmd;
-char *arg;
-char **slotstr;
-char **rest;
+static int
+run_changer_command(
+ char * cmd,
+ char * arg,
+ char ** slotstr,
+ char ** rest)
{
int exitcode;
char *result_copy;
int ch;
if (slotstr) {
- *slotstr = NULL;
+ *slotstr = NULL;
}
if (rest) {
- *rest = NULL;
+ *rest = NULL;
}
exitcode = changer_command(cmd, arg);
s = changer_resultstr;
skip_non_whitespace(s, ch);
s[-1] = '\0';
if (slotstr) {
- *slotstr = newstralloc(*slotstr, slot);
+ *slotstr = newstralloc(*slotstr, slot);
}
- s[-1] = ch;
+ s[-1] = (char)ch;
skip_whitespace(s, ch);
- if(rest) {
- *rest = s - 1;
+ if (rest) {
+ *rest = s - 1;
}
if(exitcode) {
return 0;
}
-int changer_reset(slotstr)
-char **slotstr;
+int
+changer_reset(
+ char ** slotstr)
{
char *rest;
return run_changer_command("-reset", (char *) NULL, slotstr, &rest);
}
-int changer_clean(slotstr)
-char **slotstr;
+int
+changer_clean(
+ char ** slotstr)
{
char *rest;
return run_changer_command("-clean", (char *) NULL, slotstr, &rest);
}
-int changer_eject(slotstr)
-char **slotstr;
+int
+changer_eject(
+ char ** slotstr)
{
char *rest;
return run_changer_command("-eject", (char *) NULL, slotstr, &rest);
}
-int changer_loadslot(inslotstr, outslotstr, devicename)
-char *inslotstr, **outslotstr, **devicename;
+int
+changer_loadslot(
+ char *inslotstr,
+ char **outslotstr,
+ char **devicename)
{
char *rest;
int rc;
return 0;
}
-/* This function is somewhat equal to changer_info with one additional
- parameter, to get information, if the changer is able to search for
- tapelabels himself. E.g. Barcodereader
- The changer_script answers with an additional parameter, if it is able
- to search. This one should be 1, if it is able to search, and 0 if it
- knows about the extension. If the additional answer is omitted, the
- changer is not able to search for a tape.
-*/
-int changer_query(nslotsp, curslotstr, backwardsp, searchable)
-int *nslotsp, *backwardsp, *searchable;
-char **curslotstr;
+
+/*
+ * This function is somewhat equal to changer_info with one additional
+ * parameter, to get information, if the changer is able to search for
+ * tapelabels himself. E.g. Barcodereader
+ * The changer_script answers with an additional parameter, if it is able
+ * to search. This one should be 1, if it is able to search, and 0 if it
+ * knows about the extension. If the additional answer is omitted, the
+ * changer is not able to search for a tape.
+ */
+
+int
+changer_query(
+ int * nslotsp,
+ char ** curslotstr,
+ int * backwardsp,
+ int * searchable)
{
char *rest;
int rc;
return 0;
}
-int changer_info(nslotsp, curslotstr, backwardsp)
-int *nslotsp, *backwardsp;
-char **curslotstr;
+int
+changer_info(
+ int * nslotsp,
+ char ** curslotstr,
+ int * backwardsp)
{
char *rest;
int rc;
/* ---------------------------- */
-/* This function first uses searchlabel and changer_search, if
- the library is able to find a tape itself. If it is not, or if
- the tape could not be found, then the normal scan is done.
-
- See interface documentation in changer.h.
-*/
-void changer_find(user_data, user_init, user_slot, searchlabel)
- void *user_data;
- int (*user_init) P((void *user_data, int rc, int nslots, int backwards,
- int searchable));
- int (*user_slot) P((void *user_data, int rc, char *slotstr,
- char *device));
- char *searchlabel;
+/*
+ * This function first uses searchlabel and changer_search, if
+ * the library is able to find a tape itself. If it is not, or if
+ * the tape could not be found, then the normal scan is done.
+ *
+ * See interface documentation in changer.h.
+ */
+
+void
+changer_find(
+ void * user_data,
+ int (*user_init)(void *, int, int, int, int),
+ int (*user_slot)(void *, int, char *, char *),
+ char * searchlabel)
{
char *slotstr, *device = NULL, *curslotstr = NULL;
int nslots, checked, backwards, rc, done, searchable;
rc = changer_query(&nslots, &curslotstr, &backwards, &searchable);
+
+ if (rc != 0) {
+ /* Problem with the changer script. Bail. */
+ fprintf(stderr, "Changer problem: %s\n", changer_resultstr);
+ return;
+ }
+
done = user_init(user_data, rc, nslots, backwards, searchable);
amfree(curslotstr);
}
if ((searchlabel!=NULL) && searchable && !done){
- rc=changer_search(searchlabel,&curslotstr,&device);
+ rc=changer_search(searchlabel, &curslotstr, &device);
if(rc == 0)
- done = user_slot(user_data, rc,curslotstr,device);
+ done = user_slot(user_data, rc, curslotstr, device);
}
slotstr = "current";
/* ---------------------------- */
-void changer_current(user_data, user_init, user_slot)
- void *user_data;
-int (*user_init) P((void *ud, int rc, int nslots, int backwards, int searchable));
-int (*user_slot) P((void *ud, int rc, char *slotstr, char *device));
+void
+changer_current(
+ void * user_data,
+ int (*user_init)(void *, int, int, int, int),
+ int (*user_slot)(void *, int, char *, char *))
{
char *device = NULL, *curslotstr = NULL;
int nslots, backwards, rc, done, searchable;
/* ---------------------------- */
-static int changer_command(cmd, arg)
- char *cmd;
- char *arg;
+static int
+changer_command(
+ char *cmd,
+ char *arg)
{
int fd[2];
- amwait_t wait_exitcode;
+ amwait_t wait_exitcode = 1;
int exitcode;
char num1[NUM_STR_SIZE];
char num2[NUM_STR_SIZE];
exitcode = 2;
goto failed;
}
- if(fd[0] < 0 || fd[0] >= FD_SETSIZE) {
- snprintf(num1, sizeof(num1), "%d", fd[0]);
- snprintf(num2, sizeof(num2), "%d", FD_SETSIZE-1);
+
+ /* make sure fd[0] != 1 */
+ if(fd[0] == 1) {
+ int a = dup(fd[0]);
+ close(fd[0]);
+ fd[0] = a;
+ }
+
+ if(fd[0] < 0 || fd[0] >= (int)FD_SETSIZE) {
+ snprintf(num1, SIZEOF(num1), "%d", fd[0]);
+ snprintf(num2, SIZEOF(num2), "%d", FD_SETSIZE-1);
changer_resultstr = vstralloc ("<error> ",
"could not create pipe for \"",
cmdstr,
exitcode = 2;
goto done;
}
- if(fd[1] < 0 || fd[1] >= FD_SETSIZE) {
- snprintf(num1, sizeof(num1), "%d", fd[1]);
- snprintf(num2, sizeof(num2), "%d", FD_SETSIZE-1);
+ if(fd[1] < 0 || fd[1] >= (int)FD_SETSIZE) {
+ snprintf(num1, SIZEOF(num1), "%d", fd[1]);
+ snprintf(num2, SIZEOF(num2), "%d", FD_SETSIZE-1);
changer_resultstr = vstralloc ("<error> ",
"could not create pipe for \"",
cmdstr,
exit(1);
}
if(arg) {
- execle(tapechanger, tapechanger, cmd, arg, NULL, safe_env());
+ execle(tapechanger, tapechanger, cmd, arg, (char *)NULL,
+ safe_env());
} else {
- execle(tapechanger, tapechanger, cmd, NULL, safe_env());
+ execle(tapechanger, tapechanger, cmd, (char *)NULL, safe_env());
}
changer_resultstr = vstralloc ("<error> ",
"could not exec \"",
goto done;
}
} else if (pid != changer_pid) {
- snprintf(num1, sizeof(num1), "%ld", (long)pid);
+ snprintf(num1, SIZEOF(num1), "%ld", (long)pid);
changer_resultstr = vstralloc ("<error> ",
"wait for \"",
tapechanger,
/* mark out-of-control changers as fatal error */
if(WIFSIGNALED(wait_exitcode)) {
- snprintf(num1, sizeof(num1), "%d", WTERMSIG(wait_exitcode));
+ snprintf(num1, SIZEOF(num1), "%d", WTERMSIG(wait_exitcode));
changer_resultstr = newvstralloc (changer_resultstr,
"<error> ",
changer_resultstr,
aclose(fd[1]);
failed:
- dbprintf(("changer: got exit: %d str: %s\n", exitcode, changer_resultstr));
+ if (exitcode != 0) {
+ dbprintf(("changer: got exit: %d str: %s\n", exitcode, changer_resultstr));
+ }
amfree(cmdstr);
return exitcode;
}
-/* This function commands the changerscript to look for a tape named
- searchlabel. If is found, the changerscript answers with the device,
- in which the tape can be accessed.
-*/
-int changer_search(searchlabel, outslotstr, devicename)
-char *searchlabel, **outslotstr, **devicename;
+
+/*
+ * This function commands the changerscript to look for a tape named
+ * searchlabel. If is found, the changerscript answers with the device,
+ * in which the tape can be accessed.
+ */
+
+int
+changer_search(
+ char * searchlabel,
+ char ** outslotstr,
+ char ** devicename)
{
char *rest;
int rc;
return 0;
}
-/* Because barcodelabel are short, and may not be the same as the
- amandalabels, the changerscript should be informed, which tapelabel
- is associated with a tape. This function should be called after
- giving a label for a tape. (Maybe also, when the label and the associated
- slot is known. e.g. during library scan.
-*/
-int changer_label (slotsp,labelstr)
-char *slotsp;
-char *labelstr;
+
+/*
+ * Because barcodelabel are short, and may not be the same as the
+ * amandalabels, the changerscript should be informed, which tapelabel
+ * is associated with a tape. This function should be called after
+ * giving a label for a tape. (Maybe also, when the label and the associated
+ * slot is known. e.g. during library scan.
+ */
+
+int
+changer_label(
+ char * slotsp,
+ char * labelstr)
{
int rc;
char *rest=NULL;
* file named AUTHORS, in the root directory of this distribution.
*/
/*
- * $Id: changer.h,v 1.12 2005/12/21 19:07:50 paddy_s Exp $
+ * $Id: changer.h,v 1.13 2006/05/25 01:47:19 johnfranks Exp $
*
* interface routines for tape changers
*/
+#ifndef CHANGER_H
+#define CHANGER_H
+
#include "amanda.h"
extern int changer_debug;
extern char *changer_resultstr;
-int changer_init P((void));
-int changer_reset P((char **slotstr));
-int changer_clean P((char **slotstr));
-int changer_eject P((char **slotstr));
-int changer_label P((char *slotsp, char *labelstr));
-int changer_info P((int *nslotsp, char **curslotstr, int *backwards));
-int changer_query P((int *nslotsp, char **curslotstr, int *backwards,
- int *searchable));
-int changer_search P((char *searchlabel, char **outslotstr, char **devicename));
-int changer_loadslot P((char *inslotstr, char **outslotstr, char **devicename));
-void changer_current P((void *user_data,
+int changer_init(void);
+int changer_reset(char **slotstr);
+int changer_clean(char **slotstr);
+int changer_eject(char **slotstr);
+int changer_label(char *slotsp, char *labelstr);
+int changer_info(int *nslotsp, char **curslotstr, int *backwards);
+int changer_query(int *nslotsp, char **curslotstr, int *backwards,
+ int *searchable);
+int changer_search(char *searchlabel, char **outslotstr, char **devicename);
+int changer_loadslot(char *inslotstr, char **outslotstr, char **devicename);
+void changer_current(void *user_data,
int (*user_init)(void *user_data,
int rc, int nslots, int backwards,
int searchable),
int (*user_slot)(void *user_data,
- int rc, char *slotstr, char *device)));
+ int rc, char *slotstr, char *device));
/* USAGE: changer_find(user_data, init_fxn, slot_fxn, searchlabel)
-void changer_find P((void *user_data,
+void changer_find(void *user_data,
int (*user_init)(void *user_data, int rc,
int nslots, int backwards,
int searchable),
int (*user_slot)(void *user_data, int rc,
char *slotstr, char *device),
- char *searchlabel));
+ char *searchlabel);
+
+#endif /* !CHANGER_H */
* Authors: the Amanda Development Team. Its members are listed in a
* file named AUTHORS, in the root directory of this distribution.
*/
-/* $Id: chunker.c,v 1.25.2.1 2006/04/23 18:52:04 martinea Exp $
+/* $Id: chunker.c,v 1.36 2006/08/24 11:23:32 martinea Exp $
*
* requests remote amandad processes to dump filesystems
*/
int fd; /* file to flush to */
char *filename; /* name of what fd points to */
int filename_seq; /* for chunking */
- long split_size; /* when to chunk */
- long chunk_size; /* size of each chunk */
- long use; /* size to use on this disk */
+ off_t split_size; /* when to chunk */
+ off_t chunk_size; /* size of each chunk */
+ off_t use; /* size to use on this disk */
char buf[DISK_BLOCK_BYTES];
char *datain; /* data buffer markers */
char *dataout;
static char *errstr = NULL;
static int abort_pending;
-static long dumpsize, headersize;
-static long dumpbytes;
-static long filesize;
+static off_t dumpsize;
+static unsigned long headersize;
+static off_t dumpbytes;
+static off_t filesize;
static char *hostname = NULL;
static char *diskname = NULL;
+static char *qdiskname = NULL;
static char *options = NULL;
static char *progname = NULL;
static int level;
static char *dumpdate = NULL;
-static char *datestamp = NULL;
static int command_in_transit;
+static char *chunker_timestamp = NULL;
static dumpfile_t file;
/* local functions */
-int main P((int, char **));
-static int write_tapeheader P((int, dumpfile_t *));
-static void databuf_init P((struct databuf *, int, char *, long, long));
-static int databuf_flush P((struct databuf *));
+int main(int, char **);
+static ssize_t write_tapeheader(int, dumpfile_t *);
+static void databuf_init(struct databuf *, int, char *, off_t, off_t);
+static int databuf_flush(struct databuf *);
-static int startup_chunker P((char *, long, long, struct databuf *));
-static int do_chunk P((int, struct databuf *));
+static int startup_chunker(char *, off_t, off_t, struct databuf *);
+static int do_chunk(int, struct databuf *);
int
-main(main_argc, main_argv)
- int main_argc;
- char **main_argv;
+main(
+ int main_argc,
+ char ** main_argv)
{
static struct databuf db;
struct cmdargs cmdargs;
unsigned long malloc_hist_2, malloc_size_2;
char *conffile;
char *q = NULL;
- char *filename;
- long chunksize, use;
+ char *filename = NULL;
+ char *qfilename = NULL;
+ off_t chunksize, use;
times_t runtime;
am_feature_t *their_features = NULL;
int a;
+ int new_argc, my_argc;
+ char **new_argv, **my_argv;
safe_fd(-1, 0);
set_pname("chunker");
+ dbopen(DBG_SUBDIR_SERVER);
+
/* Don't die when child closes pipe */
signal(SIGPIPE, SIG_IGN);
erroutput_type = (ERR_AMANDALOG|ERR_INTERACTIVE);
set_logerror(logerror);
- if (main_argc > 1) {
- config_name = stralloc(main_argv[1]);
+ parse_server_conf(main_argc, main_argv, &new_argc, &new_argv);
+ my_argc = new_argc;
+ my_argv = new_argv;
+
+ if (my_argc > 1) {
+ config_name = stralloc(my_argv[1]);
config_dir = vstralloc(CONFIG_DIR, "/", config_name, "/", NULL);
} else {
char my_cwd[STR_SIZE];
- if (getcwd(my_cwd, sizeof(my_cwd)) == NULL) {
+ if (getcwd(my_cwd, SIZEOF(my_cwd)) == NULL) {
error("cannot determine current working directory");
+ /*NOTREACHED*/
}
config_dir = stralloc2(my_cwd, "/");
if ((config_name = strrchr(my_cwd, '/')) != NULL) {
conffile = stralloc2(config_dir, CONFFILE_NAME);
if(read_conffile(conffile)) {
error("errors processing config file \"%s\"", conffile);
+ /*NOTREACHED*/
}
amfree(conffile);
+ dbrename(config_name, DBG_SUBDIR_SERVER);
+
+ report_bad_conf_arg();
+
fprintf(stderr,
"%s: pid %ld executable %s version %s\n",
get_pname(), (long) getpid(),
- main_argv[0], version());
+ my_argv[0], version());
fflush(stderr);
/* now, make sure we are a valid user */
- if (getpwuid(getuid()) == NULL)
+ if (getpwuid(getuid()) == NULL) {
error("can't get login name for my uid %ld", (long)getuid());
+ /*NOTREACHED*/
+ }
signal(SIGPIPE, SIG_IGN);
signal(SIGCHLD, SIG_IGN);
cmd = getcmd(&cmdargs);
if(cmd == START) {
if(cmdargs.argc <= 1)
- error("error [dumper START: not enough args: datestamp]");
- datestamp = newstralloc(datestamp, cmdargs.argv[2]);
+ error("error [dumper START: not enough args: timestamp]");
+ chunker_timestamp = newstralloc(chunker_timestamp, cmdargs.argv[2]);
}
else {
error("Didn't get START command");
if(a >= cmdargs.argc) {
error("error [chunker PORT-WRITE: not enough args: handle]");
+ /*NOTREACHED*/
}
handle = newstralloc(handle, cmdargs.argv[a++]);
if(a >= cmdargs.argc) {
error("error [chunker PORT-WRITE: not enough args: filename]");
+ /*NOTREACHED*/
}
- filename = cmdargs.argv[a++];
+ qfilename = newstralloc(qfilename, cmdargs.argv[a++]);
+ if (filename != NULL)
+ amfree(filename);
+ filename = unquote_string(qfilename);
+ amfree(qfilename);
if(a >= cmdargs.argc) {
error("error [chunker PORT-WRITE: not enough args: hostname]");
+ /*NOTREACHED*/
}
hostname = newstralloc(hostname, cmdargs.argv[a++]);
if(a >= cmdargs.argc) {
error("error [chunker PORT-WRITE: not enough args: features]");
+ /*NOTREACHED*/
}
am_release_feature_set(their_features);
their_features = am_string_to_feature(cmdargs.argv[a++]);
if(a >= cmdargs.argc) {
error("error [chunker PORT-WRITE: not enough args: diskname]");
+ /*NOTREACHED*/
}
- diskname = newstralloc(diskname, cmdargs.argv[a++]);
+ qdiskname = newstralloc(qdiskname, cmdargs.argv[a++]);
+ if (diskname != NULL)
+ amfree(diskname);
+ diskname = unquote_string(qdiskname);
if(a >= cmdargs.argc) {
error("error [chunker PORT-WRITE: not enough args: level]");
+ /*NOTREACHED*/
}
level = atoi(cmdargs.argv[a++]);
if(a >= cmdargs.argc) {
error("error [chunker PORT-WRITE: not enough args: dumpdate]");
+ /*NOTREACHED*/
}
dumpdate = newstralloc(dumpdate, cmdargs.argv[a++]);
if(a >= cmdargs.argc) {
error("error [chunker PORT-WRITE: not enough args: chunksize]");
+ /*NOTREACHED*/
}
- chunksize = atoi(cmdargs.argv[a++]);
- chunksize = am_floor(chunksize, DISK_BLOCK_KB);
+ chunksize = OFF_T_ATOI(cmdargs.argv[a++]);
+ chunksize = am_floor(chunksize, (off_t)DISK_BLOCK_KB);
if(a >= cmdargs.argc) {
error("error [chunker PORT-WRITE: not enough args: progname]");
+ /*NOTREACHED*/
}
progname = newstralloc(progname, cmdargs.argv[a++]);
if(a >= cmdargs.argc) {
error("error [chunker PORT-WRITE: not enough args: use]");
+ /*NOTREACHED*/
}
- use = am_floor(atoi(cmdargs.argv[a++]), DISK_BLOCK_KB);
+ use = am_floor(OFF_T_ATOI(cmdargs.argv[a++]), DISK_BLOCK_KB);
if(a >= cmdargs.argc) {
error("error [chunker PORT-WRITE: not enough args: options]");
+ /*NOTREACHED*/
}
options = newstralloc(options, cmdargs.argv[a++]);
if(a != cmdargs.argc) {
error("error [chunker PORT-WRITE: too many args: %d != %d]",
cmdargs.argc, a);
+ /*NOTREACHED*/
}
if((infd = startup_chunker(filename, use, chunksize, &db)) < 0) {
double rt;
runtime = stopclock();
- rt = runtime.r.tv_sec+runtime.r.tv_usec/1000000.0;
- snprintf(kb_str, sizeof(kb_str), "%ld", dumpsize - headersize);
- snprintf(kps_str, sizeof(kps_str), "%3.1f",
- rt ? dumpsize / rt : 0.0);
+ rt = (double)(runtime.r.tv_sec) +
+ ((double)(runtime.r.tv_usec) / 1000000.0);
+ snprintf(kb_str, SIZEOF(kb_str), OFF_T_FMT,
+ (OFF_T_FMT_TYPE)(dumpsize - (off_t)headersize));
+ snprintf(kps_str, SIZEOF(kps_str), "%3.1lf",
+ isnormal(rt) ? (double)dumpsize / rt : 0.0);
errstr = newvstralloc(errstr,
"sec ", walltime_str(runtime),
" kb ", kb_str,
cmd = getcmd(&cmdargs);
switch(cmd) {
case DONE:
- putresult(DONE, "%s %ld %s\n",
- handle, dumpsize - headersize, q);
+ putresult(DONE, "%s " OFF_T_FMT " %s\n", handle,
+ (OFF_T_FMT_TYPE)(dumpsize - (off_t)headersize), q);
log_add(L_SUCCESS, "%s %s %s %d [%s]",
- hostname, diskname, datestamp, level, errstr);
+ hostname, qdiskname, chunker_timestamp, level, errstr);
break;
case BOGUS:
case TRYAGAIN:
case FAILED:
case ABORT_FINISHED:
- if(dumpsize > DISK_BLOCK_KB) {
- putresult(PARTIAL, "%s %ld %s\n",
- handle, dumpsize - headersize, q);
+ if(dumpsize > (off_t)DISK_BLOCK_KB) {
+ putresult(PARTIAL, "%s " OFF_T_FMT " %s\n", handle,
+ (OFF_T_FMT_TYPE)(dumpsize - (off_t)headersize),
+ q);
log_add(L_PARTIAL, "%s %s %s %d [%s]",
- hostname, diskname, datestamp, level, errstr);
+ hostname, qdiskname, chunker_timestamp, level, errstr);
}
else {
errstr = newvstralloc(errstr,
q = squotef("[%s]",errstr);
putresult(FAILED, "%s %s\n", handle, q);
log_add(L_FAIL, "%s %s %s %d [%s]",
- hostname, diskname, datestamp, level, errstr);
+ hostname, qdiskname, chunker_timestamp, level, errstr);
}
default: break;
}
}
putresult(FAILED, "%s %s\n", handle, q);
log_add(L_FAIL, "%s %s %s %d [%s]",
- hostname, diskname, datestamp, level, errstr);
+ hostname, qdiskname, chunker_timestamp, level, errstr);
amfree(q);
}
}
+ amfree(filename);
+ amfree(db.filename);
break;
default:
/* } while(cmd != QUIT); */
+ free_new_argv(new_argc, new_argv);
+ free_server_config();
amfree(errstr);
- amfree(datestamp);
+ amfree(chunker_timestamp);
amfree(handle);
amfree(hostname);
amfree(diskname);
+ amfree(qdiskname);
amfree(dumpdate);
amfree(progname);
amfree(options);
if (malloc_size_1 != malloc_size_2)
malloc_list(fileno(stderr), malloc_hist_1, malloc_hist_2);
- exit(0);
+ dbclose();
+
+ return (0); /* exit */
}
/*
* on success, or -1 on error.
*/
static int
-startup_chunker(filename, use, chunksize, db)
- char *filename;
- long use;
- long chunksize;
- struct databuf *db;
+startup_chunker(
+ char * filename,
+ off_t use,
+ off_t chunksize,
+ struct databuf * db)
{
int infd, outfd;
char *tmp_filename, *pc;
- int data_port, data_socket;
+ in_port_t data_port;
+ int data_socket;
data_port = 0;
- data_socket = stream_server(&data_port, -1, STREAM_BUFSIZE);
+ data_socket = stream_server(&data_port, 0, STREAM_BUFSIZE, 0);
if(data_socket < 0) {
errstr = stralloc2("error creating stream server: ", strerror(errno));
putresult(PORT, "%d\n", data_port);
- infd = stream_accept(data_socket, CONNECT_TIMEOUT, -1, NETWORK_BLOCK_BYTES);
+ infd = stream_accept(data_socket, CONNECT_TIMEOUT, 0, STREAM_BUFSIZE);
if(infd == -1) {
errstr = stralloc2("error accepting stream: ", strerror(errno));
return -1;
amfree(tmp_filename);
aclose(infd);
if(save_errno == ENOSPC) {
- putresult(NO_ROOM, "%s %lu", handle, use);
+ putresult(NO_ROOM, "%s " OFF_T_FMT "\n",
+ handle, (OFF_T_FMT_TYPE)use);
return -2;
} else {
return -1;
}
static int
-do_chunk(infd, db)
- int infd;
- struct databuf *db;
+do_chunk(
+ int infd,
+ struct databuf * db)
{
- int nread;
+ ssize_t nread;
char header_buf[DISK_BLOCK_BYTES];
startclock();
- dumpsize = headersize = dumpbytes = filesize = 0;
+ dumpsize = dumpbytes = filesize = (off_t)0;
+ headersize = 0;
+ memset(header_buf, 0, sizeof(header_buf));
/*
* The first thing we should receive is the file header, which we
* need to save into "file", as well as write out. Later, the
* chunk code will rewrite it.
*/
- nread = fullread(infd, header_buf, sizeof(header_buf));
+ nread = fullread(infd, header_buf, SIZEOF(header_buf));
if (nread != DISK_BLOCK_BYTES) {
char number1[NUM_STR_SIZE];
char number2[NUM_STR_SIZE];
if(nread < 0) {
errstr = stralloc2("cannot read header: ", strerror(errno));
} else {
- snprintf(number1, sizeof(number1), "%d", nread);
- snprintf(number2, sizeof(number2), "%d", DISK_BLOCK_BYTES);
+ snprintf(number1, SIZEOF(number1), SSIZE_T_FMT,
+ (SSIZE_T_FMT_TYPE)nread);
+ snprintf(number2, SIZEOF(number2), "%d", DISK_BLOCK_BYTES);
errstr = vstralloc("cannot read header: got ",
number1,
" instead of ",
}
return 0;
}
- parse_file_header(header_buf, &file, nread);
+ parse_file_header(header_buf, &file, (size_t)nread);
if(write_tapeheader(db->fd, &file)) {
int save_errno = errno;
- errstr = squotef("write_tapeheader file \"%s\": %s",
+ errstr = squotef("write_tapeheader file %s: %s",
db->filename, strerror(errno));
if(save_errno == ENOSPC) {
- putresult(NO_ROOM, "%s %lu\n", handle,
- db->use+db->split_size-dumpsize);
+ putresult(NO_ROOM, "%s " OFF_T_FMT "\n", handle,
+ (OFF_T_FMT_TYPE)(db->use+db->split_size-dumpsize));
}
return 0;
}
- dumpsize += DISK_BLOCK_KB;
- filesize = DISK_BLOCK_KB;
+ dumpsize += (off_t)DISK_BLOCK_KB;
+ filesize = (off_t)DISK_BLOCK_KB;
headersize += DISK_BLOCK_KB;
/*
* We've written the file header. Now, just write data until the
* end.
*/
- while ((nread = fullread(infd, db->buf, db->datalimit - db->datain)) > 0) {
+ while ((nread = fullread(infd, db->buf,
+ (size_t)(db->datalimit - db->datain))) > 0) {
db->datain += nread;
while(db->dataout < db->datain) {
if(!databuf_flush(db)) {
return 0;
}
}
- if(dumpbytes > 0) {
- dumpsize++; /* count partial final KByte */
- filesize++;
+ if(dumpbytes > (off_t)0) {
+ dumpsize += (off_t)1; /* count partial final KByte */
+ filesize += (off_t)1;
}
return 1;
}
* Initialize a databuf. Takes a writeable file descriptor.
*/
static void
-databuf_init(db, fd, filename, use, chunk_size)
- struct databuf *db;
- int fd;
- char *filename;
- long use;
- long chunk_size;
+databuf_init(
+ struct databuf * db,
+ int fd,
+ char * filename,
+ off_t use,
+ off_t chunk_size)
{
db->fd = fd;
db->filename = stralloc(filename);
- db->filename_seq = 0;
+ db->filename_seq = (off_t)0;
db->chunk_size = chunk_size;
db->split_size = (db->chunk_size > use) ? use : db->chunk_size;
- db->use = (use>db->split_size) ? use - db->split_size : 0;
+ db->use = (use > db->split_size) ? use - db->split_size : (off_t)0;
db->datain = db->dataout = db->buf;
- db->datalimit = db->buf + sizeof(db->buf);
+ db->datalimit = db->buf + SIZEOF(db->buf);
}
* Write out the buffer to the backing file
*/
static int
-databuf_flush(db)
- struct databuf *db;
+databuf_flush(
+ struct databuf * db)
{
struct cmdargs cmdargs;
int rc = 1;
- int written;
- long left_in_chunk;
+ ssize_t written;
+ off_t left_in_chunk;
char *arg_filename = NULL;
+ char *qarg_filename = NULL;
char *new_filename = NULL;
char *tmp_filename = NULL;
char sequence[NUM_STR_SIZE];
/*
* See if we need to split this file.
*/
- while (db->split_size > 0 && dumpsize >= db->split_size) {
- if( db->use == 0 ) {
+ while (db->split_size > (off_t)0 && dumpsize >= db->split_size) {
+ if( db->use == (off_t)0 ) {
/*
* Probably no more space on this disk. Request some more.
*/
if(a >= cmdargs.argc) {
error("error [chunker CONTINUE: not enough args: filename]");
+ /*NOTREACHED*/
}
- arg_filename = newstralloc(arg_filename, cmdargs.argv[a++]);
+ qarg_filename = newstralloc(qarg_filename, cmdargs.argv[a++]);
+ if (arg_filename != NULL)
+ amfree(arg_filename);
+ arg_filename = unquote_string(qarg_filename);
if(a >= cmdargs.argc) {
error("error [chunker CONTINUE: not enough args: chunksize]");
+ /*NOTREACHED*/
}
- db->chunk_size = atoi(cmdargs.argv[a++]);
- db->chunk_size = am_floor(db->chunk_size, DISK_BLOCK_KB);
+ db->chunk_size = OFF_T_ATOI(cmdargs.argv[a++]);
+ db->chunk_size = am_floor(db->chunk_size, (off_t)DISK_BLOCK_KB);
if(a >= cmdargs.argc) {
error("error [chunker CONTINUE: not enough args: use]");
+ /*NOTREACHED*/
}
- db->use = atoi(cmdargs.argv[a++]);
+ db->use = OFF_T_ATOI(cmdargs.argv[a++]);
if(a != cmdargs.argc) {
error("error [chunker CONTINUE: too many args: %d != %d]",
cmdargs.argc, a);
+ /*NOTREACHED*/
}
if(strcmp(db->filename, arg_filename) == 0) {
left_in_chunk = db->chunk_size - filesize;
if(left_in_chunk > db->use) {
db->split_size += db->use;
- db->use = 0;
+ db->use = (off_t)0;
} else {
db->split_size += left_in_chunk;
db->use -= left_in_chunk;
}
- if(left_in_chunk > 0) {
+ if(left_in_chunk > (off_t)0) {
/*
* We still have space in this chunk.
*/
q = stralloc("(no input?)");
}
error("error [bad command after RQ-MORE-DISK: \"%s\"]", q);
+ /*NOTREACHED*/
}
}
* First, open the new chunk file, and give it a new header
* that has no cont_filename pointer.
*/
- snprintf(sequence, sizeof(sequence), "%d", db->filename_seq);
+ snprintf(sequence, SIZEOF(sequence), "%d", db->filename_seq);
new_filename = newvstralloc(new_filename,
db->filename,
".",
int save_errno = errno;
if(save_errno == ENOSPC) {
- putresult(NO_ROOM, "%s %lu\n",
- handle,
- db->use+db->split_size-dumpsize);
- db->use = 0; /* force RQ_MORE_DISK */
+ putresult(NO_ROOM, "%s " OFF_T_FMT "\n", handle,
+ (OFF_T_FMT_TYPE)(db->use+db->split_size-dumpsize));
+ db->use = (off_t)0; /* force RQ_MORE_DISK */
db->split_size = dumpsize;
continue;
}
aclose(newfd);
if(save_errno == ENOSPC) {
- putresult(NO_ROOM, "%s %lu\n",
- handle,
- db->use+db->split_size-dumpsize);
- db->use = 0; /* force RQ_MORE DISK */
+ putresult(NO_ROOM, "%s " OFF_T_FMT "\n", handle,
+ (OFF_T_FMT_TYPE)(db->use+db->split_size-dumpsize));
+ db->use = (off_t)0; /* force RQ_MORE DISK */
db->split_size = dumpsize;
continue;
}
- errstr = squotef("write_tapeheader file \"%s\": %s",
+ errstr = squotef("write_tapeheader file %s: %s",
tmp_filename,
strerror(errno));
rc = 0;
* Now, update the header of the current file to point
* to the next chunk, and then close it.
*/
- if (lseek(db->fd, (off_t)0, SEEK_SET) < 0) {
- errstr = squotef("lseek holding file \"%s\": %s",
+ if (lseek(db->fd, (off_t)0, SEEK_SET) < (off_t)0) {
+ errstr = squotef("lseek holding file %s: %s",
db->filename,
strerror(errno));
aclose(newfd);
}
file.type = save_type;
- strncpy(file.cont_filename, new_filename, sizeof(file.cont_filename));
- file.cont_filename[sizeof(file.cont_filename)] = '\0';
+ strncpy(file.cont_filename, new_filename, SIZEOF(file.cont_filename));
+ file.cont_filename[SIZEOF(file.cont_filename)] = '\0';
if(write_tapeheader(db->fd, &file)) {
errstr = squotef("write_tapeheader file \"%s\": %s",
db->filename,
/*
* Update when we need to chunk again
*/
- if(db->use <= DISK_BLOCK_KB) {
+ if(db->use <= (off_t)DISK_BLOCK_KB) {
/*
* Cheat and use one more block than allowed so we can make
* some progress.
*/
- db->split_size += 2 * DISK_BLOCK_KB;
- db->use = 0;
+ db->split_size += (off_t)(2 * DISK_BLOCK_KB);
+ db->use = (off_t)0;
} else if(db->chunk_size > db->use) {
db->split_size += db->use;
- db->use = 0;
+ db->use = (off_t)0;
} else {
db->split_size += db->chunk_size;
db->use -= db->chunk_size;
amfree(tmp_filename);
amfree(new_filename);
- dumpsize += DISK_BLOCK_KB;
- filesize = DISK_BLOCK_KB;
+ dumpsize += (off_t)DISK_BLOCK_KB;
+ filesize = (off_t)DISK_BLOCK_KB;
headersize += DISK_BLOCK_KB;
db->filename_seq++;
}
/*
* Write out the buffer
*/
- written = fullwrite(db->fd, db->dataout, db->datain - db->dataout);
+ written = fullwrite(db->fd, db->dataout,
+ (size_t)(db->datain - db->dataout));
if (written > 0) {
db->dataout += written;
- dumpbytes += written;
+ dumpbytes += (off_t)written;
}
- dumpsize += (dumpbytes / 1024);
- filesize += (dumpbytes / 1024);
+ dumpsize += (dumpbytes / (off_t)1024);
+ filesize += (dumpbytes / (off_t)1024);
dumpbytes %= 1024;
if (written < 0) {
if (errno != ENOSPC) {
* NO-ROOM is informational only. Later, RQ_MORE_DISK will be
* issued to use another holding disk.
*/
- putresult(NO_ROOM, "%s %lu\n", handle, db->use+db->split_size-dumpsize);
- db->use = 0; /* force RQ_MORE_DISK */
+ putresult(NO_ROOM, "%s " OFF_T_FMT "\n", handle,
+ (OFF_T_FMT_TYPE)(db->use+db->split_size-dumpsize));
+ db->use = (off_t)0; /* force RQ_MORE_DISK */
db->split_size = dumpsize;
goto common_exit;
}
common_exit:
amfree(new_filename);
- amfree(tmp_filename);
+ /*@i@*/ amfree(tmp_filename);
amfree(arg_filename);
+ amfree(qarg_filename);
return rc;
}
/*
* Send an Amanda dump header to the output file.
*/
-static int
-write_tapeheader(outfd, file)
- int outfd;
- dumpfile_t *file;
+static ssize_t
+write_tapeheader(
+ int outfd,
+ dumpfile_t *file)
{
char buffer[DISK_BLOCK_BYTES];
- int written;
+ ssize_t written;
file->blocksize = DISK_BLOCK_BYTES;
- build_header(buffer, file, sizeof(buffer));
+ build_header(buffer, file, SIZEOF(buffer));
+
+ written = fullwrite(outfd, buffer, SIZEOF(buffer));
+ if(written == (ssize_t)sizeof(buffer))
+ return 0;
+
+ if(written < 0)
+ return written;
- written = fullwrite(outfd, buffer, sizeof(buffer));
- if(written == sizeof(buffer)) return 0;
- if(written < 0) return written;
errno = ENOSPC;
- return -1;
+ return (ssize_t)-1;
}
* University of Maryland at College Park
*/
/*
- * $Id: conffile.c,v 1.127 2006/03/15 16:26:13 martinea Exp $
+ * $Id: conffile.c,v 1.156 2006/07/26 15:17:37 martinea Exp $
*
* read configuration file
*/
-/*
- *
- * XXX - I'm not happy *at all* with this implementation, but I don't
- * think YACC would be any easier. A more table based implementation
- * would be better. Also clean up memory leaks.
- */
+
#include "amanda.h"
#include "arglist.h"
-
+#include "util.h"
#include "conffile.h"
#include "diskfile.h"
#include "driverio.h"
#define INT_MAX 2147483647
#endif
-#define BIGINT 1000000000 /* 2 million yrs @ 1 per day */
-
-/* internal types and variables */
-
-typedef enum {
- UNKNOWN, ANY, COMMA, LBRACE, RBRACE, NL, END,
- IDENT, INT, LONG, AM64, BOOL, REAL, STRING, TIME,
-
- /* config parameters */
- INCLUDEFILE,
- ORG, MAILTO, DUMPUSER,
- TAPECYCLE, TAPEDEV, CHNGRDEV, CHNGRFILE, LABELSTR,
- BUMPPERCENT, BUMPSIZE, BUMPDAYS, BUMPMULT, ETIMEOUT, DTIMEOUT, CTIMEOUT,
- TAPEBUFS, TAPELIST, DISKFILE, INFOFILE, LOGDIR, LOGFILE,
- DISKDIR, DISKSIZE, INDEXDIR, NETUSAGE, INPARALLEL, DUMPORDER, TIMEOUT,
- TPCHANGER, RUNTAPES,
- DEFINE, DUMPTYPE, TAPETYPE, INTERFACE,
- PRINTER, AUTOFLUSH, RESERVE, MAXDUMPSIZE,
- COLUMNSPEC,
- AMRECOVER_DO_FSF, AMRECOVER_CHECK_LABEL, AMRECOVER_CHANGER,
- LABEL_NEW_TAPES,
-
- TAPERALGO, FIRST, FIRSTFIT, LARGEST, LARGESTFIT, SMALLEST, LAST,
- DISPLAYUNIT,
-
- /* kerberos 5 */
- KRB5KEYTAB, KRB5PRINCIPAL,
-
- /* holding disk */
- COMMENT, DIRECTORY, USE, CHUNKSIZE,
-
- /* dump type */
- /*COMMENT,*/ PROGRAM, DUMPCYCLE, RUNSPERCYCLE, MAXCYCLE, MAXDUMPS,
- OPTIONS, PRIORITY, FREQUENCY, INDEX, MAXPROMOTEDAY,
- STARTTIME, COMPRESS, ENCRYPT, AUTH, STRATEGY, ESTIMATE,
- SKIP_INCR, SKIP_FULL, RECORD, HOLDING,
- EXCLUDE, INCLUDE, KENCRYPT, IGNORE, COMPRATE, TAPE_SPLITSIZE,
- SPLIT_DISKBUFFER, FALLBACK_SPLITSIZE, SRVCOMPPROG, CLNTCOMPPROG,
- SRV_ENCRYPT, CLNT_ENCRYPT, SRV_DECRYPT_OPT, CLNT_DECRYPT_OPT,
-
- /* tape type */
- /*COMMENT,*/ BLOCKSIZE, FILE_PAD, LBL_TEMPL, FILEMARK, LENGTH, SPEED,
-
- /* network interface */
- /*COMMENT, USE,*/
-
- /* dump options (obsolete) */
- EXCLUDE_FILE, EXCLUDE_LIST,
-
- /* compress, estimate, encryption */
- NONE, FAST, BEST, SERVER, CLIENT, CALCSIZE, CUSTOM,
-
- /* priority */
- LOW, MEDIUM, HIGH,
-
- /* dump strategy */
- SKIP, STANDARD, NOFULL, NOINC, HANOI, INCRONLY,
-
- /* exclude list */
- LIST, EFILE, APPEND, OPTIONAL,
-
- /* numbers */
- INFINITY, MULT1, MULT7, MULT1K, MULT1M, MULT1G,
-
- /* boolean */
- ATRUE, AFALSE,
-
- RAWTAPEDEV
-} tok_t;
-
-typedef struct { /* token table entry */
- char *keyword;
- tok_t token;
-} keytab_t;
-
-keytab_t *keytable;
-
-typedef union {
- int i;
- long l;
- am64_t am64;
- double r;
- char *s;
-} val_t;
-
/* this corresponds to the normal output of amanda, but may
* be adapted to any spacing as you like.
*/
{ "HostName", 0, 12, 12, 0, "%-*.*s", "HOSTNAME" },
{ "Disk", 1, 11, 11, 0, "%-*.*s", "DISK" },
{ "Level", 1, 1, 1, 0, "%*.*d", "L" },
- { "OrigKB", 1, 7, 0, 0, "%*.*f", "ORIG-KB" },
- { "OutKB", 1, 7, 0, 0, "%*.*f", "OUT-KB" },
- { "Compress", 1, 6, 1, 0, "%*.*f", "COMP%" },
+ { "OrigKB", 1, 7, 0, 0, "%*.*lf", "ORIG-KB" },
+ { "OutKB", 1, 7, 0, 0, "%*.*lf", "OUT-KB" },
+ { "Compress", 1, 6, 1, 0, "%*.*lf", "COMP%" },
{ "DumpTime", 1, 7, 7, 0, "%*.*s", "MMM:SS" },
- { "DumpRate", 1, 6, 1, 0, "%*.*f", "KB/s" },
+ { "DumpRate", 1, 6, 1, 0, "%*.*lf", "KB/s" },
{ "TapeTime", 1, 6, 6, 0, "%*.*s", "MMM:SS" },
- { "TapeRate", 1, 6, 1, 0, "%*.*f", "KB/s" },
+ { "TapeRate", 1, 6, 1, 0, "%*.*lf", "KB/s" },
{ NULL, 0, 0, 0, 0, NULL, NULL }
};
/* configuration parameters */
-/* strings */
-static val_t conf_org;
-static val_t conf_mailto;
-static val_t conf_dumpuser;
-static val_t conf_printer;
-static val_t conf_tapedev;
-static val_t conf_rawtapedev;
-static val_t conf_tpchanger;
-static val_t conf_chngrdev;
-static val_t conf_chngrfile;
-static val_t conf_labelstr;
-static val_t conf_tapelist;
-static val_t conf_infofile;
-static val_t conf_logdir;
-static val_t conf_diskfile;
-static val_t conf_diskdir;
-static val_t conf_tapetype;
-static val_t conf_indexdir;
-static val_t conf_columnspec;
-static val_t conf_dumporder;
-static val_t conf_amrecover_changer;
-
-/* ints */
-static val_t conf_dumpcycle;
-static val_t conf_runspercycle;
-static val_t conf_maxcycle;
-static val_t conf_tapecycle;
-static val_t conf_runtapes;
-static val_t conf_disksize;
-static val_t conf_netusage;
-static val_t conf_inparallel;
-static val_t conf_timeout;
-static val_t conf_maxdumps;
-static val_t conf_bumppercent;
-static val_t conf_bumpsize;
-static val_t conf_bumpdays;
-static val_t conf_etimeout;
-static val_t conf_dtimeout;
-static val_t conf_ctimeout;
-static val_t conf_tapebufs;
-static val_t conf_autoflush;
-static val_t conf_reserve;
-static val_t conf_maxdumpsize;
-static val_t conf_amrecover_do_fsf;
-static val_t conf_amrecover_check_label;
-static val_t conf_taperalgo;
-static val_t conf_displayunit;
-static val_t conf_krb5keytab;
-static val_t conf_krb5principal;
-static val_t conf_label_new_tapes;
-
-/* reals */
-static val_t conf_bumpmult;
+val_t server_conf[CNF_CNF];
+
+command_option_t *server_options = NULL;
/* other internal variables */
static holdingdisk_t hdcur;
static interface_t ifcur;
-static int seen_org;
-static int seen_mailto;
-static int seen_dumpuser;
-static int seen_rawtapedev;
-static int seen_printer;
-static int seen_tapedev;
-static int seen_tpchanger;
-static int seen_chngrdev;
-static int seen_chngrfile;
-static int seen_labelstr;
-static int seen_runtapes;
-static int seen_maxdumps;
-static int seen_tapelist;
-static int seen_infofile;
-static int seen_diskfile;
-static int seen_diskdir;
-static int seen_logdir;
-static int seen_bumppercent;
-static int seen_bumpsize;
-static int seen_bumpmult;
-static int seen_bumpdays;
-static int seen_tapetype;
-static int seen_dumpcycle;
-static int seen_runspercycle;
-static int seen_maxcycle;
-static int seen_tapecycle;
-static int seen_disksize;
-static int seen_netusage;
-static int seen_inparallel;
-static int seen_dumporder;
-static int seen_timeout;
-static int seen_indexdir;
-static int seen_etimeout;
-static int seen_dtimeout;
-static int seen_ctimeout;
-static int seen_tapebufs;
-static int seen_autoflush;
-static int seen_reserve;
-static int seen_maxdumpsize;
-static int seen_columnspec;
-static int seen_amrecover_do_fsf;
-static int seen_amrecover_check_label;
-static int seen_amrecover_changer;
-static int seen_taperalgo;
-static int seen_displayunit;
-static int seen_krb5keytab;
-static int seen_krb5principal;
-static int seen_label_new_tapes;
-
-static int allow_overwrites;
-static int token_pushed;
-
-static tok_t tok, pushed_tok;
-static val_t tokenval;
-
-static int line_num, got_parserror;
static dumptype_t *dumplist = NULL;
static tapetype_t *tapelist = NULL;
static interface_t *interface_list = NULL;
-static FILE *conf = (FILE *)NULL;
-static char *confname = NULL;
/* predeclare local functions */
-static void init_defaults P((void));
-static void read_conffile_recursively P((char *filename));
-
-static int read_confline P((void));
-static void get_holdingdisk P((void));
-static void init_holdingdisk_defaults P((void));
-static void save_holdingdisk P((void));
-static void get_dumptype P((void));
-static void init_dumptype_defaults P((void));
-static void save_dumptype P((void));
-static void copy_dumptype P((void));
-static void get_tapetype P((void));
-static void init_tapetype_defaults P((void));
-static void save_tapetype P((void));
-static void copy_tapetype P((void));
-static void get_interface P((void));
-static void init_interface_defaults P((void));
-static void save_interface P((void));
-static void copy_interface P((void));
-static void get_dumpopts P((void));
-static void get_comprate P((void));
-static void get_compress P((void));
-static void get_encrypt P((void));
-static void get_priority P((void));
-static void get_strategy P((void));
-static void get_estimate P((void));
-static void get_exclude P((void));
-static void get_include P((void));
-static void get_taperalgo P((val_t *c_taperalgo, int *s_taperalgo));
-
-static void get_simple P((val_t *var, int *seen, tok_t type));
-static int get_time P((void));
-static int get_int P((void));
-static long get_long P((void));
-static am64_t get_am64_t P((void));
-static int get_bool P((void));
-static void ckseen P((int *seen));
-static void parserror P((char *format, ...))
- __attribute__ ((format (printf, 1, 2)));
-static tok_t lookup_keyword P((char *str));
-static void unget_conftoken P((void));
-static void get_conftoken P((tok_t exp));
+char *get_token_name(tok_t);
+
+
+void validate_positive0 (t_conf_var *, val_t *);
+void validate_positive1 (t_conf_var *, val_t *);
+void validate_runspercycle(t_conf_var *, val_t *);
+void validate_bumppercent (t_conf_var *, val_t *);
+void validate_bumpmult (t_conf_var *, val_t *);
+void validate_inparallel (t_conf_var *, val_t *);
+void validate_displayunit (t_conf_var *, val_t *);
+void validate_reserve (t_conf_var *, val_t *);
+void validate_use (t_conf_var *, val_t *);
+void validate_chunksize (t_conf_var *, val_t *);
+void validate_blocksize (t_conf_var *, val_t *);
+
+static void init_defaults(void);
+static void read_conffile_recursively(char *filename);
+
+static int read_confline(void);
+static void get_holdingdisk(void);
+static void init_holdingdisk_defaults(void);
+static void save_holdingdisk(void);
+static void get_dumptype(void);
+static void init_dumptype_defaults(void);
+static void save_dumptype(void);
+static void copy_dumptype(void);
+static void get_tapetype(void);
+static void init_tapetype_defaults(void);
+static void save_tapetype(void);
+static void copy_tapetype(void);
+static void get_interface(void);
+static void init_interface_defaults(void);
+static void save_interface(void);
+static void copy_interface(void);
+static void get_comprate(t_conf_var *, val_t *);
+static void get_compress(t_conf_var *, val_t *);
+static void get_encrypt (t_conf_var *, val_t *);
+static void get_holding (t_conf_var *, val_t *);
+static void get_priority(t_conf_var *, val_t *);
+static void get_strategy(t_conf_var *, val_t *);
+static void get_estimate(t_conf_var *, val_t *);
+static void get_exclude (t_conf_var *, val_t *);
+/*static void get_include(t_conf_var *, val_t *);*/
+static void get_taperalgo(t_conf_var *, val_t *);
+
+keytab_t server_keytab[] = {
+ { "AMANDAD_PATH", CONF_AMANDAD_PATH },
+ { "AMRECOVER_CHANGER", CONF_AMRECOVER_CHANGER },
+ { "AMRECOVER_CHECK_LABEL", CONF_AMRECOVER_CHECK_LABEL },
+ { "AMRECOVER_DO_FSF", CONF_AMRECOVER_DO_FSF },
+ { "APPEND", CONF_APPEND },
+ { "AUTH", CONF_AUTH },
+ { "AUTO", CONF_AUTO },
+ { "AUTOFLUSH", CONF_AUTOFLUSH },
+ { "BEST", CONF_BEST },
+ { "BLOCKSIZE", CONF_BLOCKSIZE },
+ { "BUMPDAYS", CONF_BUMPDAYS },
+ { "BUMPMULT", CONF_BUMPMULT },
+ { "BUMPPERCENT", CONF_BUMPPERCENT },
+ { "BUMPSIZE", CONF_BUMPSIZE },
+ { "CALCSIZE", CONF_CALCSIZE },
+ { "CHANGERDEV", CONF_CHNGRDEV },
+ { "CHANGERFILE", CONF_CHNGRFILE },
+ { "CHUNKSIZE", CONF_CHUNKSIZE },
+ { "CLIENT", CONF_CLIENT },
+ { "CLIENT_CUSTOM_COMPRESS", CONF_CLNTCOMPPROG },
+ { "CLIENT_DECRYPT_OPTION", CONF_CLNT_DECRYPT_OPT },
+ { "CLIENT_ENCRYPT", CONF_CLNT_ENCRYPT },
+ { "CLIENT_USERNAME", CONF_CLIENT_USERNAME },
+ { "COLUMNSPEC", CONF_COLUMNSPEC },
+ { "COMMENT", CONF_COMMENT },
+ { "COMPRATE", CONF_COMPRATE },
+ { "COMPRESS", CONF_COMPRESS },
+ { "CTIMEOUT", CONF_CTIMEOUT },
+ { "CUSTOM", CONF_CUSTOM },
+ { "DEFINE", CONF_DEFINE },
+ { "DIRECTORY", CONF_DIRECTORY },
+ { "DISKFILE", CONF_DISKFILE },
+ { "DISPLAYUNIT", CONF_DISPLAYUNIT },
+ { "DTIMEOUT", CONF_DTIMEOUT },
+ { "DUMPCYCLE", CONF_DUMPCYCLE },
+ { "DUMPORDER", CONF_DUMPORDER },
+ { "DUMPTYPE", CONF_DUMPTYPE },
+ { "DUMPUSER", CONF_DUMPUSER },
+ { "ENCRYPT", CONF_ENCRYPT },
+ { "ESTIMATE", CONF_ESTIMATE },
+ { "ETIMEOUT", CONF_ETIMEOUT },
+ { "EXCLUDE", CONF_EXCLUDE },
+ { "EXCLUDE-FILE", CONF_EXCLUDE_FILE },
+ { "EXCLUDE-LIST", CONF_EXCLUDE_LIST },
+ { "FALLBACK_SPLITSIZE", CONF_FALLBACK_SPLITSIZE },
+ { "FAST", CONF_FAST },
+ { "FILE", CONF_EFILE },
+ { "FILE-PAD", CONF_FILE_PAD },
+ { "FILEMARK", CONF_FILEMARK },
+ { "FIRST", CONF_FIRST },
+ { "FIRSTFIT", CONF_FIRSTFIT },
+ { "HANOI", CONF_HANOI },
+ { "HIGH", CONF_HIGH },
+ { "HOLDINGDISK", CONF_HOLDING },
+ { "IGNORE", CONF_IGNORE },
+ { "INCLUDE", CONF_INCLUDE },
+ { "INCLUDEFILE", CONF_INCLUDEFILE },
+ { "INCRONLY", CONF_INCRONLY },
+ { "INDEX", CONF_INDEX },
+ { "INDEXDIR", CONF_INDEXDIR },
+ { "INFOFILE", CONF_INFOFILE },
+ { "INPARALLEL", CONF_INPARALLEL },
+ { "INTERFACE", CONF_INTERFACE },
+ { "KENCRYPT", CONF_KENCRYPT },
+ { "KRB5KEYTAB", CONF_KRB5KEYTAB },
+ { "KRB5PRINCIPAL", CONF_KRB5PRINCIPAL },
+ { "LABELSTR", CONF_LABELSTR },
+ { "LABEL_NEW_TAPES", CONF_LABEL_NEW_TAPES },
+ { "LARGEST", CONF_LARGEST },
+ { "LARGESTFIT", CONF_LARGESTFIT },
+ { "LAST", CONF_LAST },
+ { "LBL-TEMPL", CONF_LBL_TEMPL },
+ { "LENGTH", CONF_LENGTH },
+ { "LIST", CONF_LIST },
+ { "LOGDIR", CONF_LOGDIR },
+ { "LOW", CONF_LOW },
+ { "MAILTO", CONF_MAILTO },
+ { "MAXDUMPS", CONF_MAXDUMPS },
+ { "MAXDUMPSIZE", CONF_MAXDUMPSIZE },
+ { "MAXPROMOTEDAY", CONF_MAXPROMOTEDAY },
+ { "MEDIUM", CONF_MEDIUM },
+ { "NETUSAGE", CONF_NETUSAGE }, /* XXX - historical */
+ { "NEVER", CONF_NEVER },
+ { "NOFULL", CONF_NOFULL },
+ { "NOINC", CONF_NOINC },
+ { "NONE", CONF_NONE },
+ { "OPTIONAL", CONF_OPTIONAL },
+ { "ORG", CONF_ORG },
+ { "PRINTER", CONF_PRINTER },
+ { "PRIORITY", CONF_PRIORITY },
+ { "PROGRAM", CONF_PROGRAM },
+ { "RAWTAPEDEV", CONF_RAWTAPEDEV },
+ { "RECORD", CONF_RECORD },
+ { "REQUIRED", CONF_REQUIRED },
+ { "RESERVE", CONF_RESERVE },
+ { "RUNSPERCYCLE", CONF_RUNSPERCYCLE },
+ { "RUNTAPES", CONF_RUNTAPES },
+ { "SERVER", CONF_SERVER },
+ { "SERVER_CUSTOM_COMPRESS", CONF_SRVCOMPPROG },
+ { "SERVER_DECRYPT_OPTION", CONF_SRV_DECRYPT_OPT },
+ { "SERVER_ENCRYPT", CONF_SRV_ENCRYPT },
+ { "SKIP", CONF_SKIP },
+ { "SKIP-FULL", CONF_SKIP_FULL },
+ { "SKIP-INCR", CONF_SKIP_INCR },
+ { "SMALLEST", CONF_SMALLEST },
+ { "SPEED", CONF_SPEED },
+ { "SPLIT_DISKBUFFER", CONF_SPLIT_DISKBUFFER },
+ { "SSH_KEYS", CONF_SSH_KEYS },
+ { "STANDARD", CONF_STANDARD },
+ { "STARTTIME", CONF_STARTTIME },
+ { "STRATEGY", CONF_STRATEGY },
+ { "TAPEBUFS", CONF_TAPEBUFS },
+ { "TAPECYCLE", CONF_TAPECYCLE },
+ { "TAPEDEV", CONF_TAPEDEV },
+ { "TAPELIST", CONF_TAPELIST },
+ { "TAPERALGO", CONF_TAPERALGO },
+ { "TAPETYPE", CONF_TAPETYPE },
+ { "TAPE_SPLITSIZE", CONF_TAPE_SPLITSIZE },
+ { "TPCHANGER", CONF_TPCHANGER },
+ { "USE", CONF_USE },
+ { "USETIMESTAMPS", CONF_USETIMESTAMPS },
+ { NULL, CONF_IDENT },
+ { NULL, CONF_UNKNOWN }
+};
+t_conf_var server_var [] = {
+ { CONF_ORG , CONFTYPE_STRING , read_string , CNF_ORG , NULL },
+ { CONF_MAILTO , CONFTYPE_STRING , read_string , CNF_MAILTO , NULL },
+ { CONF_DUMPUSER , CONFTYPE_STRING , read_string , CNF_DUMPUSER , NULL },
+ { CONF_PRINTER , CONFTYPE_STRING , read_string , CNF_PRINTER , NULL },
+ { CONF_TAPEDEV , CONFTYPE_STRING , read_string , CNF_TAPEDEV , NULL },
+ { CONF_TPCHANGER , CONFTYPE_STRING , read_string , CNF_TPCHANGER , NULL },
+ { CONF_CHNGRDEV , CONFTYPE_STRING , read_string , CNF_CHNGRDEV , NULL },
+ { CONF_CHNGRFILE , CONFTYPE_STRING , read_string , CNF_CHNGRFILE , NULL },
+ { CONF_LABELSTR , CONFTYPE_STRING , read_string , CNF_LABELSTR , NULL },
+ { CONF_TAPELIST , CONFTYPE_STRING , read_string , CNF_TAPELIST , NULL },
+ { CONF_DISKFILE , CONFTYPE_STRING , read_string , CNF_DISKFILE , NULL },
+ { CONF_INFOFILE , CONFTYPE_STRING , read_string , CNF_INFOFILE , NULL },
+ { CONF_LOGDIR , CONFTYPE_STRING , read_string , CNF_LOGDIR , NULL },
+ { CONF_INDEXDIR , CONFTYPE_STRING , read_string , CNF_INDEXDIR , NULL },
+ { CONF_TAPETYPE , CONFTYPE_IDENT , read_ident , CNF_TAPETYPE , NULL },
+ { CONF_DUMPCYCLE , CONFTYPE_INT , read_int , CNF_DUMPCYCLE , validate_positive0 },
+ { CONF_RUNSPERCYCLE , CONFTYPE_INT , read_int , CNF_RUNSPERCYCLE , validate_runspercycle },
+ { CONF_RUNTAPES , CONFTYPE_INT , read_int , CNF_RUNTAPES , validate_positive0 },
+ { CONF_TAPECYCLE , CONFTYPE_INT , read_int , CNF_TAPECYCLE , validate_positive1 },
+ { CONF_BUMPDAYS , CONFTYPE_INT , read_int , CNF_BUMPDAYS , validate_positive1 },
+ { CONF_BUMPSIZE , CONFTYPE_AM64 , read_am64 , CNF_BUMPSIZE , validate_positive1 },
+ { CONF_BUMPPERCENT , CONFTYPE_INT , read_int , CNF_BUMPPERCENT , validate_bumppercent },
+ { CONF_BUMPMULT , CONFTYPE_REAL , read_real , CNF_BUMPMULT , validate_bumpmult },
+ { CONF_NETUSAGE , CONFTYPE_INT , read_int , CNF_NETUSAGE , validate_positive1 },
+ { CONF_INPARALLEL , CONFTYPE_INT , read_int , CNF_INPARALLEL , validate_inparallel },
+ { CONF_DUMPORDER , CONFTYPE_STRING , read_string , CNF_DUMPORDER , NULL },
+ { CONF_MAXDUMPS , CONFTYPE_INT , read_int , CNF_MAXDUMPS , validate_positive1 },
+ { CONF_ETIMEOUT , CONFTYPE_TIME , read_time , CNF_ETIMEOUT , NULL },
+ { CONF_DTIMEOUT , CONFTYPE_TIME , read_time , CNF_DTIMEOUT , validate_positive1 },
+ { CONF_CTIMEOUT , CONFTYPE_TIME , read_time , CNF_CTIMEOUT , validate_positive1 },
+ { CONF_TAPEBUFS , CONFTYPE_INT , read_int , CNF_TAPEBUFS , validate_positive1 },
+ { CONF_RAWTAPEDEV , CONFTYPE_STRING , read_string , CNF_RAWTAPEDEV , NULL },
+ { CONF_COLUMNSPEC , CONFTYPE_STRING , read_string , CNF_COLUMNSPEC , NULL },
+ { CONF_TAPERALGO , CONFTYPE_TAPERALGO, get_taperalgo, CNF_TAPERALGO , NULL },
+ { CONF_DISPLAYUNIT , CONFTYPE_STRING , read_string , CNF_DISPLAYUNIT , validate_displayunit },
+ { CONF_AUTOFLUSH , CONFTYPE_BOOL , read_bool , CNF_AUTOFLUSH , NULL },
+ { CONF_RESERVE , CONFTYPE_INT , read_int , CNF_RESERVE , validate_reserve },
+ { CONF_MAXDUMPSIZE , CONFTYPE_AM64 , read_am64 , CNF_MAXDUMPSIZE , NULL },
+ { CONF_KRB5KEYTAB , CONFTYPE_STRING , read_string , CNF_KRB5KEYTAB , NULL },
+ { CONF_KRB5PRINCIPAL , CONFTYPE_STRING , read_string , CNF_KRB5PRINCIPAL , NULL },
+ { CONF_LABEL_NEW_TAPES , CONFTYPE_STRING , read_string , CNF_LABEL_NEW_TAPES , NULL },
+ { CONF_USETIMESTAMPS , CONFTYPE_BOOL , read_bool , CNF_USETIMESTAMPS , NULL },
+ { CONF_AMRECOVER_DO_FSF , CONFTYPE_BOOL , read_bool , CNF_AMRECOVER_DO_FSF , NULL },
+ { CONF_AMRECOVER_CHANGER , CONFTYPE_STRING , read_string , CNF_AMRECOVER_CHANGER , NULL },
+ { CONF_AMRECOVER_CHECK_LABEL, CONFTYPE_BOOL , read_bool , CNF_AMRECOVER_CHECK_LABEL, NULL },
+ { CONF_UNKNOWN , CONFTYPE_INT , NULL , CNF_CNF , NULL }
+};
/*
** ------------------------
** External entry points
** ------------------------
*/
-int read_conffile(filename)
-char *filename;
+int
+read_conffile(
+ char *filename)
{
interface_t *ip;
init_defaults();
- /* We assume that confname & conf are initialized to NULL above */
+ /* We assume that conf_confname & conf are initialized to NULL above */
read_conffile_recursively(filename);
+ /* overwrite with command line option */
+ command_overwrite(server_options, server_var, server_keytab, server_conf,
+ "");
+
if(got_parserror != -1 ) {
- if(lookup_tapetype(conf_tapetype.s) == NULL) {
- char *save_confname = confname;
+ if(lookup_tapetype(server_conf[CNF_TAPETYPE].v.s) == NULL) {
+ char *save_confname = conf_confname;
- confname = filename;
- if(!seen_tapetype)
- parserror("default tapetype %s not defined", conf_tapetype.s);
+ conf_confname = filename;
+ if(!server_conf[CNF_TAPETYPE].seen)
+ conf_parserror("default tapetype %s not defined", server_conf[CNF_TAPETYPE].v.s);
else {
- line_num = seen_tapetype;
- parserror("tapetype %s not defined", conf_tapetype.s);
+ conf_line_num = server_conf[CNF_TAPETYPE].seen;
+ conf_parserror("tapetype %s not defined", server_conf[CNF_TAPETYPE].v.s);
}
- confname = save_confname;
+ conf_confname = save_confname;
}
}
- ip = alloc(sizeof(interface_t));
- malloc_mark(ip);
- ip->name = "";
- ip->seen = seen_netusage;
- ip->comment = "implicit from NETUSAGE";
- ip->maxusage = conf_netusage.i;
+ ip = alloc(SIZEOF(interface_t));
+ ip->name = stralloc("default");
+ ip->seen = server_conf[CNF_NETUSAGE].seen;
+ conf_init_string(&ip->value[INTER_COMMENT], "implicit from NETUSAGE");
+ conf_init_int(&ip->value[INTER_MAXUSAGE], server_conf[CNF_NETUSAGE].v.i);
ip->curusage = 0;
ip->next = interface_list;
interface_list = ip;
return got_parserror;
}
-struct byname {
- char *name;
- confparm_t parm;
- tok_t typ;
-} byname_table [] = {
- { "ORG", CNF_ORG, STRING },
- { "MAILTO", CNF_MAILTO, STRING },
- { "DUMPUSER", CNF_DUMPUSER, STRING },
- { "PRINTER", CNF_PRINTER, STRING },
- { "TAPEDEV", CNF_TAPEDEV, STRING },
- { "TPCHANGER", CNF_TPCHANGER, STRING },
- { "CHANGERDEV", CNF_CHNGRDEV, STRING },
- { "CHANGERFILE", CNF_CHNGRFILE, STRING },
- { "LABELSTR", CNF_LABELSTR, STRING },
- { "TAPELIST", CNF_TAPELIST, STRING },
- { "DISKFILE", CNF_DISKFILE, STRING },
- { "INFOFILE", CNF_INFOFILE, STRING },
- { "LOGDIR", CNF_LOGDIR, STRING },
- /*{ "LOGFILE", CNF_LOGFILE, STRING },*/
- /*{ "DISKDIR", CNF_DISKDIR, STRING },*/
- { "INDEXDIR", CNF_INDEXDIR, STRING },
- { "TAPETYPE", CNF_TAPETYPE, STRING },
- { "DUMPCYCLE", CNF_DUMPCYCLE, INT },
- { "RUNSPERCYCLE", CNF_RUNSPERCYCLE, INT },
- { "MINCYCLE", CNF_DUMPCYCLE, INT },
- { "RUNTAPES", CNF_RUNTAPES, INT },
- { "TAPECYCLE", CNF_TAPECYCLE, INT },
- /*{ "DISKSIZE", CNF_DISKSIZE, INT },*/
- { "BUMPDAYS", CNF_BUMPDAYS, INT },
- { "BUMPSIZE", CNF_BUMPSIZE, INT },
- { "BUMPPERCENT", CNF_BUMPPERCENT, INT },
- { "BUMPMULT", CNF_BUMPMULT, REAL },
- { "NETUSAGE", CNF_NETUSAGE, INT },
- { "INPARALLEL", CNF_INPARALLEL, INT },
- { "DUMPORDER", CNF_DUMPORDER, STRING },
- /*{ "TIMEOUT", CNF_TIMEOUT, INT },*/
- { "MAXDUMPS", CNF_MAXDUMPS, INT },
- { "ETIMEOUT", CNF_ETIMEOUT, INT },
- { "DTIMEOUT", CNF_DTIMEOUT, INT },
- { "CTIMEOUT", CNF_CTIMEOUT, INT },
- { "TAPEBUFS", CNF_TAPEBUFS, INT },
- { "RAWTAPEDEV", CNF_RAWTAPEDEV, STRING },
- { "COLUMNSPEC", CNF_COLUMNSPEC, STRING },
- { "AMRECOVER_DO_FSF", CNF_AMRECOVER_DO_FSF, BOOL },
- { "AMRECOVER_CHECK_LABEL", CNF_AMRECOVER_CHECK_LABEL, BOOL },
- { "AMRECOVER_CHANGER", CNF_AMRECOVER_CHANGER, STRING },
- { "TAPERALGO", CNF_TAPERALGO, INT },
- { "DISPLAYUNIT", CNF_DISPLAYUNIT, STRING },
- { "AUTOFLUSH", CNF_AUTOFLUSH, BOOL },
- { "RESERVE", CNF_RESERVE, INT },
- { "MAXDUMPSIZE", CNF_MAXDUMPSIZE, AM64 },
- { "KRB5KEYTAB", CNF_KRB5KEYTAB, STRING },
- { "KRB5PRINCIPAL", CNF_KRB5PRINCIPAL, STRING },
- { "LABEL_NEW_TAPES", CNF_LABEL_NEW_TAPES, STRING },
- { NULL }
-};
+void
+validate_positive0(
+ struct s_conf_var *np,
+ val_t *val)
+{
+ switch(val->type) {
+ case CONFTYPE_INT:
+ if(val->v.i < 0)
+ conf_parserror("%s must be positive", get_token_name(np->token));
+ break;
+ case CONFTYPE_LONG:
+ if(val->v.l < 0)
+ conf_parserror("%s must be positive", get_token_name(np->token));
+ break;
+ case CONFTYPE_AM64:
+ if(val->v.am64 < 0)
+ conf_parserror("%s must be positive", get_token_name(np->token));
+ break;
+ default:
+ conf_parserror("validate_positive0 invalid type %d\n", val->type);
+ }
+}
+
+void
+validate_positive1(
+ struct s_conf_var *np,
+ val_t *val)
+{
+ switch(val->type) {
+ case CONFTYPE_INT:
+ if(val->v.i < 1)
+ conf_parserror("%s must be positive", get_token_name(np->token));
+ break;
+ case CONFTYPE_LONG:
+ if(val->v.l < 1)
+ conf_parserror("%s must be positive", get_token_name(np->token));
+ break;
+ case CONFTYPE_AM64:
+ if(val->v.am64 < 1)
+ conf_parserror("%s must be positive", get_token_name(np->token));
+ break;
+ case CONFTYPE_TIME:
+ if(val->v.t < 1)
+ conf_parserror("%s must be positive", get_token_name(np->token));
+ break;
+ default:
+ conf_parserror("validate_positive1 invalid type %d\n", val->type);
+ }
+}
+
+void
+validate_runspercycle(
+ struct s_conf_var *np,
+ val_t *val)
+{
+ np = np;
+ if(val->v.i < -1)
+ conf_parserror("runspercycle must be >= -1");
+}
+
+void
+validate_bumppercent(
+ struct s_conf_var *np,
+ val_t *val)
+{
+ np = np;
+ if(val->v.i < 0 || val->v.i > 100)
+ conf_parserror("bumppercent must be between 0 and 100");
+}
+
+void
+validate_inparallel(
+ struct s_conf_var *np,
+ val_t *val)
+{
+ np = np;
+ if(val->v.i < 1 || val->v.i >MAX_DUMPERS)
+ conf_parserror("inparallel must be between 1 and MAX_DUMPERS (%d)",
+ MAX_DUMPERS);
+}
+
+void
+validate_bumpmult(
+ struct s_conf_var *np,
+ val_t *val)
+{
+ np = np;
+ if(val->v.r < 0.999) {
+ conf_parserror("bumpmult must be positive");
+ }
+}
+
+void
+validate_displayunit(
+ struct s_conf_var *np,
+ val_t *val)
+{
+ np = np;
+ if(strcmp(val->v.s, "k") == 0 ||
+ strcmp(val->v.s, "K") == 0) {
+ val->v.s[0] = (char)toupper(val->v.s[0]);
+ unit_divisor=1;
+ }
+ else if(strcmp(val->v.s, "m") == 0 ||
+ strcmp(val->v.s, "M") == 0) {
+ val->v.s[0] = (char)toupper(val->v.s[0]);
+ unit_divisor=1024;
+ }
+ else if(strcmp(val->v.s, "g") == 0 ||
+ strcmp(val->v.s, "G") == 0) {
+ val->v.s[0] = (char)toupper(val->v.s[0]);
+ unit_divisor=1024*1024;
+ }
+ else if(strcmp(val->v.s, "t") == 0 ||
+ strcmp(val->v.s, "T") == 0) {
+ val->v.s[0] = (char)toupper(val->v.s[0]);
+ unit_divisor=1024*1024*1024;
+ }
+ else {
+ conf_parserror("displayunit must be k,m,g or t.");
+ }
+}
+
+void
+validate_reserve(
+ struct s_conf_var *np,
+ val_t *val)
+{
+ np = np;
+ if(val->v.i < 0 || val->v.i > 100)
+ conf_parserror("reserve must be between 0 and 100");
+}
+
+void
+validate_use(
+ struct s_conf_var *np,
+ val_t *val)
+{
+ np = np;
+ val->v.am64 = am_floor(val->v.am64, DISK_BLOCK_KB);
+}
+
+void
+validate_chunksize(
+ struct s_conf_var *np,
+ val_t *val)
+{
+ np = np;
+ if(val->v.am64 == 0) {
+ val->v.am64 = ((AM64_MAX / 1024) - (2 * DISK_BLOCK_KB));
+ }
+ else if(val->v.am64 < 0) {
+ conf_parserror("Negative chunksize (%lld) is no longer supported", val->v.am64);
+ }
+ val->v.am64 = am_floor(val->v.am64, (off_t)DISK_BLOCK_KB);
+}
+
+void
+validate_blocksize(
+ struct s_conf_var *np,
+ val_t *val)
+{
+ np = np;
+ if(val->v.l < DISK_BLOCK_KB) {
+ conf_parserror("Tape blocksize must be at least %d KBytes",
+ DISK_BLOCK_KB);
+ } else if(val->v.l > MAX_TAPE_BLOCK_KB) {
+ conf_parserror("Tape blocksize must not be larger than %d KBytes",
+ MAX_TAPE_BLOCK_KB);
+ }
+}
-char *getconf_byname(str)
-char *str;
+char *
+getconf_byname(
+ char *str)
{
static char *tmpstr;
char number[NUM_STR_SIZE];
- struct byname *np;
+ t_conf_var *np;
+ keytab_t *kt;
char *s;
char ch;
tmpstr = stralloc(str);
s = tmpstr;
while((ch = *s++) != '\0') {
- if(islower((int)ch)) s[-1] = toupper(ch);
+ if(islower((int)ch))
+ s[-1] = (char)toupper(ch);
+ }
+ for(kt = server_keytab; kt->token != CONF_UNKNOWN; kt++) {
+ if(kt->keyword && strcmp(kt->keyword, tmpstr) == 0)
+ break;
}
- for(np = byname_table; np->name != NULL; np++)
- if(strcmp(np->name, tmpstr) == 0) break;
+ if(kt->token == CONF_UNKNOWN)
+ return NULL;
+
+ for(np = server_var; np->token != CONF_UNKNOWN; np++) {
+ if(np->token == kt->token)
+ break;
+ }
- if(np->name == NULL) return NULL;
+ if(np->token == CONF_UNKNOWN) return NULL;
- if(np->typ == INT) {
- snprintf(number, sizeof(number), "%d", getconf_int(np->parm));
+ if(np->type == CONFTYPE_INT) {
+ snprintf(number, sizeof(number), "%d", server_conf[np->parm].v.i);
tmpstr = newstralloc(tmpstr, number);
- } else if(np->typ == BOOL) {
- if(getconf_int(np->parm) == 0) {
+ } else if(np->type == CONFTYPE_BOOL) {
+ if(getconf_boolean(np->parm) == 0) {
tmpstr = newstralloc(tmpstr, "off");
- }
- else {
+ } else {
tmpstr = newstralloc(tmpstr, "on");
}
- } else if(np->typ == REAL) {
- snprintf(number, sizeof(number), "%f", getconf_real(np->parm));
+ } else if(np->type == CONFTYPE_REAL) {
+ snprintf(number, sizeof(number), "%lf", server_conf[np->parm].v.r);
+ tmpstr = newstralloc(tmpstr, number);
+ } else if(np->type == CONFTYPE_AM64){
+ snprintf(number, sizeof(number), OFF_T_FMT,
+ (OFF_T_FMT_TYPE)server_conf[np->parm].v.am64);
tmpstr = newstralloc(tmpstr, number);
} else {
tmpstr = newstralloc(tmpstr, getconf_str(np->parm));
return tmpstr;
}
-int getconf_seen(parm)
-confparm_t parm;
-{
- switch(parm) {
- case CNF_ORG: return seen_org;
- case CNF_MAILTO: return seen_mailto;
- case CNF_DUMPUSER: return seen_dumpuser;
- case CNF_PRINTER: return seen_printer;
- case CNF_TAPEDEV: return seen_tapedev;
- case CNF_TPCHANGER: return seen_tpchanger;
- case CNF_CHNGRDEV: return seen_chngrdev;
- case CNF_CHNGRFILE: return seen_chngrfile;
- case CNF_LABELSTR: return seen_labelstr;
- case CNF_RUNTAPES: return seen_runtapes;
- case CNF_MAXDUMPS: return seen_maxdumps;
- case CNF_TAPELIST: return seen_tapelist;
- case CNF_INFOFILE: return seen_infofile;
- case CNF_DISKFILE: return seen_diskfile;
- /*case CNF_DISKDIR: return seen_diskdir;*/
- case CNF_LOGDIR: return seen_logdir;
- /*case CNF_LOGFILE: return seen_logfile;*/
- case CNF_BUMPPERCENT: return seen_bumppercent;
- case CNF_BUMPSIZE: return seen_bumpsize;
- case CNF_BUMPMULT: return seen_bumpmult;
- case CNF_BUMPDAYS: return seen_bumpdays;
- case CNF_TAPETYPE: return seen_tapetype;
- case CNF_DUMPCYCLE: return seen_dumpcycle;
- case CNF_RUNSPERCYCLE: return seen_runspercycle;
- /*case CNF_MAXCYCLE: return seen_maxcycle;*/
- case CNF_TAPECYCLE: return seen_tapecycle;
- /*case CNF_DISKSIZE: return seen_disksize;*/
- case CNF_NETUSAGE: return seen_netusage;
- case CNF_INPARALLEL: return seen_inparallel;
- case CNF_DUMPORDER: return seen_dumporder;
- /*case CNF_TIMEOUT: return seen_timeout;*/
- case CNF_INDEXDIR: return seen_indexdir;
- case CNF_ETIMEOUT: return seen_etimeout;
- case CNF_DTIMEOUT: return seen_dtimeout;
- case CNF_CTIMEOUT: return seen_ctimeout;
- case CNF_TAPEBUFS: return seen_tapebufs;
- case CNF_RAWTAPEDEV: return seen_rawtapedev;
- case CNF_AUTOFLUSH: return seen_autoflush;
- case CNF_RESERVE: return seen_reserve;
- case CNF_MAXDUMPSIZE: return seen_maxdumpsize;
- case CNF_AMRECOVER_DO_FSF: return seen_amrecover_do_fsf;
- case CNF_AMRECOVER_CHECK_LABEL: return seen_amrecover_check_label;
- case CNF_AMRECOVER_CHANGER: return seen_amrecover_changer;
- case CNF_TAPERALGO: return seen_taperalgo;
- case CNF_DISPLAYUNIT: return seen_displayunit;
- case CNF_KRB5KEYTAB: return seen_krb5keytab;
- case CNF_KRB5PRINCIPAL: return seen_krb5principal;
- case CNF_LABEL_NEW_TAPES: return seen_label_new_tapes;
- default: return 0;
- }
-}
-
-int getconf_int(parm)
-confparm_t parm;
-{
- int r = 0;
-
- switch(parm) {
-
- case CNF_DUMPCYCLE: r = conf_dumpcycle.i; break;
- case CNF_RUNSPERCYCLE: r = conf_runspercycle.i; break;
- case CNF_TAPECYCLE: r = conf_tapecycle.i; break;
- case CNF_RUNTAPES: r = conf_runtapes.i; break;
- /*case CNF_DISKSIZE: r = conf_disksize.i; break;*/
- case CNF_BUMPPERCENT: r = conf_bumppercent.i; break;
- case CNF_BUMPSIZE: r = conf_bumpsize.i; break;
- case CNF_BUMPDAYS: r = conf_bumpdays.i; break;
- case CNF_NETUSAGE: r = conf_netusage.i; break;
- case CNF_INPARALLEL: r = conf_inparallel.i; break;
- /*case CNF_TIMEOUT: r = conf_timeout.i; break;*/
- case CNF_MAXDUMPS: r = conf_maxdumps.i; break;
- case CNF_ETIMEOUT: r = conf_etimeout.i; break;
- case CNF_DTIMEOUT: r = conf_dtimeout.i; break;
- case CNF_CTIMEOUT: r = conf_ctimeout.i; break;
- case CNF_TAPEBUFS: r = conf_tapebufs.i; break;
- case CNF_AUTOFLUSH: r = conf_autoflush.i; break;
- case CNF_RESERVE: r = conf_reserve.i; break;
- case CNF_AMRECOVER_DO_FSF: r = conf_amrecover_do_fsf.i; break;
- case CNF_AMRECOVER_CHECK_LABEL: r = conf_amrecover_check_label.i; break;
- case CNF_TAPERALGO: r = conf_taperalgo.i; break;
+int
+getconf_seen(
+ confparm_t parm)
+{
+ t_conf_var *np;
+ np = get_np(server_var, parm);
+ return(server_conf[np->parm].seen);
+}
- default:
- error("error [unknown getconf_int parm: %d]", parm);
- /* NOTREACHED */
+int
+getconf_boolean(
+ confparm_t parm)
+{
+ t_conf_var *np;
+ np = get_np(server_var, parm);
+ if (np->type != CONFTYPE_BOOL) {
+ error("getconf_boolean: np is not a CONFTYPE_BOOL");
+ /*NOTREACHED*/
}
- return r;
+ return(server_conf[np->parm].v.i != 0);
}
-am64_t getconf_am64(parm)
-confparm_t parm;
+int
+getconf_int(
+ confparm_t parm)
{
- am64_t r = 0;
+ t_conf_var *np;
+ np = get_np(server_var, parm);
+ if (np->type != CONFTYPE_INT) {
+ error("getconf_int: np is not a CONFTYPE_INT");
+ /*NOTREACHED*/
+ }
+ return(server_conf[np->parm].v.i);
+}
- switch(parm) {
- case CNF_MAXDUMPSIZE: r = conf_maxdumpsize.am64; break;
+long
+getconf_long(
+ confparm_t parm)
+{
+ t_conf_var *np;
+ np = get_np(server_var, parm);
+ if (np->type != CONFTYPE_LONG) {
+ error("getconf_long: np is not a CONFTYPE_LONG");
+ /*NOTREACHED*/
+ }
+ return(server_conf[np->parm].v.l);
+}
- default:
- error("error [unknown getconf_am64 parm: %d]", parm);
- /* NOTREACHED */
+time_t
+getconf_time(
+ confparm_t parm)
+{
+ t_conf_var *np;
+ np = get_np(server_var, parm);
+ if (np->type != CONFTYPE_TIME) {
+ error("getconf_time: np is not a CONFTYPE_TIME");
+ /*NOTREACHED*/
}
- return r;
+ return(server_conf[np->parm].v.t);
}
-double getconf_real(parm)
-confparm_t parm;
+ssize_t
+getconf_size(
+ confparm_t parm)
{
- double r = 0;
+ t_conf_var *np;
+ np = get_np(server_var, parm);
+ if (np->type != CONFTYPE_SIZE) {
+ error("getconf_size: np is not a CONFTYPE_SIZE");
+ /*NOTREACHED*/
+ }
+ return(server_conf[np->parm].v.size);
+}
- switch(parm) {
+off_t
+getconf_am64(
+ confparm_t parm)
+{
+ t_conf_var *np;
+ np = get_np(server_var, parm);
+ if (np->type != CONFTYPE_AM64) {
+ error("getconf_am64: np is not a CONFTYPE_AM64");
+ /*NOTREACHED*/
+ }
+ return(server_conf[np->parm].v.am64);
+}
- case CNF_BUMPMULT: r = conf_bumpmult.r; break;
+double
+getconf_real(
+ confparm_t parm)
+{
+ t_conf_var *np;
+ np = get_np(server_var, parm);
+ if (np->type != CONFTYPE_REAL) {
+ error("getconf_real: np is not a CONFTYPE_REAL");
+ /*NOTREACHED*/
+ }
+ return(server_conf[np->parm].v.r);
+}
- default:
- error("error [unknown getconf_real parm: %d]", parm);
- /* NOTREACHED */
- }
- return r;
-}
-
-char *getconf_str(parm)
-confparm_t parm;
-{
- char *r = 0;
-
- switch(parm) {
-
- case CNF_ORG: r = conf_org.s; break;
- case CNF_MAILTO: r = conf_mailto.s; break;
- case CNF_DUMPUSER: r = conf_dumpuser.s; break;
- case CNF_PRINTER: r = conf_printer.s; break;
- case CNF_TAPEDEV: r = conf_tapedev.s; break;
- case CNF_TPCHANGER: r = conf_tpchanger.s; break;
- case CNF_CHNGRDEV: r = conf_chngrdev.s; break;
- case CNF_CHNGRFILE: r = conf_chngrfile.s; break;
- case CNF_LABELSTR: r = conf_labelstr.s; break;
- case CNF_TAPELIST: r = conf_tapelist.s; break;
- case CNF_INFOFILE: r = conf_infofile.s; break;
- case CNF_DUMPORDER: r = conf_dumporder.s; break;
- case CNF_LOGDIR: r = conf_logdir.s; break;
- /*case CNF_LOGFILE: r = conf_logfile.s; break;*/
- case CNF_DISKFILE: r = conf_diskfile.s; break;
- /*case CNF_DISKDIR: r = conf_diskdir.s; break;*/
- case CNF_TAPETYPE: r = conf_tapetype.s; break;
- case CNF_INDEXDIR: r = conf_indexdir.s; break;
- case CNF_RAWTAPEDEV: r = conf_rawtapedev.s; break;
- case CNF_COLUMNSPEC: r = conf_columnspec.s; break;
- case CNF_AMRECOVER_CHANGER: r = conf_amrecover_changer.s; break;
- case CNF_DISPLAYUNIT: r = conf_displayunit.s; break;
- case CNF_KRB5PRINCIPAL: r = conf_krb5principal.s; break;
- case CNF_KRB5KEYTAB: r = conf_krb5keytab.s; break;
- case CNF_LABEL_NEW_TAPES: r = conf_label_new_tapes.s; break;
+char *
+getconf_str(
+ confparm_t parm)
+{
+ t_conf_var *np;
+ np = get_np(server_var, parm);
+ if (np->type != CONFTYPE_STRING && np->type != CONFTYPE_IDENT) {
+ error("getconf_str: np is not a CONFTYPE_STRING|CONFTYPE_IDENT: %d", parm);
+ /*NOTREACHED*/
+ }
+ return(server_conf[np->parm].v.s);
+}
- default:
- error("error [unknown getconf_str parm: %d]", parm);
- /* NOTREACHED */
+int
+getconf_taperalgo(
+ confparm_t parm)
+{
+ t_conf_var *np;
+ np = get_np(server_var, parm);
+ if (np->type != CONFTYPE_TAPERALGO) {
+ error("getconf_taperalgo: np is not a CONFTYPE_TAPERALGO");
+ /*NOTREACHED*/
}
- return r;
+ return(server_conf[np->parm].v.i);
}
-holdingdisk_t *getconf_holdingdisks()
+holdingdisk_t *
+getconf_holdingdisks(
+ void)
{
return holdingdisks;
}
-dumptype_t *lookup_dumptype(str)
-char *str;
+dumptype_t *
+lookup_dumptype(
+ char *str)
{
dumptype_t *p;
for(p = dumplist; p != NULL; p = p->next) {
- if(strcmp(p->name, str) == 0) return p;
+ if(strcasecmp(p->name, str) == 0) return p;
}
return NULL;
}
-tapetype_t *lookup_tapetype(str)
-char *str;
+tapetype_t *
+lookup_tapetype(
+ char *str)
{
tapetype_t *p;
for(p = tapelist; p != NULL; p = p->next) {
- if(strcmp(p->name, str) == 0) return p;
+ if(strcasecmp(p->name, str) == 0) return p;
}
return NULL;
}
-interface_t *lookup_interface(str)
-char *str;
+interface_t *
+lookup_interface(
+ char *str)
{
+#ifndef __lint
interface_t *p;
+#endif
- if(str == NULL) return interface_list;
- for(p = interface_list; p != NULL; p = p->next) {
- if(strcmp(p->name, str) == 0) return p;
+ if (str == NULL)
+ return interface_list;
+
+#ifndef __lint
+ for (p = interface_list; p != NULL; p = p->next) {
+ if (strcasecmp(p->name, str) == 0)
+ return p;
}
+#endif
return NULL;
}
*/
-static void init_defaults()
+static void
+init_defaults(
+ void)
{
char *s;
#else
s = "YOUR ORG";
#endif
- conf_org.s = stralloc(s);
- malloc_mark(conf_org.s);
- conf_mailto.s = stralloc("operators");
- malloc_mark(conf_mailto.s);
- conf_dumpuser.s = stralloc(CLIENT_LOGIN);
- malloc_mark(conf_dumpuser.s);
+ conf_init_string(&server_conf[CNF_ORG], s);
+ conf_init_string(&server_conf[CNF_MAILTO], "operators");
+ conf_init_string(&server_conf[CNF_DUMPUSER], CLIENT_LOGIN);
#ifdef DEFAULT_TAPE_DEVICE
s = DEFAULT_TAPE_DEVICE;
#else
s = "/dev/rmt8";
#endif
- conf_tapedev.s = stralloc(s);
- malloc_mark(conf_tapedev.s);
-#ifdef DEFAULT_RAW_TAPE_DEVICE
- s = DEFAULT_RAW_TAPE_DEVICE;
-#else
- s = "/dev/rawft0";
-#endif
- conf_rawtapedev.s = stralloc(s);
- malloc_mark(conf_rawtapedev.s);
- conf_tpchanger.s = stralloc("");
- malloc_mark(conf_tpchanger.s);
+ conf_init_string(&server_conf[CNF_TAPEDEV], s);
#ifdef DEFAULT_CHANGER_DEVICE
s = DEFAULT_CHANGER_DEVICE;
#else
s = "/dev/null";
#endif
- conf_chngrdev.s = stralloc(s);
- malloc_mark(conf_chngrdev.s);
- conf_chngrfile.s = stralloc("/usr/adm/amanda/changer-status");
- malloc_mark(conf_chngrfile.s);
- conf_labelstr.s = stralloc(".*");
- malloc_mark(conf_labelstr.s);
- conf_tapelist.s = stralloc("tapelist");
- malloc_mark(conf_tapelist.s);
- conf_infofile.s = stralloc("/usr/adm/amanda/curinfo");
- malloc_mark(conf_infofile.s);
- conf_logdir.s = stralloc("/usr/adm/amanda");
- malloc_mark(conf_logdir.s);
- conf_diskfile.s = stralloc("disklist");
- malloc_mark(conf_diskfile.s);
- conf_diskdir.s = stralloc("/dumps/amanda");
- malloc_mark(conf_diskdir.s);
- conf_tapetype.s = stralloc("EXABYTE");
- malloc_mark(conf_tapetype.s);
- conf_indexdir.s = stralloc("/usr/adm/amanda/index");
- malloc_mark(conf_indexdir.s);
- conf_columnspec.s = stralloc("");
- malloc_mark(conf_columnspec.s);
- conf_dumporder.s = stralloc("ttt");
- malloc_mark(conf_dumporder.s);
- conf_amrecover_changer.s = stralloc("");
- conf_printer.s = stralloc("");
- conf_displayunit.s = stralloc("k");
- conf_label_new_tapes.s = stralloc("");
-
- conf_krb5keytab.s = stralloc("/.amanda-v5-keytab");
- conf_krb5principal.s = stralloc("service/amanda");
-
- conf_dumpcycle.i = 10;
- conf_runspercycle.i = 0;
- conf_tapecycle.i = 15;
- conf_runtapes.i = 1;
- conf_disksize.i = 0;
- conf_netusage.i = 300;
- conf_inparallel.i = 10;
- conf_maxdumps.i = 1;
- conf_timeout.i = 2;
- conf_bumppercent.i = 0;
- conf_bumpsize.i = 10*1024;
- conf_bumpdays.i = 2;
- conf_bumpmult.r = 1.5;
- conf_etimeout.i = 300;
- conf_dtimeout.i = 1800;
- conf_ctimeout.i = 30;
- conf_tapebufs.i = 20;
- conf_autoflush.i = 0;
- conf_reserve.i = 100;
- conf_maxdumpsize.am64 = -1;
- conf_amrecover_do_fsf.i = 1;
- conf_amrecover_check_label.i = 1;
- conf_taperalgo.i = 0;
+ conf_init_string(&server_conf[CNF_CHNGRDEV], s);
+ conf_init_string(&server_conf[CNF_CHNGRFILE], "/usr/adm/amanda/changer-status");
+#ifdef DEFAULT_RAW_TAPE_DEVICE
+ s = DEFAULT_RAW_TAPE_DEVICE;
+#else
+ s = "/dev/rawft0";
+#endif
+ conf_init_string (&server_conf[CNF_LABELSTR] , ".*");
+ conf_init_string (&server_conf[CNF_TAPELIST] , "tapelist");
+ conf_init_string (&server_conf[CNF_DISKFILE] , "disklist");
+ conf_init_string (&server_conf[CNF_INFOFILE] , "/usr/adm/amanda/curinfo");
+ conf_init_string (&server_conf[CNF_LOGDIR] , "/usr/adm/amanda");
+ conf_init_string (&server_conf[CNF_INDEXDIR] , "/usr/adm/amanda/index");
+ conf_init_ident (&server_conf[CNF_TAPETYPE] , "EXABYTE");
+ conf_init_int (&server_conf[CNF_DUMPCYCLE] , 10);
+ conf_init_int (&server_conf[CNF_RUNSPERCYCLE] , 0);
+ conf_init_int (&server_conf[CNF_TAPECYCLE] , 15);
+ conf_init_int (&server_conf[CNF_NETUSAGE] , 300);
+ conf_init_int (&server_conf[CNF_INPARALLEL] , 10);
+ conf_init_string (&server_conf[CNF_DUMPORDER] , "ttt");
+ conf_init_int (&server_conf[CNF_BUMPPERCENT] , 0);
+ conf_init_am64 (&server_conf[CNF_BUMPSIZE] , (off_t)10*1024);
+ conf_init_real (&server_conf[CNF_BUMPMULT] , 1.5);
+ conf_init_int (&server_conf[CNF_BUMPDAYS] , 2);
+ conf_init_string (&server_conf[CNF_TPCHANGER] , "");
+ conf_init_int (&server_conf[CNF_RUNTAPES] , 1);
+ conf_init_int (&server_conf[CNF_MAXDUMPS] , 1);
+ conf_init_time (&server_conf[CNF_ETIMEOUT] , (time_t)300);
+ conf_init_time (&server_conf[CNF_DTIMEOUT] , (time_t)1800);
+ conf_init_time (&server_conf[CNF_CTIMEOUT] , (time_t)30);
+ conf_init_int (&server_conf[CNF_TAPEBUFS] , 20);
+ conf_init_string (&server_conf[CNF_RAWTAPEDEV] , s);
+ conf_init_string (&server_conf[CNF_PRINTER] , "");
+ conf_init_bool (&server_conf[CNF_AUTOFLUSH] , 0);
+ conf_init_int (&server_conf[CNF_RESERVE] , 100);
+ conf_init_am64 (&server_conf[CNF_MAXDUMPSIZE] , (off_t)-1);
+ conf_init_string (&server_conf[CNF_COLUMNSPEC] , "");
+ conf_init_bool (&server_conf[CNF_AMRECOVER_DO_FSF] , 1);
+ conf_init_string (&server_conf[CNF_AMRECOVER_CHANGER] , "");
+ conf_init_bool (&server_conf[CNF_AMRECOVER_CHECK_LABEL], 1);
+ conf_init_taperalgo(&server_conf[CNF_TAPERALGO] , 0);
+ conf_init_string (&server_conf[CNF_DISPLAYUNIT] , "k");
+ conf_init_string (&server_conf[CNF_KRB5KEYTAB] , "/.amanda-v5-keytab");
+ conf_init_string (&server_conf[CNF_KRB5PRINCIPAL] , "service/amanda");
+ conf_init_string (&server_conf[CNF_LABEL_NEW_TAPES] , "");
+ conf_init_bool (&server_conf[CNF_USETIMESTAMPS] , 0);
/* defaults for internal variables */
- seen_org = 0;
- seen_mailto = 0;
- seen_dumpuser = 0;
- seen_tapedev = 0;
- seen_rawtapedev = 0;
- seen_printer = 0;
- seen_tpchanger = 0;
- seen_chngrdev = 0;
- seen_chngrfile = 0;
- seen_labelstr = 0;
- seen_runtapes = 0;
- seen_maxdumps = 0;
- seen_tapelist = 0;
- seen_infofile = 0;
- seen_diskfile = 0;
- seen_diskdir = 0;
- seen_logdir = 0;
- seen_bumppercent = 0;
- seen_bumpsize = 0;
- seen_bumpmult = 0;
- seen_bumpdays = 0;
- seen_tapetype = 0;
- seen_dumpcycle = 0;
- seen_runspercycle = 0;
- seen_maxcycle = 0;
- seen_tapecycle = 0;
- seen_disksize = 0;
- seen_netusage = 0;
- seen_inparallel = 0;
- seen_dumporder = 0;
- seen_timeout = 0;
- seen_indexdir = 0;
- seen_etimeout = 0;
- seen_dtimeout = 0;
- seen_ctimeout = 0;
- seen_tapebufs = 0;
- seen_autoflush = 0;
- seen_reserve = 0;
- seen_maxdumpsize = 0;
- seen_columnspec = 0;
- seen_amrecover_do_fsf = 0;
- seen_amrecover_check_label = 0;
- seen_amrecover_changer = 0;
- seen_taperalgo = 0;
- seen_displayunit = 0;
- seen_krb5keytab = 0;
- seen_krb5principal = 0;
- seen_label_new_tapes = 0;
-
- line_num = got_parserror = 0;
+ conf_line_num = got_parserror = 0;
allow_overwrites = 0;
token_pushed = 0;
/* create some predefined dumptypes for backwards compatability */
init_dumptype_defaults();
- dpcur.name = "NO-COMPRESS"; dpcur.seen = -1;
- dpcur.compress = COMP_NONE; dpcur.s_compress = -1;
+ dpcur.name = stralloc("NO-COMPRESS");
+ dpcur.seen = -1;
+ conf_set_compress(&dpcur.value[DUMPTYPE_COMPRESS], COMP_NONE);
save_dumptype();
init_dumptype_defaults();
- dpcur.name = "COMPRESS-FAST"; dpcur.seen = -1;
- dpcur.compress = COMP_FAST; dpcur.s_compress = -1;
+ dpcur.name = stralloc("COMPRESS-FAST");
+ dpcur.seen = -1;
+ conf_set_compress(&dpcur.value[DUMPTYPE_COMPRESS], COMP_FAST);
save_dumptype();
init_dumptype_defaults();
- dpcur.name = "COMPRESS-BEST"; dpcur.seen = -1;
- dpcur.compress = COMP_BEST; dpcur.s_compress = -1;
+ dpcur.name = stralloc("COMPRESS-BEST");
+ dpcur.seen = -1;
+ conf_set_compress(&dpcur.value[DUMPTYPE_COMPRESS], COMP_BEST);
save_dumptype();
init_dumptype_defaults();
- dpcur.name = "COMPRESS-CUST"; dpcur.seen = -1;
- dpcur.compress = COMP_CUST; dpcur.s_compress = -1;
+ dpcur.name = stralloc("COMPRESS-CUST");
+ dpcur.seen = -1;
+ conf_set_compress(&dpcur.value[DUMPTYPE_COMPRESS], COMP_CUST);
save_dumptype();
init_dumptype_defaults();
- dpcur.name = "SRVCOMPRESS"; dpcur.seen = -1;
- dpcur.compress = COMP_SERV_FAST; dpcur.s_compress = -1;
+ dpcur.name = stralloc("SRVCOMPRESS");
+ dpcur.seen = -1;
+ conf_set_compress(&dpcur.value[DUMPTYPE_COMPRESS], COMP_SERV_FAST);
save_dumptype();
init_dumptype_defaults();
- dpcur.name = "BSD-AUTH"; dpcur.seen = -1;
- amfree(dpcur.security_driver);
- dpcur.security_driver = stralloc("BSD"); dpcur.s_security_driver = -1;
+ dpcur.name = stralloc("BSD-AUTH");
+ dpcur.seen = -1;
+ conf_set_string(&dpcur.value[DUMPTYPE_SECURITY_DRIVER], "BSD");
save_dumptype();
init_dumptype_defaults();
- dpcur.name = "KRB4-AUTH"; dpcur.seen = -1;
- amfree(dpcur.security_driver);
- dpcur.security_driver = stralloc("KRB4"); dpcur.s_security_driver = -1;
+ dpcur.name = stralloc("KRB4-AUTH");
+ dpcur.seen = -1;
+ conf_set_string(&dpcur.value[DUMPTYPE_SECURITY_DRIVER], "KRB4");
save_dumptype();
init_dumptype_defaults();
- dpcur.name = "NO-RECORD"; dpcur.seen = -1;
- dpcur.record = 0; dpcur.s_record = -1;
+ dpcur.name = stralloc("NO-RECORD");
+ dpcur.seen = -1;
+ conf_set_bool(&dpcur.value[DUMPTYPE_RECORD], 0);
save_dumptype();
init_dumptype_defaults();
- dpcur.name = "NO-HOLD"; dpcur.seen = -1;
- dpcur.no_hold = 1; dpcur.s_no_hold = -1;
+ dpcur.name = stralloc("NO-HOLD");
+ dpcur.seen = -1;
+ conf_set_holding(&dpcur.value[DUMPTYPE_HOLDINGDISK], HOLD_NEVER);
save_dumptype();
init_dumptype_defaults();
- dpcur.name = "NO-FULL"; dpcur.seen = -1;
- dpcur.strategy = DS_NOFULL; dpcur.s_strategy = -1;
+ dpcur.name = stralloc("NO-FULL");
+ dpcur.seen = -1;
+ conf_set_strategy(&dpcur.value[DUMPTYPE_STRATEGY], DS_NOFULL);
save_dumptype();
}
-static void read_conffile_recursively(filename)
-char *filename;
+static void
+read_conffile_recursively(
+ char *filename)
{
- extern int errno;
-
/* Save globals used in read_confline(), elsewhere. */
- int save_line_num = line_num;
- FILE *save_conf = conf;
- char *save_confname = confname;
+ int save_line_num = conf_line_num;
+ FILE *save_conf = conf_conf;
+ char *save_confname = conf_confname;
+ int rc;
if (*filename == '/' || config_dir == NULL) {
- confname = stralloc(filename);
+ conf_confname = stralloc(filename);
} else {
- confname = stralloc2(config_dir, filename);
+ conf_confname = stralloc2(config_dir, filename);
}
- if((conf = fopen(confname, "r")) == NULL) {
- fprintf(stderr, "could not open conf file \"%s\": %s\n", confname,
+ if((conf_conf = fopen(conf_confname, "r")) == NULL) {
+ fprintf(stderr, "could not open conf file \"%s\": %s\n", conf_confname,
strerror(errno));
- amfree(confname);
+ amfree(conf_confname);
got_parserror = -1;
return;
}
- line_num = 0;
+ conf_line_num = 0;
/* read_confline() can invoke us recursively via "includefile" */
- while(read_confline());
- afclose(conf);
+ do {
+ rc = read_confline();
+ } while (rc != 0);
+ afclose(conf_conf);
- amfree(confname);
+ amfree(conf_confname);
- /* Restore globals */
- line_num = save_line_num;
- conf = save_conf;
- confname = save_confname;
+ /* Restore servers */
+ conf_line_num = save_line_num;
+ conf_conf = save_conf;
+ conf_confname = save_confname;
}
/* ------------------------ */
-keytab_t main_keytable[] = {
- { "BUMPDAYS", BUMPDAYS },
- { "BUMPMULT", BUMPMULT },
- { "BUMPSIZE", BUMPSIZE },
- { "BUMPPERCENT", BUMPPERCENT },
- { "DEFINE", DEFINE },
- { "DISKDIR", DISKDIR }, /* XXX - historical */
- { "DISKFILE", DISKFILE },
- { "DISKSIZE", DISKSIZE }, /* XXX - historical */
- { "DUMPCYCLE", DUMPCYCLE },
- { "RUNSPERCYCLE", RUNSPERCYCLE },
- { "DUMPTYPE", DUMPTYPE },
- { "DUMPUSER", DUMPUSER },
- { "PRINTER", PRINTER },
- { "HOLDINGDISK", HOLDING },
- { "INCLUDEFILE", INCLUDEFILE },
- { "INDEXDIR", INDEXDIR },
- { "INFOFILE", INFOFILE },
- { "INPARALLEL", INPARALLEL },
- { "DUMPORDER", DUMPORDER },
- { "INTERFACE", INTERFACE },
- { "LABELSTR", LABELSTR },
- { "LOGDIR", LOGDIR },
- { "LOGFILE", LOGFILE }, /* XXX - historical */
- { "MAILTO", MAILTO },
- { "MAXCYCLE", MAXCYCLE }, /* XXX - historical */
- { "MAXDUMPS", MAXDUMPS },
- { "MINCYCLE", DUMPCYCLE }, /* XXX - historical */
- { "NETUSAGE", NETUSAGE }, /* XXX - historical */
- { "ORG", ORG },
- { "RUNTAPES", RUNTAPES },
- { "TAPECYCLE", TAPECYCLE },
- { "TAPEDEV", TAPEDEV },
- { "TAPELIST", TAPELIST },
- { "TAPETYPE", TAPETYPE },
- { "TIMEOUT", TIMEOUT }, /* XXX - historical */
- { "TPCHANGER", TPCHANGER },
- { "CHANGERDEV", CHNGRDEV },
- { "CHANGERFILE", CHNGRFILE },
- { "ETIMEOUT", ETIMEOUT },
- { "DTIMEOUT", DTIMEOUT },
- { "CTIMEOUT", CTIMEOUT },
- { "TAPEBUFS", TAPEBUFS },
- { "RAWTAPEDEV", RAWTAPEDEV },
- { "AUTOFLUSH", AUTOFLUSH },
- { "RESERVE", RESERVE },
- { "MAXDUMPSIZE", MAXDUMPSIZE },
- { "COLUMNSPEC", COLUMNSPEC },
- { "AMRECOVER_DO_FSF", AMRECOVER_DO_FSF },
- { "AMRECOVER_CHECK_LABEL", AMRECOVER_CHECK_LABEL },
- { "AMRECOVER_CHANGER", AMRECOVER_CHANGER },
- { "TAPERALGO", TAPERALGO },
- { "DISPLAYUNIT", DISPLAYUNIT },
- { "KRB5KEYTAB", KRB5KEYTAB },
- { "KRB5PRINCIPAL", KRB5PRINCIPAL },
- { "LABEL_NEW_TAPES", LABEL_NEW_TAPES },
- { NULL, IDENT }
-};
-
-static int read_confline()
+static int
+read_confline(
+ void)
{
- keytable = main_keytable;
+ t_conf_var *np;
- line_num += 1;
- get_conftoken(ANY);
+ keytable = server_keytab;
+
+ conf_line_num += 1;
+ get_conftoken(CONF_ANY);
switch(tok) {
- case INCLUDEFILE:
+ case CONF_INCLUDEFILE:
{
char *fn;
+ char *cname;
- get_conftoken(STRING);
- fn = tokenval.s;
- read_conffile_recursively(fn);
- }
- break;
-
- case ORG: get_simple(&conf_org, &seen_org, STRING); break;
- case MAILTO: get_simple(&conf_mailto, &seen_mailto, STRING); break;
- case DUMPUSER: get_simple(&conf_dumpuser, &seen_dumpuser, STRING); break;
- case PRINTER: get_simple(&conf_printer, &seen_printer, STRING); break;
- case DUMPCYCLE: get_simple(&conf_dumpcycle, &seen_dumpcycle, INT);
- if(conf_dumpcycle.i < 0) {
- parserror("dumpcycle must be positive");
- }
- break;
- case RUNSPERCYCLE: get_simple(&conf_runspercycle, &seen_runspercycle, INT);
- if(conf_runspercycle.i < -1) {
- parserror("runspercycle must be >= -1");
- }
- break;
- case MAXCYCLE: get_simple(&conf_maxcycle, &seen_maxcycle, INT); break;
- case TAPECYCLE: get_simple(&conf_tapecycle, &seen_tapecycle, INT);
- if(conf_tapecycle.i < 1) {
- parserror("tapecycle must be positive");
- }
- break;
- case RUNTAPES: get_simple(&conf_runtapes, &seen_runtapes, INT);
- if(conf_runtapes.i < 0) {
- parserror("runtapes must be positive");
- }
- break;
- case TAPEDEV: get_simple(&conf_tapedev, &seen_tapedev, STRING); break;
- case RAWTAPEDEV:get_simple(&conf_rawtapedev,&seen_rawtapedev,STRING); break;
- case TPCHANGER: get_simple(&conf_tpchanger, &seen_tpchanger, STRING); break;
- case CHNGRDEV: get_simple(&conf_chngrdev, &seen_chngrdev, STRING); break;
- case CHNGRFILE: get_simple(&conf_chngrfile, &seen_chngrfile, STRING); break;
- case LABELSTR: get_simple(&conf_labelstr, &seen_labelstr, STRING); break;
- case TAPELIST: get_simple(&conf_tapelist, &seen_tapelist, STRING); break;
- case INFOFILE: get_simple(&conf_infofile, &seen_infofile, STRING); break;
- case LOGDIR: get_simple(&conf_logdir, &seen_logdir, STRING); break;
- case DISKFILE: get_simple(&conf_diskfile, &seen_diskfile, STRING); break;
- case BUMPMULT: get_simple(&conf_bumpmult, &seen_bumpmult, REAL);
- if(conf_bumpmult.r < 0.999) {
- parserror("bumpmult must be positive");
- }
- break;
- case BUMPPERCENT: get_simple(&conf_bumppercent, &seen_bumppercent, INT);
- if(conf_bumppercent.i < 0 || conf_bumppercent.i > 100) {
- parserror("bumppercent must be between 0 and 100");
- }
- break;
- case BUMPSIZE: get_simple(&conf_bumpsize, &seen_bumpsize, INT);
- if(conf_bumpsize.i < 1) {
- parserror("bumpsize must be positive");
- }
- break;
- case BUMPDAYS: get_simple(&conf_bumpdays, &seen_bumpdays, INT);
- if(conf_bumpdays.i < 1) {
- parserror("bumpdays must be positive");
- }
- break;
- case NETUSAGE: get_simple(&conf_netusage, &seen_netusage, INT);
- if(conf_netusage.i < 1) {
- parserror("netusage must be positive");
- }
- break;
- case INPARALLEL:get_simple(&conf_inparallel,&seen_inparallel,INT);
- if(conf_inparallel.i < 1 || conf_inparallel.i >MAX_DUMPERS){
- parserror(
- "inparallel must be between 1 and MAX_DUMPERS (%d)",
- MAX_DUMPERS);
- }
- break;
- case DUMPORDER: get_simple(&conf_dumporder, &seen_dumporder, STRING); break;
- case TIMEOUT: get_simple(&conf_timeout, &seen_timeout, INT); break;
- case MAXDUMPS: get_simple(&conf_maxdumps, &seen_maxdumps, INT);
- if(conf_maxdumps.i < 1) {
- parserror("maxdumps must be positive");
- }
- break;
- case TAPETYPE: get_simple(&conf_tapetype, &seen_tapetype, IDENT); break;
- case INDEXDIR: get_simple(&conf_indexdir, &seen_indexdir, STRING); break;
- case ETIMEOUT: get_simple(&conf_etimeout, &seen_etimeout, INT); break;
- case DTIMEOUT: get_simple(&conf_dtimeout, &seen_dtimeout, INT);
- if(conf_dtimeout.i < 1) {
- parserror("dtimeout must be positive");
- }
- break;
- case CTIMEOUT: get_simple(&conf_ctimeout, &seen_ctimeout, INT);
- if(conf_ctimeout.i < 1) {
- parserror("ctimeout must be positive");
- }
- break;
- case TAPEBUFS: get_simple(&conf_tapebufs, &seen_tapebufs, INT);
- if(conf_tapebufs.i < 1) {
- parserror("tapebufs must be positive");
- }
- break;
- case AUTOFLUSH: get_simple(&conf_autoflush, &seen_autoflush, BOOL); break;
- case RESERVE: get_simple(&conf_reserve, &seen_reserve, INT);
- if(conf_reserve.i < 0 || conf_reserve.i > 100) {
- parserror("reserve must be between 0 and 100");
- }
- break;
- case MAXDUMPSIZE:get_simple(&conf_maxdumpsize,&seen_maxdumpsize,AM64); break;
- case COLUMNSPEC:get_simple(&conf_columnspec,&seen_columnspec,STRING); break;
-
- case AMRECOVER_DO_FSF: get_simple(&conf_amrecover_do_fsf,&seen_amrecover_do_fsf, BOOL); break;
- case AMRECOVER_CHECK_LABEL: get_simple(&conf_amrecover_check_label,&seen_amrecover_check_label, BOOL); break;
- case AMRECOVER_CHANGER: get_simple(&conf_amrecover_changer,&seen_amrecover_changer, STRING); break;
-
- case TAPERALGO: get_taperalgo(&conf_taperalgo,&seen_taperalgo); break;
- case DISPLAYUNIT: get_simple(&conf_displayunit,&seen_displayunit, STRING);
- if(strcmp(conf_displayunit.s,"k") == 0 ||
- strcmp(conf_displayunit.s,"K") == 0) {
- conf_displayunit.s[0] = toupper(conf_displayunit.s[0]);
- unit_divisor=1;
- }
- else if(strcmp(conf_displayunit.s,"m") == 0 ||
- strcmp(conf_displayunit.s,"M") == 0) {
- conf_displayunit.s[0] = toupper(conf_displayunit.s[0]);
- unit_divisor=1024;
- }
- else if(strcmp(conf_displayunit.s,"g") == 0 ||
- strcmp(conf_displayunit.s,"G") == 0) {
- conf_displayunit.s[0] = toupper(conf_displayunit.s[0]);
- unit_divisor=1024*1024;
- }
- else if(strcmp(conf_displayunit.s,"t") == 0 ||
- strcmp(conf_displayunit.s,"T") == 0) {
- conf_displayunit.s[0] = toupper(conf_displayunit.s[0]);
- unit_divisor=1024*1024*1024;
- }
- else {
- parserror("displayunit must be k,m,g or t.");
- }
- break;
-
- /* kerberos 5 bits. only useful when kerberos 5 built in... */
- case KRB5KEYTAB: get_simple(&conf_krb5keytab, &seen_krb5keytab, STRING); break;
- case KRB5PRINCIPAL: get_simple(&conf_krb5principal,&seen_krb5principal,STRING); break;
-
- case LOGFILE: /* XXX - historical */
- /* truncate the filename part and pretend he said "logdir" */
- {
- char *p;
-
- get_simple(&conf_logdir, &seen_logdir, STRING);
-
- p = strrchr(conf_logdir.s, '/');
- if (p != (char *)0) *p = '\0';
- }
- break;
-
- case DISKDIR:
- {
- char *s;
-
- get_conftoken(STRING);
- s = tokenval.s;
-
- if(!seen_diskdir) {
- conf_diskdir.s = newstralloc(conf_diskdir.s, s);
- seen_diskdir = line_num;
+ get_conftoken(CONF_STRING);
+ fn = tokenval.v.s;
+ if (*fn == '/' || config_dir == NULL) {
+ cname = stralloc(fn);
+ } else {
+ cname = stralloc2(config_dir, fn);
}
-
- init_holdingdisk_defaults();
- hdcur.name = "default from DISKDIR";
- hdcur.seen = line_num;
- hdcur.diskdir = stralloc(s);
- hdcur.s_disk = line_num;
- hdcur.disksize = conf_disksize.i;
- hdcur.s_size = seen_disksize;
- save_holdingdisk();
- }
- break;
-
- case DISKSIZE:
- {
- int i;
-
- i = get_int();
- i = (i / DISK_BLOCK_KB) * DISK_BLOCK_KB;
-
- if(!seen_disksize) {
- conf_disksize.i = i;
- seen_disksize = line_num;
+ if ( cname != NULL && (access(cname, R_OK) == 0)) {
+ read_conffile_recursively(cname);
+ amfree(cname);
+ } else {
+ conf_parserror("cannot open %s: %s\n", fn, strerror(errno));
}
-
- if(holdingdisks != NULL)
- holdingdisks->disksize = i;
+ amfree(cname);
+
}
-
break;
- case HOLDING:
+ case CONF_HOLDING:
get_holdingdisk();
break;
- case DEFINE:
- get_conftoken(ANY);
- if(tok == DUMPTYPE) get_dumptype();
- else if(tok == TAPETYPE) get_tapetype();
- else if(tok == INTERFACE) get_interface();
- else parserror("DUMPTYPE, INTERFACE or TAPETYPE expected");
+ case CONF_DEFINE:
+ get_conftoken(CONF_ANY);
+ if(tok == CONF_DUMPTYPE) get_dumptype();
+ else if(tok == CONF_TAPETYPE) get_tapetype();
+ else if(tok == CONF_INTERFACE) get_interface();
+ else conf_parserror("DUMPTYPE, INTERFACE or TAPETYPE expected");
break;
- case LABEL_NEW_TAPES:
- get_simple(&conf_label_new_tapes, &seen_label_new_tapes, STRING);
- break;
- case NL: /* empty line */
+ case CONF_NL: /* empty line */
break;
- case END: /* end of file */
+
+ case CONF_END: /* end of file */
return 0;
+
default:
- parserror("configuration keyword expected");
+ {
+ for(np = server_var; np->token != CONF_UNKNOWN; np++)
+ if(np->token == tok) break;
+
+ if(np->token == CONF_UNKNOWN) {
+ conf_parserror("configuration keyword expected");
+ } else {
+ np->read_function(np, &server_conf[np->parm]);
+ if(np->validate)
+ np->validate(np, &server_conf[np->parm]);
+ }
+ }
}
- if(tok != NL) get_conftoken(NL);
+ if(tok != CONF_NL)
+ get_conftoken(CONF_NL);
return 1;
}
-keytab_t holding_keytable[] = {
- { "DIRECTORY", DIRECTORY },
- { "COMMENT", COMMENT },
- { "USE", USE },
- { "CHUNKSIZE", CHUNKSIZE },
- { NULL, IDENT }
+t_conf_var holding_var [] = {
+ { CONF_DIRECTORY, CONFTYPE_STRING, read_string, HOLDING_DISKDIR , NULL },
+ { CONF_COMMENT , CONFTYPE_STRING, read_string, HOLDING_COMMENT , NULL },
+ { CONF_USE , CONFTYPE_AM64 , read_am64 , HOLDING_DISKSIZE , validate_use },
+ { CONF_CHUNKSIZE, CONFTYPE_AM64 , read_am64 , HOLDING_CHUNKSIZE, validate_chunksize },
+ { CONF_UNKNOWN , CONFTYPE_INT , NULL , HOLDING_HOLDING , NULL }
};
-static void get_holdingdisk()
+static void
+get_holdingdisk(
+ void)
{
- int done;
+ char *prefix;
int save_overwrites;
- keytab_t *save_kt;
save_overwrites = allow_overwrites;
allow_overwrites = 1;
- save_kt = keytable;
- keytable = holding_keytable;
-
init_holdingdisk_defaults();
- get_conftoken(IDENT);
- hdcur.name = stralloc(tokenval.s);
- malloc_mark(hdcur.name);
- hdcur.seen = line_num;
+ get_conftoken(CONF_IDENT);
+ hdcur.name = stralloc(tokenval.v.s);
+ hdcur.seen = conf_line_num;
- get_conftoken(LBRACE);
- get_conftoken(NL);
-
- done = 0;
- do {
- line_num += 1;
- get_conftoken(ANY);
- switch(tok) {
-
- case COMMENT:
- get_simple((val_t *)&hdcur.comment, &hdcur.s_comment, STRING);
- break;
- case DIRECTORY:
- get_simple((val_t *)&hdcur.diskdir, &hdcur.s_disk, STRING);
- break;
- case USE:
- get_simple((val_t *)&hdcur.disksize, &hdcur.s_size, LONG);
- hdcur.disksize = am_floor(hdcur.disksize, DISK_BLOCK_KB);
- break;
- case CHUNKSIZE:
- get_simple((val_t *)&hdcur.chunksize, &hdcur.s_csize, LONG);
- if(hdcur.chunksize == 0) {
- hdcur.chunksize = ((INT_MAX / 1024) - (2 * DISK_BLOCK_KB));
- } else if(hdcur.chunksize < 0) {
- parserror("Negative chunksize (%ld) is no longer supported",
- hdcur.chunksize);
- }
- hdcur.chunksize = am_floor(hdcur.chunksize, DISK_BLOCK_KB);
- break;
- case RBRACE:
- done = 1;
- break;
- case NL: /* empty line */
- break;
- case END: /* end of file */
- done = 1;
- default:
- parserror("holding disk parameter expected");
- }
- if(tok != NL && tok != END) get_conftoken(NL);
- } while(!done);
+ prefix = vstralloc( "HOLDINGDISK:", hdcur.name, ":", NULL);
+ read_block(server_options, holding_var, server_keytab, hdcur.value, prefix,
+ "holding disk parameter expected", 1, NULL);
+ amfree(prefix);
+ get_conftoken(CONF_NL);
+ hdcur.disksize = holdingdisk_get_disksize(&hdcur);
save_holdingdisk();
allow_overwrites = save_overwrites;
- keytable = save_kt;
}
-static void init_holdingdisk_defaults()
+static void
+init_holdingdisk_defaults(
+ void)
{
- hdcur.comment = stralloc("");
- hdcur.diskdir = stralloc(conf_diskdir.s);
- malloc_mark(hdcur.diskdir);
- hdcur.disksize = 0;
- hdcur.chunksize = 1024*1024/**1024*/; /* 1 Gb = 1M counted in 1Kb blocks */
-
- hdcur.s_comment = 0;
- hdcur.s_disk = 0;
- hdcur.s_size = 0;
- hdcur.s_csize = 0;
+ conf_init_string(&hdcur.value[HOLDING_COMMENT] , "");
+ conf_init_string(&hdcur.value[HOLDING_DISKDIR] , "");
+ conf_init_am64(&hdcur.value[HOLDING_DISKSIZE] , (off_t)0);
+ /* 1 Gb = 1M counted in 1Kb blocks */
+ conf_init_am64(&hdcur.value[HOLDING_CHUNKSIZE], (off_t)1024*1024);
hdcur.up = (void *)0;
+ hdcur.disksize = 0LL;
}
-static void save_holdingdisk()
+static void
+save_holdingdisk(
+ void)
{
holdingdisk_t *hp;
hp = alloc(sizeof(holdingdisk_t));
- malloc_mark(hp);
*hp = hdcur;
hp->next = holdingdisks;
holdingdisks = hp;
}
-keytab_t dumptype_keytable[] = {
- { "AUTH", AUTH },
- { "BUMPDAYS", BUMPDAYS },
- { "BUMPMULT", BUMPMULT },
- { "BUMPSIZE", BUMPSIZE },
- { "BUMPPERCENT", BUMPPERCENT },
- { "COMMENT", COMMENT },
- { "COMPRATE", COMPRATE },
- { "COMPRESS", COMPRESS },
- { "ENCRYPT", ENCRYPT },
- { "SERVER_DECRYPT_OPTION", SRV_DECRYPT_OPT },
- { "CLIENT_DECRYPT_OPTION", CLNT_DECRYPT_OPT },
- { "DUMPCYCLE", DUMPCYCLE },
- { "EXCLUDE", EXCLUDE },
- { "FREQUENCY", FREQUENCY }, /* XXX - historical */
- { "HOLDINGDISK", HOLDING },
- { "IGNORE", IGNORE },
- { "INCLUDE", INCLUDE },
- { "INDEX", INDEX },
- { "KENCRYPT", KENCRYPT },
- { "MAXCYCLE", MAXCYCLE }, /* XXX - historical */
- { "MAXDUMPS", MAXDUMPS },
- { "MAXPROMOTEDAY", MAXPROMOTEDAY },
- { "OPTIONS", OPTIONS }, /* XXX - historical */
- { "PRIORITY", PRIORITY },
- { "PROGRAM", PROGRAM },
- { "RECORD", RECORD },
- { "SKIP-FULL", SKIP_FULL },
- { "SKIP-INCR", SKIP_INCR },
- { "STARTTIME", STARTTIME },
- { "STRATEGY", STRATEGY },
- { "TAPE_SPLITSIZE", TAPE_SPLITSIZE },
- { "SPLIT_DISKBUFFER", SPLIT_DISKBUFFER },
- { "FALLBACK_SPLITSIZE", FALLBACK_SPLITSIZE },
- { "ESTIMATE", ESTIMATE },
- { "SERVER_CUSTOM_COMPRESS", SRVCOMPPROG },
- { "CLIENT_CUSTOM_COMPRESS", CLNTCOMPPROG },
- { "SERVER_ENCRYPT", SRV_ENCRYPT },
- { "CLIENT_ENCRYPT", CLNT_ENCRYPT },
- { NULL, IDENT }
+t_conf_var dumptype_var [] = {
+ { CONF_COMMENT , CONFTYPE_STRING , read_string , DUMPTYPE_COMMENT , NULL },
+ { CONF_AUTH , CONFTYPE_STRING , read_string , DUMPTYPE_SECURITY_DRIVER , NULL },
+ { CONF_BUMPDAYS , CONFTYPE_INT , read_int , DUMPTYPE_BUMPDAYS , NULL },
+ { CONF_BUMPMULT , CONFTYPE_REAL , read_real , DUMPTYPE_BUMPMULT , NULL },
+ { CONF_BUMPSIZE , CONFTYPE_AM64 , read_am64 , DUMPTYPE_BUMPSIZE , NULL },
+ { CONF_BUMPPERCENT , CONFTYPE_INT , read_int , DUMPTYPE_BUMPPERCENT , NULL },
+ { CONF_COMPRATE , CONFTYPE_REAL , get_comprate, DUMPTYPE_COMPRATE , NULL },
+ { CONF_COMPRESS , CONFTYPE_INT , get_compress, DUMPTYPE_COMPRESS , NULL },
+ { CONF_ENCRYPT , CONFTYPE_INT , get_encrypt , DUMPTYPE_ENCRYPT , NULL },
+ { CONF_DUMPCYCLE , CONFTYPE_INT , read_int , DUMPTYPE_DUMPCYCLE , validate_positive0 },
+ { CONF_EXCLUDE , CONFTYPE_EXINCLUDE, get_exclude , DUMPTYPE_EXCLUDE , NULL },
+ { CONF_INCLUDE , CONFTYPE_EXINCLUDE, get_exclude , DUMPTYPE_INCLUDE , NULL },
+ { CONF_IGNORE , CONFTYPE_BOOL , read_bool , DUMPTYPE_IGNORE , NULL },
+ { CONF_HOLDING , CONFTYPE_HOLDING , get_holding , DUMPTYPE_HOLDINGDISK , NULL },
+ { CONF_INDEX , CONFTYPE_BOOL , read_bool , DUMPTYPE_INDEX , NULL },
+ { CONF_KENCRYPT , CONFTYPE_BOOL , read_bool , DUMPTYPE_KENCRYPT , NULL },
+ { CONF_MAXDUMPS , CONFTYPE_INT , read_int , DUMPTYPE_MAXDUMPS , validate_positive1 },
+ { CONF_MAXPROMOTEDAY , CONFTYPE_INT , read_int , DUMPTYPE_MAXPROMOTEDAY , validate_positive0 },
+ { CONF_PRIORITY , CONFTYPE_PRIORITY , get_priority, DUMPTYPE_PRIORITY , NULL },
+ { CONF_PROGRAM , CONFTYPE_STRING , read_string , DUMPTYPE_PROGRAM , NULL },
+ { CONF_RECORD , CONFTYPE_BOOL , read_bool , DUMPTYPE_RECORD , NULL },
+ { CONF_SKIP_FULL , CONFTYPE_BOOL , read_bool , DUMPTYPE_SKIP_FULL , NULL },
+ { CONF_SKIP_INCR , CONFTYPE_BOOL , read_bool , DUMPTYPE_SKIP_INCR , NULL },
+ { CONF_STARTTIME , CONFTYPE_TIME , read_time , DUMPTYPE_START_T , NULL },
+ { CONF_STRATEGY , CONFTYPE_INT , get_strategy, DUMPTYPE_STRATEGY , NULL },
+ { CONF_TAPE_SPLITSIZE , CONFTYPE_AM64 , read_am64 , DUMPTYPE_TAPE_SPLITSIZE , validate_positive0 },
+ { CONF_SPLIT_DISKBUFFER , CONFTYPE_STRING , read_string , DUMPTYPE_SPLIT_DISKBUFFER , NULL },
+ { CONF_ESTIMATE , CONFTYPE_INT , get_estimate, DUMPTYPE_ESTIMATE , NULL },
+ { CONF_SRV_ENCRYPT , CONFTYPE_STRING , read_string , DUMPTYPE_SRV_ENCRYPT , NULL },
+ { CONF_CLNT_ENCRYPT , CONFTYPE_STRING , read_string , DUMPTYPE_CLNT_ENCRYPT , NULL },
+ { CONF_AMANDAD_PATH , CONFTYPE_STRING , read_string , DUMPTYPE_AMANDAD_PATH , NULL },
+ { CONF_CLIENT_USERNAME , CONFTYPE_STRING , read_string , DUMPTYPE_CLIENT_USERNAME , NULL },
+ { CONF_SSH_KEYS , CONFTYPE_STRING , read_string , DUMPTYPE_SSH_KEYS , NULL },
+ { CONF_SRVCOMPPROG , CONFTYPE_STRING , read_string , DUMPTYPE_SRVCOMPPROG , NULL },
+ { CONF_CLNTCOMPPROG , CONFTYPE_STRING , read_string , DUMPTYPE_CLNTCOMPPROG , NULL },
+ { CONF_FALLBACK_SPLITSIZE, CONFTYPE_AM64 , read_am64 , DUMPTYPE_FALLBACK_SPLITSIZE, NULL },
+ { CONF_SRV_DECRYPT_OPT , CONFTYPE_STRING , read_string , DUMPTYPE_SRV_DECRYPT_OPT , NULL },
+ { CONF_CLNT_DECRYPT_OPT , CONFTYPE_STRING , read_string , DUMPTYPE_CLNT_DECRYPT_OPT , NULL },
+ { CONF_UNKNOWN , CONFTYPE_INT , NULL , DUMPTYPE_DUMPTYPE , NULL }
};
-dumptype_t *read_dumptype(name, from, fname, linenum)
- char *name;
- FILE *from;
- char *fname;
- int *linenum;
+dumptype_t *
+read_dumptype(
+ char *name,
+ FILE *from,
+ char *fname,
+ int *linenum)
{
- int done;
int save_overwrites;
- keytab_t *save_kt;
- val_t tmpval;
FILE *saved_conf = NULL;
char *saved_fname = NULL;
+ char *prefix;
if (from) {
- saved_conf = conf;
- conf = from;
+ saved_conf = conf_conf;
+ conf_conf = from;
}
if (fname) {
- saved_fname = confname;
- confname = fname;
+ saved_fname = conf_confname;
+ conf_confname = fname;
}
if (linenum)
- line_num = *linenum;
+ conf_line_num = *linenum;
save_overwrites = allow_overwrites;
allow_overwrites = 1;
- save_kt = keytable;
- keytable = dumptype_keytable;
-
init_dumptype_defaults();
-
if (name) {
dpcur.name = name;
} else {
- get_conftoken(IDENT);
- dpcur.name = stralloc(tokenval.s);
- malloc_mark(dpcur.name);
+ get_conftoken(CONF_IDENT);
+ dpcur.name = stralloc(tokenval.v.s);
}
+ dpcur.seen = conf_line_num;
- dpcur.seen = line_num;
+ prefix = vstralloc( "DUMPTYPE:", dpcur.name, ":", NULL);
+ read_block(server_options, dumptype_var, server_keytab, dpcur.value,
+ prefix, "dumptype parameter expected",
+ (name == NULL), *copy_dumptype);
+ amfree(prefix);
+ if(!name)
+ get_conftoken(CONF_NL);
- if (! name) {
- get_conftoken(LBRACE);
- get_conftoken(NL);
- }
+ /* XXX - there was a stupidity check in here for skip-incr and
+ ** skip-full. This check should probably be somewhere else. */
- done = 0;
- do {
- line_num += 1;
- get_conftoken(ANY);
- switch(tok) {
-
- case AUTH:
- get_simple((val_t *)&dpcur.security_driver,
- &dpcur.s_security_driver, STRING);
- break;
- case COMMENT:
- get_simple((val_t *)&dpcur.comment, &dpcur.s_comment, STRING);
- break;
- case COMPRATE:
- get_comprate();
- break;
- case COMPRESS:
- get_compress();
- break;
- case ENCRYPT:
- get_encrypt();
- break;
- case SRV_DECRYPT_OPT:
- get_simple((val_t *)&dpcur.srv_decrypt_opt, &dpcur.s_srv_decrypt_opt, STRING);
- break;
- case CLNT_DECRYPT_OPT:
- get_simple((val_t *)&dpcur.clnt_decrypt_opt, &dpcur.s_clnt_decrypt_opt, STRING);
- break;
- case DUMPCYCLE:
- get_simple((val_t *)&dpcur.dumpcycle, &dpcur.s_dumpcycle, INT);
- if(dpcur.dumpcycle < 0) {
- parserror("dumpcycle must be positive");
- }
- break;
- case EXCLUDE:
- get_exclude();
- break;
- case FREQUENCY:
- get_simple((val_t *)&dpcur.frequency, &dpcur.s_frequency, INT);
- break;
- case HOLDING:
- get_simple(&tmpval, &dpcur.s_no_hold, BOOL);
- dpcur.no_hold = (tmpval.i == 0);
- break;
- case IGNORE:
- get_simple(&tmpval, &dpcur.s_ignore, BOOL);
- dpcur.ignore = (tmpval.i != 0);
- break;
- case INCLUDE:
- get_include();
- break;
- case INDEX:
- get_simple(&tmpval, &dpcur.s_index, BOOL);
- dpcur.index = (tmpval.i != 0);
- break;
- case KENCRYPT:
- get_simple(&tmpval, &dpcur.s_kencrypt, BOOL);
- dpcur.kencrypt = (tmpval.i != 0);
- break;
- case MAXCYCLE:
- get_simple((val_t *)&conf_maxcycle, &dpcur.s_maxcycle, INT);
- break;
- case MAXDUMPS:
- get_simple((val_t *)&dpcur.maxdumps, &dpcur.s_maxdumps, INT);
- if(dpcur.maxdumps < 1) {
- parserror("maxdumps must be positive");
- }
- break;
- case MAXPROMOTEDAY:
- get_simple((val_t *)&dpcur.maxpromoteday, &dpcur.s_maxpromoteday, INT);
- if(dpcur.maxpromoteday < 0) {
- parserror("dpcur.maxpromoteday must be >= 0");
- }
- break;
- case BUMPPERCENT:
- get_simple((val_t *)&dpcur.bumppercent, &dpcur.s_bumppercent, INT);
- if(dpcur.bumppercent < 0 || dpcur.bumppercent > 100) {
- parserror("bumppercent must be between 0 and 100");
- }
- break;
- case BUMPSIZE:
- get_simple((val_t *)&dpcur.bumpsize, &dpcur.s_bumpsize, INT);
- if(dpcur.bumpsize < 1) {
- parserror("bumpsize must be positive");
- }
- break;
- case BUMPDAYS:
- get_simple((val_t *)&dpcur.bumpdays, &dpcur.s_bumpdays, INT);
- if(dpcur.bumpdays < 1) {
- parserror("bumpdays must be positive");
- }
- break;
- case BUMPMULT:
- get_simple((val_t *)&dpcur.bumpmult, &dpcur.s_bumpmult, REAL);
- if(dpcur.bumpmult < 0.999) {
- parserror("bumpmult must be positive (%f)",dpcur.bumpmult);
- }
- break;
- case OPTIONS:
- get_dumpopts();
- break;
- case PRIORITY:
- get_priority();
- break;
- case PROGRAM:
- get_simple((val_t *)&dpcur.program, &dpcur.s_program, STRING);
- break;
- case RECORD:
- get_simple(&tmpval, &dpcur.s_record, BOOL);
- dpcur.record = (tmpval.i != 0);
- break;
- case SKIP_FULL:
- get_simple(&tmpval, &dpcur.s_skip_full, BOOL);
- dpcur.skip_full = (tmpval.i != 0);
- break;
- case SKIP_INCR:
- get_simple(&tmpval, &dpcur.s_skip_incr, BOOL);
- dpcur.skip_incr = (tmpval.i != 0);
- break;
- case STARTTIME:
- get_simple((val_t *)&dpcur.start_t, &dpcur.s_start_t, TIME);
- break;
- case STRATEGY:
- get_strategy();
- break;
- case ESTIMATE:
- get_estimate();
- break;
- case IDENT:
- copy_dumptype();
- break;
- case TAPE_SPLITSIZE:
- get_simple((val_t *)&dpcur.tape_splitsize, &dpcur.s_tape_splitsize, INT);
- if(dpcur.tape_splitsize < 0) {
- parserror("tape_splitsize must be >= 0");
- }
- break;
- case SPLIT_DISKBUFFER:
- get_simple((val_t *)&dpcur.split_diskbuffer, &dpcur.s_split_diskbuffer, STRING);
- break;
- case FALLBACK_SPLITSIZE:
- get_simple((val_t *)&dpcur.fallback_splitsize, &dpcur.s_fallback_splitsize, INT);
- if(dpcur.fallback_splitsize < 0) {
- parserror("fallback_splitsize must be >= 0");
- }
- break;
- case SRVCOMPPROG:
- get_simple((val_t *)&dpcur.srvcompprog, &dpcur.s_srvcompprog, STRING);
- break;
- case CLNTCOMPPROG:
- get_simple((val_t *)&dpcur.clntcompprog, &dpcur.s_clntcompprog, STRING);
- break;
- case SRV_ENCRYPT:
- get_simple((val_t *)&dpcur.srv_encrypt, &dpcur.s_srv_encrypt, STRING);
- break;
- case CLNT_ENCRYPT:
- get_simple((val_t *)&dpcur.clnt_encrypt, &dpcur.s_clnt_encrypt, STRING);
- break;
- case RBRACE:
- done = 1;
- break;
- case NL: /* empty line */
- break;
- case END: /* end of file */
- done = 1;
- default:
- parserror("dump type parameter expected");
- }
- if(tok != NL && tok != END &&
- /* When a name is specified, we shouldn't consume the NL
- after the RBRACE. */
- (tok != RBRACE || name == 0))
- get_conftoken(NL);
- } while(!done);
-
- /* XXX - there was a stupidity check in here for skip-incr and
- ** skip-full. This check should probably be somewhere else. */
-
- save_dumptype();
+ save_dumptype();
allow_overwrites = save_overwrites;
- keytable = save_kt;
if (linenum)
- *linenum = line_num;
+ *linenum = conf_line_num;
if (fname)
- confname = saved_fname;
+ conf_confname = saved_fname;
if (from)
- conf = saved_conf;
+ conf_conf = saved_conf;
return lookup_dumptype(dpcur.name);
}
-static void get_dumptype()
+static void
+get_dumptype(void)
{
read_dumptype(NULL, NULL, NULL, NULL);
}
-static void init_dumptype_defaults()
-{
- dpcur.comment = stralloc("");
- dpcur.program = stralloc("DUMP");
- dpcur.srvcompprog = stralloc("");
- dpcur.clntcompprog = stralloc("");
- dpcur.srv_encrypt = stralloc("");
- dpcur.clnt_encrypt = stralloc("");
- dpcur.exclude_file = NULL;
- dpcur.exclude_list = NULL;
- dpcur.include_file = NULL;
- dpcur.include_list = NULL;
- dpcur.priority = 1;
- dpcur.dumpcycle = conf_dumpcycle.i;
- dpcur.maxcycle = conf_maxcycle.i;
- dpcur.frequency = 1;
- dpcur.maxdumps = conf_maxdumps.i;
- dpcur.maxpromoteday = 10000;
- dpcur.bumppercent = conf_bumppercent.i;
- dpcur.bumpsize = conf_bumpsize.i;
- dpcur.bumpdays = conf_bumpdays.i;
- dpcur.bumpmult = conf_bumpmult.r;
- dpcur.start_t = 0;
- dpcur.security_driver = stralloc("BSD");
-
- /* options */
- dpcur.record = 1;
- dpcur.strategy = DS_STANDARD;
- dpcur.estimate = ES_CLIENT;
- dpcur.compress = COMP_FAST;
- dpcur.encrypt = ENCRYPT_NONE;
- dpcur.srv_decrypt_opt = stralloc("-d");
- dpcur.clnt_decrypt_opt = stralloc("-d");
- dpcur.comprate[0] = dpcur.comprate[1] = 0.50;
- dpcur.skip_incr = dpcur.skip_full = 0;
- dpcur.no_hold = 0;
- dpcur.kencrypt = 0;
- dpcur.ignore = 0;
- dpcur.index = 0;
- dpcur.tape_splitsize = 0;
- dpcur.split_diskbuffer = NULL;
- dpcur.fallback_splitsize = 10 * 1024;
-
- dpcur.s_comment = 0;
- dpcur.s_program = 0;
- dpcur.s_srvcompprog = 0;
- dpcur.s_clntcompprog = 0;
- dpcur.s_clnt_encrypt= 0;
- dpcur.s_srv_encrypt= 0;
-
- dpcur.s_exclude_file = 0;
- dpcur.s_exclude_list = 0;
- dpcur.s_include_file = 0;
- dpcur.s_include_list = 0;
- dpcur.s_priority = 0;
- dpcur.s_dumpcycle = 0;
- dpcur.s_maxcycle = 0;
- dpcur.s_frequency = 0;
- dpcur.s_maxdumps = 0;
- dpcur.s_maxpromoteday = 0;
- dpcur.s_bumppercent = 0;
- dpcur.s_bumpsize = 0;
- dpcur.s_bumpdays = 0;
- dpcur.s_bumpmult = 0;
- dpcur.s_start_t = 0;
- dpcur.s_security_driver = 0;
- dpcur.s_record = 0;
- dpcur.s_strategy = 0;
- dpcur.s_estimate = 0;
- dpcur.s_compress = 0;
- dpcur.s_encrypt = 0;
- dpcur.s_srv_decrypt_opt = 0;
- dpcur.s_clnt_decrypt_opt = 0;
- dpcur.s_comprate = 0;
- dpcur.s_skip_incr = 0;
- dpcur.s_skip_full = 0;
- dpcur.s_no_hold = 0;
- dpcur.s_kencrypt = 0;
- dpcur.s_ignore = 0;
- dpcur.s_index = 0;
- dpcur.s_tape_splitsize = 0;
- dpcur.s_split_diskbuffer = 0;
- dpcur.s_fallback_splitsize = 0;
-}
-
-static void save_dumptype()
+static void
+init_dumptype_defaults(void)
{
- dumptype_t *dp;
+ dpcur.name = NULL;
+ conf_init_string (&dpcur.value[DUMPTYPE_COMMENT] , "");
+ conf_init_string (&dpcur.value[DUMPTYPE_PROGRAM] , "DUMP");
+ conf_init_string (&dpcur.value[DUMPTYPE_SRVCOMPPROG] , "");
+ conf_init_string (&dpcur.value[DUMPTYPE_CLNTCOMPPROG] , "");
+ conf_init_string (&dpcur.value[DUMPTYPE_SRV_ENCRYPT] , "");
+ conf_init_string (&dpcur.value[DUMPTYPE_CLNT_ENCRYPT] , "");
+ conf_init_string (&dpcur.value[DUMPTYPE_AMANDAD_PATH] , "X");
+ conf_init_string (&dpcur.value[DUMPTYPE_CLIENT_USERNAME] , "X");
+ conf_init_string (&dpcur.value[DUMPTYPE_SSH_KEYS] , "X");
+ conf_init_string (&dpcur.value[DUMPTYPE_SECURITY_DRIVER] , "BSD");
+ conf_init_exinclude(&dpcur.value[DUMPTYPE_EXCLUDE]);
+ conf_init_exinclude(&dpcur.value[DUMPTYPE_INCLUDE]);
+ conf_init_priority (&dpcur.value[DUMPTYPE_PRIORITY] , 1);
+ conf_init_int (&dpcur.value[DUMPTYPE_DUMPCYCLE] , server_conf[CNF_DUMPCYCLE].v.i);
+ conf_init_int (&dpcur.value[DUMPTYPE_MAXDUMPS] , server_conf[CNF_MAXDUMPS].v.i);
+ conf_init_int (&dpcur.value[DUMPTYPE_MAXPROMOTEDAY] , 10000);
+ conf_init_int (&dpcur.value[DUMPTYPE_BUMPPERCENT] , server_conf[CNF_BUMPPERCENT].v.i);
+ conf_init_am64 (&dpcur.value[DUMPTYPE_BUMPSIZE] , server_conf[CNF_BUMPSIZE].v.am64);
+ conf_init_int (&dpcur.value[DUMPTYPE_BUMPDAYS] , server_conf[CNF_BUMPDAYS].v.i);
+ conf_init_real (&dpcur.value[DUMPTYPE_BUMPMULT] , server_conf[CNF_BUMPMULT].v.r);
+ conf_init_time (&dpcur.value[DUMPTYPE_START_T] , (time_t)0);
+ conf_init_strategy (&dpcur.value[DUMPTYPE_STRATEGY] , DS_STANDARD);
+ conf_init_estimate (&dpcur.value[DUMPTYPE_ESTIMATE] , ES_CLIENT);
+ conf_init_compress (&dpcur.value[DUMPTYPE_COMPRESS] , COMP_FAST);
+ conf_init_encrypt (&dpcur.value[DUMPTYPE_ENCRYPT] , ENCRYPT_NONE);
+ conf_init_string (&dpcur.value[DUMPTYPE_SRV_DECRYPT_OPT] , "-d");
+ conf_init_string (&dpcur.value[DUMPTYPE_CLNT_DECRYPT_OPT] , "-d");
+ conf_init_rate (&dpcur.value[DUMPTYPE_COMPRATE] , 0.50, 0.50);
+ conf_init_am64 (&dpcur.value[DUMPTYPE_TAPE_SPLITSIZE] , (off_t)0);
+ conf_init_am64 (&dpcur.value[DUMPTYPE_FALLBACK_SPLITSIZE], (off_t)10 * 1024);
+ conf_init_string (&dpcur.value[DUMPTYPE_SPLIT_DISKBUFFER] , NULL);
+ conf_init_bool (&dpcur.value[DUMPTYPE_RECORD] , 1);
+ conf_init_bool (&dpcur.value[DUMPTYPE_SKIP_INCR] , 0);
+ conf_init_bool (&dpcur.value[DUMPTYPE_SKIP_FULL] , 0);
+ conf_init_holding (&dpcur.value[DUMPTYPE_HOLDINGDISK] , HOLD_AUTO);
+ conf_init_bool (&dpcur.value[DUMPTYPE_KENCRYPT] , 0);
+ conf_init_bool (&dpcur.value[DUMPTYPE_IGNORE] , 0);
+ conf_init_bool (&dpcur.value[DUMPTYPE_INDEX] , 1);
+}
+
+static void
+save_dumptype(void)
+{
+ dumptype_t *dp, *dp1;;
dp = lookup_dumptype(dpcur.name);
if(dp != (dumptype_t *)0) {
- parserror("dumptype %s already defined on line %d", dp->name, dp->seen);
+ conf_parserror("dumptype %s already defined on line %d", dp->name, dp->seen);
return;
}
dp = alloc(sizeof(dumptype_t));
- malloc_mark(dp);
*dp = dpcur;
- dp->next = dumplist;
- dumplist = dp;
+ dp->next = NULL;
+ /* add at end of list */
+ if(!dumplist)
+ dumplist = dp;
+ else {
+ dp1 = dumplist;
+ while (dp1->next != NULL) {
+ dp1 = dp1->next;
+ }
+ dp1->next = dp;
+ }
}
-static void copy_dumptype()
+static void
+copy_dumptype(void)
{
dumptype_t *dt;
+ int i;
- dt = lookup_dumptype(tokenval.s);
+ dt = lookup_dumptype(tokenval.v.s);
if(dt == NULL) {
- parserror("dump type parameter expected");
+ conf_parserror("dumptype parameter expected");
return;
}
-#define dtcopy(v,s) if(dt->s) { dpcur.v = dt->v; dpcur.s = dt->s; }
-
- if(dt->s_comment) {
- dpcur.comment = newstralloc(dpcur.comment, dt->comment);
- dpcur.s_comment = dt->s_comment;
- }
- if(dt->s_program) {
- dpcur.program = newstralloc(dpcur.program, dt->program);
- dpcur.s_program = dt->s_program;
- }
- if(dt->s_security_driver) {
- dpcur.security_driver = newstralloc(dpcur.security_driver,
- dt->security_driver);
- dpcur.s_security_driver = dt->s_security_driver;
- }
- if(dt->s_srvcompprog) {
- dpcur.srvcompprog = newstralloc(dpcur.srvcompprog, dt->srvcompprog);
- dpcur.s_srvcompprog = dt->s_srvcompprog;
- }
- if(dt->s_clntcompprog) {
- dpcur.clntcompprog = newstralloc(dpcur.clntcompprog, dt->clntcompprog);
- dpcur.s_clntcompprog = dt->s_clntcompprog;
- }
- if(dt->s_srv_encrypt) {
- dpcur.srv_encrypt = newstralloc(dpcur.srv_encrypt, dt->srv_encrypt);
- dpcur.s_srv_encrypt = dt->s_srv_encrypt;
- }
- if(dt->s_clnt_encrypt) {
- dpcur.clnt_encrypt = newstralloc(dpcur.clnt_encrypt, dt->clnt_encrypt);
- dpcur.s_clnt_encrypt = dt->s_clnt_encrypt;
- }
- if(dt->s_srv_decrypt_opt) {
- dpcur.srv_decrypt_opt = newstralloc(dpcur.srv_decrypt_opt, dt->srv_decrypt_opt);
- dpcur.s_srv_decrypt_opt = dt->s_srv_decrypt_opt;
- }
- if(dt->s_clnt_decrypt_opt) {
- dpcur.clnt_decrypt_opt = newstralloc(dpcur.clnt_decrypt_opt, dt->clnt_decrypt_opt);
- dpcur.s_clnt_decrypt_opt = dt->s_clnt_decrypt_opt;
- }
-
- if(dt->s_exclude_file) {
- dpcur.exclude_file = duplicate_sl(dt->exclude_file);
- dpcur.s_exclude_file = dt->s_exclude_file;
- }
- if(dt->s_exclude_list) {
- dpcur.exclude_list = duplicate_sl(dt->exclude_list);
- dpcur.s_exclude_list = dt->s_exclude_list;
- }
- if(dt->s_include_file) {
- dpcur.include_file = duplicate_sl(dt->include_file);
- dpcur.s_include_file = dt->s_include_file;
- }
- if(dt->s_include_list) {
- dpcur.include_list = duplicate_sl(dt->include_list);
- dpcur.s_include_list = dt->s_include_list;
- }
- dtcopy(priority, s_priority);
- dtcopy(dumpcycle, s_dumpcycle);
- dtcopy(maxcycle, s_maxcycle);
- dtcopy(frequency, s_frequency);
- dtcopy(maxdumps, s_maxdumps);
- dtcopy(maxpromoteday, s_maxpromoteday);
- dtcopy(bumppercent, s_bumppercent);
- dtcopy(bumpsize, s_bumpsize);
- dtcopy(bumpdays, s_bumpdays);
- dtcopy(bumpmult, s_bumpmult);
- dtcopy(start_t, s_start_t);
- dtcopy(record, s_record);
- dtcopy(strategy, s_strategy);
- dtcopy(estimate, s_estimate);
- dtcopy(compress, s_compress);
- dtcopy(encrypt, s_encrypt);
- dtcopy(comprate[0], s_comprate);
- dtcopy(comprate[1], s_comprate);
- dtcopy(skip_incr, s_skip_incr);
- dtcopy(skip_full, s_skip_full);
- dtcopy(no_hold, s_no_hold);
- dtcopy(kencrypt, s_kencrypt);
- dtcopy(ignore, s_ignore);
- dtcopy(index, s_index);
- dtcopy(tape_splitsize, s_tape_splitsize);
- dtcopy(split_diskbuffer, s_split_diskbuffer);
- dtcopy(fallback_splitsize, s_fallback_splitsize);
-}
-
-keytab_t tapetype_keytable[] = {
- { "COMMENT", COMMENT },
- { "LBL-TEMPL", LBL_TEMPL },
- { "BLOCKSIZE", BLOCKSIZE },
- { "FILE-PAD", FILE_PAD },
- { "FILEMARK", FILEMARK },
- { "LENGTH", LENGTH },
- { "SPEED", SPEED },
- { NULL, IDENT }
+ for(i=0; i < DUMPTYPE_DUMPTYPE; i++) {
+ if(dt->value[i].seen) {
+ free_val_t(&dpcur.value[i]);
+ copy_val_t(&dpcur.value[i], &dt->value[i]);
+ }
+ }
+}
+
+t_conf_var tapetype_var [] = {
+ { CONF_COMMENT , CONFTYPE_STRING, read_string, TAPETYPE_COMMENT , NULL },
+ { CONF_LBL_TEMPL, CONFTYPE_STRING, read_string, TAPETYPE_LBL_TEMPL, NULL },
+ { CONF_BLOCKSIZE, CONFTYPE_SIZE , read_size , TAPETYPE_BLOCKSIZE, validate_blocksize },
+ { CONF_LENGTH , CONFTYPE_AM64 , read_am64 , TAPETYPE_LENGTH , validate_positive0 },
+ { CONF_FILEMARK , CONFTYPE_AM64 , read_am64 , TAPETYPE_FILEMARK , NULL },
+ { CONF_SPEED , CONFTYPE_INT , read_int , TAPETYPE_SPEED , validate_positive0 },
+ { CONF_FILE_PAD , CONFTYPE_BOOL , read_bool , TAPETYPE_FILE_PAD , NULL },
+ { CONF_UNKNOWN , CONFTYPE_INT , NULL , TAPETYPE_TAPETYPE , NULL }
};
-static void get_tapetype()
+static void
+get_tapetype(void)
{
- int done;
int save_overwrites;
- val_t value;
-
- keytab_t *save_kt;
+ char *prefix;
save_overwrites = allow_overwrites;
allow_overwrites = 1;
- save_kt = keytable;
- keytable = tapetype_keytable;
-
init_tapetype_defaults();
- get_conftoken(IDENT);
- tpcur.name = stralloc(tokenval.s);
- malloc_mark(tpcur.name);
- tpcur.seen = line_num;
-
- get_conftoken(LBRACE);
- get_conftoken(NL);
-
- done = 0;
- do {
- line_num += 1;
- get_conftoken(ANY);
- switch(tok) {
+ get_conftoken(CONF_IDENT);
+ tpcur.name = stralloc(tokenval.v.s);
+ tpcur.seen = conf_line_num;
- case RBRACE:
- done = 1;
- break;
- case COMMENT:
- get_simple((val_t *)&tpcur.comment, &tpcur.s_comment, STRING);
- break;
- case LBL_TEMPL:
- get_simple((val_t *)&tpcur.lbl_templ, &tpcur.s_lbl_templ, STRING);
- break;
- case BLOCKSIZE:
- get_simple((val_t *)&tpcur.blocksize, &tpcur.s_blocksize, LONG);
- if(tpcur.blocksize < DISK_BLOCK_KB) {
- parserror("Tape blocksize must be at least %d KBytes",
- DISK_BLOCK_KB);
- } else if(tpcur.blocksize > MAX_TAPE_BLOCK_KB) {
- parserror("Tape blocksize must not be larger than %d KBytes",
- MAX_TAPE_BLOCK_KB);
- }
- break;
- case FILE_PAD:
- get_simple(&value, &tpcur.s_file_pad, BOOL);
- tpcur.file_pad = (value.i != 0);
- break;
- case LENGTH:
- get_simple(&value, &tpcur.s_length, LONG);
- if(value.l < 0) {
- parserror("Tape length must be positive");
- }
- else {
- tpcur.length = (unsigned long) value.l;
- }
- break;
- case FILEMARK:
- get_simple(&value, &tpcur.s_filemark, LONG);
- if(value.l < 0) {
- parserror("Tape file mark size must be positive");
- }
- else {
- tpcur.filemark = (unsigned long) value.l;
- }
- break;
- case SPEED:
- get_simple((val_t *)&tpcur.speed, &tpcur.s_speed, INT);
- if(tpcur.speed < 0) {
- parserror("Speed must be positive");
- }
- break;
- case IDENT:
- copy_tapetype();
- break;
- case NL: /* empty line */
- break;
- case END: /* end of file */
- done = 1;
- default:
- parserror("tape type parameter expected");
- }
- if(tok != NL && tok != END) get_conftoken(NL);
- } while(!done);
+ prefix = vstralloc( "TAPETYPE:", tpcur.name, ":", NULL);
+ read_block(server_options, tapetype_var, server_keytab, tpcur.value,
+ prefix, "tapetype parameter expected", 1, ©_tapetype);
+ amfree(prefix);
+ get_conftoken(CONF_NL);
save_tapetype();
allow_overwrites = save_overwrites;
- keytable = save_kt;
}
-static void init_tapetype_defaults()
+static void
+init_tapetype_defaults(void)
{
- tpcur.comment = stralloc("");
- tpcur.lbl_templ = stralloc("");
- tpcur.blocksize = (DISK_BLOCK_KB);
- tpcur.file_pad = 1;
- tpcur.length = 2000 * 1024;
- tpcur.filemark = 1000;
- tpcur.speed = 200;
-
- tpcur.s_comment = 0;
- tpcur.s_lbl_templ = 0;
- tpcur.s_blocksize = 0;
- tpcur.s_file_pad = 0;
- tpcur.s_length = 0;
- tpcur.s_filemark = 0;
- tpcur.s_speed = 0;
+ conf_init_string(&tpcur.value[TAPETYPE_COMMENT] , "");
+ conf_init_string(&tpcur.value[TAPETYPE_LBL_TEMPL], "");
+ conf_init_size (&tpcur.value[TAPETYPE_BLOCKSIZE], DISK_BLOCK_KB);
+ conf_init_am64 (&tpcur.value[TAPETYPE_LENGTH] , (off_t)2000 * 1024);
+ conf_init_am64 (&tpcur.value[TAPETYPE_FILEMARK] , (off_t)1000);
+ conf_init_int (&tpcur.value[TAPETYPE_SPEED] , 200);
+ conf_init_bool (&tpcur.value[TAPETYPE_FILE_PAD] , 1);
}
-static void save_tapetype()
+static void
+save_tapetype(void)
{
- tapetype_t *tp;
+ tapetype_t *tp, *tp1;
tp = lookup_tapetype(tpcur.name);
if(tp != (tapetype_t *)0) {
amfree(tpcur.name);
- parserror("tapetype %s already defined on line %d", tp->name, tp->seen);
+ conf_parserror("tapetype %s already defined on line %d", tp->name, tp->seen);
return;
}
tp = alloc(sizeof(tapetype_t));
- malloc_mark(tp);
*tp = tpcur;
- tp->next = tapelist;
- tapelist = tp;
+ /* add at end of list */
+ if(!tapelist)
+ tapelist = tp;
+ else {
+ tp1 = tapelist;
+ while (tp1->next != NULL) {
+ tp1 = tp1->next;
+ }
+ tp1->next = tp;
+ }
}
-static void copy_tapetype()
+static void
+copy_tapetype(void)
{
tapetype_t *tp;
+ int i;
- tp = lookup_tapetype(tokenval.s);
+ tp = lookup_tapetype(tokenval.v.s);
if(tp == NULL) {
- parserror("tape type parameter expected");
+ conf_parserror("tape type parameter expected");
return;
}
-#define ttcopy(v,s) if(tp->s) { tpcur.v = tp->v; tpcur.s = tp->s; }
-
- if(tp->s_comment) {
- tpcur.comment = newstralloc(tpcur.comment, tp->comment);
- tpcur.s_comment = tp->s_comment;
- }
- if(tp->s_lbl_templ) {
- tpcur.lbl_templ = newstralloc(tpcur.lbl_templ, tp->lbl_templ);
- tpcur.s_lbl_templ = tp->s_lbl_templ;
+ for(i=0; i < TAPETYPE_TAPETYPE; i++) {
+ if(tp->value[i].seen) {
+ free_val_t(&tpcur.value[i]);
+ copy_val_t(&tpcur.value[i], &tp->value[i]);
+ }
}
- ttcopy(blocksize, s_blocksize);
- ttcopy(file_pad, s_file_pad);
- ttcopy(length, s_length);
- ttcopy(filemark, s_filemark);
- ttcopy(speed, s_speed);
}
-keytab_t interface_keytable[] = {
- { "COMMENT", COMMENT },
- { "USE", USE },
- { NULL, IDENT }
+t_conf_var interface_var [] = {
+ { CONF_COMMENT, CONFTYPE_STRING, read_string, INTER_COMMENT , NULL },
+ { CONF_USE , CONFTYPE_INT , read_int , INTER_MAXUSAGE, validate_positive1 },
+ { CONF_UNKNOWN, CONFTYPE_INT , NULL , INTER_INTER , NULL }
};
-static void get_interface()
+static void
+get_interface(void)
{
- int done;
int save_overwrites;
- keytab_t *save_kt;
+ char *prefix;
save_overwrites = allow_overwrites;
allow_overwrites = 1;
- save_kt = keytable;
- keytable = interface_keytable;
-
init_interface_defaults();
- get_conftoken(IDENT);
- ifcur.name = stralloc(tokenval.s);
- malloc_mark(ifcur.name);
- ifcur.seen = line_num;
+ get_conftoken(CONF_IDENT);
+ ifcur.name = stralloc(tokenval.v.s);
+ ifcur.seen = conf_line_num;
- get_conftoken(LBRACE);
- get_conftoken(NL);
-
- done = 0;
- do {
- line_num += 1;
- get_conftoken(ANY);
- switch(tok) {
-
- case RBRACE:
- done = 1;
- break;
- case COMMENT:
- get_simple((val_t *)&ifcur.comment, &ifcur.s_comment, STRING);
- break;
- case USE:
- get_simple((val_t *)&ifcur.maxusage, &ifcur.s_maxusage, INT);
- if(ifcur.maxusage <1) {
- parserror("use must bbe positive");
- }
- break;
- case IDENT:
- copy_interface();
- break;
- case NL: /* empty line */
- break;
- case END: /* end of file */
- done = 1;
- default:
- parserror("interface parameter expected");
- }
- if(tok != NL && tok != END) get_conftoken(NL);
- } while(!done);
+ prefix = vstralloc( "INTERFACE:", ifcur.name, ":", NULL);
+ read_block(server_options, interface_var, server_keytab, ifcur.value,
+ prefix, "interface parameter expected", 1, ©_interface);
+ amfree(prefix);
+ get_conftoken(CONF_NL);
save_interface();
allow_overwrites = save_overwrites;
- keytable = save_kt;
return;
}
-static void init_interface_defaults()
+static void
+init_interface_defaults(void)
{
- ifcur.comment = stralloc("");
- ifcur.maxusage = 300;
-
- ifcur.s_comment = 0;
- ifcur.s_maxusage = 0;
+ conf_init_string(&ifcur.value[INTER_COMMENT] , "");
+ conf_init_int (&ifcur.value[INTER_MAXUSAGE], 300);
ifcur.curusage = 0;
}
-static void save_interface()
+static void
+save_interface(void)
{
- interface_t *ip;
+ interface_t *ip, *ip1;
ip = lookup_interface(ifcur.name);
if(ip != (interface_t *)0) {
- parserror("interface %s already defined on line %d", ip->name, ip->seen);
+ conf_parserror("interface %s already defined on line %d", ip->name,
+ ip->seen);
return;
}
ip = alloc(sizeof(interface_t));
- malloc_mark(ip);
*ip = ifcur;
- ip->next = interface_list;
- interface_list = ip;
+ /* add at end of list */
+ if(!interface_list) {
+ interface_list = ip;
+ } else {
+ ip1 = interface_list;
+ while (ip1->next != NULL) {
+ ip1 = ip1->next;
+ }
+ ip1->next = ip;
+ }
}
-static void copy_interface()
+static void
+copy_interface(void)
{
+/*
+ int i;
+ t_xxx *np;
+ keytab_t *kt;
+
+ val_t val;
+*/
interface_t *ip;
+ int i;
- ip = lookup_interface(tokenval.s);
+ ip = lookup_interface(tokenval.v.s);
if(ip == NULL) {
- parserror("interface parameter expected");
+ conf_parserror("interface parameter expected");
return;
}
-#define ifcopy(v,s) if(ip->s) { ifcur.v = ip->v; ifcur.s = ip->s; }
-
- if(ip->s_comment) {
- ifcur.comment = newstralloc(ifcur.comment, ip->comment);
- ifcur.s_comment = ip->s_comment;
- }
- ifcopy(maxusage, s_maxusage);
-}
-
-keytab_t dumpopts_keytable[] = {
- { "COMPRESS", COMPRESS },
- { "ENCRYPT", ENCRYPT },
- { "INDEX", INDEX },
- { "EXCLUDE-FILE", EXCLUDE_FILE },
- { "EXCLUDE-LIST", EXCLUDE_LIST },
- { "KENCRYPT", KENCRYPT },
- { "SKIP-FULL", SKIP_FULL },
- { "SKIP-INCR", SKIP_INCR },
- { NULL, IDENT }
-};
-
-static void get_dumpopts() /* XXX - for historical compatability */
-{
- int done;
- keytab_t *save_kt;
-
- save_kt = keytable;
- keytable = dumpopts_keytable;
-
- done = 0;
- do {
- get_conftoken(ANY);
- switch(tok) {
- case COMPRESS: ckseen(&dpcur.s_compress); dpcur.compress = COMP_FAST; break;
- case ENCRYPT: ckseen(&dpcur.s_encrypt); dpcur.encrypt = ENCRYPT_NONE; break;
- case EXCLUDE_FILE:
- ckseen(&dpcur.s_exclude_file);
- get_conftoken(STRING);
- dpcur.exclude_file = append_sl(dpcur.exclude_file, tokenval.s);
- break;
- case EXCLUDE_LIST:
- ckseen(&dpcur.s_exclude_list);
- get_conftoken(STRING);
- dpcur.exclude_list = append_sl(dpcur.exclude_list, tokenval.s);
- break;
- case KENCRYPT: ckseen(&dpcur.s_kencrypt); dpcur.kencrypt = 1; break;
- case SKIP_INCR: ckseen(&dpcur.s_skip_incr); dpcur.skip_incr= 1; break;
- case SKIP_FULL: ckseen(&dpcur.s_skip_full); dpcur.skip_full= 1; break;
- case INDEX: ckseen(&dpcur.s_index); dpcur.index = 1; break;
- case IDENT:
- copy_dumptype();
- break;
- case NL: done = 1; break;
- case COMMA: break;
- case END:
- done = 1;
- default:
- parserror("dump option expected");
+ for(i=0; i < INTER_INTER; i++) {
+ if(ip->value[i].seen) {
+ free_val_t(&ifcur.value[i]);
+ copy_val_t(&ifcur.value[i], &ip->value[i]);
}
- } while(!done);
-
- keytable = save_kt;
+ }
}
-static void get_comprate()
+static void
+get_comprate(
+ t_conf_var *np,
+ val_t *val)
{
- val_t var;
-
- get_simple(&var, &dpcur.s_comprate, REAL);
- dpcur.comprate[0] = dpcur.comprate[1] = var.r;
- if(dpcur.comprate[0] < 0) {
- parserror("full compression rate must be >= 0");
+ np = np;
+ get_conftoken(CONF_REAL);
+ val->v.rate[0] = tokenval.v.r;
+ val->v.rate[1] = tokenval.v.r;
+ val->seen = tokenval.seen;
+ if(tokenval.v.r < 0) {
+ conf_parserror("full compression rate must be >= 0");
}
- get_conftoken(ANY);
+ get_conftoken(CONF_ANY);
switch(tok) {
- case NL:
+ case CONF_NL:
+ return;
+
+ case CONF_END:
return;
- case COMMA:
+
+ case CONF_COMMA:
break;
+
default:
unget_conftoken();
}
- get_conftoken(REAL);
- dpcur.comprate[1] = tokenval.r;
- if(dpcur.comprate[1] < 0) {
- parserror("incremental compression rate must be >= 0");
+ get_conftoken(CONF_REAL);
+ val->v.rate[1] = tokenval.v.r;
+ if(tokenval.v.r < 0) {
+ conf_parserror("incremental compression rate must be >= 0");
}
}
-keytab_t compress_keytable[] = {
- { "BEST", BEST },
- { "CLIENT", CLIENT },
- { "FAST", FAST },
- { "NONE", NONE },
- { "SERVER", SERVER },
- { "CUSTOM", CUSTOM },
- { NULL, IDENT }
-};
-
-static void get_compress()
+static void
+get_compress(
+ t_conf_var *np,
+ val_t *val)
{
- keytab_t *save_kt;
int serv, clie, none, fast, best, custom;
int done;
- int comp;
-
- save_kt = keytable;
- keytable = compress_keytable;
+ comp_t comp;
- ckseen(&dpcur.s_compress);
+ np = np;
+ ckseen(&val->seen);
serv = clie = none = fast = best = custom = 0;
done = 0;
do {
- get_conftoken(ANY);
+ get_conftoken(CONF_ANY);
switch(tok) {
- case NONE: none = 1; break;
- case FAST: fast = 1; break;
- case BEST: best = 1; break;
- case CLIENT: clie = 1; break;
- case SERVER: serv = 1; break;
- case CUSTOM: custom=1; break;
- case NL: done = 1; break;
+ case CONF_NONE: none = 1; break;
+ case CONF_FAST: fast = 1; break;
+ case CONF_BEST: best = 1; break;
+ case CONF_CLIENT: clie = 1; break;
+ case CONF_SERVER: serv = 1; break;
+ case CONF_CUSTOM: custom=1; break;
+ case CONF_NL: done = 1; break;
+ case CONF_END: done = 1; break;
default:
done = 1;
serv = clie = 1; /* force an error */
if(!none && !fast && !best && custom) comp = COMP_SERV_CUST;
}
- if(comp == -1) {
- parserror("NONE, CLIENT FAST, CLIENT BEST, CLIENT CUSTOM, SERVER FAST, SERVER BEST or SERVER CUSTOM expected");
+ if((int)comp == -1) {
+ conf_parserror("NONE, CLIENT FAST, CLIENT BEST, CLIENT CUSTOM, SERVER FAST, SERVER BEST or SERVER CUSTOM expected");
comp = COMP_NONE;
}
- dpcur.compress = comp;
-
- keytable = save_kt;
+ val->v.i = (int)comp;
}
-keytab_t encrypt_keytable[] = {
- { "NONE", NONE },
- { "CLIENT", CLIENT },
- { "SERVER", SERVER },
- { NULL, IDENT }
-};
-
-static void get_encrypt()
+static void
+get_encrypt(
+ t_conf_var *np,
+ val_t *val)
{
- keytab_t *save_kt;
- int encrypt;
-
- save_kt = keytable;
- keytable = encrypt_keytable;
+ encrypt_t encrypt;
- ckseen(&dpcur.s_encrypt);
+ np = np;
+ ckseen(&val->seen);
- get_conftoken(ANY);
+ get_conftoken(CONF_ANY);
switch(tok) {
- case NONE:
+ case CONF_NONE:
encrypt = ENCRYPT_NONE;
break;
- case CLIENT:
+
+ case CONF_CLIENT:
encrypt = ENCRYPT_CUST;
break;
- case SERVER:
+
+ case CONF_SERVER:
encrypt = ENCRYPT_SERV_CUST;
break;
+
default:
- parserror("NONE, CLIENT or SERVER expected");
+ conf_parserror("NONE, CLIENT or SERVER expected");
encrypt = ENCRYPT_NONE;
+ break;
}
- dpcur.encrypt = encrypt;
- keytable = save_kt;
+ val->v.i = (int)encrypt;
}
-keytab_t taperalgo_keytable[] = {
- { "FIRST", FIRST },
- { "FIRSTFIT", FIRSTFIT },
- { "LARGEST", LARGEST },
- { "LARGESTFIT", LARGESTFIT },
- { "SMALLEST", SMALLEST },
- { "LAST", LAST },
- { NULL, IDENT }
-};
-
-static void get_taperalgo(c_taperalgo, s_taperalgo)
-val_t *c_taperalgo;
-int *s_taperalgo;
+static void
+get_holding(
+ t_conf_var *np,
+ val_t *val)
{
- keytab_t *save_kt;
+ dump_holdingdisk_t holding;
- save_kt = keytable;
- keytable = taperalgo_keytable;
+ np = np;
+ ckseen(&val->seen);
- ckseen(s_taperalgo);
+ get_conftoken(CONF_ANY);
+ switch(tok) {
+ case CONF_NEVER:
+ holding = HOLD_NEVER;
+ break;
- get_conftoken(ANY);
+ case CONF_AUTO:
+ holding = HOLD_AUTO;
+ break;
+
+ case CONF_REQUIRED:
+ holding = HOLD_REQUIRED;
+ break;
+
+ default: /* can be a BOOLEAN */
+ unget_conftoken();
+ holding = (dump_holdingdisk_t)get_bool();
+ if (holding == 0)
+ holding = HOLD_NEVER;
+ else if (holding == 1 || holding == 2)
+ holding = HOLD_AUTO;
+ else
+ conf_parserror("NEVER, AUTO or REQUIRED expected");
+ break;
+ }
+
+ val->v.i = (int)holding;
+}
+
+static void
+get_taperalgo(
+ t_conf_var *np,
+ val_t *val)
+{
+ np = np;
+ ckseen(&val->seen);
+
+ get_conftoken(CONF_ANY);
switch(tok) {
- case FIRST: c_taperalgo->i = ALGO_FIRST; break;
- case FIRSTFIT: c_taperalgo->i = ALGO_FIRSTFIT; break;
- case LARGEST: c_taperalgo->i = ALGO_LARGEST; break;
- case LARGESTFIT: c_taperalgo->i = ALGO_LARGESTFIT; break;
- case SMALLEST: c_taperalgo->i = ALGO_SMALLEST; break;
- case LAST: c_taperalgo->i = ALGO_LAST; break;
+ case CONF_FIRST: val->v.i = ALGO_FIRST; break;
+ case CONF_FIRSTFIT: val->v.i = ALGO_FIRSTFIT; break;
+ case CONF_LARGEST: val->v.i = ALGO_LARGEST; break;
+ case CONF_LARGESTFIT: val->v.i = ALGO_LARGESTFIT; break;
+ case CONF_SMALLEST: val->v.i = ALGO_SMALLEST; break;
+ case CONF_LAST: val->v.i = ALGO_LAST; break;
default:
- parserror("FIRST, FIRSTFIT, LARGEST, LARGESTFIT, SMALLEST or LAST expected");
+ conf_parserror("FIRST, FIRSTFIT, LARGEST, LARGESTFIT, SMALLEST or LAST expected");
}
-
- keytable = save_kt;
}
-keytab_t priority_keytable[] = {
- { "HIGH", HIGH },
- { "LOW", LOW },
- { "MEDIUM", MEDIUM },
- { NULL, IDENT }
-};
-
-static void get_priority()
+static void
+get_priority(
+ t_conf_var *np,
+ val_t *val)
{
int pri;
- keytab_t *save_kt;
-
- save_kt = keytable;
- keytable = priority_keytable;
- ckseen(&dpcur.s_priority);
+ np = np;
+ ckseen(&val->seen);
- get_conftoken(ANY);
+ get_conftoken(CONF_ANY);
switch(tok) {
- case LOW: pri = 0; break;
- case MEDIUM: pri = 1; break;
- case HIGH: pri = 2; break;
- case INT: pri = tokenval.i; break;
+ case CONF_LOW: pri = 0; break;
+ case CONF_MEDIUM: pri = 1; break;
+ case CONF_HIGH: pri = 2; break;
+ case CONF_INT: pri = tokenval.v.i; break;
default:
- parserror("LOW, MEDIUM, HIGH or integer expected");
+ conf_parserror("LOW, MEDIUM, HIGH or integer expected");
pri = 0;
}
- dpcur.priority = pri;
-
- keytable = save_kt;
+ val->v.i = pri;
}
-keytab_t strategy_keytable[] = {
- { "HANOI", HANOI },
- { "NOFULL", NOFULL },
- { "NOINC", NOINC },
- { "SKIP", SKIP },
- { "STANDARD", STANDARD },
- { "INCRONLY", INCRONLY },
- { NULL, IDENT }
-};
-
-static void get_strategy()
+static void
+get_strategy(
+ t_conf_var *np,
+ val_t *val)
{
int strat;
- keytab_t *save_kt;
-
- save_kt = keytable;
- keytable = strategy_keytable;
- ckseen(&dpcur.s_strategy);
+ np = np;
+ ckseen(&val->seen);
- get_conftoken(ANY);
+ get_conftoken(CONF_ANY);
switch(tok) {
- case SKIP:
+ case CONF_SKIP:
strat = DS_SKIP;
break;
- case STANDARD:
+ case CONF_STANDARD:
strat = DS_STANDARD;
break;
- case NOFULL:
+ case CONF_NOFULL:
strat = DS_NOFULL;
break;
- case NOINC:
+ case CONF_NOINC:
strat = DS_NOINC;
break;
- case HANOI:
+ case CONF_HANOI:
strat = DS_HANOI;
break;
- case INCRONLY:
+ case CONF_INCRONLY:
strat = DS_INCRONLY;
break;
default:
- parserror("STANDARD or NOFULL expected");
+ conf_parserror("STANDARD or NOFULL expected");
strat = DS_STANDARD;
}
- dpcur.strategy = strat;
-
- keytable = save_kt;
+ val->v.i = strat;
}
-keytab_t estimate_keytable[] = {
- { "CLIENT", CLIENT },
- { "SERVER", SERVER },
- { "CALCSIZE", CALCSIZE }
-};
-
-static void get_estimate()
+static void
+get_estimate(
+ t_conf_var *np,
+ val_t *val)
{
int estime;
- keytab_t *save_kt;
- save_kt = keytable;
- keytable = estimate_keytable;
+ np = np;
+ ckseen(&val->seen);
- ckseen(&dpcur.s_estimate);
-
- get_conftoken(ANY);
+ get_conftoken(CONF_ANY);
switch(tok) {
- case CLIENT:
+ case CONF_CLIENT:
estime = ES_CLIENT;
break;
- case SERVER:
+ case CONF_SERVER:
estime = ES_SERVER;
break;
- case CALCSIZE:
+ case CONF_CALCSIZE:
estime = ES_CALCSIZE;
break;
default:
- parserror("CLIENT, SERVER or CALCSIZE expected");
+ conf_parserror("CLIENT, SERVER or CALCSIZE expected");
estime = ES_CLIENT;
}
- dpcur.estimate = estime;
-
- keytable = save_kt;
+ val->v.i = estime;
}
-keytab_t exclude_keytable[] = {
- { "LIST", LIST },
- { "FILE", EFILE },
- { "APPEND", APPEND },
- { "OPTIONAL", OPTIONAL },
- { NULL, IDENT }
-};
-
-static void get_exclude()
+static void
+get_exclude(
+ t_conf_var *np,
+ val_t *val)
{
- int list, got_one = 0;
- keytab_t *save_kt;
+ int file, got_one = 0;
sl_t *exclude;
int optional = 0;
- int append = 0;
- save_kt = keytable;
- keytable = exclude_keytable;
-
- get_conftoken(ANY);
- if(tok == LIST) {
- list = 1;
- exclude = dpcur.exclude_list;
- ckseen(&dpcur.s_exclude_list);
- get_conftoken(ANY);
+ np = np;
+ get_conftoken(CONF_ANY);
+ if(tok == CONF_LIST) {
+ file = 0;
+ get_conftoken(CONF_ANY);
}
else {
- list = 0;
- exclude = dpcur.exclude_file;
- ckseen(&dpcur.s_exclude_file);
- if(tok == EFILE) get_conftoken(ANY);
+ file = 1;
+ if(tok == CONF_EFILE) get_conftoken(CONF_ANY);
}
+ val->v.exinclude.type = file;
+ exclude = val->v.exinclude.sl;
+ ckseen(&val->seen);
- if(tok == OPTIONAL) {
- get_conftoken(ANY);
+ if(tok == CONF_OPTIONAL) {
+ get_conftoken(CONF_ANY);
optional = 1;
}
- if(tok == APPEND) {
- get_conftoken(ANY);
- append = 1;
+ if(tok == CONF_APPEND) {
+ get_conftoken(CONF_ANY);
}
else {
free_sl(exclude);
exclude = NULL;
- append = 0;
}
- while(tok == STRING) {
- exclude = append_sl(exclude, tokenval.s);
+ while(tok == CONF_STRING) {
+ exclude = append_sl(exclude, tokenval.v.s);
got_one = 1;
- get_conftoken(ANY);
+ get_conftoken(CONF_ANY);
}
unget_conftoken();
if(got_one == 0) { free_sl(exclude); exclude = NULL; }
- if(list == 0)
- dpcur.exclude_file = exclude;
- else {
- dpcur.exclude_list = exclude;
- if(!append || optional)
- dpcur.exclude_optional = optional;
- }
-
- keytable = save_kt;
+ val->v.exinclude.sl = exclude;
+ val->v.exinclude.optional = optional;
}
-
-static void get_include()
+/*
+static void get_include(np, val)
+ t_conf_var *np;
+ val_t *val;
{
int list, got_one = 0;
- keytab_t *save_kt;
sl_t *include;
int optional = 0;
int append = 0;
- save_kt = keytable;
- keytable = exclude_keytable;
-
- get_conftoken(ANY);
- if(tok == LIST) {
+ get_conftoken(CONF_ANY);
+ if(tok == CONF_LIST) {
list = 1;
- include = dpcur.include_list;
- ckseen(&dpcur.s_include_list);
- get_conftoken(ANY);
+ include = dpcur.value[DUMPTYPE_INCLUDE_LIST].v.sl;
+ ckseen(&dpcur.value[DUMPTYPE_INCLUDE_LIST].seen);
+ get_conftoken(CONF_ANY);
}
else {
list = 0;
- include = dpcur.include_file;
- ckseen(&dpcur.s_include_file);
- if(tok == EFILE) get_conftoken(ANY);
+ include = dpcur.value[DUMPTYPE_INCLUDE_FILE].v.sl;
+ ckseen(&dpcur.value[DUMPTYPE_INCLUDE_FILE].seen);
+ if(tok == CONF_EFILE) get_conftoken(CONF_ANY);
}
- if(tok == OPTIONAL) {
- get_conftoken(ANY);
+ if(tok == CONF_OPTIONAL) {
+ get_conftoken(CONF_ANY);
optional = 1;
}
- if(tok == APPEND) {
- get_conftoken(ANY);
+ if(tok == CONF_APPEND) {
+ get_conftoken(CONF_ANY);
append = 1;
}
else {
append = 0;
}
- while(tok == STRING) {
- include = append_sl(include, tokenval.s);
+ while(tok == CONF_STRING) {
+ include = append_sl(include, tokenval.v.s);
got_one = 1;
- get_conftoken(ANY);
+ get_conftoken(CONF_ANY);
}
unget_conftoken();
if(got_one == 0) { free_sl(include); include = NULL; }
if(list == 0)
- dpcur.include_file = include;
+ dpcur.value[DUMPTYPE_INCLUDE_FILE].v.sl = include;
else {
- dpcur.include_list = include;
+ dpcur.value[DUMPTYPE_INCLUDE_LIST].v.sl = include;
if(!append || optional)
- dpcur.include_optional = optional;
+ dpcur.value[DUMPTYPE_INCLUDE_OPTIONAL].v.i = optional;
}
-
- keytable = save_kt;
}
-
+*/
/* ------------------------ */
-
-static void get_simple(var, seen, type)
-val_t *var;
-int *seen;
-tok_t type;
-{
- ckseen(seen);
-
- switch(type) {
- case STRING:
- case IDENT:
- get_conftoken(type);
- var->s = newstralloc(var->s, tokenval.s);
- malloc_mark(var->s);
- break;
- case INT:
- var->i = get_int();
- break;
- case LONG:
- var->l = get_long();
- break;
- case AM64:
- var->am64 = get_am64_t();
- break;
- case BOOL:
- var->i = get_bool();
- break;
- case REAL:
- get_conftoken(REAL);
- var->r = tokenval.r;
- break;
- case TIME:
- var->i = get_time();
- break;
- default:
- error("error [unknown get_simple type: %d]", type);
- /* NOTREACHED */
- }
- return;
-}
-
-static int get_time()
-{
- time_t st = start_time.r.tv_sec;
- struct tm *stm;
- int hhmm;
-
- get_conftoken(INT);
- hhmm = tokenval.i;
-
- stm = localtime(&st);
- st -= stm->tm_sec + 60 * (stm->tm_min + 60 * stm->tm_hour);
- st += ((hhmm/100*60) + hhmm%100)*60;
-
- if (st-start_time.r.tv_sec<-43200)
- st += 86400;
-
- return st;
-}
-
-keytab_t numb_keytable[] = {
- { "B", MULT1 },
- { "BPS", MULT1 },
- { "BYTE", MULT1 },
- { "BYTES", MULT1 },
- { "DAY", MULT1 },
- { "DAYS", MULT1 },
- { "INF", INFINITY },
- { "K", MULT1K },
- { "KB", MULT1K },
- { "KBPS", MULT1K },
- { "KBYTE", MULT1K },
- { "KBYTES", MULT1K },
- { "KILOBYTE", MULT1K },
- { "KILOBYTES", MULT1K },
- { "KPS", MULT1K },
- { "M", MULT1M },
- { "MB", MULT1M },
- { "MBPS", MULT1M },
- { "MBYTE", MULT1M },
- { "MBYTES", MULT1M },
- { "MEG", MULT1M },
- { "MEGABYTE", MULT1M },
- { "MEGABYTES", MULT1M },
- { "G", MULT1G },
- { "GB", MULT1G },
- { "GBPS", MULT1G },
- { "GBYTE", MULT1G },
- { "GBYTES", MULT1G },
- { "GIG", MULT1G },
- { "GIGABYTE", MULT1G },
- { "GIGABYTES", MULT1G },
- { "MPS", MULT1M },
- { "TAPE", MULT1 },
- { "TAPES", MULT1 },
- { "WEEK", MULT7 },
- { "WEEKS", MULT7 },
- { NULL, IDENT }
-};
-
-static int get_int()
-{
- int val;
- keytab_t *save_kt;
-
- save_kt = keytable;
- keytable = numb_keytable;
-
- get_conftoken(ANY);
-
- switch(tok) {
- case AM64:
- if(abs(tokenval.am64) > INT_MAX)
- parserror("value too large");
- val = (int) tokenval.am64;
- break;
- case INFINITY:
- val = (int) BIGINT;
- break;
- default:
- parserror("an integer expected");
- val = 0;
- }
-
- /* get multiplier, if any */
- get_conftoken(ANY);
-
- switch(tok) {
- case NL: /* multiply by one */
- case MULT1:
- case MULT1K:
- break;
- case MULT7:
- if(abs(val) > INT_MAX/7)
- parserror("value too large");
- val *= 7;
- break;
- case MULT1M:
- if(abs(val) > INT_MAX/1024)
- parserror("value too large");
- val *= 1024;
- break;
- case MULT1G:
- if(abs(val) > INT_MAX/(1024*1024))
- parserror("value too large");
- val *= 1024*1024;
- break;
- default: /* it was not a multiplier */
- unget_conftoken();
- }
-
- keytable = save_kt;
-
- return val;
-}
-
-static long get_long()
-{
- long val;
- keytab_t *save_kt;
-
- save_kt = keytable;
- keytable = numb_keytable;
-
- get_conftoken(ANY);
-
- switch(tok) {
- case AM64:
- if(tokenval.am64 > LONG_MAX || tokenval.am64 < LONG_MIN)
- parserror("value too large");
- val = (long) tokenval.am64;
- break;
- case INFINITY:
- val = (long) LONG_MAX;
- break;
- default:
- parserror("a long expected");
- val = 0;
- }
-
- /* get multiplier, if any */
- get_conftoken(ANY);
-
- switch(tok) {
- case NL: /* multiply by one */
- case MULT1:
- case MULT1K:
- break;
- case MULT7:
- if(val > LONG_MAX/7 || val < LONG_MIN/7)
- parserror("value too large");
- val *= 7;
- break;
- case MULT1M:
- if(val > LONG_MAX/1024 || val < LONG_MIN/7)
- parserror("value too large");
- val *= 1024;
- break;
- case MULT1G:
- if(val > LONG_MAX/(1024*1024) || val < LONG_MIN/(1024*1024))
- parserror("value too large");
- val *= 1024*1024;
- break;
- default: /* it was not a multiplier */
- unget_conftoken();
- }
-
- keytable = save_kt;
-
- return val;
-}
-
-static am64_t get_am64_t()
-{
- am64_t val;
- keytab_t *save_kt;
-
- save_kt = keytable;
- keytable = numb_keytable;
-
- get_conftoken(ANY);
-
- switch(tok) {
- case AM64:
- val = tokenval.am64;
- break;
- case INFINITY:
- val = AM64_MAX;
- break;
- default:
- parserror("a am64 expected %d", tok);
- val = 0;
- }
-
- /* get multiplier, if any */
- get_conftoken(ANY);
-
- switch(tok) {
- case NL: /* multiply by one */
- case MULT1:
- case MULT1K:
- break;
- case MULT7:
- if(val > AM64_MAX/7 || val < AM64_MIN/7)
- parserror("value too large");
- val *= 7;
- break;
- case MULT1M:
- if(val > AM64_MAX/1024 || val < AM64_MIN/1024)
- parserror("value too large");
- val *= 1024;
- break;
- case MULT1G:
- if(val > AM64_MAX/(1024*1024) || val < AM64_MIN/(1024*1024))
- parserror("value too large");
- val *= 1024*1024;
- break;
- default: /* it was not a multiplier */
- unget_conftoken();
- }
-
- keytable = save_kt;
-
- return val;
-}
-
-keytab_t bool_keytable[] = {
- { "Y", ATRUE },
- { "YES", ATRUE },
- { "T", ATRUE },
- { "TRUE", ATRUE },
- { "ON", ATRUE },
- { "N", AFALSE },
- { "NO", AFALSE },
- { "F", AFALSE },
- { "FALSE", AFALSE },
- { "OFF", AFALSE },
- { NULL, IDENT }
-};
-
-static int get_bool()
-{
- int val;
- keytab_t *save_kt;
-
- save_kt = keytable;
- keytable = bool_keytable;
-
- get_conftoken(ANY);
-
- switch(tok) {
- case INT:
- val = tokenval.i ? 1 : 0;
- break;
- case ATRUE:
- val = 1;
- break;
- case AFALSE:
- val = 0;
- break;
- case NL:
- default:
- unget_conftoken();
- val = 2; /* no argument - most likely TRUE */
- }
-
- keytable = save_kt;
-
- return val;
-}
-
-static void ckseen(seen)
-int *seen;
-{
- if(*seen && !allow_overwrites) {
- parserror("duplicate parameter, prev def on line %d", *seen);
- }
- *seen = line_num;
-}
-
-printf_arglist_function(static void parserror, char *, format)
-{
- va_list argp;
-
- /* print error message */
-
- fprintf(stderr, "\"%s\", line %d: ", confname, line_num);
- arglist_start(argp, format);
- vfprintf(stderr, format, argp);
- arglist_end(argp);
- fputc('\n', stderr);
-
- got_parserror = 1;
-}
-
-static tok_t lookup_keyword(str)
-char *str;
-{
- keytab_t *kwp;
-
- /* switch to binary search if performance warrants */
-
- for(kwp = keytable; kwp->keyword != NULL; kwp++) {
- if(strcmp(kwp->keyword, str) == 0) break;
- }
- return kwp->token;
-}
-
-static char tkbuf[4096];
-
-/* push the last token back (can only unget ANY tokens) */
-static void unget_conftoken()
-{
- token_pushed = 1;
- pushed_tok = tok;
- tok = UNKNOWN;
- return;
-}
-
-static void get_conftoken(exp)
-tok_t exp;
-{
- int ch, d;
- am64_t am64;
- char *buf;
- int token_overflow;
-
- if(token_pushed) {
- token_pushed = 0;
- tok = pushed_tok;
-
- /* If it looked like a key word before then look it
- ** up again in the current keyword table. */
- switch(tok) {
- case LONG: case AM64:
- case INT: case REAL: case STRING:
- case LBRACE: case RBRACE: case COMMA:
- case NL: case END: case UNKNOWN:
- break;
- default:
- if(exp == IDENT) tok = IDENT;
- else tok = lookup_keyword(tokenval.s);
- }
- }
- else {
- ch = getc(conf);
-
- while(ch != EOF && ch != '\n' && isspace(ch)) ch = getc(conf);
- if(ch == '#') { /* comment - eat everything but eol/eof */
- while((ch = getc(conf)) != EOF && ch != '\n') {}
- }
-
- if(isalpha(ch)) { /* identifier */
- buf = tkbuf;
- token_overflow = 0;
- do {
- if(islower(ch)) ch = toupper(ch);
- if(buf < tkbuf+sizeof(tkbuf)-1) {
- *buf++ = ch;
- } else {
- *buf = '\0';
- if(!token_overflow) {
- parserror("token too long: %.20s...", tkbuf);
- }
- token_overflow = 1;
- }
- ch = getc(conf);
- } while(isalnum(ch) || ch == '_' || ch == '-');
-
- ungetc(ch, conf);
- *buf = '\0';
-
- tokenval.s = tkbuf;
-
- if(token_overflow) tok = UNKNOWN;
- else if(exp == IDENT) tok = IDENT;
- else tok = lookup_keyword(tokenval.s);
- }
- else if(isdigit(ch)) { /* integer */
- int sign;
- if (1) {
- sign = 1;
- } else {
- negative_number: /* look for goto negative_number below */
- sign = -1;
- }
- tokenval.am64 = 0;
- do {
- tokenval.am64 = tokenval.am64 * 10 + (ch - '0');
- ch = getc(conf);
- } while(isdigit(ch));
- if(ch != '.') {
- if(exp == INT) {
- tok = INT;
- tokenval.i *= sign;
- }
- else if(exp == LONG) {
- tok = LONG;
- tokenval.l *= sign;
- }
- else if(exp != REAL) {
- tok = AM64;
- tokenval.am64 *= sign;
- } else {
- /* automatically convert to real when expected */
- am64 = tokenval.am64;
- tokenval.r = sign * (double) am64;
- tok = REAL;
- }
- }
- else {
- /* got a real number, not an int */
- am64 = tokenval.am64;
- tokenval.r = sign * (double) am64;
- am64=0; d=1;
- ch = getc(conf);
- while(isdigit(ch)) {
- am64 = am64 * 10 + (ch - '0');
- d = d * 10;
- ch = getc(conf);
- }
- tokenval.r += sign * ((double)am64)/d;
- tok = REAL;
- }
- ungetc(ch,conf);
- }
- else switch(ch) {
-
- case '"': /* string */
- buf = tkbuf;
- token_overflow = 0;
- ch = getc(conf);
- while(ch != '"' && ch != '\n' && ch != EOF) {
- if(buf < tkbuf+sizeof(tkbuf)-1) {
- *buf++ = ch;
- } else {
- *buf = '\0';
- if(!token_overflow) {
- parserror("string too long: %.20s...", tkbuf);
- }
- token_overflow = 1;
- }
- ch = getc(conf);
- }
- if(ch != '"') {
- parserror("missing end quote");
- ungetc(ch, conf);
- }
- *buf = '\0';
- tokenval.s = tkbuf;
- if(token_overflow) tok = UNKNOWN;
- else tok = STRING;
- break;
-
- case '-':
- ch = getc(conf);
- if (isdigit(ch))
- goto negative_number;
- else {
- ungetc(ch, conf);
- tok = UNKNOWN;
- }
- break;
- case ',': tok = COMMA; break;
- case '{': tok = LBRACE; break;
- case '}': tok = RBRACE; break;
- case '\n': tok = NL; break;
- case EOF: tok = END; break;
- default: tok = UNKNOWN;
- }
- }
-
- if(exp != ANY && tok != exp) {
- char *str;
- keytab_t *kwp;
-
- switch(exp) {
- case LBRACE: str = "\"{\""; break;
- case RBRACE: str = "\"}\""; break;
- case COMMA: str = "\",\""; break;
-
- case NL: str = "end of line"; break;
- case END: str = "end of file"; break;
- case INT: str = "an integer"; break;
- case REAL: str = "a real number"; break;
- case STRING: str = "a quoted string"; break;
- case IDENT: str = "an identifier"; break;
- default:
- for(kwp = keytable; kwp->keyword != NULL; kwp++)
- if(exp == kwp->token) break;
- if(kwp->keyword == NULL) str = "token not";
- else str = kwp->keyword;
- }
- parserror("%s expected", str);
- tok = exp;
- if(tok == INT) tokenval.i = 0;
- else tokenval.s = "";
- }
-
- return;
-}
-
-int ColumnDataCount()
+int
+ColumnDataCount(void )
{
- return sizeof(ColumnData) / sizeof(ColumnData[0]);
+ return (int)(SIZEOF(ColumnData) / SIZEOF(ColumnData[0]));
}
/* conversion from string to table index
*/
int
-StringToColumn(s)
- char *s;
+StringToColumn(
+ char *s)
{
int cn;
}
char
-LastChar(s)
- char *s;
+LastChar(
+ char *s)
{
return s[strlen(s)-1];
}
int
-SetColumDataFromString(ci, s, errstr)
- ColumnInfo* ci;
- char *s;
- char **errstr;
+SetColumDataFromString(
+ ColumnInfo* ci,
+ char *s,
+ char **errstr)
{
+#ifdef TEST
+ char *myname= "SetColumDataFromString";
+#endif
+ ci = ci;
+
/* Convert from a Columspec string to our internal format
* of columspec. The purpose is to provide this string
* as configuration paramter in the amanda.conf file or
* output as it was all the time.
* ElB, 1999-02-24.
*/
-#ifdef TEST
- char *myname= "SetColumDataFromString";
-#endif
while (s && *s) {
int Space, Width;
return -1;
}
ColumnData[cn].Width= Width;
- ColumnData[cn].PrefixSpace= Space;
+ ColumnData[cn].PrefixSpace = Space;
if (LastChar(ColumnData[cn].Format) == 's') {
if (Width < 0)
ColumnData[cn].MaxWidth= 1;
ColumnData[cn].Precision= Width;
}
else if (Width < ColumnData[cn].Precision)
- ColumnData[cn].Precision= Width;
+ ColumnData[cn].Precision = Width;
s= strchr(eon+1, ',');
if (s != NULL)
s++;
}
-char *taperalgo2str(taperalgo)
-int taperalgo;
-{
- if(taperalgo == ALGO_FIRST) return "FIRST";
- if(taperalgo == ALGO_FIRSTFIT) return "FIRSTFIT";
- if(taperalgo == ALGO_LARGEST) return "LARGEST";
- if(taperalgo == ALGO_LARGESTFIT) return "LARGESTFIT";
- if(taperalgo == ALGO_SMALLEST) return "SMALLEST";
- if(taperalgo == ALGO_LAST) return "LAST";
- return "UNKNOWN";
-}
-
-long int getconf_unit_divisor()
+long int
+getconf_unit_divisor(void)
{
return unit_divisor;
}
/* ------------------------ */
-#ifdef TEST
-
void
-dump_configuration(filename)
- char *filename;
+dump_configuration(
+ char *filename)
{
tapetype_t *tp;
dumptype_t *dp;
interface_t *ip;
holdingdisk_t *hp;
- time_t st;
- struct tm *stm;
+ int i;
+ t_conf_var *np;
+ keytab_t *kt;
+ char *prefix;
printf("AMANDA CONFIGURATION FROM FILE \"%s\":\n\n", filename);
- printf("conf_org = \"%s\"\n", getconf_str(CNF_ORG));
- printf("conf_mailto = \"%s\"\n", getconf_str(CNF_MAILTO));
- printf("conf_dumpuser = \"%s\"\n", getconf_str(CNF_DUMPUSER));
- printf("conf_printer = \"%s\"\n", getconf_str(CNF_PRINTER));
- printf("conf_tapedev = \"%s\"\n", getconf_str(CNF_TAPEDEV));
- printf("conf_rawtapedev = \"%s\"\n", getconf_str(CNF_RAWTAPEDEV));
- printf("conf_tpchanger = \"%s\"\n", getconf_str(CNF_TPCHANGER));
- printf("conf_chngrdev = \"%s\"\n", getconf_str(CNF_CHNGRDEV));
- printf("conf_chngrfile = \"%s\"\n", getconf_str(CNF_CHNGRFILE));
- printf("conf_labelstr = \"%s\"\n", getconf_str(CNF_LABELSTR));
- printf("conf_tapelist = \"%s\"\n", getconf_str(CNF_TAPELIST));
- printf("conf_infofile = \"%s\"\n", getconf_str(CNF_INFOFILE));
- printf("conf_logdir = \"%s\"\n", getconf_str(CNF_LOGDIR));
- printf("conf_diskfile = \"%s\"\n", getconf_str(CNF_DISKFILE));
- printf("conf_tapetype = \"%s\"\n", getconf_str(CNF_TAPETYPE));
-
- printf("conf_dumpcycle = %d\n", getconf_int(CNF_DUMPCYCLE));
- printf("conf_runspercycle = %d\n", getconf_int(CNF_RUNSPERCYCLE));
- printf("conf_runtapes = %d\n", getconf_int(CNF_RUNTAPES));
- printf("conf_tapecycle = %d\n", getconf_int(CNF_TAPECYCLE));
- printf("conf_bumppercent = %d\n", getconf_int(CNF_BUMPPERCENT));
- printf("conf_bumpsize = %d\n", getconf_int(CNF_BUMPSIZE));
- printf("conf_bumpdays = %d\n", getconf_int(CNF_BUMPDAYS));
- printf("conf_bumpmult = %f\n", getconf_real(CNF_BUMPMULT));
- printf("conf_netusage = %d\n", getconf_int(CNF_NETUSAGE));
- printf("conf_inparallel = %d\n", getconf_int(CNF_INPARALLEL));
- printf("conf_dumporder = \"%s\"\n", getconf_str(CNF_DUMPORDER));
- /*printf("conf_timeout = %d\n", getconf_int(CNF_TIMEOUT));*/
- printf("conf_maxdumps = %d\n", getconf_int(CNF_MAXDUMPS));
- printf("conf_etimeout = %d\n", getconf_int(CNF_ETIMEOUT));
- printf("conf_dtimeout = %d\n", getconf_int(CNF_DTIMEOUT));
- printf("conf_ctimeout = %d\n", getconf_int(CNF_CTIMEOUT));
- printf("conf_tapebufs = %d\n", getconf_int(CNF_TAPEBUFS));
- printf("conf_autoflush = %d\n", getconf_int(CNF_AUTOFLUSH));
- printf("conf_reserve = %d\n", getconf_int(CNF_RESERVE));
- printf("conf_maxdumpsize = " AM64_FMT "\n", getconf_am64(CNF_MAXDUMPSIZE));
- printf("conf_amrecover_do_fsf = %d\n", getconf_int(CNF_AMRECOVER_DO_FSF));
- printf("conf_amrecover_check_label = %d\n", getconf_int(CNF_AMRECOVER_CHECK_LABEL));
- printf("conf_amrecover_changer = \"%s\"\n", getconf_str(CNF_AMRECOVER_CHANGER));
- printf("conf_taperalgo = %s\n", taperalgo2str(getconf_int(CNF_TAPERALGO)));
- printf("conf_displayunit = %s\n", getconf_str(CNF_DISPLAYUNIT));
-
- /*printf("conf_diskdir = \"%s\"\n", getconf_str(CNF_DISKDIR));*/
- /*printf("conf_disksize = %d\n", getconf_int(CNF_DISKSIZE));*/
- printf("conf_columnspec = \"%s\"\n", getconf_str(CNF_COLUMNSPEC));
- printf("conf_indexdir = \"%s\"\n", getconf_str(CNF_INDEXDIR));
- printf("num_holdingdisks = %d\n", num_holdingdisks);
- printf("conf_krb5keytab = \"%s\"\n", getconf_str(CNF_KRB5KEYTAB));
- printf("conf_krb5principal = \"%s\"\n", getconf_str(CNF_KRB5PRINCIPAL));
- printf("conf_label_new_tapes = \"%s\"\n", getconf_str(CNF_LABEL_NEW_TAPES));
- for(hp = holdingdisks; hp != NULL; hp = hp->next) {
- printf("\nHOLDINGDISK %s:\n", hp->name);
- printf(" COMMENT \"%s\"\n", hp->comment);
- printf(" DISKDIR \"%s\"\n", hp->diskdir);
- printf(" SIZE %ld\n", (long)hp->disksize);
- printf(" CHUNKSIZE %ld\n", (long)hp->chunksize);
- }
+ for(i=0; i < CNF_CNF; i++) {
+ for(np=server_var; np->token != CONF_UNKNOWN; np++) {
+ if(np->parm == i)
+ break;
+ }
+ if(np->token == CONF_UNKNOWN)
+ error("server bad value");
- for(tp = tapelist; tp != NULL; tp = tp->next) {
- printf("\nTAPETYPE %s:\n", tp->name);
- printf(" COMMENT \"%s\"\n", tp->comment);
- printf(" LBL_TEMPL %s\n", tp->lbl_templ);
- printf(" BLOCKSIZE %ld\n", (long)tp->blocksize);
- printf(" FILE_PAD %s\n", (tp->file_pad) ? "YES" : "NO");
- printf(" LENGTH %lu\n", (unsigned long)tp->length);
- printf(" FILEMARK %lu\n", (unsigned long)tp->filemark);
- printf(" SPEED %ld\n", (long)tp->speed);
+ for(kt = server_keytab; kt->token != CONF_UNKNOWN; kt++)
+ if(kt->token == np->token) break;
+ if(kt->token == CONF_UNKNOWN)
+ error("server bad token");
+
+ printf("%-21s %s\n", kt->keyword, conf_print(&server_conf[i]));
}
- for(dp = dumplist; dp != NULL; dp = dp->next) {
- printf("\nDUMPTYPE %s:\n", dp->name);
- printf(" COMMENT \"%s\"\n", dp->comment);
- printf(" PROGRAM \"%s\"\n", dp->program);
- printf(" SERVER_CUSTOM_COMPRESS \"%s\"\n", dp->srvcompprog);
- printf(" CLIENT_CUSTOM_COMPRESS \"%s\"\n", dp->clntcompprog);
- printf(" SERVER_ENCRYPT \"%s\"\n", dp->srv_encrypt);
- printf(" CLIENT_ENCRYPT \"%s\"\n", dp->clnt_encrypt);
- printf(" SERVER_DECRYPT_OPTION \"%s\"\n", dp->srv_decrypt_opt);
- printf(" CLIENT_DECRYPT_OPTION \"%s\"\n", dp->clnt_decrypt_opt);
- printf(" PRIORITY %ld\n", (long)dp->priority);
- printf(" DUMPCYCLE %ld\n", (long)dp->dumpcycle);
- st = dp->start_t;
- if(st) {
- stm = localtime(&st);
- printf(" STARTTIME %d:%02d:%02d\n",
- stm->tm_hour, stm->tm_min, stm->tm_sec);
- }
- if(dp->exclude_file) {
- sle_t *excl;
- printf(" EXCLUDE FILE");
- for(excl = dp->exclude_file->first; excl != NULL; excl =excl->next){
- printf(" \"%s\"", excl->name);
- }
- printf("\n");
- }
- if(dp->exclude_list) {
- sle_t *excl;
- printf(" EXCLUDE LIST");
- for(excl = dp->exclude_list->first; excl != NULL; excl =excl->next){
- printf(" \"%s\"", excl->name);
- }
- printf("\n");
- }
- if(dp->include_file) {
- sle_t *incl;
- printf(" INCLUDE FILE");
- for(incl = dp->include_file->first; incl != NULL; incl =incl->next){
- printf(" \"%s\"", incl->name);
- }
- printf("\n");
- }
- if(dp->include_list) {
- sle_t *incl;
- printf(" INCLUDE LIST");
- for(incl = dp->include_list->first; incl != NULL; incl =incl->next){
- printf(" \"%s\"", incl->name);
+ for(hp = holdingdisks; hp != NULL; hp = hp->next) {
+ printf("\nHOLDINGDISK %s {\n", hp->name);
+ for(i=0; i < HOLDING_HOLDING; i++) {
+ for(np=holding_var; np->token != CONF_UNKNOWN; np++) {
+ if(np->parm == i)
+ break;
}
- printf("\n");
- }
- printf(" FREQUENCY %ld\n", (long)dp->frequency);
- printf(" MAXDUMPS %d\n", dp->maxdumps);
- printf(" MAXPROMOTEDAY %d\n", dp->maxpromoteday);
- printf(" STRATEGY ");
- switch(dp->strategy) {
- case DS_SKIP:
- printf("SKIP");
- break;
- case DS_STANDARD:
- printf("STANDARD");
- break;
- case DS_NOFULL:
- printf("NOFULL");
- break;
- case DS_NOINC:
- printf("NOINC");
- break;
- case DS_HANOI:
- printf("HANOI");
- break;
- case DS_INCRONLY:
- printf("INCRONLY");
- break;
- }
- putchar('\n');
- printf(" ESTIMATE ");
- switch(dp->estimate) {
- case ES_CLIENT:
- printf("CLIENT");
- break;
- case ES_SERVER:
- printf("SERVER");
- break;
- case ES_CALCSIZE:
- printf("CALCSIZE");
- break;
- }
- putchar('\n');
- printf(" COMPRATE %f, %f\n", dp->comprate[0], dp->comprate[1]);
+ if(np->token == CONF_UNKNOWN)
+ error("holding bad value");
- printf(" OPTIONS: ");
+ for(kt = server_keytab; kt->token != CONF_UNKNOWN; kt++) {
+ if(kt->token == np->token)
+ break;
+ }
+ if(kt->token == CONF_UNKNOWN)
+ error("holding bad token");
- switch(dp->compress) {
- case COMP_NONE:
- printf("NO-COMPRESS ");
- break;
- case COMP_FAST:
- printf("COMPRESS-FAST ");
- break;
- case COMP_BEST:
- printf("COMPRESS-BEST ");
- break;
- case COMP_CUST:
- printf("COMPRESS-CUST ");
- break;
- case COMP_SERV_FAST:
- printf("SRVCOMP-FAST ");
- break;
- case COMP_SERV_BEST:
- printf("SRVCOMP-BEST ");
- break;
- case COMP_SERV_CUST:
- printf("SRVCOMP-CUST ");
- break;
+ printf(" %-9s %s\n", kt->keyword, conf_print(&hp->value[i]));
}
+ printf("}\n");
+ }
- switch(dp->encrypt) {
- case ENCRYPT_NONE:
- printf("ENCRYPT-NONE ");
- break;
- case ENCRYPT_CUST:
- printf("ENCRYPT-CUST ");
- break;
- case ENCRYPT_SERV_CUST:
- printf("ENCRYPT-SERV-CUST ");
- break;
+ for(tp = tapelist; tp != NULL; tp = tp->next) {
+ printf("\nDEFINE TAPETYPE %s {\n", tp->name);
+ for(i=0; i < TAPETYPE_TAPETYPE; i++) {
+ for(np=tapetype_var; np->token != CONF_UNKNOWN; np++)
+ if(np->parm == i) break;
+ if(np->token == CONF_UNKNOWN)
+ error("tapetype bad value");
+
+ for(kt = server_keytab; kt->token != CONF_UNKNOWN; kt++)
+ if(kt->token == np->token) break;
+ if(kt->token == CONF_UNKNOWN)
+ error("tapetype bad token");
+
+ printf(" %-9s %s\n", kt->keyword, conf_print(&tp->value[i]));
}
+ printf("}\n");
+ }
- if(!dp->record) printf("NO-");
- printf("RECORD");
- printf(" %s-AUTH", dp->security_driver);
- if(dp->skip_incr) printf(" SKIP-INCR");
- if(dp->skip_full) printf(" SKIP-FULL");
- if(dp->no_hold) printf(" NO-HOLD");
- if(dp->kencrypt) printf(" KENCRYPT");
- /* an ignored disk will never reach this point */
- assert(!dp->ignore);
- if(dp->index) printf(" INDEX");
- putchar('\n');
+ for(dp = dumplist; dp != NULL; dp = dp->next) {
+ if(dp->seen == -1)
+ prefix = "#";
+ else
+ prefix = "";
+ printf("\n%sDEFINE DUMPTYPE %s {\n", prefix, dp->name);
+ for(i=0; i < DUMPTYPE_DUMPTYPE; i++) {
+ for(np=dumptype_var; np->token != CONF_UNKNOWN; np++)
+ if(np->parm == i) break;
+ if(np->token == CONF_UNKNOWN)
+ error("dumptype bad value");
+
+ for(kt = server_keytab; kt->token != CONF_UNKNOWN; kt++)
+ if(kt->token == np->token) break;
+ if(kt->token == CONF_UNKNOWN)
+ error("dumptype bad token");
+
+ printf("%s %-19s %s\n", prefix, kt->keyword, conf_print(&dp->value[i]));
+ }
+ printf("%s}\n", prefix);
}
for(ip = interface_list; ip != NULL; ip = ip->next) {
- printf("\nINTERFACE %s:\n", ip->name);
- printf(" COMMENT \"%s\"\n", ip->comment);
- printf(" USE %d\n", ip->maxusage);
+ if(strcmp(ip->name,"default") == 0)
+ prefix = "#";
+ else
+ prefix = "";
+ printf("\n%sDEFINE INTERFACE %s {\n", prefix, ip->name);
+ for(i=0; i < INTER_INTER; i++) {
+ for(np=interface_var; np->token != CONF_UNKNOWN; np++)
+ if(np->parm == i) break;
+ if(np->token == CONF_UNKNOWN)
+ error("interface bad value");
+
+ for(kt = server_keytab; kt->token != CONF_UNKNOWN; kt++)
+ if(kt->token == np->token) break;
+ if(kt->token == CONF_UNKNOWN)
+ error("interface bad token");
+
+ printf("%s %-9s %s\n", prefix, kt->keyword, conf_print(&ip->value[i]));
+ }
+ printf("%s}\n",prefix);
}
+
}
+#ifdef TEST
+
int
-main(argc, argv)
- int argc;
- char *argv[];
+main(
+ int argc,
+ char *argv[])
{
char *conffile;
char *diskfile;
#endif /* TEST */
char *
-generic_get_security_conf(string, arg)
- char *string;
- void *arg;
+generic_get_security_conf(
+ char *string,
+ void *arg)
{
+ arg = arg;
if(!string || !*string)
return(NULL);
}
return(NULL);
}
+
+char *
+get_token_name(
+ tok_t token)
+{
+ keytab_t *kt;
+
+ for(kt = server_keytab; kt->token != CONF_UNKNOWN; kt++)
+ if(kt->token == token) break;
+
+ if(kt->token == CONF_UNKNOWN)
+ return("");
+ return(kt->keyword);
+}
+
+void
+parse_server_conf(
+ int parse_argc,
+ char **parse_argv,
+ int *new_argc,
+ char ***new_argv)
+{
+ int i;
+ char **my_argv;
+ char *myarg, *value;
+ command_option_t *server_option;
+
+ server_options = alloc((size_t)(parse_argc+1) * SIZEOF(*server_options));
+ server_option = server_options;
+ server_option->name = NULL;
+
+ my_argv = alloc((size_t)parse_argc * SIZEOF(char *));
+ *new_argv = my_argv;
+ *new_argc = 0;
+ i=0;
+ while(i<parse_argc) {
+ if(strncmp(parse_argv[i],"-o",2) == 0) {
+ if(strlen(parse_argv[i]) > 2)
+ myarg = &parse_argv[i][2];
+ else {
+ i++;
+ if(i >= parse_argc)
+ error("expect something after -o");
+ myarg = parse_argv[i];
+ }
+ value = index(myarg,'=');
+ if (value == NULL) {
+ conf_parserror("Must specify a value for %s.\n", myarg);
+ } else {
+ *value = '\0';
+ value++;
+ server_option->used = 0;
+ server_option->name = stralloc(myarg);
+ server_option->value = stralloc(value);
+ server_option++;
+ server_option->name = NULL;
+ }
+ }
+ else {
+ my_argv[*new_argc] = stralloc(parse_argv[i]);
+ *new_argc += 1;
+ }
+ i++;
+ }
+}
+
+void
+report_bad_conf_arg(void)
+{
+ command_option_t *command_option;
+
+ for(command_option = server_options; command_option->name != NULL;
+ command_option++) {
+ if(command_option->used == 0) {
+ fprintf(stderr,"argument -o%s=%s not used\n",
+ command_option->name, command_option->value);
+ }
+ }
+}
+
+void
+free_server_config(void)
+{
+ holdingdisk_t *hp, *hpnext;
+ dumptype_t *dp, *dpnext;
+ tapetype_t *tp, *tpnext;
+ interface_t *ip, *ipnext;
+ command_option_t *server_option;
+ int i;
+
+ for(hp=holdingdisks; hp != NULL; hp = hpnext) {
+ amfree(hp->name);
+ for(i=0; i<HOLDING_HOLDING-1; i++) {
+ free_val_t(&hp->value[i]);
+ }
+ hpnext = hp->next;
+ amfree(hp);
+ }
+
+ for(dp=dumplist; dp != NULL; dp = dpnext) {
+ amfree(dp->name);
+ for(i=0; i<DUMPTYPE_DUMPTYPE-1; i++) {
+ free_val_t(&dp->value[i]);
+ }
+ dpnext = dp->next;
+ amfree(dp);
+ }
+
+ for(tp=tapelist; tp != NULL; tp = tpnext) {
+ amfree(tp->name);
+ for(i=0; i<TAPETYPE_TAPETYPE-1; i++) {
+ free_val_t(&tp->value[i]);
+ }
+ tpnext = tp->next;
+ amfree(tp);
+ }
+
+ for(ip=interface_list; ip != NULL; ip = ipnext) {
+ amfree(ip->name);
+ for(i=0; i<INTER_INTER-1; i++) {
+ free_val_t(&ip->value[i]);
+ }
+ ipnext = ip->next;
+ amfree(ip);
+ }
+
+ if(server_options) {
+ for(server_option = server_options; server_option->name != NULL;
+ server_option++) {
+ amfree(server_option->name);
+ amfree(server_option->value);
+ }
+ amfree(server_options);
+ }
+
+ for(i=0; i<CNF_CNF-1; i++)
+ free_val_t(&server_conf[i]);
+}
* University of Maryland at College Park
*/
/*
- * $Id: conffile.h,v 1.60 2005/12/21 19:07:50 paddy_s Exp $
+ * $Id: conffile.h,v 1.72 2006/07/26 15:17:37 martinea Exp $
*
* interface for config file reading code
*/
#define CONFFILE_H
#include "amanda.h"
-#include "sl.h"
+#include "util.h"
#define CONFFILE_NAME "amanda.conf"
-typedef enum conf_e {
+typedef enum {
CNF_ORG,
CNF_MAILTO,
CNF_DUMPUSER,
CNF_DISKFILE,
CNF_INFOFILE,
CNF_LOGDIR,
- CNF_DISKDIR,
CNF_INDEXDIR,
CNF_TAPETYPE,
CNF_DUMPCYCLE,
CNF_RUNSPERCYCLE,
- CNF_MAXCYCLE,
CNF_TAPECYCLE,
- CNF_DISKSIZE,
CNF_NETUSAGE,
CNF_INPARALLEL,
CNF_DUMPORDER,
- CNF_TIMEOUT,
CNF_BUMPPERCENT,
CNF_BUMPSIZE,
CNF_BUMPMULT,
CNF_DISPLAYUNIT,
CNF_KRB5KEYTAB,
CNF_KRB5PRINCIPAL,
- CNF_LABEL_NEW_TAPES
+ CNF_LABEL_NEW_TAPES,
+ CNF_USETIMESTAMPS,
+ CNF_CNF
} confparm_t;
+typedef enum tapetype_e {
+ TAPETYPE_COMMENT,
+ TAPETYPE_LBL_TEMPL,
+ TAPETYPE_BLOCKSIZE,
+ TAPETYPE_LENGTH,
+ TAPETYPE_FILEMARK,
+ TAPETYPE_SPEED,
+ TAPETYPE_FILE_PAD,
+ TAPETYPE_TAPETYPE
+} tapetype_ee;
+
typedef struct tapetype_s {
struct tapetype_s *next;
int seen;
char *name;
- char *comment;
- char *lbl_templ;
- long blocksize;
- unsigned long length;
- unsigned long filemark;
- int speed;
- int file_pad;
-
- /* seen flags */
- int s_comment;
- int s_lbl_templ;
- int s_blocksize;
- int s_file_pad;
- int s_length;
- int s_filemark;
- int s_speed;
+ val_t value[TAPETYPE_TAPETYPE];
} tapetype_t;
+#define tapetype_get(tapetype, field) (tapetype->field)
+#define tapetype_get_name(tapetype) tapetype->name
+#define tapetype_get_seen(tapetype) tapetype->seen
+#define tapetype_get_comment(tapetype) get_conftype_string(&tapetype->value[TAPETYPE_COMMENT])
+#define tapetype_get_lbl_templ(tapetype) get_conftype_string(&tapetype->value[TAPETYPE_LBL_TEMPL])
+#define tapetype_get_blocksize(tapetype) get_conftype_size (&tapetype->value[TAPETYPE_BLOCKSIZE])
+#define tapetype_get_length(tapetype) get_conftype_am64 (&tapetype->value[TAPETYPE_LENGTH])
+#define tapetype_get_filemark(tapetype) get_conftype_am64 (&tapetype->value[TAPETYPE_FILEMARK])
+#define tapetype_get_speed(tapetype) get_conftype_int (&tapetype->value[TAPETYPE_SPEED])
+#define tapetype_get_file_pad(tapetype) get_conftype_bool (&tapetype->value[TAPETYPE_FILE_PAD])
+
/* Dump strategies */
#define DS_SKIP 0 /* Don't do any dumps at all */
#define DS_STANDARD 1 /* Standard (0 1 1 1 1 2 2 2 ...) */
#define ES_SERVER 1 /* server estimate */
#define ES_CALCSIZE 2 /* calcsize estimate */
-/* Compression types */
-typedef enum {
- COMP_NONE, /* No compression */
- COMP_FAST, /* Fast compression on client */
- COMP_BEST, /* Best compression on client */
- COMP_CUST, /* Custom compression on client */
- COMP_SERV_FAST, /* Fast compression on server */
- COMP_SERV_BEST, /* Best compression on server */
- COMP_SERV_CUST /* Custom compression on server */
-} comp_t;
-
-/* Encryption types */
-typedef enum {
- ENCRYPT_NONE, /* No encryption */
- ENCRYPT_CUST, /* Custom encryption on client */
- ENCRYPT_SERV_CUST, /* Custom encryption on server */
-} encrypt_t;
-
#define ALGO_FIRST 0
#define ALGO_FIRSTFIT 1
#define ALGO_LARGEST 2
#define ALGO_SMALLEST 4
#define ALGO_LAST 5
+typedef enum dumptype_e {
+ DUMPTYPE_COMMENT,
+ DUMPTYPE_PROGRAM,
+ DUMPTYPE_SRVCOMPPROG,
+ DUMPTYPE_CLNTCOMPPROG,
+ DUMPTYPE_SRV_ENCRYPT,
+ DUMPTYPE_CLNT_ENCRYPT,
+ DUMPTYPE_AMANDAD_PATH,
+ DUMPTYPE_CLIENT_USERNAME,
+ DUMPTYPE_SSH_KEYS,
+ DUMPTYPE_SECURITY_DRIVER,
+ DUMPTYPE_EXCLUDE,
+ DUMPTYPE_INCLUDE,
+ DUMPTYPE_PRIORITY,
+ DUMPTYPE_DUMPCYCLE,
+ DUMPTYPE_MAXDUMPS,
+ DUMPTYPE_MAXPROMOTEDAY,
+ DUMPTYPE_BUMPPERCENT,
+ DUMPTYPE_BUMPSIZE,
+ DUMPTYPE_BUMPDAYS,
+ DUMPTYPE_BUMPMULT,
+ DUMPTYPE_START_T,
+ DUMPTYPE_STRATEGY,
+ DUMPTYPE_ESTIMATE,
+ DUMPTYPE_COMPRESS,
+ DUMPTYPE_ENCRYPT,
+ DUMPTYPE_SRV_DECRYPT_OPT,
+ DUMPTYPE_CLNT_DECRYPT_OPT,
+ DUMPTYPE_COMPRATE,
+ DUMPTYPE_TAPE_SPLITSIZE,
+ DUMPTYPE_FALLBACK_SPLITSIZE,
+ DUMPTYPE_SPLIT_DISKBUFFER,
+ DUMPTYPE_RECORD,
+ DUMPTYPE_SKIP_INCR,
+ DUMPTYPE_SKIP_FULL,
+ DUMPTYPE_HOLDINGDISK,
+ DUMPTYPE_KENCRYPT,
+ DUMPTYPE_IGNORE,
+ DUMPTYPE_INDEX,
+ DUMPTYPE_DUMPTYPE
+} dumptype_ee;
+
typedef struct dumptype_s {
struct dumptype_s *next;
int seen;
char *name;
- char *comment;
- char *program;
- char *srvcompprog;
- char *clntcompprog;
- char *srv_encrypt;
- char *clnt_encrypt;
- sl_t *exclude_file;
- sl_t *exclude_list;
- sl_t *include_file;
- sl_t *include_list;
- int exclude_optional;
- int include_optional;
- int priority;
- int dumpcycle;
- int maxcycle;
- int frequency;
- char *security_driver;
- int maxdumps;
- int maxpromoteday;
- int bumppercent;
- int bumpsize;
- int bumpdays;
- double bumpmult;
- time_t start_t;
- int strategy;
- int estimate;
- comp_t compress;
- encrypt_t encrypt;
- char *srv_decrypt_opt;
- char *clnt_decrypt_opt;
- float comprate[2]; /* first is full, second is incremental */
- long tape_splitsize;
- char *split_diskbuffer;
- long fallback_splitsize;
- /* flag options */
- unsigned int record:1;
- unsigned int skip_incr:1;
- unsigned int skip_full:1;
- unsigned int no_hold:1;
- unsigned int kencrypt:1;
- unsigned int ignore:1;
- unsigned int index:1;
-
- /* seen flags */
- int s_comment;
- int s_program;
- int s_srvcompprog;
- int s_clntcompprog;
- int s_srv_encrypt;
- int s_clnt_encrypt;
- int s_exclude_file;
- int s_exclude_list;
- int s_include_file;
- int s_include_list;
- int s_exclude_optional;
- int s_include_optional;
- int s_priority;
- int s_dumpcycle;
- int s_maxcycle;
- int s_frequency;
- int s_security_driver;
- int s_maxdumps;
- int s_maxpromoteday;
- int s_bumppercent;
- int s_bumpsize;
- int s_bumpdays;
- int s_bumpmult;
- int s_start_t;
- int s_strategy;
- int s_estimate;
- int s_compress;
- int s_encrypt;
- int s_srv_decrypt_opt;
- int s_clnt_decrypt_opt;
- int s_comprate;
- int s_record;
- int s_skip_incr;
- int s_skip_full;
- int s_no_hold;
- int s_kencrypt;
- int s_ignore;
- int s_index;
- int s_tape_splitsize;
- int s_split_diskbuffer;
- int s_fallback_splitsize;
+ val_t value[DUMPTYPE_DUMPTYPE];
} dumptype_t;
+#define dumptype_get_name(dumptype) dumptype->name
+#define dumptype_get_seen(dumptype) dumptype->seen
+#define dumptype_get_comment(dumptype) get_conftype_string (&dumptype->value[DUMPTYPE_COMMENT])
+#define dumptype_get_program(dumptype) get_conftype_string (&dumptype->value[DUMPTYPE_PROGRAM])
+#define dumptype_get_srvcompprog(dumptype) get_conftype_string (&dumptype->value[DUMPTYPE_SRVCOMPPROG])
+#define dumptype_get_clntcompprog(dumptype) get_conftype_string (&dumptype->value[DUMPTYPE_CLNTCOMPPROG])
+#define dumptype_get_srv_encrypt(dumptype) get_conftype_string (&dumptype->value[DUMPTYPE_SRV_ENCRYPT])
+#define dumptype_get_clnt_encrypt(dumptype) get_conftype_string (&dumptype->value[DUMPTYPE_CLNT_ENCRYPT])
+#define dumptype_get_amandad_path(dumptype) get_conftype_string (&dumptype->value[DUMPTYPE_AMANDAD_PATH])
+#define dumptype_get_client_username(dumptype) get_conftype_string (&dumptype->value[DUMPTYPE_CLIENT_USERNAME])
+#define dumptype_get_ssh_keys(dumptype) get_conftype_string (&dumptype->value[DUMPTYPE_SSH_KEYS])
+#define dumptype_get_security_driver(dumptype) get_conftype_string (&dumptype->value[DUMPTYPE_SECURITY_DRIVER])
+#define dumptype_get_exclude(dumptype) get_conftype_exinclude(&dumptype->value[DUMPTYPE_EXCLUDE])
+#define dumptype_get_include(dumptype) get_conftype_exinclude(&dumptype->value[DUMPTYPE_INCLUDE])
+#define dumptype_get_priority(dumptype) get_conftype_priority (&dumptype->value[DUMPTYPE_PRIORITY])
+#define dumptype_get_dumpcycle(dumptype) get_conftype_int (&dumptype->value[DUMPTYPE_DUMPCYCLE])
+#define dumptype_get_maxcycle(dumptype) get_conftype_int (&dumptype->value[DUMPTYPE_MAXCYCLE])
+#define dumptype_get_frequency(dumptype) get_conftype_int (&dumptype->value[DUMPTYPE_FREQUENCY])
+#define dumptype_get_maxdumps(dumptype) get_conftype_int (&dumptype->value[DUMPTYPE_MAXDUMPS])
+#define dumptype_get_maxpromoteday(dumptype) get_conftype_int (&dumptype->value[DUMPTYPE_MAXPROMOTEDAY])
+#define dumptype_get_bumppercent(dumptype) get_conftype_int (&dumptype->value[DUMPTYPE_BUMPPERCENT])
+#define dumptype_get_bumpsize(dumptype) get_conftype_am64 (&dumptype->value[DUMPTYPE_BUMPSIZE])
+#define dumptype_get_bumpdays(dumptype) get_conftype_int (&dumptype->value[DUMPTYPE_BUMPDAYS])
+#define dumptype_get_bumpmult(dumptype) get_conftype_real (&dumptype->value[DUMPTYPE_BUMPMULT])
+#define dumptype_get_start_t(dumptype) get_conftype_time (&dumptype->value[DUMPTYPE_START_T])
+#define dumptype_get_strategy(dumptype) get_conftype_strategy (&dumptype->value[DUMPTYPE_STRATEGY])
+#define dumptype_get_estimate(dumptype) get_conftype_estimate (&dumptype->value[DUMPTYPE_ESTIMATE])
+#define dumptype_get_compress(dumptype) get_conftype_compress (&dumptype->value[DUMPTYPE_COMPRESS])
+#define dumptype_get_encrypt(dumptype) get_conftype_encrypt (&dumptype->value[DUMPTYPE_ENCRYPT])
+#define dumptype_get_srv_decrypt_opt(dumptype) get_conftype_string (&dumptype->value[DUMPTYPE_SRV_DECRYPT_OPT])
+#define dumptype_get_clnt_decrypt_opt(dumptype) get_conftype_string (&dumptype->value[DUMPTYPE_CLNT_DECRYPT_OPT])
+#define dumptype_get_comprate(dumptype) dumptype->value[DUMPTYPE_COMPRATE].v.rate
+#define dumptype_get_tape_splitsize(dumptype) get_conftype_am64 (&dumptype->value[DUMPTYPE_TAPE_SPLITSIZE])
+#define dumptype_get_fallback_splitsize(dumptype) get_conftype_am64 (&dumptype->value[DUMPTYPE_FALLBACK_SPLITSIZE])
+#define dumptype_get_split_diskbuffer(dumptype) get_conftype_string (&dumptype->value[DUMPTYPE_SPLIT_DISKBUFFER])
+#define dumptype_get_record(dumptype) get_conftype_bool (&dumptype->value[DUMPTYPE_RECORD])
+#define dumptype_get_skip_incr(dumptype) get_conftype_bool (&dumptype->value[DUMPTYPE_SKIP_INCR])
+#define dumptype_get_skip_full(dumptype) get_conftype_bool (&dumptype->value[DUMPTYPE_SKIP_FULL])
+#define dumptype_get_to_holdingdisk(dumptype) get_conftype_hold (&dumptype->value[DUMPTYPE_HOLDINGDISK])
+#define dumptype_get_kencrypt(dumptype) get_conftype_bool (&dumptype->value[DUMPTYPE_KENCRYPT])
+#define dumptype_get_ignore(dumptype) get_conftype_bool (&dumptype->value[DUMPTYPE_IGNORE])
+#define dumptype_get_index(dumptype) get_conftype_bool (&dumptype->value[DUMPTYPE_INDEX])
+
/* A network interface */
+typedef enum interface_e {
+ INTER_COMMENT,
+ INTER_MAXUSAGE,
+ INTER_INTER
+} interface_ee;
+
+
typedef struct interface_s {
struct interface_s *next;
int seen;
char *name;
- char *comment;
- int maxusage; /* bandwidth we can consume [kb/s] */
+ val_t value[INTER_INTER];
- /* seen flags */
- int s_comment;
- int s_maxusage;
-
- int curusage; /* current usage */
+ unsigned long curusage; /* current usage */
} interface_t;
+#define interface_get_name(interface) interface->name
+#define interface_get_seen(interface) interface->seen
+#define interface_get_comment(interface) get_conftype_string(&interface->value[INTER_COMMENT])
+#define interface_get_maxusage(interface) get_conftype_int (&interface->value[INTER_MAXUSAGE])
+
/* A holding disk */
+typedef enum holdingdisk_e {
+ HOLDING_COMMENT,
+ HOLDING_DISKDIR,
+ HOLDING_DISKSIZE,
+ HOLDING_CHUNKSIZE,
+ HOLDING_HOLDING
+} holdingdisk_ee;
+
typedef struct holdingdisk_s {
struct holdingdisk_s *next;
int seen;
char *name;
- char *comment;
- char *diskdir;
- long disksize;
- long chunksize;
-
- int s_comment;
- int s_disk;
- int s_size;
- int s_csize;
+ val_t value[HOLDING_HOLDING];
void *up; /* generic user pointer */
+ off_t disksize;
} holdingdisk_t;
+#define holdingdisk_get_name(holdingdisk) (holdingdisk)->name
+#define holdingdisk_get_seen(holdingdisk) (holdingdisk)->seen
+#define holdingdisk_get_comment(holdingdisk) get_conftype_string(&(holdingdisk)->value[HOLDING_COMMENT])
+#define holdingdisk_get_diskdir(holdingdisk) get_conftype_string(&(holdingdisk)->value[HOLDING_DISKDIR])
+#define holdingdisk_get_disksize(holdingdisk) get_conftype_am64 (&(holdingdisk)->value[HOLDING_DISKSIZE])
+#define holdingdisk_get_chunksize(holdingdisk) get_conftype_am64 (&(holdingdisk)->value[HOLDING_CHUNKSIZE])
+
/* for each column we define some values on how to
* format this column element
*/
typedef struct {
char *Name; /* column name */
- char PrefixSpace; /* the blank space to print before this
+ int PrefixSpace; /* the blank space to print before this
* column. It is used to get the space
* between the colums
*/
- char Width; /* the widht of the column itself */
- char Precision; /* the precision if its a float */
- char MaxWidth; /* if set, Width will be recalculated
+ int Width; /* the width of the column itself */
+ int Precision; /* the precision if its a float */
+ int MaxWidth; /* if set, Width will be recalculated
* to the space needed */
char *Format; /* the printf format string for this
* column element
extern holdingdisk_t *holdingdisks;
extern int num_holdingdisks;
-int read_conffile P((char *filename));
-int getconf_seen P((confparm_t parameter));
-int getconf_int P((confparm_t parameter));
-am64_t getconf_am64 P((confparm_t parameter));
-double getconf_real P((confparm_t parameter));
-char *getconf_str P((confparm_t parameter));
-char *getconf_byname P((char *confname));
-dumptype_t *lookup_dumptype P((char *identifier));
-dumptype_t *read_dumptype P((char *name, FILE *from, char *fname, int *linenum));
-tapetype_t *lookup_tapetype P((char *identifier));
-interface_t *lookup_interface P((char *identifier));
-holdingdisk_t *getconf_holdingdisks P((void));
-long int getconf_unit_divisor P((void));
-
-int ColumnDataCount P((void));
-int StringToColumn P((char *s));
-char LastChar P((char *s));
-int SetColumDataFromString P((ColumnInfo* ci, char *s, char **errstr));
-
-char *taperalgo2str P((int taperalgo));
+void parse_server_conf(int parse_argc, char **parse_argv, int *new_argc,
+ char ***new_argv);
+void report_bad_conf_arg(void);
+void free_server_config(void);
+
+int read_conffile(char *filename);
+int getconf_seen(confparm_t parameter);
+int getconf_boolean(confparm_t parameter);
+int getconf_int(confparm_t parameter);
+long getconf_long(confparm_t parameter);
+ssize_t getconf_size(confparm_t parameter);
+time_t getconf_time(confparm_t parameter);
+off_t getconf_am64(confparm_t parameter);
+double getconf_real(confparm_t parameter);
+char *getconf_str(confparm_t parameter);
+int getconf_taperalgo(confparm_t parameter);
+char *getconf_byname(char *confname);
+dumptype_t *lookup_dumptype(char *identifier);
+dumptype_t *read_dumptype(char *name, FILE *from, char *fname, int *linenum);
+tapetype_t *lookup_tapetype(char *identifier);
+interface_t *lookup_interface(char *identifier);
+holdingdisk_t *getconf_holdingdisks(void);
+long int getconf_unit_divisor(void);
+void dump_configuration(char *filename);
+int ColumnDataCount(void);
+int StringToColumn(char *s);
+char LastChar(char *s);
+int SetColumDataFromString(ColumnInfo* ci, char *s, char **errstr);
/* this is in securityconf.h */
-char *generic_get_security_conf P((char *, void *));
+char *generic_get_security_conf(char *, void *);
#endif /* ! CONFFILE_H */
* Authors: the Amanda Development Team. Its members are listed in a
* file named AUTHORS, in the root directory of this distribution.
*/
-/* $Id: disk_history.c,v 1.12 2006/01/16 00:07:01 martinea Exp $
+/* $Id: disk_history.c,v 1.13 2006/05/25 01:47:19 johnfranks Exp $
*
* functions for obtaining backup history
*/
static DUMP_ITEM *disk_hist = NULL;
-void clear_list P((void))
+void
+clear_list(void)
{
DUMP_ITEM *item, *this;
}
/* add item, maintain list ordered by oldest date last */
-void add_dump(date, level, tape, file, partnum)
-char *date;
-int level;
-char *tape;
-int file;
-int partnum;
+
+void
+add_dump(
+ char * date,
+ int level,
+ char * tape,
+ off_t file,
+ int partnum)
{
DUMP_ITEM *new, *item, *before;
int isafile = 0;
- new = (DUMP_ITEM *)alloc(sizeof(DUMP_ITEM));
- strncpy(new->date, date, sizeof(new->date)-1);
- new->date[sizeof(new->date)-1] = '\0';
+ new = (DUMP_ITEM *)alloc(SIZEOF(DUMP_ITEM));
+ strncpy(new->date, date, SIZEOF(new->date)-1);
+ new->date[SIZEOF(new->date)-1] = '\0';
new->level = level;
- strncpy(new->tape, tape, sizeof(new->tape)-1);
- new->tape[sizeof(new->tape)-1] = '\0';
+ strncpy(new->tape, tape, SIZEOF(new->tape)-1);
+ new->tape[SIZEOF(new->tape)-1] = '\0';
new->file = file;
if(partnum == -1) new->is_split = 0;
else new->is_split = 1;
new->tapes = NULL;
- if(new->tape[0] == '/') isafile = 1; /* XXX kludgey, like this whole thing */
+ if(new->tape[0] == '/')
+ isafile = 1; /* XXX kludgey, like this whole thing */
if (disk_hist == NULL)
{
}
-DUMP_ITEM *first_dump P((void))
+DUMP_ITEM *
+first_dump(void)
{
return disk_hist;
}
-
-DUMP_ITEM *next_dump(item)
-DUMP_ITEM *item;
-{
- return item->next;
-}
* Authors: the Amanda Development Team. Its members are listed in a
* file named AUTHORS, in the root directory of this distribution.
*/
-/* $Id: disk_history.h,v 1.4 2005/10/11 01:17:01 vectro Exp $
+/* $Id: disk_history.h,v 1.6 2006/05/25 01:47:19 johnfranks Exp $
*
* interface for obtaining disk backup history
*/
+#ifndef DISK_HISTORY_H
+#define DISK_HISTORY_H
#include "tapelist.h"
typedef struct DUMP_ITEM
{
- char date[11];
+ char date[20];
int level;
int is_split;
char tape[256];
tapelist_t *tapes;
- int file;
+ off_t file;
struct DUMP_ITEM *next;
}
DUMP_ITEM;
-extern void clear_list P((void));
-extern void add_dump P((char *date, int level, char *tape, int file, int partnum));
-extern DUMP_ITEM *first_dump P((void));
-extern DUMP_ITEM *next_dump P((DUMP_ITEM *item));
+#define next_dump(item) ((item)->next)
+
+extern void clear_list(void);
+extern void add_dump(char *date, int level, char *tape, off_t file, int partnum);
+extern DUMP_ITEM *first_dump(void);
+#endif /* !DISK_HISTORY_H */
* University of Maryland at College Park
*/
/*
- * $Id: diskfile.c,v 1.73 2006/03/10 13:51:06 martinea Exp $
+ * $Id: diskfile.c,v 1.95 2006/07/26 15:17:37 martinea Exp $
*
* read disklist file
*/
static am_host_t *hostlist;
/* local functions */
-static char *upcase P((char *st));
-static int parse_diskline P((disklist_t *, const char *, FILE *, int *, char **));
-static void parserror P((const char *, int, const char *, ...))
+static char *upcase(char *st);
+static int parse_diskline(disklist_t *, const char *, FILE *, int *, char **);
+static void disk_parserror(const char *, int, const char *, ...)
__attribute__ ((format (printf, 3, 4)));
int
-read_diskfile(filename, lst)
- const char *filename;
- disklist_t *lst;
+read_diskfile(
+ const char *filename,
+ disklist_t *lst)
{
FILE *diskf;
int line_num;
char *line;
/* initialize */
-
hostlist = NULL;
lst->head = lst->tail = NULL;
line_num = 0;
if ((diskf = fopen(filename, "r")) == NULL) {
- error("could not open disklist file \"%s\": %s",
- filename, strerror(errno));
+ return -1;
+ /*NOTREACHED*/
}
while ((line = agets(diskf)) != NULL) {
line_num++;
- if (parse_diskline(lst, filename, diskf, &line_num, &line) < 0) {
- amfree(line);
- afclose(diskf);
- return (-1);
+ if (line[0] != '\0') {
+ if (parse_diskline(lst, filename, diskf, &line_num, &line) < 0) {
+ amfree(line);
+ afclose(diskf);
+ return (-1);
+ }
}
amfree(line);
}
}
am_host_t *
-lookup_host(hostname)
- const char *hostname;
+lookup_host(
+ const char *hostname)
{
am_host_t *p;
}
disk_t *
-lookup_disk(hostname, diskname)
- const char *hostname, *diskname;
+lookup_disk(
+ const char *hostname,
+ const char *diskname)
{
am_host_t *host;
disk_t *disk;
return (NULL);
}
-void enqueue_disk(list, disk) /* put disk on end of queue */
-disklist_t *list;
-disk_t *disk;
+
+/*
+ * put disk on end of queue
+ */
+
+void
+enqueue_disk(
+ disklist_t *list,
+ disk_t * disk)
{
if(list->tail == NULL) list->head = disk;
else list->tail->next = disk;
disk->next = NULL;
}
-void headqueue_disk(list, disk) /* put disk on head of queue */
-disklist_t *list;
-disk_t *disk;
+
+/*
+ * put disk on head of queue
+ */
+
+void
+headqueue_disk(
+ disklist_t *list,
+ disk_t * disk)
{
if(list->head == NULL) list->tail = disk;
else list->head->prev = disk;
disk->prev = NULL;
}
-void insert_disk(list, disk, cmp) /* insert in sorted order */
-disklist_t *list;
-disk_t *disk;
-int (*cmp) P((disk_t *a, disk_t *b));
+
+/*
+ * insert in sorted order
+ */
+
+void
+insert_disk(
+ disklist_t *list,
+ disk_t * disk,
+ int (*cmp)(disk_t *a, disk_t *b))
{
disk_t *prev, *ptr;
else ptr->prev = disk;
}
-disk_t *add_disk(list, hostname, diskname)
-disklist_t *list;
-char *hostname;
-char *diskname;
+disk_t *
+add_disk(
+ disklist_t *list,
+ char * hostname,
+ char * diskname)
{
disk_t *disk;
am_host_t *host;
- disk = alloc(sizeof(disk_t));
+ disk = alloc(SIZEOF(disk_t));
disk->line = 0;
- disk->tape_splitsize = 0;
+ disk->tape_splitsize = (off_t)0;
disk->split_diskbuffer = NULL;
- disk->fallback_splitsize = 0;
+ disk->fallback_splitsize = (off_t)0;
disk->name = stralloc(diskname);
disk->device = stralloc(diskname);
disk->spindle = -1;
disk->encrypt = ENCRYPT_NONE;
disk->start_t = 0;
disk->todo = 1;
+ disk->index = 1;
+ disk->exclude_list = NULL;
+ disk->exclude_file = NULL;
+ disk->include_list = NULL;
+ disk->include_file = NULL;
host = lookup_host(hostname);
if(host == NULL) {
- host = alloc(sizeof(am_host_t));
+ host = alloc(SIZEOF(am_host_t));
host->next = hostlist;
hostlist = host;
return disk;
}
-int find_disk(list, disk)
-disklist_t *list;
-disk_t *disk;
-/* check if disk is present in list. Return true if so, false otherwise. */
-{
-disk_t *t;
- for( t = list->head; t && t != disk; t = t->next );
+/*
+ * check if disk is present in list. Return true if so, false otherwise.
+ */
- return t == disk;
+int
+find_disk(
+ disklist_t *list,
+ disk_t * disk)
+{
+ disk_t *t;
+
+ t = list->head;
+ while ((t != NULL) && (t != disk)) {
+ t = t->next;
+ }
+ return (t == disk);
}
-void sort_disk(in, out, cmp) /* sort a whole queue */
-disklist_t *in;
-disklist_t *out;
-int (*cmp) P((disk_t *a, disk_t *b));
+
+/*
+ * sort a whole queue
+ */
+
+void
+sort_disk(
+ disklist_t *in,
+ disklist_t *out,
+ int (*cmp)(disk_t *a, disk_t *b))
{
disklist_t *tmp;
disk_t *disk;
insert_disk(out, disk, cmp);
}
-disk_t *dequeue_disk(list) /* remove disk from front of queue */
-disklist_t *list;
+
+/*
+ * remove disk from front of queue
+ */
+
+disk_t *
+dequeue_disk(
+ disklist_t *list)
{
disk_t *disk;
return disk;
}
-void remove_disk(list, disk)
-disklist_t *list;
-disk_t *disk;
+void
+remove_disk(
+ disklist_t *list,
+ disk_t * disk)
{
if(disk->prev == NULL) list->head = disk->next;
else disk->prev->next = disk->next;
disk->prev = disk->next = NULL;
}
-void free_disklist(disklist_t* dl) {
- while (dl->head != NULL) {
- free(dequeue_disk(dl));
- }
+void
+free_disklist(
+ disklist_t* dl)
+{
+ disk_t *dp;
+ am_host_t *host, *hostnext;
+
+ while (dl->head != NULL) {
+ dp = dequeue_disk(dl);
+ amfree(dp->name);
+ free_sl(dp->exclude_file);
+ free_sl(dp->exclude_list);
+ free_sl(dp->include_file);
+ free_sl(dp->include_list);
+ free(dp);
+ }
+
+ for(host=hostlist; host != NULL; host = hostnext) {
+ amfree(host->hostname);
+ am_release_feature_set(host->features);
+ host->features = NULL;
+ hostnext = host->next;
+ amfree(host);
+ }
+ hostlist=NULL;
}
-static char *upcase(st)
-char *st;
+static char *
+upcase(
+ char *st)
{
char *s = st;
while(*s) {
- if(islower((int)*s)) *s = toupper((int)*s);
+ if(islower((int)*s)) *s = (char)toupper((int)*s);
s++;
}
return st;
}
+/* return 0 on success */
+/* return -1 on error */
static int
-parse_diskline(lst, filename, diskf, line_num_p, line_p)
- disklist_t *lst;
- const char *filename;
- FILE *diskf;
- int *line_num_p;
- char **line_p;
+parse_diskline(
+ disklist_t *lst,
+ const char *filename,
+ FILE * diskf,
+ int * line_num_p,
+ /*@keep@*/ char ** line_p)
{
am_host_t *host;
disk_t *disk;
interface_t *netif = 0;
char *hostname = NULL;
char *diskname, *diskdevice;
+ char *dumptype;
char *s, *fp;
int ch, dup = 0;
char *line = *line_p;
skip_whitespace(s, ch);
if(ch == '\0' || ch == '#') {
- parserror(filename, line_num, "disk device name expected");
- if (host == NULL) amfree(hostname);
+ disk_parserror(filename, line_num, "disk device name expected");
+ amfree(hostname);
return (-1);
}
+
fp = s - 1;
- skip_non_whitespace(s, ch);
+ skip_quoted_string(s, ch);
s[-1] = '\0';
- diskname = stralloc(fp);
+ diskname = unquote_string(fp);
skip_whitespace(s, ch);
if(ch == '\0' || ch == '#') {
- parserror(filename, line_num, "disk dumptype expected");
- if(host == NULL) amfree(hostname);
+ disk_parserror(filename, line_num, "disk dumptype expected");
+ amfree(hostname);
amfree(diskname);
- return 1;
+ return (-1);
}
fp = s - 1;
- skip_non_whitespace(s, ch);
+ skip_quoted_string(s, ch);
s[-1] = '\0';
/* diskdevice */
- diskdevice = stralloc(fp);
- if(fp[0] != '{' && (dtype = lookup_dumptype(upcase(fp))) == NULL) {
- skip_whitespace(s, ch);
- if(ch == '\0' || ch == '#') {
- parserror(filename, line_num, "disk dumptype expected");
- if(host == NULL) amfree(hostname);
- amfree(diskdevice);
- amfree(diskname);
- return 1;
+ dumptype = NULL;
+ diskdevice = NULL;
+ dumptype = unquote_string(fp);
+ if(fp[0] != '{') {
+ if ((dtype = lookup_dumptype(dumptype)) == NULL) {
+ diskdevice = dumptype;
+ skip_whitespace(s, ch);
+ if(ch == '\0' || ch == '#') {
+ disk_parserror(filename, line_num,
+ "disk dumptype '%s' not found", dumptype);
+ amfree(hostname);
+ amfree(diskdevice);
+ amfree(diskname);
+ return (-1);
+ }
+
+ fp = s - 1;
+ skip_quoted_string(s, ch);
+ s[-1] = '\0';
+ dumptype = unquote_string(fp);
}
- fp = s - 1;
- skip_non_whitespace(s, ch);
- s[-1] = '\0';
- }
- else {
- amfree(diskdevice);
}
+ else
+ amfree(dumptype);
/* check for duplicate disk */
if(host && (disk = lookup_disk(hostname, diskname)) != NULL) {
- parserror(filename, line_num,
+ disk_parserror(filename, line_num,
"duplicate disk record, previous on line %d", disk->line);
dup = 1;
} else {
- disk = alloc(sizeof(disk_t));
+ disk = alloc(SIZEOF(disk_t));
malloc_mark(disk);
disk->line = line_num;
disk->name = diskname;
}
if (fp[0] == '{') {
- s[-1] = ch;
+ s[-1] = (char)ch;
s = fp+2;
skip_whitespace(s, ch);
if (ch != '\0' && ch != '#') {
- parserror(filename, line_num,
+ disk_parserror(filename, line_num,
"expected line break after `{\', ignoring rest of line");
}
if (strchr(s-1, '}') &&
(strchr(s-1, '#') == NULL ||
strchr(s-1, '}') < strchr(s-1, '#'))) {
- if(host == NULL) amfree(hostname);
+ disk_parserror(filename, line_num,"'}' on same line than '{'");
+ amfree(hostname);
if(!dup) {
amfree(disk->device);
amfree(disk->name);
dtype = read_dumptype(vstralloc("custom(", hostname,
":", disk->name, ")", 0),
diskf, (char*)filename, line_num_p);
-
- *line_p = line = agets(diskf);
- line_num = *line_num_p; /* no incr, read_dumptype did it already */
-
if (dtype == NULL || dup) {
- if(host == NULL) amfree(hostname);
+ disk_parserror(filename, line_num,
+ "read of custom dumptype failed");
+ amfree(hostname);
if(!dup) {
amfree(disk->device);
amfree(disk->name);
return (-1);
}
+ *line_p = line = agets(diskf);
+ line_num = *line_num_p; /* no incr, read_dumptype did it already */
+
if (line == NULL)
*line_p = line = stralloc("");
s = line;
ch = *s++;
- } else if((dtype = lookup_dumptype(upcase(fp))) == NULL) {
- parserror(filename, line_num, "undefined dumptype `%s'", fp);
- if(host == NULL) amfree(hostname);
- if (!dup) {
- amfree(disk->device);
- amfree(disk->name);
- amfree(disk);
- } else {
- amfree(diskdevice);
- amfree(diskname);
+ } else {
+ if((dtype = lookup_dumptype(dumptype)) == NULL) {
+ char *qdt = quote_string(dumptype);
+
+ disk_parserror(filename, line_num, "undefined dumptype `%s'", qdt);
+ amfree(qdt);
+ amfree(dumptype);
+ amfree(hostname);
+ if (!dup) {
+ amfree(disk->device);
+ amfree(disk->name);
+ amfree(disk);
+ } else {
+ amfree(diskdevice);
+ amfree(diskname);
+ }
+ return (-1);
}
- return (-1);
}
if (dup) {
- if (host == NULL) amfree(hostname);
+ amfree(hostname);
amfree(diskdevice);
amfree(diskname);
return (-1);
}
- disk->dtype_name = dtype->name;
- disk->program = dtype->program;
- disk->exclude_file = duplicate_sl(dtype->exclude_file);
- disk->exclude_list = duplicate_sl(dtype->exclude_list);
- disk->include_file = duplicate_sl(dtype->include_file);
- disk->include_list = duplicate_sl(dtype->include_list);
- disk->exclude_optional = dtype->exclude_optional;
- disk->include_optional = dtype->include_optional;
- disk->priority = dtype->priority;
- disk->dumpcycle = dtype->dumpcycle;
- disk->frequency = dtype->frequency;
- disk->security_driver = dtype->security_driver;
- disk->maxdumps = dtype->maxdumps;
- disk->tape_splitsize = dtype->tape_splitsize;
- disk->split_diskbuffer = dtype->split_diskbuffer;
- disk->fallback_splitsize = dtype->fallback_splitsize;
- disk->maxpromoteday = dtype->maxpromoteday;
- disk->bumppercent = dtype->bumppercent;
- disk->bumpsize = dtype->bumpsize;
- disk->bumpdays = dtype->bumpdays;
- disk->bumpmult = dtype->bumpmult;
- disk->start_t = dtype->start_t;
- disk->strategy = dtype->strategy;
- disk->estimate = dtype->estimate;
- disk->compress = dtype->compress;
- disk->srvcompprog = dtype->srvcompprog;
- disk->clntcompprog = dtype->clntcompprog;
- disk->encrypt = dtype->encrypt;
- disk->srv_decrypt_opt = dtype->srv_decrypt_opt;
- disk->clnt_decrypt_opt = dtype->clnt_decrypt_opt;
- disk->srv_encrypt = dtype->srv_encrypt;
- disk->clnt_encrypt = dtype->clnt_encrypt;
- disk->comprate[0] = dtype->comprate[0];
- disk->comprate[1] = dtype->comprate[1];
- disk->record = dtype->record;
- disk->skip_incr = dtype->skip_incr;
- disk->skip_full = dtype->skip_full;
- disk->no_hold = dtype->no_hold;
- disk->kencrypt = dtype->kencrypt;
- disk->index = dtype->index;
- disk->todo = 1;
+ disk->dtype_name = dtype->name;
+ disk->program = dumptype_get_program(dtype);
+ if(dumptype_get_exclude(dtype).type == 0) {
+ disk->exclude_list = duplicate_sl(dumptype_get_exclude(dtype).sl);
+ disk->exclude_file = NULL;
+ }
+ else {
+ disk->exclude_file = duplicate_sl(dumptype_get_exclude(dtype).sl);
+ disk->exclude_list = NULL;
+ }
+ disk->exclude_optional = dumptype_get_exclude(dtype).optional;
+ if(dumptype_get_include(dtype).type == 0) {
+ disk->include_list = duplicate_sl(dumptype_get_include(dtype).sl);
+ disk->include_file = NULL;
+ }
+ else {
+ disk->include_file = duplicate_sl(dumptype_get_include(dtype).sl);
+ disk->include_list = NULL;
+ }
+ disk->include_optional = dumptype_get_include(dtype).optional;
+ disk->priority = dumptype_get_priority(dtype);
+ disk->dumpcycle = dumptype_get_dumpcycle(dtype);
+/* disk->frequency = dumptype_get_frequency(dtype);*/
+ disk->security_driver = dumptype_get_security_driver(dtype);
+ disk->maxdumps = dumptype_get_maxdumps(dtype);
+ disk->tape_splitsize = dumptype_get_tape_splitsize(dtype);
+ disk->split_diskbuffer = dumptype_get_split_diskbuffer(dtype);
+ disk->fallback_splitsize = dumptype_get_fallback_splitsize(dtype);
+ disk->maxpromoteday = dumptype_get_maxpromoteday(dtype);
+ disk->bumppercent = dumptype_get_bumppercent(dtype);
+ disk->bumpsize = dumptype_get_bumpsize(dtype);
+ disk->bumpdays = dumptype_get_bumpdays(dtype);
+ disk->bumpmult = dumptype_get_bumpmult(dtype);
+ disk->start_t = dumptype_get_start_t(dtype);
+ disk->strategy = dumptype_get_strategy(dtype);
+ disk->estimate = dumptype_get_estimate(dtype);
+ disk->compress = dumptype_get_compress(dtype);
+ disk->srvcompprog = dumptype_get_srvcompprog(dtype);
+ disk->clntcompprog = dumptype_get_clntcompprog(dtype);
+ disk->encrypt = dumptype_get_encrypt(dtype);
+ disk->srv_decrypt_opt = dumptype_get_srv_decrypt_opt(dtype);
+ disk->clnt_decrypt_opt = dumptype_get_clnt_decrypt_opt(dtype);
+ disk->srv_encrypt = dumptype_get_srv_encrypt(dtype);
+ disk->clnt_encrypt = dumptype_get_clnt_encrypt(dtype);
+ disk->amandad_path = dumptype_get_amandad_path(dtype);
+ disk->client_username = dumptype_get_client_username(dtype);
+ disk->ssh_keys = dumptype_get_ssh_keys(dtype);
+ disk->comprate[0] = dumptype_get_comprate(dtype)[0];
+ disk->comprate[1] = dumptype_get_comprate(dtype)[1];
+
+ /*
+ * Boolean parameters with no value (Appears here as value 2) defaults
+ * to TRUE for backward compatibility and for logical consistency.
+ */
+ disk->record = dumptype_get_record(dtype) != 0;
+ disk->skip_incr = dumptype_get_skip_incr(dtype) != 0;
+ disk->skip_full = dumptype_get_skip_full(dtype) != 0;
+ disk->to_holdingdisk = dumptype_get_to_holdingdisk(dtype);
+ disk->kencrypt = dumptype_get_kencrypt(dtype) != 0;
+ disk->index = dumptype_get_index(dtype) != 0;
+
+ disk->todo = 1;
skip_whitespace(s, ch);
fp = s - 1;
if(ch && ch != '#') { /* get optional spindle number */
char *fp1;
int is_digit=1;
+
skip_non_whitespace(s, ch);
s[-1] = '\0';
fp1=fp;
}
}
if(is_digit == 0) {
- parserror(filename, line_num, "non-integer spindle `%s'", fp);
- if(host == NULL) amfree(hostname);
+ disk_parserror(filename, line_num, "non-integer spindle `%s'", fp);
+ amfree(hostname);
amfree(disk->name);
amfree(disk);
- return 1;
+ return (-1);
}
disk->spindle = atoi(fp);
skip_integer(s, ch);
skip_non_whitespace(s, ch);
s[-1] = '\0';
if((netif = lookup_interface(upcase(fp))) == NULL) {
- parserror(filename, line_num,
+ disk_parserror(filename, line_num,
"undefined network interface `%s'", fp);
- if(host == NULL) amfree(hostname);
+ amfree(hostname);
amfree(disk->name);
amfree(disk);
return (-1);
}
} else {
- netif = lookup_interface("");
+ netif = lookup_interface("default");
}
skip_whitespace(s, ch);
if(ch && ch != '#') { /* now we have garbage, ignore it */
- parserror(filename, line_num, "end of line expected");
+ disk_parserror(filename, line_num, "end of line expected");
}
- if(dtype->ignore || dtype->strategy == DS_SKIP) {
- if(host == NULL) amfree(hostname);
+ if(dumptype_get_ignore(dtype) || dumptype_get_strategy(dtype) == DS_SKIP) {
+ amfree(hostname);
amfree(disk->name);
amfree(disk);
- return (1);
+ return (0);
}
/* success, add disk to lists */
if(host == NULL) { /* new host */
- host = alloc(sizeof(am_host_t));
+ host = alloc(SIZEOF(am_host_t));
malloc_mark(host);
host->next = hostlist;
hostlist = host;
}
-printf_arglist_function2(static void parserror, const char *, filename,
+printf_arglist_function2(void disk_parserror, const char *, filename,
int, line_num, const char *, format)
{
va_list argp;
}
-void dump_queue(st, q, npr, f)
-char *st;
-disklist_t q;
-int npr; /* we print first npr disks on queue, plus last two */
-FILE *f;
+void
+dump_queue(
+ char * st,
+ disklist_t q,
+ int npr, /* we print first npr disks on queue, plus last two */
+ FILE * f)
{
disk_t *d,*p;
int pos;
+ char *qname;
if(empty(q)) {
fprintf(f, "%s QUEUE: empty\n", st);
}
fprintf(f, "%s QUEUE:\n", st);
for(pos = 0, d = q.head, p = NULL; d != NULL; p = d, d = d->next, pos++) {
+ qname = quote_string(d->name);
if(pos < npr) fprintf(f, "%3d: %-10s %-4s\n",
- pos, d->host->hostname, d->name);
+ pos, d->host->hostname, qname);
+ amfree(qname);
}
if(pos > npr) {
if(pos > npr+2) fprintf(f, " ...\n");
}
}
-char *optionstr(dp, their_features, fdout)
-disk_t *dp;
-am_feature_t * their_features;
-FILE *fdout;
+char *
+optionstr(
+ disk_t * dp,
+ am_feature_t * their_features,
+ FILE * fdout)
{
char *auth_opt = NULL;
char *kencrypt_opt = "";
char *compress_opt = "";
- char *encrypt_opt = "";
- char *decrypt_opt ="";
+ char *encrypt_opt = stralloc("");
+ char *decrypt_opt = stralloc("");
char *record_opt = "";
char *index_opt = "";
char *exclude_file = NULL;
sle_t *excl;
int nb_exclude_file;
int nb_include_file;
+ char *qdpname;
+ char *qname;
+ int err=0;
- if(dp->host
- && am_has_feature(dp->host->features, fe_options_auth)) {
+ assert(dp != NULL);
+ assert(dp->host != NULL);
+
+ qdpname = quote_string(dp->name);
+ if(am_has_feature(dp->host->features, fe_options_auth)) {
auth_opt = vstralloc("auth=", dp->security_driver, ";", NULL);
} else if(strcasecmp(dp->security_driver, "bsd") == 0) {
if(am_has_feature(dp->host->features, fe_options_bsd_auth))
else if(fdout) {
fprintf(fdout,
"WARNING: %s:%s does not support auth or bsd-auth\n",
- dp->host->hostname, dp->name);
+ dp->host->hostname, qdpname);
}
} else if(strcasecmp(dp->security_driver, "krb4") == 0) {
if(am_has_feature(dp->host->features, fe_options_krb4_auth))
else if(fdout) {
fprintf(fdout,
"WARNING: %s:%s does not support auth or krb4-auth\n",
- dp->host->hostname, dp->name);
+ dp->host->hostname, qdpname);
}
if(dp->kencrypt) {
if(am_has_feature(dp->host->features, fe_options_kencrypt)) {
else if(fdout) {
fprintf(fdout,
"WARNING: %s:%s does not support kencrypt\n",
- dp->host->hostname, dp->name);
+ dp->host->hostname, qdpname);
}
}
}
else if(fdout) {
fprintf(fdout,
"WARNING: %s:%s does not support fast compression\n",
- dp->host->hostname, dp->name);
+ dp->host->hostname, qdpname);
}
break;
case COMP_BEST:
else if(fdout) {
fprintf(fdout,
"WARNING: %s:%s does not support best compression\n",
- dp->host->hostname, dp->name);
+ dp->host->hostname, qdpname);
}
break;
case COMP_CUST:
if (BSTRNCMP(compress_opt, "comp-cust=;") == 0){
if(fdout) {
fprintf(fdout,
- "WARNING: %s:%s client custom compression with no compression program specified\n",
- dp->host->hostname, dp->name);
+ "ERROR: %s:%s client custom compression with no compression program specified\n",
+ dp->host->hostname, qdpname);
}
+ err++;
}
}
else if(fdout) {
fprintf(fdout,
"WARNING: %s:%s does not support client custom compression\n",
- dp->host->hostname, dp->name);
+ dp->host->hostname, qdpname);
}
break;
case COMP_SERV_FAST:
if (BSTRNCMP(compress_opt, "srvcomp-cust=;") == 0){
if(fdout) {
fprintf(fdout,
- "WARNING: %s:%s server custom compression with no compression program specified\n",
- dp->host->hostname, dp->name);
+ "ERROR: %s:%s server custom compression with no compression program specified\n",
+ dp->host->hostname, qdpname);
}
+ err++;
}
}
else if(fdout) {
fprintf(fdout,
"WARNING: %s:%s does not support server custom compression\n",
- dp->host->hostname, dp->name);
+ dp->host->hostname, qdpname);
}
break;
}
switch(dp->encrypt) {
case ENCRYPT_CUST:
if(am_has_feature(their_features, fe_options_encrypt_cust)) {
- encrypt_opt = vstralloc("encrypt-cust=", dp->clnt_encrypt, ";", NULL);
+ encrypt_opt = newvstralloc(encrypt_opt, "encrypt-cust=",
+ dp->clnt_encrypt, ";", NULL);
if (BSTRNCMP(encrypt_opt, "encrypt-cust=;") == 0) {
if(fdout) {
fprintf(fdout,
- "WARNING: %s:%s encrypt client with no encryption program specified\n",
- dp->host->hostname, dp->name);
+ "ERROR: %s:%s encrypt client with no encryption program specified\n",
+ dp->host->hostname, qdpname);
+ }
+ err++;
+ }
+ if ( dp->compress == COMP_SERV_FAST ||
+ dp->compress == COMP_SERV_BEST ||
+ dp->compress == COMP_SERV_CUST ) {
+ if(fdout) {
+ fprintf(fdout,
+ "ERROR: %s:Client encryption with server compression is not supported. See amanda.conf(5) for detail.\n", dp->host->hostname);
}
+ err++;
}
if(dp->clnt_decrypt_opt) {
if(am_has_feature(their_features, fe_options_client_decrypt_option)) {
- decrypt_opt = vstralloc("client-decrypt-option=", dp->clnt_decrypt_opt, ";", NULL);
+ decrypt_opt = newvstralloc(decrypt_opt, "client-decrypt-option=",
+ dp->clnt_decrypt_opt, ";", NULL);
}
else if(fdout) {
fprintf(fdout,
"WARNING: %s:%s does not support client decrypt option\n",
- dp->host->hostname, dp->name);
+ dp->host->hostname, qdpname);
}
}
}
else if(fdout) {
fprintf(fdout,
"WARNING: %s:%s does not support client data encryption\n",
- dp->host->hostname, dp->name);
+ dp->host->hostname, qdpname);
}
break;
case ENCRYPT_SERV_CUST:
if(am_has_feature(their_features, fe_options_encrypt_serv_cust)) {
- encrypt_opt = vstralloc("encrypt-serv-cust=", dp->srv_encrypt, ";", NULL);
+ encrypt_opt = newvstralloc(encrypt_opt, "encrypt-serv-cust=",
+ dp->srv_encrypt, ";", NULL);
if (BSTRNCMP(encrypt_opt, "encrypt-serv-cust=;") == 0){
if(fdout) {
fprintf(fdout,
- "WARNING: %s:%s encrypt server with no encryption program specified\n",
- dp->host->hostname, dp->name);
+ "ERROR: %s:%s encrypt server with no encryption program specified\n",
+ dp->host->hostname, qdpname);
}
+ err++;
}
if(dp->srv_decrypt_opt) {
if(am_has_feature(their_features, fe_options_server_decrypt_option)) {
- decrypt_opt = vstralloc("server-decrypt-option=", dp->srv_decrypt_opt, ";", NULL);
+ decrypt_opt = newvstralloc(decrypt_opt, "server-decrypt-option=",
+ dp->srv_decrypt_opt, ";", NULL);
}
else if(fdout) {
fprintf(fdout,
"WARNING: %s:%s does not support server decrypt option\n",
- dp->host->hostname, dp->name);
+ dp->host->hostname, qdpname);
}
}
}
else if(fdout) {
fprintf(fdout,
"WARNING: %s:%s does not support server data encryption\n",
- dp->host->hostname, dp->name);
+ dp->host->hostname, qdpname);
}
break;
}
}
else if(fdout) {
fprintf(fdout, "WARNING: %s:%s does not support no record\n",
- dp->host->hostname, dp->name);
+ dp->host->hostname, qdpname);
}
}
}
else if(fdout) {
fprintf(fdout, "WARNING: %s:%s does not support index\n",
- dp->host->hostname, dp->name);
+ dp->host->hostname, qdpname);
}
}
dp->exclude_file->nb_element == 1) {
for(excl = dp->exclude_file->first; excl != NULL;
excl = excl->next) {
- exc = newvstralloc( exc, "exclude-file=", excl->name,
- ";", NULL);
+ qname = quote_string(excl->name);
+ exc = newvstralloc( exc, "exclude-file=", qname, ";", NULL);
strappend(exclude_file, exc);
+ amfree(qname);
}
} else {
- exc = newvstralloc(exc, "exclude-file=",
- dp->exclude_file->last->name, ";", NULL);
+ qname = quote_string(dp->exclude_file->last->name);
+ exc = newvstralloc(exc, "exclude-file=", qname, ";", NULL);
strappend(exclude_file, exc);
if(fdout) {
fprintf(fdout,
"WARNING: %s:%s does not support multiple exclude\n",
- dp->host->hostname, dp->name);
+ dp->host->hostname, qdpname);
}
+ amfree(qname);
}
} else if(fdout) {
fprintf(fdout, "WARNING: %s:%s does not support exclude file\n",
- dp->host->hostname, dp->name);
+ dp->host->hostname, qdpname);
}
}
exclude_list = stralloc("");
(dp->exclude_list->nb_element == 1 && nb_exclude_file == 0)) {
for(excl = dp->exclude_list->first; excl != NULL;
excl = excl->next) {
- exc = newvstralloc( exc, "exclude-list=", excl->name,
- ";", NULL);
+ qname = quote_string(excl->name);
+ exc = newvstralloc( exc, "exclude-list=", qname, ";", NULL);
strappend(exclude_list, exc);
+ amfree(qname);
}
} else {
- exc = newvstralloc(exc, "exclude-list=",
- dp->exclude_list->last->name, ";", NULL);
+ qname = quote_string(dp->exclude_list->last->name);
+ exc = newvstralloc(exc, "exclude-list=", qname, ";", NULL);
strappend(exclude_list, exc);
if(fdout) {
fprintf(fdout,
"WARNING: %s:%s does not support multiple exclude\n",
- dp->host->hostname, dp->name);
+ dp->host->hostname, qdpname);
}
+ amfree(qname);
}
} else if(fdout) {
fprintf(fdout, "WARNING: %s:%s does not support exclude list\n",
- dp->host->hostname, dp->name);
+ dp->host->hostname, qdpname);
}
}
dp->include_file->nb_element == 1) {
for(excl = dp->include_file->first; excl != NULL;
excl = excl->next) {
- exc = newvstralloc( exc, "include-file=", excl->name,
- ";", NULL);
+ qname = quote_string(excl->name);
+ exc = newvstralloc(exc, "include-file=", qname, ";", NULL);
strappend(include_file, exc);
+ amfree(qname);
}
} else {
- exc = newvstralloc(exc, "include-file=",
- dp->include_file->last->name, ";", NULL);
+ qname = quote_string(dp->include_file->last->name);
+ exc = newvstralloc(exc, "include-file=", qname, ";", NULL);
strappend(include_file, exc);
if(fdout) {
fprintf(fdout,
"WARNING: %s:%s does not support multiple include\n",
- dp->host->hostname, dp->name);
+ dp->host->hostname, qdpname);
}
+ amfree(qname);
}
} else if(fdout) {
fprintf(fdout, "WARNING: %s:%s does not support include file\n",
- dp->host->hostname, dp->name);
+ dp->host->hostname, qdpname);
}
}
include_list = stralloc("");
(dp->include_list->nb_element == 1 && nb_include_file == 0)) {
for(excl = dp->include_list->first; excl != NULL;
excl = excl->next) {
- exc = newvstralloc( exc, "include-list=", excl->name,
- ";", NULL);
+ qname = quote_string(excl->name);
+ exc = newvstralloc(exc, "include-list=", qname, ";", NULL);
strappend(include_list, exc);
+ amfree(qname);
}
} else {
- exc = newvstralloc(exc, "include-list=",
- dp->include_list->last->name, ";", NULL);
+ qname = quote_string(dp->include_list->last->name);
+ exc = newvstralloc(exc, "include-list=", qname, ";", NULL);
strappend(include_list, exc);
if(fdout) {
fprintf(fdout,
"WARNING: %s:%s does not support multiple include\n",
- dp->host->hostname, dp->name);
+ dp->host->hostname, qdpname);
}
+ amfree(qname);
}
} else if(fdout) {
fprintf(fdout, "WARNING: %s:%s does not support include list\n",
- dp->host->hostname, dp->name);
+ dp->host->hostname, qdpname);
}
}
else if(fdout) {
fprintf(fdout,
"WARNING: %s:%s does not support optional exclude\n",
- dp->host->hostname, dp->name);
+ dp->host->hostname, qdpname);
}
}
if(dp->include_optional) {
else if(fdout) {
fprintf(fdout,
"WARNING: %s:%s does not support optional include\n",
- dp->host->hostname, dp->name);
+ dp->host->hostname, qdpname);
}
}
excl_opt,
incl_opt,
NULL);
+ amfree(qdpname);
amfree(auth_opt);
amfree(exclude_list);
amfree(exclude_file);
amfree(include_file);
amfree(include_list);
amfree(exc);
+ amfree(decrypt_opt);
+ amfree(encrypt_opt);
- return result;
+ /* result contains at least 'auth=...' */
+ if ( err ) {
+ amfree(result);
+ return NULL;
+ } else {
+ return result;
+ }
}
-void match_disklist(disklist_t *origqp, int sargc, char **sargv)
+char *
+match_disklist(
+ disklist_t *origqp,
+ int sargc,
+ char ** sargv)
{
char *prevhost = NULL;
+ char *errstr = NULL;
int i;
int match_a_host;
int match_a_disk;
disk_t *dp;
if(sargc <= 0)
- return;
+ return NULL;
for(dp = origqp->head; dp != NULL; dp = dp->next) {
if(dp->todo == 1)
(dp->device && match_disk(sargv[i], dp->device)))) {
if(match_a_host) {
error("Argument %s match a host and a disk",sargv[i]);
+ /*NOTREACHED*/
}
else {
if(dp->todo == -1) {
prev_match = 1;
}
else {
- prev_match = 0;
- /*error("%s match nothing",sargv[i]);*/
+ vstrextend(&errstr, "Argument '", sargv[i], "' match neither a host nor a disk.\n", NULL);
}
}
}
if(dp->todo == -1)
dp->todo = 0;
}
+
+ return errstr;
}
-
+
#ifdef TEST
-static void dump_disk P((const disk_t *));
-static void dump_disklist P((const disklist_t *));
-int main P((int, char *[]));
+static void dump_disk(const disk_t *);
+static void dump_disklist(const disklist_t *);
+int main(int, char *[]);
static void
-dump_disk(dp)
- const disk_t *dp;
+dump_disk(
+ const disk_t * dp)
{
printf(" DISK %s (HOST %s, LINE %d) TYPE %s NAME %s SPINDLE %d\n",
dp->name, dp->host->hostname, dp->line, dp->dtype_name,
}
static void
-dump_disklist(lst)
- const disklist_t *lst;
+dump_disklist(
+ const disklist_t * lst)
{
const disk_t *dp, *prev;
const am_host_t *hp;
}
int
-main(argc, argv)
- int argc;
- char *argv[];
+main(
+ int argc,
+ char ** argv)
{
char *conffile;
char *conf_diskfile;
set_pname("diskfile");
+ dbopen(DBG_SUBDIR_SERVER);
+
/* Don't die when child closes pipe */
signal(SIGPIPE, SIG_IGN);
* University of Maryland at College Park
*/
/*
- * $Id: diskfile.h,v 1.32 2005/12/09 03:22:52 paddy_s Exp $
+ * $Id: diskfile.h,v 1.38 2006/06/22 20:41:33 martinea Exp $
*
* interface for disklist file reading code
*/
} am_host_t;
typedef struct disk_s {
- int line; /* line number of last definition */
+ int line; /* line number of last definition */
struct disk_s *prev, *next; /* doubly linked disk list */
- am_host_t *host; /* host list */
+ am_host_t *host; /* host list */
struct disk_s *hostnext;
- char *name; /* label name for disk */
- char *device; /* device name for disk, eg "sd0g" */
- char *dtype_name; /* name of dump type XXX shouldn't need this */
- char *program; /* dump program, eg DUMP, GNUTAR */
- char *srvcompprog; /* custom compression server filter */
- char *clntcompprog; /* custom compression client filter */
- char *srv_encrypt; /* custom encryption server filter */
- char *clnt_encrypt; /* custom encryption client filter */
- sl_t *exclude_file; /* file exclude spec */
- sl_t *exclude_list; /* exclude list */
- sl_t *include_file; /* file include spec */
- sl_t *include_list; /* include list */
- int exclude_optional; /* exclude list are optional */
- int include_optional; /* include list are optional */
- long priority; /* priority of disk */
- long tape_splitsize; /* size of dumpfile chunks on tape */
- char *split_diskbuffer; /* place where we can buffer PORT-WRITE dumps other than RAM */
- long fallback_splitsize; /* size for in-RAM PORT-WRITE buffers */
- long dumpcycle; /* days between fulls */
- long frequency; /* XXX - not used */
- char *security_driver; /* type of authentication (per disk) */
- int maxdumps; /* max number of parallel dumps (per system) */
- int maxpromoteday; /* maximum of promote day */
- int bumppercent;
- int bumpsize;
- int bumpdays;
- double bumpmult;
- time_t start_t; /* start this dump after this time */
- int strategy; /* what dump strategy to use */
- int estimate; /* what estimate strategy to use */
- int compress; /* type of compression to use */
- int encrypt; /* type of encryption to use */
- char *srv_decrypt_opt; /* server-side decryption option parameter to use */
- char *clnt_decrypt_opt; /* client-side decryption option parameter to use */
- float comprate[2]; /* default compression rates */
+ char *name; /* label name for disk */
+ char *device; /* device name for disk, eg "sd0g" */
+ char *dtype_name; /* name of dump type XXX shouldn't need this */
+ char *program; /* dump program, eg DUMP, STAR, GNUTAR */
+ char *srvcompprog; /* custom compression server filter */
+ char *clntcompprog; /* custom compression client filter */
+ char *srv_encrypt; /* custom encryption server filter */
+ char *clnt_encrypt; /* custom encryption client filter */
+ char *amandad_path; /* amandad path on the client */
+ char *client_username; /* username to connect on the client */
+ char *ssh_keys; /* ssh_key file to use */
+ sl_t *exclude_file; /* file exclude spec */
+ sl_t *exclude_list; /* exclude list */
+ sl_t *include_file; /* file include spec */
+ sl_t *include_list; /* include list */
+ int exclude_optional; /* exclude list are optional */
+ int include_optional; /* include list are optional */
+ int priority; /* priority of disk */
+ off_t tape_splitsize; /* size of dumpfile chunks on tape */
+ char *split_diskbuffer; /* place where we can buffer PORT-WRITE dumps other than RAM */
+ off_t fallback_splitsize; /* size for in-RAM PORT-WRITE buffers */
+ int dumpcycle; /* days between fulls */
+ long frequency; /* XXX - not used */
+ char *security_driver; /* type of authentication (per disk) */
+ int maxdumps; /* max number of parallel dumps (per system) */
+ int maxpromoteday; /* maximum of promote day */
+ int bumppercent;
+ off_t bumpsize;
+ int bumpdays;
+ double bumpmult;
+ time_t start_t; /* start this dump after this time */
+ int strategy; /* what dump strategy to use */
+ int estimate; /* what estimate strategy to use */
+ int compress; /* type of compression to use */
+ int encrypt; /* type of encryption to use */
+ char *srv_decrypt_opt; /* server-side decryption option parameter to use */
+ char *clnt_decrypt_opt; /* client-side decryption option parameter to use */
+ double comprate[2]; /* default compression rates */
/* flag options */
- unsigned int record:1; /* record dump in /etc/dumpdates ? */
- unsigned int skip_incr:1; /* incs done externally ? */
- unsigned int skip_full:1; /* fulls done externally ? */
- unsigned int no_hold:1; /* don't use holding disk ? */
- unsigned int kencrypt:1;
- unsigned int index:1; /* produce an index ? */
- int spindle; /* spindle # - for parallel dumps */
- int inprogress; /* being dumped now? */
- int todo;
- void *up; /* generic user pointer */
+ int record; /* record dump in /etc/dumpdates ? */
+ int skip_incr; /* incs done externally ? */
+ int skip_full; /* fulls done externally ? */
+ int to_holdingdisk; /* use holding disk ? */
+ int kencrypt;
+ int index; /* produce an index ? */
+ int spindle; /* spindle # - for parallel dumps */
+ int inprogress; /* being dumped now? */
+ int todo;
+ void *up; /* generic user pointer */
} disk_t;
typedef struct disklist_s {
#define empty(dlist) ((dlist).head == NULL)
-int read_diskfile P((const char *, disklist_t *));
+int read_diskfile(const char *, disklist_t *);
-am_host_t *lookup_host P((const char *hostname));
-disk_t *lookup_disk P((const char *hostname, const char *diskname));
+am_host_t *lookup_host(const char *hostname);
+disk_t *lookup_disk(const char *hostname, const char *diskname);
-disk_t *add_disk P((disklist_t *list, char *hostname, char *diskname));
+disk_t *add_disk(disklist_t *list, char *hostname, char *diskname);
-void enqueue_disk P((disklist_t *list, disk_t *disk));
-void headqueue_disk P((disklist_t *list, disk_t *disk));
-void insert_disk P((disklist_t *list, disk_t *disk, int (*f)(disk_t *a, disk_t *b)));
-int find_disk P((disklist_t *list, disk_t *disk));
-void sort_disk P((disklist_t *in, disklist_t *out, int (*f)(disk_t *a, disk_t *b)));
-disk_t *dequeue_disk P((disklist_t *list));
-void remove_disk P((disklist_t *list, disk_t *disk));
+void enqueue_disk(disklist_t *list, disk_t *disk);
+void headqueue_disk(disklist_t *list, disk_t *disk);
+void insert_disk(disklist_t *list, disk_t *disk, int (*f)(disk_t *a, disk_t *b));
+int find_disk(disklist_t *list, disk_t *disk);
+void sort_disk(disklist_t *in, disklist_t *out, int (*f)(disk_t *a, disk_t *b));
+disk_t *dequeue_disk(disklist_t *list);
+void remove_disk(disklist_t *list, disk_t *disk);
-void dump_queue P((char *str, disklist_t q, int npr, FILE *f));
+void dump_queue(char *str, disklist_t q, int npr, FILE *f);
-char *optionstr P((disk_t *dp, am_feature_t *their_features, FILE *fdout));
+char *optionstr(disk_t *dp, am_feature_t *their_features, FILE *fdout);
-void match_disklist P((disklist_t *origqp, int sargc, char **sargv));
-void free_disklist P((disklist_t *dl));
+char *match_disklist(disklist_t *origqp, int sargc, char **sargv);
+void free_disklist(disklist_t *dl);
#endif /* ! DISKFILE_H */
* file named AUTHORS, in the root directory of this distribution.
*/
/*
- * $Id: driver.c,v 1.165.2.2 2006/04/23 23:04:33 martinea Exp $
+ * $Id: driver.c,v 1.198 2006/08/24 01:57:16 paddy_s Exp $
*
* controlling process for the Amanda backup system
*/
* tape. Probably not effective though, should do this in planner.
*/
-/*#define HOLD_DEBUG*/
+#define HOLD_DEBUG
#include "amanda.h"
#include "clock.h"
static int pending_aborts;
static disk_t *taper_disk;
static int degraded_mode;
-static unsigned long reserved_space;
-static unsigned long total_disksize;
+static off_t reserved_space;
+static off_t total_disksize;
static char *dumper_program;
static char *chunker_program;
static int inparallel;
static int nodump = 0;
-static unsigned long tape_length, tape_left = 0;
+static off_t tape_length = (off_t)0;
+static off_t tape_left = (off_t)0;
static int current_tape = 1;
static int conf_taperalgo;
static int conf_runtapes;
static time_t sleep_time;
static int idle_reason;
-static char *datestamp;
-static char *timestamp;
+static char *driver_timestamp;
+static char *hd_driver_timestamp;
static am_host_t *flushhost = NULL;
static int need_degraded=0;
static event_handle_t *dumpers_ev_time = NULL;
static event_handle_t *schedule_ev_read = NULL;
-static void allocate_bandwidth P((interface_t *ip, int kps));
-static int assign_holdingdisk P((assignedhd_t **holdp, disk_t *diskp));
-static void adjust_diskspace P((disk_t *diskp, cmd_t cmd));
-static void delete_diskspace P((disk_t *diskp));
-static assignedhd_t **build_diskspace P((char *destname));
-static int client_constrained P((disk_t *dp));
-static void deallocate_bandwidth P((interface_t *ip, int kps));
-static void dump_schedule P((disklist_t *qp, char *str));
-static int dump_to_tape P((disk_t *dp));
-static assignedhd_t **find_diskspace P((unsigned long size, int *cur_idle,
- assignedhd_t *preferred));
-static int free_kps P((interface_t *ip));
-static unsigned long free_space P((void));
-static void dumper_result P((disk_t *dp));
-static void handle_dumper_result P((void *));
-static void handle_chunker_result P((void *));
-static void handle_dumpers_time P((void *));
-static void handle_taper_result P((void *));
-static void holdingdisk_state P((char *time_str));
-static dumper_t *idle_dumper P((void));
-static void interface_state P((char *time_str));
-static int num_busy_dumpers P((void));
-static int queue_length P((disklist_t q));
-static disklist_t read_flush P((void));
-static void read_schedule P((void *cookie));
-static void short_dump_state P((void));
-static void startaflush P((void));
-static void start_degraded_mode P((disklist_t *queuep));
-static void start_some_dumps P((disklist_t *rq));
-static void continue_port_dumps();
-static void update_failed_dump_to_tape P((disk_t *));
+static int wait_children(int count);
+static void wait_for_children(void);
+static void allocate_bandwidth(interface_t *ip, unsigned long kps);
+static int assign_holdingdisk(assignedhd_t **holdp, disk_t *diskp);
+static void adjust_diskspace(disk_t *diskp, cmd_t cmd);
+static void delete_diskspace(disk_t *diskp);
+static assignedhd_t **build_diskspace(char *destname);
+static int client_constrained(disk_t *dp);
+static void deallocate_bandwidth(interface_t *ip, unsigned long kps);
+static void dump_schedule(disklist_t *qp, char *str);
+static int dump_to_tape(disk_t *dp);
+static assignedhd_t **find_diskspace(off_t size, int *cur_idle,
+ assignedhd_t *preferred);
+static unsigned long free_kps(interface_t *ip);
+static off_t free_space(void);
+static void dumper_result(disk_t *dp);
+static void handle_dumper_result(void *);
+static void handle_chunker_result(void *);
+static void handle_dumpers_time(void *);
+static void handle_taper_result(void *);
+static void holdingdisk_state(char *time_str);
+static dumper_t *idle_dumper(void);
+static void interface_state(char *time_str);
+static int queue_length(disklist_t q);
+static disklist_t read_flush(void);
+static void read_schedule(void *cookie);
+static void short_dump_state(void);
+static void startaflush(void);
+static void start_degraded_mode(disklist_t *queuep);
+static void start_some_dumps(disklist_t *rq);
+static void continue_port_dumps(void);
+static void update_failed_dump_to_tape(disk_t *);
#if 0
-static void dump_state P((const char *str));
+static void dump_state(const char *str);
#endif
-int main P((int main_argc, char **main_argv));
+int main(int main_argc, char **main_argv);
static const char *idle_strings[] = {
#define NOT_IDLE 0
};
int
-main(main_argc, main_argv)
- int main_argc;
- char **main_argv;
+main(
+ int main_argc,
+ char ** main_argv)
{
disklist_t origq;
disk_t *diskp;
int result_argc;
char *result_argv[MAX_ARGS+1];
char *taper_program;
- amwait_t retstat;
char *conf_tapetype;
tapetype_t *tape;
+ char *line;
+ int new_argc, my_argc;
+ char **new_argv, **my_argv;
safe_fd(-1, 0);
- setvbuf(stdout, (char *)NULL, _IOLBF, 0);
- setvbuf(stderr, (char *)NULL, _IOLBF, 0);
+ setvbuf(stdout, (char *)NULL, (int)_IOLBF, 0);
+ setvbuf(stderr, (char *)NULL, (int)_IOLBF, 0);
set_pname("driver");
+ dbopen(DBG_SUBDIR_SERVER);
+
+ atexit(wait_for_children);
+
/* Don't die when child closes pipe */
signal(SIGPIPE, SIG_IGN);
startclock();
+ parse_server_conf(main_argc, main_argv, &new_argc, &new_argv);
+ my_argc = new_argc;
+ my_argv = new_argv;
+
printf("%s: pid %ld executable %s version %s\n",
- get_pname(), (long) getpid(), main_argv[0], version());
+ get_pname(), (long) getpid(), my_argv[0], version());
- if (main_argc > 1) {
- config_name = stralloc(main_argv[1]);
+ if (my_argc > 1) {
+ config_name = stralloc(my_argv[1]);
config_dir = vstralloc(CONFIG_DIR, "/", config_name, "/", NULL);
- if(main_argc > 2) {
- if(strncmp(main_argv[2], "nodump", 6) == 0) {
+ if(my_argc > 2) {
+ if(strncmp(my_argv[2], "nodump", 6) == 0) {
nodump = 1;
}
}
} else {
+
char my_cwd[STR_SIZE];
- if (getcwd(my_cwd, sizeof(my_cwd)) == NULL) {
+ if (getcwd(my_cwd, SIZEOF(my_cwd)) == NULL) {
error("cannot determine current working directory");
+ /*NOTREACHED*/
}
config_dir = stralloc2(my_cwd, "/");
if ((config_name = strrchr(my_cwd, '/')) != NULL) {
conffile = stralloc2(config_dir, CONFFILE_NAME);
if(read_conffile(conffile)) {
error("errors processing config file \"%s\"", conffile);
+ /*NOTREACHED*/
}
amfree(conffile);
- amfree(datestamp);
- datestamp = construct_datestamp(NULL);
- timestamp = construct_timestamp(NULL);
- log_add(L_START,"date %s", datestamp);
+ dbrename(config_name, DBG_SUBDIR_SERVER);
+
+ report_bad_conf_arg();
+
+ amfree(driver_timestamp);
+ /* read timestamp from stdin */
+ while ((line = agets(stdin)) != NULL) {
+ if (line[0] != '\0')
+ break;
+ amfree(line);
+ }
+ if ( line == NULL ) {
+ error("Did not get DATE line from planner");
+ /*NOTREACHED*/
+ }
+ driver_timestamp = alloc(15);
+ strncpy(driver_timestamp, &line[5], 14);
+ driver_timestamp[14] = '\0';
+ amfree(line);
+ log_add(L_START,"date %s", driver_timestamp);
+
+ /* check that we don't do many dump in a day and usetimestamps is off */
+ if(strlen(driver_timestamp) == 8) {
+ char *conf_logdir = getconf_str(CNF_LOGDIR);
+ char *logfile = vstralloc(conf_logdir, "/log.",
+ driver_timestamp, ".0", NULL);
+ char *oldlogfile = vstralloc(conf_logdir, "/oldlog/log.",
+ driver_timestamp, ".0", NULL);
+ if(access(logfile, F_OK) == 0 || access(oldlogfile, F_OK) == 0) {
+ log_add(L_WARNING, "WARNING: This is not the first amdump run today. Enable the usetimestamps option in the configuration file if you want to run amdump more than once per calendar day.");
+ }
+ amfree(oldlogfile);
+ amfree(logfile);
+ hd_driver_timestamp = construct_timestamp(NULL);
+ }
+ else {
+ hd_driver_timestamp = stralloc(driver_timestamp);
+ }
taper_program = vstralloc(libexecdir, "/", "taper", versionsuffix(), NULL);
dumper_program = vstralloc(libexecdir, "/", "dumper", versionsuffix(),
chunker_program = vstralloc(libexecdir, "/", "chunker", versionsuffix(),
NULL);
- conf_taperalgo = getconf_int(CNF_TAPERALGO);
+ conf_taperalgo = getconf_taperalgo(CNF_TAPERALGO);
conf_tapetype = getconf_str(CNF_TAPETYPE);
conf_runtapes = getconf_int(CNF_RUNTAPES);
tape = lookup_tapetype(conf_tapetype);
- tape_length = tape->length;
- printf("driver: tape size %ld\n", tape_length);
-
- /* taper takes a while to get going, so start it up right away */
-
- init_driverio();
- if(conf_runtapes > 0) {
- startup_tape_process(taper_program);
- taper_cmd(START_TAPER, datestamp, NULL, 0, NULL);
- }
+ tape_length = tapetype_get_length(tape);
+ printf("driver: tape size " OFF_T_FMT "\n", (OFF_T_FMT_TYPE)tape_length);
/* start initializing: read in databases */
} else {
conf_diskfile = stralloc2(config_dir, conf_diskfile);
}
- if (read_diskfile(conf_diskfile, &origq) < 0)
+ if (read_diskfile(conf_diskfile, &origq) < 0) {
error("could not load disklist \"%s\"", conf_diskfile);
+ /*NOTREACHED*/
+ }
amfree(conf_diskfile);
/* set up any configuration-dependent variables */
inparallel = getconf_int(CNF_INPARALLEL);
- reserve = getconf_int(CNF_RESERVE);
+ reserve = (unsigned long)getconf_int(CNF_RESERVE);
- total_disksize = 0;
+ total_disksize = (off_t)0;
for(hdp = getconf_holdingdisks(), dsk = 0; hdp != NULL; hdp = hdp->next, dsk++) {
- hdp->up = (void *)alloc(sizeof(holdalloc_t));
+ hdp->up = (void *)alloc(SIZEOF(holdalloc_t));
holdalloc(hdp)->allocated_dumpers = 0;
- holdalloc(hdp)->allocated_space = 0L;
+ holdalloc(hdp)->allocated_space = (off_t)0;
- if(get_fs_stats(hdp->diskdir, &fs) == -1
- || access(hdp->diskdir, W_OK) == -1) {
+ if(get_fs_stats(holdingdisk_get_diskdir(hdp), &fs) == -1
+ || access(holdingdisk_get_diskdir(hdp), W_OK) == -1) {
log_add(L_WARNING, "WARNING: ignoring holding disk %s: %s\n",
- hdp->diskdir, strerror(errno));
+ holdingdisk_get_diskdir(hdp), strerror(errno));
hdp->disksize = 0L;
continue;
}
- if(fs.avail != -1) {
- if(hdp->disksize > 0) {
+ if(fs.avail != (off_t)-1) {
+ if(hdp->disksize > (off_t)0) {
if(hdp->disksize > fs.avail) {
log_add(L_WARNING,
- "WARNING: %s: %ld KB requested, but only %ld KB available.",
- hdp->diskdir, hdp->disksize, fs.avail);
+ "WARNING: %s: " OFF_T_FMT " KB requested, "
+ "but only " OFF_T_FMT " KB available.",
+ holdingdisk_get_diskdir(hdp),
+ (OFF_T_FMT_TYPE)hdp->disksize,
+ (OFF_T_FMT_TYPE)fs.avail);
hdp->disksize = fs.avail;
}
}
- else if(fs.avail + hdp->disksize < 0) {
+ else if((fs.avail + hdp->disksize) < (off_t)0) {
log_add(L_WARNING,
- "WARNING: %s: not %ld KB free.",
- hdp->diskdir, -hdp->disksize);
- hdp->disksize = 0L;
+ "WARNING: %s: not " OFF_T_FMT " KB free.",
+ holdingdisk_get_diskdir(hdp), -hdp->disksize);
+ hdp->disksize = (off_t)0;
continue;
}
else
hdp->disksize += fs.avail;
}
- printf("driver: adding holding disk %d dir %s size %ld chunksize %ld\n",
- dsk, hdp->diskdir, hdp->disksize, hdp->chunksize);
+ printf("driver: adding holding disk %d dir %s size "
+ OFF_T_FMT " chunksize " OFF_T_FMT "\n",
+ dsk, holdingdisk_get_diskdir(hdp),
+ (OFF_T_FMT_TYPE)hdp->disksize,
+ (OFF_T_FMT_TYPE)(holdingdisk_get_chunksize(hdp)));
newdir = newvstralloc(newdir,
- hdp->diskdir, "/", timestamp,
+ holdingdisk_get_diskdir(hdp), "/", hd_driver_timestamp,
NULL);
if(!mkholdingdir(newdir)) {
- hdp->disksize = 0L;
+ hdp->disksize = (off_t)0;
}
total_disksize += hdp->disksize;
}
- reserved_space = total_disksize * (reserve / 100.0);
+ reserved_space = total_disksize * (off_t)(reserve / 100);
- printf("reserving %ld out of %ld for degraded-mode dumps\n",
- reserved_space, free_space());
+ printf("reserving " OFF_T_FMT " out of " OFF_T_FMT
+ " for degraded-mode dumps\n",
+ (OFF_T_FMT_TYPE)reserved_space, (OFF_T_FMT_TYPE)free_space());
amfree(newdir);
if(inparallel > MAX_DUMPERS) inparallel = MAX_DUMPERS;
+ /* taper takes a while to get going, so start it up right away */
+
+ init_driverio();
+ if(conf_runtapes > 0) {
+ startup_tape_process(taper_program);
+ taper_cmd(START_TAPER, driver_timestamp, NULL, 0, NULL);
+ }
+
/* fire up the dumpers now while we are waiting */
- if(!nodump) startup_dump_processes(dumper_program, inparallel);
+ if(!nodump) startup_dump_processes(dumper_program, inparallel, driver_timestamp);
/*
* Read schedule from stdin. Usually, this is a pipe from planner,
log_add(L_STATS, "startup time %s", walltime_str(curclock()));
- printf("driver: start time %s inparallel %d bandwidth %d diskspace %lu",
- walltime_str(curclock()), inparallel, free_kps((interface_t *)0),
- free_space());
+ printf("driver: start time %s inparallel %d bandwidth %lu diskspace "
+ OFF_T_FMT " ", walltime_str(curclock()), inparallel,
+ free_kps((interface_t *)0), (OFF_T_FMT_TYPE)free_space());
printf(" dir %s datestamp %s driver: drain-ends tapeq %s big-dumpers %s\n",
- "OBSOLETE", datestamp, taperalgo2str(conf_taperalgo),
+ "OBSOLETE", driver_timestamp, taperalgo2str(conf_taperalgo),
getconf_str(CNF_DUMPORDER));
fflush(stdout);
if(!need_degraded) startaflush();
if(!nodump)
- schedule_ev_read = event_register(0, EV_READFD, read_schedule, NULL);
+ schedule_ev_read = event_register((event_id_t)0, EV_READFD, read_schedule, NULL);
short_dump_state();
event_loop(0);
while(!empty(runq) && taper > 0) {
diskp = dequeue_disk(&runq);
- if(!degraded_mode) {
+ if (diskp->to_holdingdisk == HOLD_REQUIRED) {
+ log_add(L_FAIL, "%s %s %s %d [%s]",
+ diskp->host->hostname, diskp->name, sched(diskp)->datestamp,
+ sched(diskp)->level,
+ "can't dump required holdingdisk");
+ }
+ else if (!degraded_mode) {
int rc = dump_to_tape(diskp);
if(rc == 1)
log_add(L_INFO,
log_add(L_FAIL, "%s %s %s %d [%s]",
diskp->host->hostname, diskp->name, sched(diskp)->datestamp,
sched(diskp)->level,
- diskp->no_hold ?
- "can't dump no-hold disk in degraded mode" :
- "no more holding disk space");
+ diskp->to_holdingdisk == HOLD_AUTO ?
+ "no more holding disk space" :
+ "can't dump no-hold disk in degraded mode");
}
short_dump_state(); /* for amstatus */
if(!nodump) {
for(dumper = dmptable; dumper < dmptable + inparallel; dumper++) {
- dumper_cmd(dumper, QUIT, NULL);
+ if(dumper->fd >= 0)
+ dumper_cmd(dumper, QUIT, NULL);
}
}
}
/* wait for all to die */
-
- while(1) {
- char number[NUM_STR_SIZE];
- pid_t pid;
- char *who;
- char *what;
- int code=0;
-
- if((pid = wait(&retstat)) == -1) {
- if(errno == EINTR) continue;
- else break;
- }
- what = NULL;
- if(! WIFEXITED(retstat)) {
- what = "signal";
- code = WTERMSIG(retstat);
- } else if(WEXITSTATUS(retstat) != 0) {
- what = "code";
- code = WEXITSTATUS(retstat);
- }
- who = NULL;
- for(dumper = dmptable; dumper < dmptable + inparallel; dumper++) {
- if(pid == dumper->pid) {
- who = stralloc(dumper->name);
- break;
- }
- }
- if(who == NULL && pid == taper_pid) {
- who = stralloc("taper");
- }
- if(what != NULL && who == NULL) {
- snprintf(number, sizeof(number), "%ld", (long)pid);
- who = stralloc2("unknown pid ", number);
- }
- if(who && what) {
- log_add(L_WARNING, "%s exited with %s %d\n", who, what, code);
- printf("driver: %s exited with %s %d\n", who, what, code);
- }
- amfree(who);
- }
-
- for(dumper = dmptable; dumper < dmptable + inparallel; dumper++) {
- amfree(dumper->name);
- }
+ wait_children(600);
for(hdp = getconf_holdingdisks(); hdp != NULL; hdp = hdp->next) {
- cleanup_holdingdisk(hdp->diskdir, 0);
+ cleanup_holdingdisk(holdingdisk_get_diskdir(hdp), 0);
amfree(hdp->up);
}
amfree(newdir);
check_unfree_serial();
printf("driver: FINISHED time %s\n", walltime_str(curclock()));
fflush(stdout);
- log_add(L_FINISH,"date %s time %s", datestamp, walltime_str(curclock()));
- amfree(datestamp);
- amfree(timestamp);
+ log_add(L_FINISH,"date %s time %s", driver_timestamp, walltime_str(curclock()));
+ amfree(driver_timestamp);
+ free_new_argv(new_argc, new_argv);
amfree(dumper_program);
amfree(taper_program);
amfree(config_dir);
malloc_list(fileno(stderr), malloc_hist_1, malloc_hist_2);
}
+ dbclose();
+
return 0;
}
+/* sleep up to count seconds, and wait for terminating child process */
+/* if sleep is negative, this function will not timeout */
+/* exit once all child process are finished or the timout expired */
+/* return 0 if no more children to wait */
+/* return 1 if some children are still alive */
+static int
+wait_children(int count)
+{
+ pid_t pid;
+ amwait_t retstat;
+ char *who;
+ char *what;
+ int code=0;
+ dumper_t *dumper;
+ int wait_errno;
+
+ do {
+ do {
+ pid = waitpid((pid_t)-1, &retstat, WNOHANG);
+ wait_errno = errno;
+ if (pid > 0) {
+ what = NULL;
+ if (! WIFEXITED(retstat)) {
+ what = "signal";
+ code = WTERMSIG(retstat);
+ } else if (WEXITSTATUS(retstat) != 0) {
+ what = "code";
+ code = WEXITSTATUS(retstat);
+ }
+ who = NULL;
+ for (dumper = dmptable; dumper < dmptable + inparallel;
+ dumper++) {
+ if (pid == dumper->pid) {
+ who = stralloc(dumper->name);
+ dumper->pid = -1;
+ break;
+ }
+ if (pid == dumper->chunker->pid) {
+ who = stralloc(dumper->chunker->name);
+ dumper->chunker->pid = -1;
+ break;
+ }
+ }
+ if (who == NULL && pid == taper_pid) {
+ who = stralloc("taper");
+ taper_pid = -1;
+ }
+ if(what != NULL && who == NULL) {
+ who = stralloc("unknown");
+ }
+ if(who && what) {
+ log_add(L_WARNING, "%s pid %u exited with %s %d\n", who,
+ (unsigned)pid, what, code);
+ printf("driver: %s pid %u exited with %s %d\n", who,
+ (unsigned)pid, what, code);
+ }
+ amfree(who);
+ }
+ } while (pid > 0 || wait_errno == EINTR);
+ if (errno != ECHILD)
+ sleep(1);
+ if (count > 0)
+ count--;
+ } while ((errno != ECHILD) && (count != 0));
+ return (errno != ECHILD);
+}
+
static void
-startaflush()
+kill_children(int signal)
+{
+ dumper_t *dumper;
+
+ if(!nodump) {
+ for(dumper = dmptable; dumper < dmptable + inparallel; dumper++) {
+ if (!dumper->down && dumper->pid > 1) {
+ printf("driver: sending signal %d to %s pid %u\n", signal,
+ dumper->name, (unsigned)dumper->pid);
+ if (kill(dumper->pid, signal) == -1 && errno == ESRCH) {
+ if (dumper->chunker)
+ dumper->chunker->pid = 0;
+ }
+ if (dumper->chunker && dumper->chunker->pid > 1) {
+ printf("driver: sending signal %d to %s pid %u\n", signal,
+ dumper->chunker->name,
+ (unsigned)dumper->chunker->pid);
+ if (kill(dumper->chunker->pid, signal) == -1 &&
+ errno == ESRCH)
+ dumper->chunker->pid = 0;
+ }
+ }
+ }
+ }
+
+ if(taper_pid > 1)
+ printf("driver: sending signal %d to %s pid %u\n", signal,
+ "taper", (unsigned)taper_pid);
+ if (kill(taper_pid, signal) == -1 && errno == ESRCH)
+ taper_pid = 0;
+}
+
+static void
+wait_for_children(void)
+{
+ dumper_t *dumper;
+
+ if(!nodump) {
+ for(dumper = dmptable; dumper < dmptable + inparallel; dumper++) {
+ if (dumper->pid > 1 && dumper->fd >= 0) {
+ dumper_cmd(dumper, QUIT, NULL);
+ if (dumper->chunker && dumper->chunker->pid > 1 &&
+ dumper->chunker->fd >= 0)
+ chunker_cmd(dumper->chunker, QUIT, NULL);
+ }
+ }
+ }
+
+ if(taper_pid > 1 && taper > 0) {
+ taper_cmd(QUIT, NULL, NULL, 0, NULL);
+ }
+
+ if(wait_children(60) == 0)
+ return;
+
+ kill_children(SIGHUP);
+ if(wait_children(60) == 0)
+ return;
+
+ kill_children(SIGKILL);
+ if(wait_children(-1) == 0)
+ return;
+
+}
+
+static void
+startaflush(void)
{
disk_t *dp = NULL;
disk_t *fit = NULL;
char *datestamp;
- unsigned int extra_tapes = 0;
+ int extra_tapes = 0;
+ char *qname;
+
if(!degraded_mode && !taper_busy && !empty(tapeq)) {
datestamp = sched(tapeq.head)->datestamp;
case ALGO_FIRSTFIT:
fit = tapeq.head;
while (fit != NULL) {
- extra_tapes = (fit->tape_splitsize > 0) ?
- conf_runtapes - current_tape : 0;
- if(sched(fit)->act_size <= (tape_left + tape_length*extra_tapes) &&
- strcmp(sched(fit)->datestamp, datestamp) <= 0) {
+ extra_tapes = (fit->tape_splitsize > (off_t)0) ?
+ conf_runtapes - current_tape : 0;
+ if(sched(fit)->act_size <= (tape_left +
+ tape_length * (off_t)extra_tapes) &&
+ strcmp(sched(fit)->datestamp, datestamp) <= 0) {
dp = fit;
fit = NULL;
}
case ALGO_LARGESTFIT:
fit = tapeq.head;
while (fit != NULL) {
- extra_tapes = (fit->tape_splitsize > 0) ?
- conf_runtapes - current_tape : 0;
- if(sched(fit)->act_size <= (tape_left + tape_length*extra_tapes) &&
+ extra_tapes = (fit->tape_splitsize > (off_t)0) ?
+ conf_runtapes - current_tape : 0;
+ if(sched(fit)->act_size <=
+ (tape_left + tape_length * (off_t)extra_tapes) &&
(!dp || sched(fit)->act_size > sched(dp)->act_size) &&
strcmp(sched(fit)->datestamp, datestamp) <= 0) {
dp = fit;
if(dp) remove_disk(&tapeq, dp);
}
if(taper_ev_read == NULL) {
- taper_ev_read = event_register(taper, EV_READFD,
+ taper_ev_read = event_register((event_id_t)taper, EV_READFD,
handle_taper_result, NULL);
}
- if (dp != NULL) {
+ if (dp) {
taper_disk = dp;
taper_busy = 1;
+ qname = quote_string(dp->name);
taper_cmd(FILE_WRITE, dp, sched(dp)->destname, sched(dp)->level,
- sched(dp)->datestamp);
- fprintf(stderr,"driver: startaflush: %s %s %s %ld %ld\n",
- taperalgo2str(conf_taperalgo), dp->host->hostname,
- dp->name, sched(taper_disk)->act_size, tape_left);
+ sched(dp)->datestamp);
+ fprintf(stderr,"driver: startaflush: %s %s %s "
+ OFF_T_FMT " " OFF_T_FMT "\n",
+ taperalgo2str(conf_taperalgo), dp->host->hostname, qname,
+ (OFF_T_FMT_TYPE)sched(taper_disk)->act_size,
+ (OFF_T_FMT_TYPE)tape_left);
if(sched(dp)->act_size <= tape_left)
tape_left -= sched(dp)->act_size;
else
- tape_left = 0;
+ tape_left = (off_t)0;
+ amfree(qname);
} else {
error("FATAL: Taper marked busy and no work found.");
/*NOTREACHED*/
static int
-client_constrained(dp)
- disk_t *dp;
+client_constrained(
+ disk_t * dp)
{
disk_t *dp2;
}
static void
-start_some_dumps(rq)
- disklist_t *rq;
+start_some_dumps(
+ disklist_t * rq)
{
int cur_idle;
disk_t *diskp, *delayed_diskp, *diskp_accept;
}
if (dumper->ev_read != NULL) {
-/* assert(dumper->ev_read == NULL);*/
event_release(dumper->ev_read);
dumper->ev_read = NULL;
}
cur_idle = NOT_IDLE;
dumporder = getconf_str(CNF_DUMPORDER);
- if(strlen(dumporder) > (dumper-dmptable)) {
+ if(strlen(dumporder) > (size_t)(dumper-dmptable)) {
dumptype = dumporder[dumper-dmptable];
}
else {
for(diskp = rq->head; diskp != NULL; diskp = diskp->next) {
assert(diskp->host != NULL && sched(diskp) != NULL);
- /* round estimate to next multiple of DISK_BLOCK_KB */
- sched(diskp)->est_size = am_round(sched(diskp)->est_size,
- DISK_BLOCK_KB);
-
if (diskp->host->start_t > now) {
cur_idle = max(cur_idle, IDLE_START_WAIT);
if (delayed_diskp == NULL || sleep_time > diskp->host->start_t) {
cur_idle = max(cur_idle, IDLE_NO_BANDWIDTH);
} else if(sched(diskp)->no_space) {
cur_idle = max(cur_idle, IDLE_NO_DISKSPACE);
+ } else if (diskp->to_holdingdisk == HOLD_NEVER) {
+ cur_idle = max(cur_idle, IDLE_NO_HOLD);
} else if ((holdp =
- find_diskspace(sched(diskp)->est_size,&cur_idle,NULL)) == NULL) {
+ find_diskspace(sched(diskp)->est_size, &cur_idle, NULL)) == NULL) {
cur_idle = max(cur_idle, IDLE_NO_DISKSPACE);
- } else if (diskp->no_hold) {
- free_assignedhd(holdp);
- cur_idle = max(cur_idle, IDLE_NO_HOLD);
} else if (client_constrained(diskp)) {
free_assignedhd(holdp);
cur_idle = max(cur_idle, IDLE_CLIENT_CONSTRAINED);
if (diskp == NULL && delayed_diskp != NULL) {
assert(sleep_time > now);
sleep_time -= now;
- dumpers_ev_time = event_register(sleep_time, EV_TIME,
+ dumpers_ev_time = event_register((event_id_t)sleep_time, EV_TIME,
handle_dumpers_time, &runq);
return;
} else if (diskp != NULL) {
- sched(diskp)->act_size = 0;
+ sched(diskp)->act_size = (off_t)0;
allocate_bandwidth(diskp->host->netif, sched(diskp)->est_kps);
sched(diskp)->activehd = assign_holdingdisk(holdp, diskp);
amfree(holdp);
sched(diskp)->dumper = dumper;
sched(diskp)->timestamp = now;
- dumper->ev_read = event_register(dumper->fd, EV_READFD,
- handle_dumper_result, dumper);
dumper->busy = 1; /* dumper is now busy */
dumper->dp = diskp; /* link disk to dumper */
remove_disk(rq, diskp); /* take it off the run queue */
- sched(diskp)->origsize = -1;
- sched(diskp)->dumpsize = -1;
- sched(diskp)->dumptime = -1;
- sched(diskp)->tapetime = -1;
+ sched(diskp)->origsize = (off_t)-1;
+ sched(diskp)->dumpsize = (off_t)-1;
+ sched(diskp)->dumptime = (time_t)0;
+ sched(diskp)->tapetime = (time_t)0;
chunker = dumper->chunker;
chunker->result = LAST_TOK;
dumper->result = LAST_TOK;
startup_chunk_process(chunker,chunker_program);
- chunker_cmd(chunker, START, (void *)datestamp);
+ chunker_cmd(chunker, START, (void *)driver_timestamp);
chunker->dumper = dumper;
chunker_cmd(chunker, PORT_WRITE, diskp);
cmd = getresult(chunker->fd, 1, &result_argc, result_argv, MAX_ARGS+1);
if(cmd != PORT) {
+ assignedhd_t **h=NULL;
+ int activehd;
+
printf("driver: did not get PORT from %s for %s:%s\n",
chunker->name, diskp->host->hostname, diskp->name);
fflush(stdout);
- return ; /* fatal problem */
- }
- chunker->ev_read = event_register(chunker->fd, EV_READFD,
- handle_chunker_result, chunker);
- dumper->output_port = atoi(result_argv[2]);
- dumper_cmd(dumper, PORT_DUMP, diskp);
+ deallocate_bandwidth(diskp->host->netif, sched(diskp)->est_kps);
+ h = sched(diskp)->holdp;
+ activehd = sched(diskp)->activehd;
+ h[activehd]->used = 0;
+ holdalloc(h[activehd]->disk)->allocated_dumpers--;
+ adjust_diskspace(diskp, DONE);
+ delete_diskspace(diskp);
+ diskp->host->inprogress--;
+ diskp->inprogress = 0;
+ sched(diskp)->dumper = NULL;
+ dumper->busy = 0;
+ dumper->dp = NULL;
+ sched(diskp)->attempted++;
+ free_serial_dp(diskp);
+ if(sched(diskp)->attempted < 2)
+ enqueue_disk(rq, diskp);
+ }
+ else {
+ dumper->ev_read = event_register((event_id_t)dumper->fd, EV_READFD,
+ handle_dumper_result, dumper);
+ chunker->ev_read = event_register((event_id_t)chunker->fd, EV_READFD,
+ handle_chunker_result, chunker);
+ dumper->output_port = atoi(result_argv[2]);
+ dumper_cmd(dumper, PORT_DUMP, diskp);
+ }
diskp->host->start_t = now + 15;
- } else if (/* cur_idle != NOT_IDLE && */
- (num_busy_dumpers() > 0 || taper_busy)) {
- /*
- * We are constrained.
- */
}
}
}
* be because a disk has a delayed start, or amanda is constrained
* by network or disk limits.
*/
+
static void
-handle_dumpers_time(cookie)
- void *cookie;
+handle_dumpers_time(
+ void * cookie)
{
disklist_t *runq = cookie;
event_release(dumpers_ev_time);
}
static void
-dump_schedule(qp, str)
- disklist_t *qp;
- char *str;
+dump_schedule(
+ disklist_t *qp,
+ char * str)
{
disk_t *dp;
+ char *qname;
printf("dump of driver schedule %s:\n--------\n", str);
for(dp = qp->head; dp != NULL; dp = dp->next) {
- printf(" %-20s %-25s lv %d t %5ld s %8lu p %d\n",
- dp->host->hostname, dp->name, sched(dp)->level,
- sched(dp)->est_time, sched(dp)->est_size, sched(dp)->priority);
+ qname = quote_string(dp->name);
+ printf(" %-20s %-25s lv %d t %5lu s " OFF_T_FMT " p %d\n",
+ dp->host->hostname, qname, sched(dp)->level,
+ sched(dp)->est_time,
+ (OFF_T_FMT_TYPE)sched(dp)->est_size, sched(dp)->priority);
+ amfree(qname);
}
printf("--------\n");
}
static void
-start_degraded_mode(queuep)
- disklist_t *queuep;
+start_degraded_mode(
+ /*@keep@*/ disklist_t *queuep)
{
disk_t *dp;
disklist_t newq;
- unsigned long est_full_size;
+ off_t est_full_size;
+ char *qname;
if (taper_ev_read != NULL) {
event_release(taper_ev_read);
dump_schedule(queuep, "before start degraded mode");
- est_full_size = 0;
+ est_full_size = (off_t)0;
while(!empty(*queuep)) {
dp = dequeue_disk(queuep);
+ qname = quote_string(dp->name);
if(sched(dp)->level != 0)
/* go ahead and do the disk as-is */
enqueue_disk(&newq, dp);
else if(sched(dp)->degr_level != -1) {
sched(dp)->level = sched(dp)->degr_level;
sched(dp)->dumpdate = sched(dp)->degr_dumpdate;
- sched(dp)->est_size = sched(dp)->degr_size;
+ sched(dp)->est_nsize = sched(dp)->degr_nsize;
+ sched(dp)->est_csize = sched(dp)->degr_csize;
sched(dp)->est_time = sched(dp)->degr_time;
sched(dp)->est_kps = sched(dp)->degr_kps;
enqueue_disk(&newq, dp);
}
else {
log_add(L_FAIL,"%s %s %s %d [can't switch to incremental dump]",
- dp->host->hostname, dp->name, sched(dp)->datestamp,
+ dp->host->hostname, qname, sched(dp)->datestamp,
sched(dp)->level);
}
}
+ amfree(qname);
}
- *queuep = newq;
+ /*@i@*/ *queuep = newq;
degraded_mode = 1;
dump_schedule(queuep, "after start degraded mode");
}
-static void continue_port_dumps()
+static void
+continue_port_dumps(void)
{
disk_t *dp, *ndp;
assignedhd_t **h;
for( dp = roomq.head; dp; dp = ndp ) {
ndp = dp->next;
/* find last holdingdisk used by this dump */
- for( i = 0, h = sched(dp)->holdp; h[i+1]; i++ );
+ for( i = 0, h = sched(dp)->holdp; h[i+1]; i++ ) {
+ (void)h; /* Quiet lint */
+ }
/* find more space */
h = find_diskspace( sched(dp)->est_size - sched(dp)->act_size,
&active_dumpers, h[i] );
if( h ) {
for(dumper = dmptable; dumper < dmptable + inparallel &&
- dumper->dp != dp; dumper++);
+ dumper->dp != dp; dumper++) {
+ (void)dp; /* Quiet lint */
+ }
assert( dumper < dmptable + inparallel );
sched(dp)->activehd = assign_holdingdisk( h, dp );
chunker_cmd( dumper->chunker, CONTINUE, dp );
* We abort that dump, hopefully not wasting too much time retrying it.
*/
remove_disk( &roomq, dp );
- chunker_cmd( sched(dp)->dumper->chunker, ABORT, NULL );
+ chunker_cmd( sched(dp)->dumper->chunker, ABORT, NULL);
dumper_cmd( sched(dp)->dumper, ABORT, NULL );
pending_aborts++;
}
static void
-handle_taper_result(void *cookie)
+handle_taper_result(
+ void * cookie)
{
disk_t *dp;
- int filenum;
+ off_t filenum;
cmd_t cmd;
int result_argc;
char *result_argv[MAX_ARGS+1];
int avail_tapes = 0;
+ (void)cookie; /* Quiet unused parameter warning */
+
assert(cookie == NULL);
do {
case DONE: /* DONE <handle> <label> <tape file> <err mess> */
if(result_argc != 5) {
error("error: [taper DONE result_argc != 5: %d", result_argc);
+ /*NOTREACHED*/
}
dp = serial2disk(result_argv[2]);
free_serial(result_argv[2]);
- filenum = atoi(result_argv[4]);
+ filenum = OFF_T_ATOI(result_argv[4]);
if(cmd == DONE) {
update_info_taper(dp, result_argv[3], filenum,
sched(dp)->level);
if (result_argc < 2) {
error("error [taper TRYAGAIN result_argc < 2: %d]",
result_argc);
+ /*NOTREACHED*/
}
dp = serial2disk(result_argv[2]);
free_serial(result_argv[2]);
/* See how many tapes we have left, but we alwyays
retry once (why?) */
current_tape++;
- if(dp->tape_splitsize > 0)
+ if(dp->tape_splitsize > (off_t)0)
avail_tapes = conf_runtapes - current_tape;
else
avail_tapes = 0;
if (result_argc != 3) {
error("error [taper SPLIT_CONTINUE result_argc != 3: %d]",
result_argc);
+ /*NOTREACHED*/
}
break;
if (result_argc != 3) {
error("error [taper SPLIT_NEEDNEXT result_argc != 3: %d]",
result_argc);
+ /*NOTREACHED*/
}
/* Update our tape counter and reset tape_left */
/* Reduce the size of the dump by amount written and reduce
tape_left by the amount left over */
dp = serial2disk(result_argv[2]);
- sched(dp)->act_size -= atoi(result_argv[3]);
+ sched(dp)->act_size -= OFF_T_ATOI(result_argv[3]);
if (sched(dp)->act_size < tape_left)
tape_left -= sched(dp)->act_size;
else
walltime_str(curclock()), dp->host->hostname, dp->name);
fflush(stdout);
log_add(L_WARNING, "Taper error: %s", result_argv[3]);
- /* FALLSTHROUGH */
+ /*FALLTHROUGH*/
case BOGUS:
if (cmd == BOGUS) {
log_add(L_WARNING, "Taper protocol error");
}
/*
- * Since we've gotten a taper error, we can't send anything more
+ * Since we received a taper error, we can't send anything more
* to the taper. Go into degraded mode to try to get everthing
* onto disk. Later, these dumps can be flushed to a new tape.
* The tape queue is zapped so that it appears empty in future
default:
error("driver received unexpected token (%s) from taper",
cmdstr[cmd]);
+ /*NOTREACHED*/
}
/*
* Wakeup any dumpers that are sleeping because of network
}
static dumper_t *
-idle_dumper()
+idle_dumper(void)
{
dumper_t *dumper;
return NULL;
}
-static int
-num_busy_dumpers()
-{
- dumper_t *dumper;
- int n;
-
- n = 0;
- for(dumper = dmptable; dumper < dmptable+inparallel; dumper++)
- if(dumper->busy) n += 1;
-
- return n;
-}
-
-
static void
-dumper_result(dp)
- disk_t *dp;
+dumper_result(
+ disk_t * dp)
{
dumper_t *dumper;
chunker_t *chunker;
assignedhd_t **h=NULL;
- int activehd, i, dummy;
- long size;
+ int activehd, i;
+ off_t dummy;
+ off_t size;
int is_partial;
dumper = sched(dp)->dumper;
if(dumper->result == DONE && chunker->result == DONE) {
update_info_dumper(dp, sched(dp)->origsize,
sched(dp)->dumpsize, sched(dp)->dumptime);
+ log_add(L_STATS, "estimate %s %s %s %d [sec %ld nkb " OFF_T_FMT
+ " ckb " OFF_T_FMT " kps %d]",
+ dp->host->hostname, dp->name, sched(dp)->datestamp,
+ sched(dp)->level,
+ sched(dp)->est_time, (OFF_T_FMT_TYPE)sched(dp)->est_nsize,
+ (OFF_T_FMT_TYPE)sched(dp)->est_csize,
+ sched(dp)->est_kps);
}
deallocate_bandwidth(dp->host->netif, sched(dp)->est_kps);
is_partial = dumper->result != DONE || chunker->result != DONE;
rename_tmp_holding(sched(dp)->destname, !is_partial);
- dummy = 0;
+ dummy = (off_t)0;
for( i = 0, h = sched(dp)->holdp; i < activehd; i++ ) {
dummy += h[i]->used;
}
delete_diskspace(dp);
enqueue_disk(&runq, dp);
}
- else if(size > DISK_BLOCK_KB) {
+ else if(size > (off_t)DISK_BLOCK_KB) {
sched(dp)->attempted = 0;
enqueue_disk(&tapeq, dp);
startaflush();
chunker->down = 1;
dp = NULL;
+ if (chunker->result == ABORT_FINISHED)
+ pending_aborts--;
continue_port_dumps();
/*
* Wakeup any dumpers that are sleeping because of network
static void
-handle_dumper_result(cookie)
- void *cookie;
+handle_dumper_result(
+ void * cookie)
{
/*static int pending_aborts = 0;*/
dumper_t *dumper = cookie;
disk_t *dp, *sdp;
cmd_t cmd;
int result_argc;
+ char *qname;
char *result_argv[MAX_ARGS+1];
assert(dumper != NULL);
if(cmd != BOGUS) {
/* result_argv[2] always contains the serial number */
sdp = serial2disk(result_argv[2]);
- assert(sdp == dp);
+ if (sdp != dp) {
+ error("%s: Invalid serial number", get_pname(), result_argv[2]);
+ /*NOTREACHED*/
+ }
}
+ qname = quote_string(dp->name);
switch(cmd) {
case DONE: /* DONE <handle> <origsize> <dumpsize> <dumptime> <errstr> */
if(result_argc != 6) {
error("error [dumper DONE result_argc != 6: %d]", result_argc);
+ /*NOTREACHED*/
}
/*free_serial(result_argv[2]);*/
- sched(dp)->origsize = (long)atof(result_argv[3]);
- sched(dp)->dumptime = (long)atof(result_argv[5]);
+ sched(dp)->origsize = OFF_T_ATOI(result_argv[3]);
+ sched(dp)->dumptime = TIME_T_ATOI(result_argv[5]);
printf("driver: finished-cmd time %s %s dumped %s:%s\n",
walltime_str(curclock()), dumper->name,
- dp->host->hostname, dp->name);
+ dp->host->hostname, qname);
fflush(stdout);
dumper->result = cmd;
/* either EOF or garbage from dumper. Turn it off */
log_add(L_WARNING, "%s pid %ld is messed up, ignoring it.\n",
dumper->name, (long)dumper->pid);
- event_release(dumper->ev_read);
- dumper->ev_read = NULL;
+ if (dumper->ev_read) {
+ event_release(dumper->ev_read);
+ dumper->ev_read = NULL;
+ }
aclose(dumper->fd);
dumper->busy = 0;
dumper->down = 1; /* mark it down so it isn't used again */
/* if it was dumping something, zap it and try again */
if(sched(dp)->attempted) {
log_add(L_FAIL, "%s %s %s %d [%s died]",
- dp->host->hostname, dp->name, sched(dp)->datestamp,
+ dp->host->hostname, qname, sched(dp)->datestamp,
sched(dp)->level, dumper->name);
}
else {
log_add(L_WARNING, "%s died while dumping %s:%s lev %d.",
- dumper->name, dp->host->hostname, dp->name,
+ dumper->name, dp->host->hostname, qname,
sched(dp)->level);
}
}
default:
assert(0);
}
+ amfree(qname);
+
/* send the dumper result to the chunker */
- if(dumper->chunker->down == 0 && dumper->chunker->fd != -1) {
+ if(dumper->chunker->down == 0 && dumper->chunker->fd != -1 &&
+ dumper->chunker->result == LAST_TOK) {
if(cmd == DONE) {
chunker_cmd(dumper->chunker, DONE, dp);
}
static void
-handle_chunker_result(cookie)
- void *cookie;
+handle_chunker_result(
+ void * cookie)
{
/*static int pending_aborts = 0;*/
chunker_t *chunker = cookie;
char *result_argv[MAX_ARGS+1];
int dummy;
int activehd = -1;
-
+ char *qname;
assert(chunker != NULL);
dumper = chunker->dumper;
if(cmd != BOGUS) {
/* result_argv[2] always contains the serial number */
sdp = serial2disk(result_argv[2]);
- assert(sdp == dp);
+ if (sdp != dp) {
+ error("%s: Invalid serial number", get_pname(), result_argv[2]);
+ /*NOTREACHED*/
+ }
}
switch(cmd) {
if(result_argc != 4) {
error("error [chunker %s result_argc != 4: %d]", cmdstr[cmd],
result_argc);
+ /*NOTREACHED*/
}
/*free_serial(result_argv[2]);*/
- sched(dp)->dumpsize = (long)atof(result_argv[3]);
+ sched(dp)->dumpsize = (off_t)atof(result_argv[3]);
+ qname = quote_string(dp->name);
printf("driver: finished-cmd time %s %s chunked %s:%s\n",
walltime_str(curclock()), chunker->name,
- dp->host->hostname, dp->name);
+ dp->host->hostname, qname);
fflush(stdout);
+ amfree(qname);
event_release(chunker->ev_read);
break;
case TRYAGAIN: /* TRY-AGAIN <handle> <errstr> */
- assert(0);
event_release(chunker->ev_read);
+ chunker->result = cmd;
+
break;
case FAILED: /* FAILED <handle> <errstr> */
/*free_serial(result_argv[2]);*/
break;
case NO_ROOM: /* NO-ROOM <handle> <missing_size> */
- assert( h && activehd >= 0 );
- h[activehd]->used -= atoi(result_argv[3]);
- h[activehd]->reserved -= atoi(result_argv[3]);
- holdalloc(h[activehd]->disk)->allocated_space -= atoi(result_argv[3]);
- h[activehd]->disk->disksize -= atoi(result_argv[3]);
+ if (!h || activehd < 0) { /* should never happen */
+ error("!h || activehd < 0");
+ /*NOTREACHED*/
+ }
+ h[activehd]->used -= OFF_T_ATOI(result_argv[3]);
+ h[activehd]->reserved -= OFF_T_ATOI(result_argv[3]);
+ holdalloc(h[activehd]->disk)->allocated_space -= OFF_T_ATOI(result_argv[3]);
+ h[activehd]->disk->disksize -= OFF_T_ATOI(result_argv[3]);
break;
case RQ_MORE_DISK: /* RQ-MORE-DISK <handle> */
- assert( h && activehd >= 0 );
+ if (!h || activehd < 0) { /* should never happen */
+ error("!h || activehd < 0");
+ /*NOTREACHED*/
+ }
holdalloc(h[activehd]->disk)->allocated_dumpers--;
h[activehd]->used = h[activehd]->reserved;
if( h[++activehd] ) { /* There's still some allocated space left.
chunker_cmd( chunker, CONTINUE, dp );
} else { /* !h[++activehd] - must allocate more space */
sched(dp)->act_size = sched(dp)->est_size; /* not quite true */
- sched(dp)->est_size = (sched(dp)->act_size/20) * 21; /* +5% */
- sched(dp)->est_size = am_round(sched(dp)->est_size, DISK_BLOCK_KB);
- if(sched(dp)->est_size <= sched(dp)->act_size + DISK_BLOCK_KB)
- sched(dp)->est_size = sched(dp)->act_size +
- 2 * DISK_BLOCK_KB;
+ sched(dp)->est_size = (sched(dp)->act_size/(off_t)20) * (off_t)21; /* +5% */
+ sched(dp)->est_size = am_round(sched(dp)->est_size, (off_t)DISK_BLOCK_KB);
+ if (sched(dp)->est_size < sched(dp)->act_size + 2*DISK_BLOCK_KB)
+ sched(dp)->est_size += 2 * DISK_BLOCK_KB;
h = find_diskspace( sched(dp)->est_size - sched(dp)->act_size,
&dummy,
h[activehd-1] );
if(dp) {
/* if it was dumping something, zap it and try again */
- assert( h && activehd >= 0 );
+ if (!h || activehd < 0) { /* should never happen */
+ error("!h || activehd < 0");
+ /*NOTREACHED*/
+ }
+ qname = quote_string(dp->name);
if(sched(dp)->attempted) {
log_add(L_FAIL, "%s %s %s %d [%s died]",
- dp->host->hostname, dp->name, sched(dp)->datestamp,
+ dp->host->hostname, qname, sched(dp)->datestamp,
sched(dp)->level, chunker->name);
}
else {
log_add(L_WARNING, "%s died while dumping %s:%s lev %d.",
- chunker->name, dp->host->hostname, dp->name,
+ chunker->name, dp->host->hostname, qname,
sched(dp)->level);
}
+ amfree(qname);
dp = NULL;
}
static disklist_t
-read_flush()
+read_flush(void)
{
sched_t *sp;
disk_t *dp;
char *s;
int ch;
disklist_t tq;
+ char *qname = NULL;
tq.head = tq.tail = NULL;
for(line = 0; (inpline = agets(stdin)) != NULL; free(inpline)) {
line++;
+ if (inpline[0] == '\0')
+ continue;
s = inpline;
ch = *s++;
skip_whitespace(s, ch); /* find the command */
if(ch == '\0') {
error("flush line %d: syntax error (no command)", line);
- continue;
+ /*NOTREACHED*/
}
command = s - 1;
skip_non_whitespace(s, ch);
if(strcmp(command,"FLUSH") != 0) {
error("flush line %d: syntax error (%s != FLUSH)", line, command);
- continue;
+ /*NOTREACHED*/
}
skip_whitespace(s, ch); /* find the hostname */
if(ch == '\0') {
error("flush line %d: syntax error (no hostname)", line);
- continue;
+ /*NOTREACHED*/
}
hostname = s - 1;
skip_non_whitespace(s, ch);
skip_whitespace(s, ch); /* find the diskname */
if(ch == '\0') {
error("flush line %d: syntax error (no diskname)", line);
- continue;
+ /*NOTREACHED*/
}
- diskname = s - 1;
- skip_non_whitespace(s, ch);
- s[-1] = '\0';
+ qname = s - 1;
+ skip_quoted_string(s, ch);
+ s[-1] = '\0'; /* terminate the disk name */
+ diskname = unquote_string(qname);
skip_whitespace(s, ch); /* find the datestamp */
if(ch == '\0') {
error("flush line %d: syntax error (no datestamp)", line);
- continue;
+ /*NOTREACHED*/
}
datestamp = s - 1;
skip_non_whitespace(s, ch);
skip_whitespace(s, ch); /* find the level number */
if(ch == '\0' || sscanf(s - 1, "%d", &level) != 1) {
error("flush line %d: syntax error (bad level)", line);
- continue;
+ /*NOTREACHED*/
}
skip_integer(s, ch);
skip_whitespace(s, ch); /* find the filename */
if(ch == '\0') {
error("flush line %d: syntax error (no filename)", line);
- continue;
+ /*NOTREACHED*/
}
destname = s - 1;
skip_non_whitespace(s, ch);
if( file.type != F_DUMPFILE) {
if( file.type != F_CONT_DUMPFILE )
log_add(L_INFO, "%s: ignoring cruft file.", destname);
+ amfree(diskname);
continue;
}
strcmp(datestamp, file.datestamp) != 0) {
log_add(L_INFO, "disk %s:%s not consistent with file %s",
hostname, diskname, destname);
+ amfree(diskname);
continue;
}
+ amfree(diskname);
dp = lookup_disk(file.name, file.disk);
continue;
}
- dp1 = (disk_t *)alloc(sizeof(disk_t));
+ dp1 = (disk_t *)alloc(SIZEOF(disk_t));
*dp1 = *dp;
dp1->next = dp1->prev = NULL;
/* add it to the flushhost list */
if(!flushhost) {
- flushhost = alloc(sizeof(am_host_t));
+ flushhost = alloc(SIZEOF(am_host_t));
flushhost->next = NULL;
flushhost->hostname = stralloc("FLUSHHOST");
flushhost->up = NULL;
dp1->hostnext = flushhost->disks;
flushhost->disks = dp1;
- sp = (sched_t *) alloc(sizeof(sched_t));
+ sp = (sched_t *) alloc(SIZEOF(sched_t));
sp->destname = stralloc(destname);
sp->level = file.dumplevel;
sp->dumpdate = NULL;
sp->degr_dumpdate = NULL;
sp->datestamp = stralloc(file.datestamp);
- sp->est_size = 0;
+ sp->est_nsize = (off_t)0;
+ sp->est_csize = (off_t)0;
sp->est_time = 0;
+ sp->est_kps = 10;
sp->priority = 0;
sp->degr_level = -1;
- sp->est_kps = 10;
sp->attempted = 0;
sp->act_size = size_holding_files(destname, 0);
sp->holdp = build_diskspace(destname);
}
amfree(inpline);
- return tq;
+ /*@i@*/ return tq;
}
static void
-read_schedule(cookie)
- void *cookie;
+read_schedule(
+ void * cookie)
{
sched_t *sp;
disk_t *dp;
- disklist_t rq;
int level, line, priority;
char *dumpdate, *degr_dumpdate;
int degr_level;
- long time, degr_time;
- unsigned long size, degr_size;
+ time_t time, degr_time;
+ time_t *time_p = &time;
+ time_t *degr_time_p = °r_time;
+ off_t nsize, csize, degr_nsize, degr_csize;
+ unsigned long kps, degr_kps;
char *hostname, *features, *diskname, *datestamp, *inpline = NULL;
char *command;
char *s;
int ch;
- long flush_size = 0;
+ off_t flush_size = (off_t)0;
+ char *qname = NULL;
- rq.head = rq.tail = NULL;
+ (void)cookie; /* Quiet unused parameter warning */
event_release(schedule_ev_read);
/* read schedule from stdin */
for(line = 0; (inpline = agets(stdin)) != NULL; free(inpline)) {
+ if (inpline[0] == '\0')
+ continue;
line++;
s = inpline;
skip_whitespace(s, ch); /* find the command */
if(ch == '\0') {
error("schedule line %d: syntax error (no command)", line);
- continue;
+ /*NOTREACHED*/
}
command = s - 1;
skip_non_whitespace(s, ch);
if(strcmp(command,"DUMP") != 0) {
error("schedule line %d: syntax error (%s != DUMP)", line, command);
- continue;
+ /*NOTREACHED*/
}
skip_whitespace(s, ch); /* find the host name */
if(ch == '\0') {
error("schedule line %d: syntax error (no host name)", line);
- continue;
+ /*NOTREACHED*/
}
hostname = s - 1;
skip_non_whitespace(s, ch);
skip_whitespace(s, ch); /* find the feature list */
if(ch == '\0') {
error("schedule line %d: syntax error (no feature list)", line);
- continue;
+ /*NOTREACHED*/
}
features = s - 1;
skip_non_whitespace(s, ch);
skip_whitespace(s, ch); /* find the disk name */
if(ch == '\0') {
error("schedule line %d: syntax error (no disk name)", line);
- continue;
+ /*NOTREACHED*/
}
- diskname = s - 1;
- skip_non_whitespace(s, ch);
- s[-1] = '\0';
+ qname = s - 1;
+ skip_quoted_string(s, ch);
+ s[-1] = '\0'; /* terminate the disk name */
+ diskname = unquote_string(qname);
skip_whitespace(s, ch); /* find the datestamp */
if(ch == '\0') {
error("schedule line %d: syntax error (no datestamp)", line);
- continue;
+ /*NOTREACHED*/
}
datestamp = s - 1;
skip_non_whitespace(s, ch);
skip_whitespace(s, ch); /* find the priority number */
if(ch == '\0' || sscanf(s - 1, "%d", &priority) != 1) {
error("schedule line %d: syntax error (bad priority)", line);
- continue;
+ /*NOTREACHED*/
}
skip_integer(s, ch);
skip_whitespace(s, ch); /* find the level number */
if(ch == '\0' || sscanf(s - 1, "%d", &level) != 1) {
error("schedule line %d: syntax error (bad level)", line);
- continue;
+ /*NOTREACHED*/
}
skip_integer(s, ch);
skip_whitespace(s, ch); /* find the dump date */
if(ch == '\0') {
error("schedule line %d: syntax error (bad dump date)", line);
- continue;
+ /*NOTREACHED*/
}
dumpdate = s - 1;
skip_non_whitespace(s, ch);
s[-1] = '\0';
- skip_whitespace(s, ch); /* find the size number */
- if(ch == '\0' || sscanf(s - 1, "%lu", &size) != 1) {
- error("schedule line %d: syntax error (bad size)", line);
- continue;
+ skip_whitespace(s, ch); /* find the native size */
+ if(ch == '\0' || sscanf(s - 1, OFF_T_FMT,
+ (OFF_T_FMT_TYPE *)&nsize) != 1) {
+ error("schedule line %d: syntax error (bad nsize)", line);
+ /*NOTREACHED*/
+ }
+ skip_integer(s, ch);
+
+ skip_whitespace(s, ch); /* find the compressed size */
+ if(ch == '\0' || sscanf(s - 1, OFF_T_FMT,
+ (OFF_T_FMT_TYPE *)&csize) != 1) {
+ error("schedule line %d: syntax error (bad csize)", line);
+ /*NOTREACHED*/
}
skip_integer(s, ch);
skip_whitespace(s, ch); /* find the time number */
- if(ch == '\0' || sscanf(s - 1, "%ld", &time) != 1) {
+ if(ch == '\0' || sscanf(s - 1, TIME_T_FMT,
+ (TIME_T_FMT_TYPE *)time_p) != 1) {
error("schedule line %d: syntax error (bad estimated time)", line);
+ /*NOTREACHED*/
+ }
+ skip_integer(s, ch);
+
+ skip_whitespace(s, ch); /* find the kps number */
+ if(ch == '\0' || sscanf(s - 1, "%lu", &kps) != 1) {
+ error("schedule line %d: syntax error (bad kps)", line);
continue;
}
skip_integer(s, ch);
if(ch != '\0') {
if(sscanf(s - 1, "%d", °r_level) != 1) {
error("schedule line %d: syntax error (bad degr level)", line);
- continue;
+ /*NOTREACHED*/
}
skip_integer(s, ch);
skip_whitespace(s, ch); /* find the degr dump date */
if(ch == '\0') {
error("schedule line %d: syntax error (bad degr dump date)", line);
- continue;
+ /*NOTREACHED*/
}
degr_dumpdate = s - 1;
skip_non_whitespace(s, ch);
s[-1] = '\0';
- skip_whitespace(s, ch); /* find the degr size number */
- if(ch == '\0' || sscanf(s - 1, "%lu", °r_size) != 1) {
- error("schedule line %d: syntax error (bad degr size)", line);
- continue;
+ skip_whitespace(s, ch); /* find the degr native size */
+ if(ch == '\0' || sscanf(s - 1, OFF_T_FMT,
+ (OFF_T_FMT_TYPE *)°r_nsize) != 1) {
+ error("schedule line %d: syntax error (bad degr nsize)", line);
+ /*NOTREACHED*/
+ }
+ skip_integer(s, ch);
+
+ skip_whitespace(s, ch); /* find the degr compressed size */
+ if(ch == '\0' || sscanf(s - 1, OFF_T_FMT,
+ (OFF_T_FMT_TYPE *)°r_csize) != 1) {
+ error("schedule line %d: syntax error (bad degr csize)", line);
+ /*NOTREACHED*/
}
skip_integer(s, ch);
skip_whitespace(s, ch); /* find the degr time number */
- if(ch == '\0' || sscanf(s - 1, "%lu", °r_time) != 1) {
+ if(ch == '\0' || sscanf(s - 1, TIME_T_FMT,
+ (TIME_T_FMT_TYPE *)degr_time_p) != 1) {
error("schedule line %d: syntax error (bad degr estimated time)", line);
- continue;
+ /*NOTREACHED*/
+ }
+ skip_integer(s, ch);
+
+ skip_whitespace(s, ch); /* find the degr kps number */
+ if(ch == '\0' || sscanf(s - 1, "%lu", °r_kps) != 1) {
+ error("schedule line %d: syntax error (bad degr kps)", line);
+ /*NOTREACHED*/
}
skip_integer(s, ch);
}
dp = lookup_disk(hostname, diskname);
if(dp == NULL) {
log_add(L_WARNING,
- "schedule line %d: %s:%s not in disklist, ignored",
- line, hostname, diskname);
+ "schedule line %d: %s:'%s' not in disklist, ignored",
+ line, hostname, qname);
+ amfree(diskname);
continue;
}
- sp = (sched_t *) alloc(sizeof(sched_t));
- sp->level = level;
+ sp = (sched_t *) alloc(SIZEOF(sched_t));
+ /*@ignore@*/
+ sp->level = level;
sp->dumpdate = stralloc(dumpdate);
- sp->est_size = DISK_BLOCK_KB + size; /* include header */
+ sp->est_nsize = DISK_BLOCK_KB + nsize; /* include header */
+ sp->est_csize = DISK_BLOCK_KB + csize; /* include header */
+ /* round estimate to next multiple of DISK_BLOCK_KB */
+ sp->est_csize = am_round(sp->est_csize, DISK_BLOCK_KB);
+ sp->est_size = sp->est_csize;
sp->est_time = time;
+ sp->est_kps = kps;
sp->priority = priority;
sp->datestamp = stralloc(datestamp);
if(degr_dumpdate) {
sp->degr_level = degr_level;
sp->degr_dumpdate = stralloc(degr_dumpdate);
- sp->degr_size = DISK_BLOCK_KB + degr_size;
+ sp->degr_nsize = DISK_BLOCK_KB + degr_nsize;
+ sp->degr_csize = DISK_BLOCK_KB + degr_csize;
+ /* round estimate to next multiple of DISK_BLOCK_KB */
+ sp->degr_csize = am_round(sp->degr_csize, DISK_BLOCK_KB);
sp->degr_time = degr_time;
+ sp->degr_kps = degr_kps;
} else {
sp->degr_level = -1;
sp->degr_dumpdate = NULL;
}
-
- if(time <= 0)
- sp->est_kps = 10;
- else
- sp->est_kps = size/time;
-
- if(sp->degr_level != -1) {
- if(degr_time <= 0)
- sp->degr_kps = 10;
- else
- sp->degr_kps = degr_size/degr_time;
- }
+ /*@end@*/
sp->attempted = 0;
- sp->act_size = 0;
+ sp->act_size = (off_t)0;
sp->holdp = NULL;
sp->activehd = -1;
sp->dumper = NULL;
remove_disk(&waitq, dp);
enqueue_disk(&runq, dp);
flush_size += sp->act_size;
+ amfree(diskname);
}
- printf("driver: flush size %ld\n", flush_size);
+ printf("driver: flush size " OFF_T_FMT "\n", (OFF_T_FMT_TYPE)flush_size);
amfree(inpline);
if(line == 0)
log_add(L_WARNING, "WARNING: got empty schedule from planner");
start_some_dumps(&runq);
}
-static int
-free_kps(ip)
- interface_t *ip;
+static unsigned long
+free_kps(
+ interface_t *ip)
{
- int res;
+ unsigned long res;
if (ip == (interface_t *)0) {
interface_t *p;
- int maxusage=0;
- int curusage=0;
+ unsigned long maxusage=0;
+ unsigned long curusage=0;
for(p = lookup_interface(NULL); p != NULL; p = p->next) {
- maxusage += p->maxusage;
+ maxusage += interface_get_maxusage(p);
curusage += p->curusage;
}
res = maxusage - curusage;
- }
- else {
- res = ip->maxusage - ip->curusage;
+#ifndef __lint
+ } else {
+ res = interface_get_maxusage(ip) - ip->curusage;
+#endif
}
return res;
}
static void
-interface_state(time_str)
- char *time_str;
+interface_state(
+ char *time_str)
{
interface_t *ip;
printf("driver: interface-state time %s", time_str);
for(ip = lookup_interface(NULL); ip != NULL; ip = ip->next) {
- printf(" if %s: free %d", ip->name, free_kps(ip));
+ printf(" if %s: free %lu", ip->name, free_kps(ip));
}
printf("\n");
}
static void
-allocate_bandwidth(ip, kps)
- interface_t *ip;
- int kps;
+allocate_bandwidth(
+ interface_t * ip,
+ unsigned long kps)
{
ip->curusage += kps;
}
static void
-deallocate_bandwidth(ip, kps)
- interface_t *ip;
- int kps;
+deallocate_bandwidth(
+ interface_t * ip,
+ unsigned long kps)
{
assert(kps <= ip->curusage);
ip->curusage -= kps;
}
/* ------------ */
-static unsigned long
-free_space()
+static off_t
+free_space(void)
{
holdingdisk_t *hdp;
- unsigned long total_free;
- long diff;
+ off_t total_free;
+ off_t diff;
- total_free = 0L;
+ total_free = (off_t)0;
for(hdp = getconf_holdingdisks(); hdp != NULL; hdp = hdp->next) {
diff = hdp->disksize - holdalloc(hdp)->allocated_space;
- if(diff > 0)
+ if(diff > (off_t)0)
total_free += diff;
}
return total_free;
}
-static assignedhd_t **
-find_diskspace(size, cur_idle, pref)
- unsigned long size;
- int *cur_idle;
- assignedhd_t *pref;
-/* We return an array of pointers to assignedhd_t. The array contains at
+/*
+ * We return an array of pointers to assignedhd_t. The array contains at
* most one entry per holding disk. The list of pointers is terminated by
* a NULL pointer. Each entry contains a pointer to a holdingdisk and
* how much diskspace to use on that disk. Later on, assign_holdingdisk
* If there is not enough room on the holdingdisks, NULL is returned.
*/
+static assignedhd_t **
+find_diskspace(
+ off_t size,
+ int * cur_idle,
+ assignedhd_t * pref)
{
assignedhd_t **result = NULL;
holdingdisk_t *minp, *hdp;
int i=0, num_holdingdisks=0; /* are we allowed to use the global thing? */
int j, minj;
char *used;
- long halloc, dalloc, hfree, dfree;
+ off_t halloc, dalloc, hfree, dfree;
- size = am_round(size, DISK_BLOCK_KB);
+ (void)cur_idle; /* Quiet unused parameter warning */
+
+ if (size < 2*DISK_BLOCK_KB)
+ size = 2*DISK_BLOCK_KB;
+ size = am_round(size, (off_t)DISK_BLOCK_KB);
#ifdef HOLD_DEBUG
- printf("%s: want %lu K\n", debug_prefix_time(": find_diskspace"), size);
+ printf("%s: want " OFF_T_FMT " K\n", debug_prefix_time(": find_diskspace"),
+ (OFF_T_FMT_TYPE)size);
fflush(stdout);
#endif
num_holdingdisks++;
}
- used = alloc(sizeof(char) * num_holdingdisks);/*disks used during this run*/
- memset( used, 0, num_holdingdisks );
- result = alloc( sizeof(assignedhd_t *) * (num_holdingdisks+1) );
+ used = alloc(SIZEOF(*used) * num_holdingdisks);/*disks used during this run*/
+ memset( used, 0, (size_t)num_holdingdisks );
+ result = alloc(SIZEOF(assignedhd_t *) * (num_holdingdisks + 1));
result[0] = NULL;
- while( i < num_holdingdisks && size > 0 ) {
+ while( i < num_holdingdisks && size > (off_t)0 ) {
/* find the holdingdisk with the fewest active dumpers and among
* those the one with the biggest free space
*/
minp = NULL; minj = -1;
for(j = 0, hdp = getconf_holdingdisks(); hdp != NULL; hdp = hdp->next, j++ ) {
if( pref && pref->disk == hdp && !used[j] &&
- holdalloc(hdp)->allocated_space <= hdp->disksize - DISK_BLOCK_KB) {
+ holdalloc(hdp)->allocated_space <= hdp->disksize - (off_t)DISK_BLOCK_KB) {
minp = hdp;
minj = j;
break;
}
- else if( holdalloc(hdp)->allocated_space <= hdp->disksize - 2*DISK_BLOCK_KB &&
+ else if( holdalloc(hdp)->allocated_space <= hdp->disksize - (off_t)(2*DISK_BLOCK_KB) &&
!used[j] &&
(!minp ||
holdalloc(hdp)->allocated_dumpers < holdalloc(minp)->allocated_dumpers ||
hfree = minp->disksize - holdalloc(minp)->allocated_space;
/* dfree = free space for data, remove 1 header for each chunksize */
- dfree = hfree - (((hfree-1)/minp->chunksize)+1) * DISK_BLOCK_KB;
+ dfree = hfree - (((hfree-(off_t)1)/holdingdisk_get_chunksize(minp))+(off_t)1) * (off_t)DISK_BLOCK_KB;
/* dalloc = space I can allocate for data */
dalloc = ( dfree < size ) ? dfree : size;
/* halloc = space to allocate, including 1 header for each chunksize */
- halloc = dalloc + (((dalloc-1)/minp->chunksize)+1) * DISK_BLOCK_KB;
+ halloc = dalloc + (((dalloc-(off_t)1)/holdingdisk_get_chunksize(minp))+(off_t)1) * (off_t)DISK_BLOCK_KB;
#ifdef HOLD_DEBUG
- printf("%s: find diskspace: size %ld hf %ld df %ld da %ld ha %ld\n",
+ printf("%s: find diskspace: size " OFF_T_FMT " hf " OFF_T_FMT
+ " df " OFF_T_FMT " da " OFF_T_FMT " ha " OFF_T_FMT "\n",
debug_prefix_time(": find_diskspace"),
- size, hfree, dfree, dalloc, halloc);
+ (OFF_T_FMT_TYPE)size,
+ (OFF_T_FMT_TYPE)hfree,
+ (OFF_T_FMT_TYPE)dfree,
+ (OFF_T_FMT_TYPE)dalloc,
+ (OFF_T_FMT_TYPE)halloc);
fflush(stdout);
#endif
size -= dalloc;
- result[i] = alloc(sizeof(assignedhd_t));
+ result[i] = alloc(SIZEOF(assignedhd_t));
result[i]->disk = minp;
result[i]->reserved = halloc;
- result[i]->used = 0;
+ result[i]->used = (off_t)0;
result[i]->destname = NULL;
result[i+1] = NULL;
i++;
} /* while i < num_holdingdisks && size > 0 */
amfree(used);
- if( size ) { /* not enough space available */
- printf("find diskspace: not enough diskspace. Left with %lu K\n", size);
+ if(size != (off_t)0) { /* not enough space available */
+ printf("find diskspace: not enough diskspace. Left with "
+ OFF_T_FMT " K\n", (OFF_T_FMT_TYPE)size);
fflush(stdout);
free_assignedhd(result);
result = NULL;
#ifdef HOLD_DEBUG
for( i = 0; result && result[i]; i++ ) {
- printf("%s: find diskspace: selected %s free %ld reserved %ld dumpers %d\n",
+ printf("%s: find diskspace: selected %s free " OFF_T_FMT " reserved " OFF_T_FMT " dumpers %d\n",
debug_prefix_time(": find_diskspace"),
- result[i]->disk->diskdir,
- result[i]->disk->disksize - holdalloc(result[i]->disk)->allocated_space,
- result[i]->reserved,
+ holdingdisk_get_diskdir(result[i]->disk),
+ (OFF_T_FMT_TYPE)(result[i]->disk->disksize -
+ holdalloc(result[i]->disk)->allocated_space),
+ (OFF_T_FMT_TYPE)result[i]->reserved,
holdalloc(result[i]->disk)->allocated_dumpers);
}
fflush(stdout);
}
static int
-assign_holdingdisk(holdp, diskp)
- assignedhd_t **holdp;
- disk_t *diskp;
+assign_holdingdisk(
+ assignedhd_t ** holdp,
+ disk_t * diskp)
{
int i, j, c, l=0;
- unsigned long size;
+ off_t size;
char *sfn = sanitise_filename(diskp->name);
char lvl[64];
assignedhd_t **new_holdp;
+ char *qname;
- snprintf( lvl, sizeof(lvl), "%d", sched(diskp)->level );
+ snprintf( lvl, SIZEOF(lvl), "%d", sched(diskp)->level );
size = am_round(sched(diskp)->est_size - sched(diskp)->act_size,
- DISK_BLOCK_KB);
+ (off_t)DISK_BLOCK_KB);
- for( c = 0; holdp[c]; c++ ); /* count number of disks */
+ for( c = 0; holdp[c]; c++ )
+ (void)c; /* count number of disks */
/* allocate memory for sched(diskp)->holdp */
- for(j = 0; sched(diskp)->holdp && sched(diskp)->holdp[j]; j++) {}
- new_holdp = (assignedhd_t **)alloc(sizeof(assignedhd_t*)*(j+c+1));
+ for(j = 0; sched(diskp)->holdp && sched(diskp)->holdp[j]; j++)
+ (void)j; /* Quiet lint */
+ new_holdp = (assignedhd_t **)alloc(SIZEOF(assignedhd_t*)*(j+c+1));
if (sched(diskp)->holdp) {
- memcpy(new_holdp, sched(diskp)->holdp, j * sizeof(*new_holdp));
+ memcpy(new_holdp, sched(diskp)->holdp, j * SIZEOF(*new_holdp));
amfree(sched(diskp)->holdp);
}
sched(diskp)->holdp = new_holdp;
if( sched(diskp)->holdp[j-1]->disk == holdp[0]->disk ) { /* Yes! */
sched(diskp)->holdp[j-1]->reserved += holdp[0]->reserved;
holdalloc(holdp[0]->disk)->allocated_space += holdp[0]->reserved;
- size = (holdp[0]->reserved>size) ? 0 : size-holdp[0]->reserved;
+ size = (holdp[0]->reserved>size) ? (off_t)0 : size-holdp[0]->reserved;
+ qname = quote_string(diskp->name);
#ifdef HOLD_DEBUG
- printf("%s: merging holding disk %s to disk %s:%s, add %lu for reserved %lu, left %lu\n",
+ printf("%s: merging holding disk %s to disk %s:%s, add " OFF_T_FMT " for reserved " OFF_T_FMT ", left " OFF_T_FMT "\n",
debug_prefix_time(": assign_holdingdisk"),
- sched(diskp)->holdp[j-1]->disk->diskdir,
- diskp->host->hostname, diskp->name,
- holdp[0]->reserved, sched(diskp)->holdp[j-1]->reserved,
- size );
+ holdingdisk_get_diskdir(sched(diskp)->holdp[j-1]->disk),
+ diskp->host->hostname, qname,
+ (OFF_T_FMT_TYPE)holdp[0]->reserved,
+ (OFF_T_FMT_TYPE)sched(diskp)->holdp[j-1]->reserved,
+ (OFF_T_FMT_TYPE)size);
fflush(stdout);
#endif
i++;
+ amfree(qname);
amfree(holdp[0]);
l=j-1;
}
/* copy assignedhd_s to sched(diskp), adjust allocated_space */
for( ; holdp[i]; i++ ) {
holdp[i]->destname = newvstralloc( holdp[i]->destname,
- holdp[i]->disk->diskdir, "/",
- timestamp, "/",
+ holdingdisk_get_diskdir(holdp[i]->disk), "/",
+ hd_driver_timestamp, "/",
diskp->host->hostname, ".",
sfn, ".",
lvl, NULL );
sched(diskp)->holdp[j++] = holdp[i];
holdalloc(holdp[i]->disk)->allocated_space += holdp[i]->reserved;
- size = (holdp[i]->reserved>size) ? 0 : size-holdp[i]->reserved;
+ size = (holdp[i]->reserved > size) ? (off_t)0 :
+ (size - holdp[i]->reserved);
+ qname = quote_string(diskp->name);
#ifdef HOLD_DEBUG
- printf("%s: %d assigning holding disk %s to disk %s:%s, reserved %lu, left %lu\n",
+ printf("%s: %d assigning holding disk %s to disk %s:%s, reserved " OFF_T_FMT ", left " OFF_T_FMT "\n",
debug_prefix_time(": assign_holdingdisk"),
- i, holdp[i]->disk->diskdir, diskp->host->hostname, diskp->name,
- holdp[i]->reserved, size );
+ i, holdingdisk_get_diskdir(holdp[i]->disk), diskp->host->hostname, qname,
+ (OFF_T_FMT_TYPE)holdp[i]->reserved,
+ (OFF_T_FMT_TYPE)size);
fflush(stdout);
#endif
+ amfree(qname);
holdp[i] = NULL; /* so it doesn't get free()d... */
}
sched(diskp)->holdp[j] = NULL;
}
static void
-adjust_diskspace(diskp, cmd)
- disk_t *diskp;
- cmd_t cmd;
+adjust_diskspace(
+ disk_t * diskp,
+ cmd_t cmd)
{
assignedhd_t **holdp;
- unsigned long total=0;
- long diff;
+ off_t total = (off_t)0;
+ off_t diff;
int i;
+ char *qname, *hqname, *qdest;
+
+ (void)cmd; /* Quiet unused parameter warning */
+ qname = quote_string(diskp->name);
+ qdest = quote_string(sched(diskp)->destname);
#ifdef HOLD_DEBUG
printf("%s: %s:%s %s\n",
debug_prefix_time(": adjust_diskspace"),
- diskp->host->hostname, diskp->name, sched(diskp)->destname);
+ diskp->host->hostname, qname, qdest);
fflush(stdout);
#endif
holdp = sched(diskp)->holdp;
- assert(holdp);
+ assert(holdp != NULL);
for( i = 0; holdp[i]; i++ ) { /* for each allocated disk */
diff = holdp[i]->used - holdp[i]->reserved;
total += holdp[i]->used;
holdalloc(holdp[i]->disk)->allocated_space += diff;
-
+ hqname = quote_string(holdp[i]->disk->name);
#ifdef HOLD_DEBUG
- printf("%s: hdisk %s done, reserved %ld used %ld diff %ld alloc %ld dumpers %d\n",
+ printf("%s: hdisk %s done, reserved " OFF_T_FMT " used " OFF_T_FMT " diff " OFF_T_FMT " alloc " OFF_T_FMT " dumpers %d\n",
debug_prefix_time(": adjust_diskspace"),
- holdp[i]->disk->name, holdp[i]->reserved, holdp[i]->used, diff,
- holdalloc(holdp[i]->disk)->allocated_space,
+ holdp[i]->disk->name,
+ (OFF_T_FMT_TYPE)holdp[i]->reserved,
+ (OFF_T_FMT_TYPE)holdp[i]->used,
+ (OFF_T_FMT_TYPE)diff,
+ (OFF_T_FMT_TYPE)holdalloc(holdp[i]->disk)->allocated_space,
holdalloc(holdp[i]->disk)->allocated_dumpers );
fflush(stdout);
#endif
holdp[i]->reserved += diff;
+ amfree(hqname);
}
sched(diskp)->act_size = total;
#ifdef HOLD_DEBUG
- printf("%s: after: disk %s:%s used %ld\n",
+ printf("%s: after: disk %s:%s used " OFF_T_FMT "\n",
debug_prefix_time(": adjust_diskspace"),
- diskp->host->hostname, diskp->name, sched(diskp)->act_size );
+ diskp->host->hostname, qname,
+ (OFF_T_FMT_TYPE)sched(diskp)->act_size);
fflush(stdout);
#endif
-
+ amfree(qdest);
+ amfree(qname);
}
static void
-delete_diskspace(diskp)
- disk_t *diskp;
+delete_diskspace(
+ disk_t *diskp)
{
assignedhd_t **holdp;
int i;
holdp = sched(diskp)->holdp;
- assert(holdp);
+ assert(holdp != NULL);
for( i = 0; holdp[i]; i++ ) { /* for each disk */
/* find all files of this dump on that disk, and subtract their
* using cont_filename */
free_assignedhd(sched(diskp)->holdp);
sched(diskp)->holdp = NULL;
- sched(diskp)->act_size = 0;
+ sched(diskp)->act_size = (off_t)0;
}
-static assignedhd_t **build_diskspace(destname)
-char *destname;
+static assignedhd_t **
+build_diskspace(
+ char * destname)
{
int i, j;
int fd;
- int buflen;
+ ssize_t buflen;
char buffer[DISK_BLOCK_BYTES];
dumpfile_t file;
assignedhd_t **result;
holdingdisk_t *hdp;
- int *used;
+ off_t *used;
int num_holdingdisks=0;
char dirname[1000], *ch;
struct stat finfo;
char *filename = destname;
+ memset(buffer, 0, sizeof(buffer));
for(hdp = getconf_holdingdisks(); hdp != NULL; hdp = hdp->next) {
num_holdingdisks++;
}
- used = alloc(sizeof(int) * num_holdingdisks);
+ used = alloc(SIZEOF(off_t) * num_holdingdisks);
for(i=0;i<num_holdingdisks;i++)
- used[i] = 0;
- result = alloc( sizeof(assignedhd_t *) * (num_holdingdisks+1) );
+ used[i] = (off_t)0;
+ result = alloc(SIZEOF(assignedhd_t *) * (num_holdingdisks + 1));
result[0] = NULL;
while(filename != NULL && filename[0] != '\0') {
strncpy(dirname, filename, 999);
for(j = 0, hdp = getconf_holdingdisks(); hdp != NULL;
hdp = hdp->next, j++ ) {
- if(strcmp(dirname,hdp->diskdir)==0) {
+ if(strcmp(dirname, holdingdisk_get_diskdir(hdp))==0) {
break;
}
}
if(stat(filename, &finfo) == -1) {
fprintf(stderr, "stat %s: %s\n", filename, strerror(errno));
- finfo.st_size = 0;
+ finfo.st_size = (off_t)0;
}
- used[j] += (finfo.st_size+1023)/1024;
+ used[j] += ((off_t)finfo.st_size+(off_t)1023)/(off_t)1024;
if((fd = open(filename,O_RDONLY)) == -1) {
fprintf(stderr,"build_diskspace: open of %s failed: %s\n",
filename, strerror(errno));
return NULL;
}
- if ((buflen = fullread(fd, buffer, sizeof(buffer))) > 0) {;
- parse_file_header(buffer, &file, buflen);
+ if ((buflen = fullread(fd, buffer, SIZEOF(buffer))) > 0) {;
+ parse_file_header(buffer, &file, (size_t)buflen);
}
close(fd);
filename = file.cont_filename;
for(j = 0, i=0, hdp = getconf_holdingdisks(); hdp != NULL;
hdp = hdp->next, j++ ) {
- if(used[j]) {
- result[i] = alloc(sizeof(assignedhd_t));
+ if(used[j] != (off_t)0) {
+ result[i] = alloc(SIZEOF(assignedhd_t));
result[i]->disk = hdp;
result[i]->reserved = used[j];
result[i]->used = used[j];
}
static void
-holdingdisk_state(time_str)
- char *time_str;
+holdingdisk_state(
+ char * time_str)
{
holdingdisk_t *hdp;
int dsk;
- long diff;
+ off_t diff;
printf("driver: hdisk-state time %s", time_str);
for(hdp = getconf_holdingdisks(), dsk = 0; hdp != NULL; hdp = hdp->next, dsk++) {
diff = hdp->disksize - holdalloc(hdp)->allocated_space;
- printf(" hdisk %d: free %ld dumpers %d", dsk, diff,
- holdalloc(hdp)->allocated_dumpers);
+ printf(" hdisk %d: free " OFF_T_FMT " dumpers %d", dsk,
+ (OFF_T_FMT_TYPE)diff, holdalloc(hdp)->allocated_dumpers);
}
printf("\n");
}
static void
-update_failed_dump_to_tape(dp)
- disk_t *dp;
+update_failed_dump_to_tape(
+ disk_t * dp)
{
/* JLM
* should simply set no_bump
* gnutar-lists might have been updated already, and a bumped
* incremental might be created. */
sched(dp)->timestamp = 0;
- update_info_dumper(dp, -1, -1, -1);
+ update_info_dumper(dp, (off_t)-1, (off_t)-1, (time_t)-1);
sched(dp)->timestamp = save_timestamp;
}
/* ------------------- */
static int
-dump_to_tape(dp)
- disk_t *dp;
+dump_to_tape(
+ disk_t * dp)
{
dumper_t *dumper;
int failed = 0;
- int filenum;
- long origsize = 0;
- long dumpsize = 0;
- long dumptime = 0;
- float tapetime = 0;
+ off_t filenum;
+ off_t origsize = (off_t)0;
+ off_t dumpsize = (off_t)0;
+ time_t dumptime = (time_t)0;
+ double tapetime = 0.0;
cmd_t cmd;
- int result_argc;
+ int result_argc, rc;
char *result_argv[MAX_ARGS+1];
int dumper_tryagain = 0;
+ char *qname;
+ qname = quote_string(dp->name);
printf("driver: dumping %s:%s directly to tape\n",
- dp->host->hostname, dp->name);
+ dp->host->hostname, qname);
fflush(stdout);
/* pick a dumper and fail if there are no idle dumpers */
dumper = idle_dumper();
if (!dumper) {
printf("driver: no idle dumpers for %s:%s.\n",
- dp->host->hostname, dp->name);
+ dp->host->hostname, qname);
fflush(stdout);
log_add(L_WARNING, "no idle dumpers for %s:%s.\n",
- dp->host->hostname, dp->name);
+ dp->host->hostname, qname);
+ amfree(qname);
return 2; /* fatal problem */
}
cmd = getresult(taper, 1, &result_argc, result_argv, MAX_ARGS+1);
if(cmd != PORT) {
printf("driver: did not get PORT from taper for %s:%s\n",
- dp->host->hostname, dp->name);
+ dp->host->hostname, qname);
fflush(stdout);
+ amfree(qname);
return 2; /* fatal problem */
}
/* copy port number */
cmd = getresult(dumper->fd, 1, &result_argc, result_argv, MAX_ARGS+1);
- if(cmd != BOGUS)
- free_serial(result_argv[2]);
-
switch(cmd) {
case BOGUS:
/* either eof or garbage from dumper */
case DONE: /* DONE <handle> <origsize> <dumpsize> <dumptime> <errstr> */
/* everything went fine */
- origsize = (long)atof(result_argv[3]);
- /*dumpsize = (long)atof(result_argv[4]);*/
- dumptime = (long)atof(result_argv[5]);
+ origsize = (off_t)atof(result_argv[3]);
+ /*dumpsize = (off_t)atof(result_argv[4]);*/
+ dumptime = (time_t)atof(result_argv[5]);
break;
case NO_ROOM: /* NO-ROOM <handle> */
dumper_cmd(dumper, ABORT, dp);
cmd = getresult(dumper->fd, 1, &result_argc, result_argv, MAX_ARGS+1);
- if(cmd != BOGUS)
- free_serial(result_argv[2]);
assert(cmd == ABORT_FINISHED);
case TRYAGAIN: /* TRY-AGAIN <handle> <errstr> */
case DONE: /* DONE <handle> <label> <tape file> <err mess> */
if(result_argc != 5) {
error("error [dump to tape DONE result_argc != 5: %d]", result_argc);
+ /*NOTREACHED*/
}
if(failed == 1) goto tryagain; /* dump didn't work */
free_serial(result_argv[2]);
- sscanf(result_argv[5],"[sec %f kb %ld ", &tapetime, &dumpsize);
+ if (*result_argv[5] == '"') {
+ /* String was quoted */
+ rc = sscanf(result_argv[5],"\"[sec %lf kb " OFF_T_FMT " ",
+ &tapetime, (OFF_T_FMT_TYPE *)&dumpsize);
+ } else {
+ /* String was not quoted */
+ rc = sscanf(result_argv[5],"[sec %lf kb " OFF_T_FMT " ",
+ &tapetime, (OFF_T_FMT_TYPE *)&dumpsize);
+ }
+ if (rc < 2) {
+ error("error [malformed result: %d items matched in '%s']",
+ rc, result_argv[5]);
+ /*NOTREACHED*/
+ }
if(cmd == DONE) {
/* every thing went fine */
update_info_dumper(dp, origsize, dumpsize, dumptime);
- filenum = atoi(result_argv[4]);
+ filenum = OFF_T_ATOI(result_argv[4]);
update_info_taper(dp, result_argv[3], filenum, sched(dp)->level);
/* note that update_info_dumper() must be run before
update_info_taper(), since update_info_dumper overwrites
case SPLIT_CONTINUE: /* SPLIT_CONTINUE <handle> <new_label> */
if (result_argc != 3) {
error("error [taper SPLIT_CONTINUE result_argc != 3: %d]", result_argc);
+ /*NOTREACHED*/
}
- fprintf(stderr, "driver: Got SPLIT_CONTINUE %s %s\n", result_argv[2], result_argv[3]);
-
+ fprintf(stderr, "driver: Got SPLIT_CONTINUE %s %s\n",
+ result_argv[2], result_argv[3]);
goto continue_port_dump;
- break;
+
case SPLIT_NEEDNEXT:
fprintf(stderr, "driver: Got SPLIT_NEEDNEXT %s %s\n", result_argv[2], result_argv[3]);
goto continue_port_dump;
- break;
+
case TAPE_ERROR: /* TAPE-ERROR <handle> <err mess> */
case BOGUS:
default:
free_serial(result_argv[2]);
failed = 2; /* fatal problem */
start_degraded_mode(&runq);
+ break;
}
/* reset statistics & return */
dp->host->inprogress -= 1;
dp->inprogress = 0;
deallocate_bandwidth(dp->host->netif, sched(dp)->est_kps);
+ amfree(qname);
return failed;
}
static int
-queue_length(q)
- disklist_t q;
+queue_length(
+ disklist_t q)
{
disk_t *p;
int len;
- for(len = 0, p = q.head; p != NULL; len++, p = p->next);
+ for(len = 0, p = q.head; p != NULL; len++, p = p->next)
+ (void)len; /* Quiet lint */
return len;
}
static void
-short_dump_state()
+short_dump_state(void)
{
int i, nidle;
char *wall_time;
wall_time = walltime_str(curclock());
printf("driver: state time %s ", wall_time);
- printf("free kps: %d space: %lu taper: ",
- free_kps((interface_t *)0), free_space());
+ printf("free kps: %lu space: " OFF_T_FMT " taper: ",
+ free_kps((interface_t *)0),
+ (OFF_T_FMT_TYPE)free_space());
if(degraded_mode) printf("DOWN");
else if(!taper_busy) printf("idle");
else printf("writing");
#if 0
static void
-dump_state(str)
- const char *str;
+dump_state(
+ const char *str)
{
int i;
disk_t *dp;
+ char *qname;
printf("================\n");
printf("driver state at time %s: %s\n", walltime_str(curclock()), str);
- printf("free kps: %d, space: %lu\n", free_kps((interface_t *)0), free_space());
+ printf("free kps: %lu, space: " OFF_T_FMT "\n",
+ free_kps((interface_t *)0),
+ (OFF_T_FMT_TYPE)free_space());
if(degraded_mode) printf("taper: DOWN\n");
else if(!taper_busy) printf("taper: idle\n");
- else printf("taper: writing %s:%s.%d est size %lu\n",
+ else printf("taper: writing %s:%s.%d est size " OFF_T_FMT "\n",
taper_disk->host->hostname, taper_disk->name,
sched(taper_disk)->level,
sched(taper_disk)->est_size);
if(!dmptable[i].busy)
printf("%s: idle\n", dmptable[i].name);
else
- printf("%s: dumping %s:%s.%d est kps %d size %lu time %ld\n",
- dmptable[i].name, dp->host->hostname, dp->name, sched(dp)->level,
+ qname = quote_string(dp->name);
+ printf("%s: dumping %s:%s.%d est kps %d size " OFF_T_FMT " time %lu\n",
+ dmptable[i].name, dp->host->hostname, qname, sched(dp)->level,
sched(dp)->est_kps, sched(dp)->est_size, sched(dp)->est_time);
+ amfree(qname);
}
dump_queue("TAPE", tapeq, 5, stdout);
dump_queue("ROOM", roomq, 5, stdout);
* University of Maryland at College Park
*/
/*
- * $Id: driverio.c,v 1.81.2.1 2006/04/23 18:52:04 martinea Exp $
+ * $Id: driverio.c,v 1.92 2006/08/24 01:57:16 paddy_s Exp $
*
* I/O-related functions for driver program
*/
#include "amanda.h"
#include "util.h"
#include "clock.h"
+#include "server_util.h"
#include "conffile.h"
#include "diskfile.h"
#include "infofile.h"
#include "logfile.h"
#include "token.h"
-#include "server_util.h"
#define GLOBAL /* the global variables defined here */
#include "driverio.h"
int nb_chunker = 0;
-static const char *childstr P((int));
+static const char *childstr(int);
-void init_driverio()
+void
+init_driverio(void)
{
dumper_t *dumper;
static const char *
-childstr(fd)
- int fd;
+childstr(
+ int fd)
{
static char buf[NUM_STR_SIZE + 32];
dumper_t *dumper;
if (dumper->chunker->fd == fd)
return (dumper->chunker->name);
}
- snprintf(buf, sizeof(buf), "unknown child (fd %d)", fd);
+ snprintf(buf, SIZEOF(buf), "unknown child (fd %d)", fd);
return (buf);
}
-void startup_tape_process(taper_program)
-char *taper_program;
+void
+startup_tape_process(
+ char *taper_program)
{
int fd[2];
- if(socketpair(AF_UNIX, SOCK_STREAM, 0, fd) == -1)
+ if(socketpair(AF_UNIX, SOCK_STREAM, 0, fd) == -1) {
error("taper pipe: %s", strerror(errno));
- if(fd[0] < 0 || fd[0] >= FD_SETSIZE) {
+ /*NOTREACHED*/
+ }
+ if(fd[0] < 0 || fd[0] >= (int)FD_SETSIZE) {
error("taper socketpair 0: descriptor %d out of range (0 .. %d)\n",
fd[0], FD_SETSIZE-1);
+ /*NOTREACHED*/
}
- if(fd[1] < 0 || fd[1] >= FD_SETSIZE) {
+ if(fd[1] < 0 || fd[1] >= (int)FD_SETSIZE) {
error("taper socketpair 1: descriptor %d out of range (0 .. %d)\n",
fd[1], FD_SETSIZE-1);
+ /*NOTREACHED*/
}
switch(taper_pid = fork()) {
case -1:
error("fork taper: %s", strerror(errno));
+ /*NOTREACHED*/
+
case 0: /* child process */
aclose(fd[0]);
if(dup2(fd[1], 0) == -1 || dup2(fd[1], 1) == -1)
error("taper dup2: %s", strerror(errno));
execle(taper_program, "taper", config_name, (char *)0, safe_env());
error("exec %s: %s", taper_program, strerror(errno));
+ /*NOTREACHED*/
+
default: /* parent process */
aclose(fd[1]);
taper = fd[0];
}
}
-void startup_dump_process(dumper, dumper_program)
-dumper_t *dumper;
-char *dumper_program;
+void
+startup_dump_process(
+ dumper_t *dumper,
+ char *dumper_program)
{
int fd[2];
- if(socketpair(AF_UNIX, SOCK_STREAM, 0, fd) == -1)
+ if(socketpair(AF_UNIX, SOCK_STREAM, 0, fd) == -1) {
error("%s pipe: %s", dumper->name, strerror(errno));
+ /*NOTREACHED*/
+ }
switch(dumper->pid = fork()) {
case -1:
error("fork %s: %s", dumper->name, strerror(errno));
+ /*NOTREACHED*/
+
case 0: /* child process */
aclose(fd[0]);
if(dup2(fd[1], 0) == -1 || dup2(fd[1], 1) == -1)
safe_env());
error("exec %s (%s): %s", dumper_program,
dumper->name, strerror(errno));
+ /*NOTREACHED*/
+
default: /* parent process */
aclose(fd[1]);
dumper->fd = fd[0];
dumper->ev_read = NULL;
dumper->busy = dumper->down = 0;
dumper->dp = NULL;
- fprintf(stderr,"driver: started %s pid %d\n",
- dumper->name, dumper->pid);
+ fprintf(stderr,"driver: started %s pid %u\n",
+ dumper->name, (unsigned)dumper->pid);
fflush(stderr);
}
}
-void startup_dump_processes(dumper_program, inparallel)
-char *dumper_program;
-int inparallel;
+void
+startup_dump_processes(
+ char *dumper_program,
+ int inparallel,
+ char *timestamp)
{
int i;
dumper_t *dumper;
char number[NUM_STR_SIZE];
for(dumper = dmptable, i = 0; i < inparallel; dumper++, i++) {
- snprintf(number, sizeof(number), "%d", i);
+ snprintf(number, SIZEOF(number), "%d", i);
dumper->name = stralloc2("dumper", number);
dumper->chunker = &chktable[i];
chktable[i].name = stralloc2("chunker", number);
chktable[i].fd = -1;
startup_dump_process(dumper, dumper_program);
+ dumper_cmd(dumper, START, (void *)timestamp);
}
}
-void startup_chunk_process(chunker, chunker_program)
-chunker_t *chunker;
-char *chunker_program;
+void
+startup_chunk_process(
+ chunker_t *chunker,
+ char *chunker_program)
{
int fd[2];
- if(socketpair(AF_UNIX, SOCK_STREAM, 0, fd) == -1)
+ if(socketpair(AF_UNIX, SOCK_STREAM, 0, fd) == -1) {
error("%s pipe: %s", chunker->name, strerror(errno));
+ /*NOTREACHED*/
+ }
switch(chunker->pid = fork()) {
case -1:
error("fork %s: %s", chunker->name, strerror(errno));
+ /*NOTREACHED*/
+
case 0: /* child process */
aclose(fd[0]);
- if(dup2(fd[1], 0) == -1 || dup2(fd[1], 1) == -1)
+ if(dup2(fd[1], 0) == -1 || dup2(fd[1], 1) == -1) {
error("%s dup2: %s", chunker->name, strerror(errno));
+ /*NOTREACHED*/
+ }
execle(chunker_program,
chunker->name ? chunker->name : "chunker",
config_name,
safe_env());
error("exec %s (%s): %s", chunker_program,
chunker->name, strerror(errno));
+ /*NOTREACHED*/
+
default: /* parent process */
aclose(fd[1]);
chunker->down = 0;
chunker->fd = fd[0];
chunker->ev_read = NULL;
- fprintf(stderr,"driver: started %s pid %d\n",
- chunker->name, chunker->pid);
+ fprintf(stderr,"driver: started %s pid %u\n",
+ chunker->name, (unsigned)chunker->pid);
fflush(stderr);
}
}
-cmd_t getresult(fd, show, result_argc, result_argv, max_arg)
-int fd;
-int show;
-int *result_argc;
-char **result_argv;
-int max_arg;
+cmd_t
+getresult(
+ int fd,
+ int show,
+ int *result_argc,
+ char **result_argv,
+ int max_arg)
{
int arg;
cmd_t t;
if((line = areads(fd)) == NULL) {
if(errno) {
error("reading result from %s: %s", childstr(fd), strerror(errno));
+ /*NOTREACHED*/
}
*result_argc = 0; /* EOF */
} else {
}
-int taper_cmd(cmd, /* optional */ ptr, destname, level, datestamp)
-cmd_t cmd;
-void *ptr;
-char *destname;
-int level;
-char *datestamp;
+int
+taper_cmd(
+ cmd_t cmd,
+ void *ptr,
+ char *destname,
+ int level,
+ char *datestamp)
{
char *cmdline = NULL;
char number[NUM_STR_SIZE];
char *diskbuffer = NULL;
disk_t *dp;
char *features;
+ char *qname;
+ char *qdest;
switch(cmd) {
case START_TAPER:
break;
case FILE_WRITE:
dp = (disk_t *) ptr;
- snprintf(number, sizeof(number), "%d", level);
- snprintf(splitsize, sizeof(splitsize), "%ld", dp->tape_splitsize);
+ qname = quote_string(dp->name);
+ qdest = quote_string(destname);
+ snprintf(number, SIZEOF(number), "%d", level);
+ snprintf(splitsize, SIZEOF(splitsize), OFF_T_FMT,
+ (OFF_T_FMT_TYPE)dp->tape_splitsize);
features = am_feature_to_string(dp->host->features);
cmdline = vstralloc(cmdstr[cmd],
" ", disk2serial(dp),
- " ", destname,
+ " ", qdest,
" ", dp->host->hostname,
" ", features,
- " ", dp->name,
+ " ", qname,
" ", number,
" ", datestamp,
" ", splitsize,
"\n", NULL);
amfree(features);
+ amfree(qdest);
+ amfree(qname);
break;
case PORT_WRITE:
dp = (disk_t *) ptr;
- snprintf(number, sizeof(number), "%d", level);
+ qname = quote_string(dp->name);
+ snprintf(number, SIZEOF(number), "%d", level);
/*
If we haven't been given a place to buffer split dumps to disk,
} else {
diskbuffer = dp->split_diskbuffer;
}
- snprintf(splitsize, sizeof(splitsize), "%ld", dp->tape_splitsize);
- snprintf(fallback_splitsize, sizeof(fallback_splitsize),
- "%ld", dp->fallback_splitsize);
+ snprintf(splitsize, SIZEOF(splitsize), OFF_T_FMT,
+ (OFF_T_FMT_TYPE)dp->tape_splitsize);
+ snprintf(fallback_splitsize, SIZEOF(fallback_splitsize), OFF_T_FMT,
+ (OFF_T_FMT_TYPE)dp->fallback_splitsize);
features = am_feature_to_string(dp->host->features);
cmdline = vstralloc(cmdstr[cmd],
" ", disk2serial(dp),
" ", dp->host->hostname,
" ", features,
- " ", dp->name,
+ " ", qname,
" ", number,
" ", datestamp,
" ", splitsize,
" ", fallback_splitsize,
"\n", NULL);
amfree(features);
+ amfree(qname);
break;
case QUIT:
cmdline = stralloc2(cmdstr[cmd], "\n");
break;
default:
error("Don't know how to send %s command to taper", cmdstr[cmd]);
+ /*NOTREACHED*/
}
+
/*
* Note: cmdline already has a '\n'.
*/
printf("driver: send-cmd time %s to taper: %s",
walltime_str(curclock()), cmdline);
fflush(stdout);
- if (fullwrite(taper, cmdline, strlen(cmdline)) < 0) {
- printf("writing taper command: %s\n", strerror(errno));
+ if ((fullwrite(taper, cmdline, strlen(cmdline))) < 0) {
+ printf("writing taper command '%s' failed: %s\n",
+ cmdline, strerror(errno));
fflush(stdout);
amfree(cmdline);
return 0;
}
+ if(cmd == QUIT) aclose(taper);
amfree(cmdline);
return 1;
}
-int dumper_cmd(dumper, cmd, /* optional */ dp)
-dumper_t *dumper;
-cmd_t cmd;
-disk_t *dp;
+int
+dumper_cmd(
+ dumper_t *dumper,
+ cmd_t cmd,
+ disk_t *dp)
{
char *cmdline = NULL;
char number[NUM_STR_SIZE];
char numberport[NUM_STR_SIZE];
char *o;
- int activehd=0;
- assignedhd_t **h=NULL;
char *device;
char *features;
-
- if(dp && sched(dp) && sched(dp)->holdp) {
- h = sched(dp)->holdp;
- activehd = sched(dp)->activehd;
- }
-
- if(dp && dp->device) {
- device = dp->device;
- }
- else {
- device = "NODEVICE";
- }
+ char *qname;
+ char *qdest;
switch(cmd) {
+ case START:
+ cmdline = vstralloc(cmdstr[cmd], " ", (char *)dp, "\n", NULL);
+ break;
case PORT_DUMP:
+ if(dp && dp->device) {
+ device = dp->device;
+ }
+ else {
+ device = "NODEVICE";
+ }
+
if (dp != NULL) {
- snprintf(number, sizeof(number), "%d", sched(dp)->level);
- snprintf(numberport, sizeof(numberport), "%d", dumper->output_port);
+ device = quote_string((dp->device) ? dp->device : "NODEVICE");
+ qname = quote_string(dp->name);
+ snprintf(number, SIZEOF(number), "%d", sched(dp)->level);
+ snprintf(numberport, SIZEOF(numberport), "%d", dumper->output_port);
features = am_feature_to_string(dp->host->features);
o = optionstr(dp, dp->host->features, NULL);
+ if ( o == NULL ) {
+ error("problem with option string, check the dumptype definition.\n");
+ }
+
cmdline = vstralloc(cmdstr[cmd],
" ", disk2serial(dp),
" ", numberport,
" ", dp->host->hostname,
" ", features,
- " ", dp->name,
+ " ", qname,
" ", device,
" ", number,
" ", sched(dp)->dumpdate,
" ", dp->program,
+ " ", dp->amandad_path,
+ " ", dp->client_username,
+ " ", dp->ssh_keys,
" |", o,
"\n", NULL);
amfree(features);
amfree(o);
+ amfree(qname);
+ amfree(device);
} else {
error("PORT-DUMP without disk pointer\n");
/*NOTREACHED*/
case QUIT:
case ABORT:
if( dp ) {
+ qdest = quote_string(sched(dp)->destname);
cmdline = vstralloc(cmdstr[cmd],
- " ", sched(dp)->destname,
+ " ", qdest,
"\n", NULL );
+ amfree(qdest);
} else {
cmdline = stralloc2(cmdstr[cmd], "\n");
}
break;
default:
error("Don't know how to send %s command to dumper", cmdstr[cmd]);
+ /*NOTREACHED*/
}
+
/*
* Note: cmdline already has a '\n'.
*/
amfree(cmdline);
return 0;
}
+ if (cmd == QUIT) aclose(dumper->fd);
}
amfree(cmdline);
return 1;
}
-int chunker_cmd(chunker, cmd, dp)
-chunker_t *chunker;
-cmd_t cmd;
-disk_t *dp;
+int
+chunker_cmd(
+ chunker_t *chunker,
+ cmd_t cmd,
+ disk_t *dp)
{
char *cmdline = NULL;
char number[NUM_STR_SIZE];
int activehd=0;
assignedhd_t **h=NULL;
char *features;
-
- if(cmd != START && dp && sched(dp) && sched(dp)->holdp) {
- h = sched(dp)->holdp;
- activehd = sched(dp)->activehd;
- }
+ char *qname;
+ char *qdest;
switch(cmd) {
case START:
cmdline = vstralloc(cmdstr[cmd], " ", (char *)dp, "\n", NULL);
break;
case PORT_WRITE:
+ if(dp && sched(dp) && sched(dp)->holdp) {
+ h = sched(dp)->holdp;
+ activehd = sched(dp)->activehd;
+ }
+
if (dp && h) {
+ qname = quote_string(dp->name);
+ qdest = quote_string(sched(dp)->destname);
holdalloc(h[activehd]->disk)->allocated_dumpers++;
- snprintf(number, sizeof(number), "%d", sched(dp)->level);
- snprintf(chunksize, sizeof(chunksize), "%ld", h[0]->disk->chunksize);
- snprintf(use, sizeof(use), "%ld", h[0]->reserved );
+ snprintf(number, SIZEOF(number), "%d", sched(dp)->level);
+ snprintf(chunksize, SIZEOF(chunksize), OFF_T_FMT,
+ (OFF_T_FMT_TYPE)holdingdisk_get_chunksize(h[0]->disk));
+ snprintf(use, SIZEOF(use), OFF_T_FMT,
+ (OFF_T_FMT_TYPE)h[0]->reserved);
features = am_feature_to_string(dp->host->features);
o = optionstr(dp, dp->host->features, NULL);
+ if ( o == NULL ) {
+ error("problem with option string, check the dumptype definition.\n");
+ }
cmdline = vstralloc(cmdstr[cmd],
" ", disk2serial(dp),
- " ", sched(dp)->destname,
+ " ", qdest,
" ", dp->host->hostname,
" ", features,
- " ", dp->name,
+ " ", qname,
" ", number,
" ", sched(dp)->dumpdate,
" ", chunksize,
"\n", NULL);
amfree(features);
amfree(o);
+ amfree(qdest);
+ amfree(qname);
} else {
error("Write command without disk and holding disk.\n",
cmdstr[cmd]);
}
break;
case CONTINUE:
- if( dp && h) {
+ if(dp && sched(dp) && sched(dp)->holdp) {
+ h = sched(dp)->holdp;
+ activehd = sched(dp)->activehd;
+ }
+
+ if(dp && h) {
+ qname = quote_string(dp->name);
+ qdest = quote_string(h[activehd]->destname);
holdalloc(h[activehd]->disk)->allocated_dumpers++;
- snprintf(chunksize, sizeof(chunksize), "%ld",
- h[activehd]->disk->chunksize );
- snprintf(use, sizeof(use), "%ld",
- h[activehd]->reserved - h[activehd]->used );
+ snprintf(chunksize, SIZEOF(chunksize), OFF_T_FMT,
+ (OFF_T_FMT_TYPE)holdingdisk_get_chunksize(h[activehd]->disk));
+ snprintf(use, SIZEOF(use), OFF_T_FMT,
+ (OFF_T_FMT_TYPE)(h[activehd]->reserved - h[activehd]->used));
cmdline = vstralloc(cmdstr[cmd],
" ", disk2serial(dp),
- " ", h[activehd]->destname,
+ " ", qdest,
" ", chunksize,
" ", use,
"\n", NULL );
+ amfree(qdest);
+ amfree(qname);
} else {
cmdline = stralloc2(cmdstr[cmd], "\n");
}
break;
case QUIT:
+ case ABORT:
cmdline = stralloc2(cmdstr[cmd], "\n");
break;
case DONE:
case FAILED:
- if( dp) {
+ if( dp ) {
cmdline = vstralloc(cmdstr[cmd],
" ", disk2serial(dp),
"\n", NULL);
break;
default:
error("Don't know how to send %s command to chunker", cmdstr[cmd]);
+ /*NOTREACHED*/
}
+
/*
* Note: cmdline already has a '\n'.
*/
amfree(cmdline);
return 0;
}
+ if (cmd == QUIT) aclose(chunker->fd);
amfree(cmdline);
return 1;
}
disk_t *dp;
} stable[MAX_SERIAL];
-disk_t *serial2disk(str)
-char *str;
+disk_t *
+serial2disk(
+ char *str)
{
int rc, s;
long gen;
rc = sscanf(str, "%d-%ld", &s, &gen);
if(rc != 2) {
error("error [serial2disk \"%s\" parse error]", str);
+ /*NOTREACHED*/
} else if (s < 0 || s >= MAX_SERIAL) {
error("error [serial out of range 0..%d: %d]", MAX_SERIAL, s);
+ /*NOTREACHED*/
}
if(gen != stable[s].gen)
- printf("driver: error time %s serial gen mismatch %s\n",
+ printf("driver: serial2disk error time %s serial gen mismatch %s\n",
walltime_str(curclock()), str);
return stable[s].dp;
}
-void free_serial(str)
-char *str;
+void
+free_serial(
+ char *str)
{
int rc, s;
long gen;
}
if(gen != stable[s].gen)
- printf("driver: error time %s serial gen mismatch\n",
- walltime_str(curclock()));
+ printf("driver: free_serial error time %s serial gen mismatch %s\n",
+ walltime_str(curclock()),str);
stable[s].gen = 0;
stable[s].dp = NULL;
}
-void free_serial_dp(dp)
-disk_t *dp;
+void
+free_serial_dp(
+ disk_t *dp)
{
int s;
}
-void check_unfree_serial()
+void
+check_unfree_serial(void)
{
int s;
}
}
-char *disk2serial(dp)
-disk_t *dp;
+char *disk2serial(
+ disk_t *dp)
{
int s;
static char str[NUM_STR_SIZE];
for(s = 0; s < MAX_SERIAL; s++) {
if(stable[s].dp == dp) {
- snprintf(str, sizeof(str), "%02d-%05ld", s, stable[s].gen);
+ snprintf(str, SIZEOF(str), "%02d-%05ld", s, stable[s].gen);
return str;
}
}
stable[s].gen = generation++;
stable[s].dp = dp;
- snprintf(str, sizeof(str), "%02d-%05ld", s, stable[s].gen);
+ snprintf(str, SIZEOF(str), "%02d-%05ld", s, stable[s].gen);
return str;
}
-void update_info_dumper(dp, origsize, dumpsize, dumptime)
- disk_t *dp;
- long origsize;
- long dumpsize;
- long dumptime;
+void
+update_info_dumper(
+ disk_t *dp,
+ off_t origsize,
+ off_t dumpsize,
+ time_t dumptime)
{
int level, i;
info_t info;
}
if (open_infofile(conf_infofile)) {
error("could not open info db \"%s\"", conf_infofile);
+ /*NOTREACHED*/
}
amfree(conf_infofile);
update_info_taper(). */
for (i = level; i < DUMP_LEVELS; ++i) {
infp = &info.inf[i];
- infp->size = -1;
- infp->csize = -1;
- infp->secs = -1;
+ infp->size = (off_t)-1;
+ infp->csize = (off_t)-1;
+ infp->secs = (time_t)-1;
infp->date = (time_t)-1;
infp->label[0] = '\0';
infp->filenum = 0;
else perfp = &info.incr;
/* Update the stats, but only if the new values are meaningful */
- if(dp->compress != COMP_NONE && origsize > 0L) {
- newperf(perfp->comp, dumpsize/(float)origsize);
+ if(dp->compress != COMP_NONE && origsize > (off_t)0) {
+ newperf(perfp->comp, (double)dumpsize/(double)origsize);
}
- if(dumptime > 0L) {
- if(dumptime >= dumpsize)
+ if(dumptime > (time_t)0) {
+ if((off_t)dumptime >= dumpsize)
newperf(perfp->rate, 1);
else
- newperf(perfp->rate, dumpsize/dumptime);
+ newperf(perfp->rate, (double)dumpsize/(double)dumptime);
}
if(getconf_int(CNF_RESERVE)<100) {
info.consecutive_runs = 1;
}
- if(origsize >=0 && dumpsize >=0) {
+ if(origsize >= (off_t)0 && dumpsize >= (off_t)0) {
for(i=NB_HISTORY-1;i>0;i--) {
info.history[i] = info.history[i-1];
}
info.history[0].secs = dumptime;
}
- if(put_info(dp->host->hostname, dp->name, &info))
- error("infofile update failed (%s,%s)\n", dp->host->hostname, dp->name);
+ if(put_info(dp->host->hostname, dp->name, &info)) {
+ error("infofile update failed (%s,'%s')\n", dp->host->hostname, dp->name);
+ /*NOTREACHED*/
+ }
close_infofile();
}
-void update_info_taper(dp, label, filenum, level)
-disk_t *dp;
-char *label;
-int filenum;
-int level;
+void
+update_info_taper(
+ disk_t *dp,
+ char *label,
+ off_t filenum,
+ int level)
{
info_t info;
stats_t *infp;
int rc;
rc = open_infofile(getconf_str(CNF_INFOFILE));
- if(rc)
+ if(rc) {
error("could not open infofile %s: %s (%d)", getconf_str(CNF_INFOFILE),
strerror(errno), rc);
+ /*NOTREACHED*/
+ }
get_info(dp->host->hostname, dp->name, &info);
infp = &info.inf[level];
/* XXX - should we record these two if no-record? */
- strncpy(infp->label, label, sizeof(infp->label)-1);
- infp->label[sizeof(infp->label)-1] = '\0';
+ strncpy(infp->label, label, SIZEOF(infp->label)-1);
+ infp->label[SIZEOF(infp->label)-1] = '\0';
infp->filenum = filenum;
info.command = NO_COMMAND;
- if(put_info(dp->host->hostname, dp->name, &info))
- error("infofile update failed (%s,%s)\n", dp->host->hostname, dp->name);
-
+ if(put_info(dp->host->hostname, dp->name, &info)) {
+ error("infofile update failed (%s,'%s')\n", dp->host->hostname, dp->name);
+ /*NOTREACHED*/
+ }
close_infofile();
}
/* Free an array of pointers to assignedhd_t after freeing the
* assignedhd_t themselves. The array must be NULL-terminated.
*/
-void free_assignedhd( ahd )
-assignedhd_t **ahd;
+void free_assignedhd(
+ assignedhd_t **ahd)
{
int i;
* University of Maryland at College Park
*/
/*
- * $Id: driverio.h,v 1.32 2005/12/03 13:27:43 martinea Exp $
+ * $Id: driverio.h,v 1.35 2006/05/25 01:47:19 johnfranks Exp $
*
* driver-related helper functions
*/
+#ifndef DRIVERIO_H
+#define DRIVERIO_H
#include "event.h"
typedef struct chunker_s {
char *name; /* name of this chunker */
- int pid; /* its pid */
+ pid_t pid; /* its pid */
int down; /* state */
int fd; /* read/write */
int result;
typedef struct dumper_s {
char *name; /* name of this dumper */
- int pid; /* its pid */
+ pid_t pid; /* its pid */
int busy, down; /* state */
int fd; /* read/write */
int result;
typedef struct assignedhd_s {
holdingdisk_t *disk;
- long used;
- long reserved;
+ off_t used;
+ off_t reserved;
char *destname;
} assignedhd_t;
typedef struct sched_s {
int attempted, priority;
int level, degr_level;
- long est_time, degr_time;
- unsigned long est_size, degr_size, act_size;
- unsigned long origsize, dumpsize;
- unsigned long dumptime, tapetime;
+ unsigned long est_time, degr_time;
+ off_t est_nsize, est_csize, est_size;
+ off_t degr_nsize, degr_csize, act_size;
+ off_t origsize, dumpsize;
+ time_t dumptime, tapetime;
char *dumpdate, *degr_dumpdate;
- int est_kps, degr_kps;
+ unsigned long est_kps, degr_kps;
char *destname; /* file/port name */
dumper_t *dumper;
assignedhd_t **holdp;
typedef struct holdalloc_s {
int allocated_dumpers;
- long allocated_space;
+ off_t allocated_space;
} holdalloc_t;
#define holdalloc(hp) ((holdalloc_t *) (hp)->up)
/* command/result tokens */
-GLOBAL int taper, taper_busy, taper_pid;
+GLOBAL int taper, taper_busy;
+GLOBAL pid_t taper_pid;
GLOBAL event_handle_t *taper_ev_read;
-void init_driverio P((void));
-void startup_tape_process P((char *taper_program));
-void startup_dump_process P((dumper_t *dumper, char *dumper_program));
-void startup_dump_processes P((char *dumper_program, int inparallel));
-void startup_chunk_process P((chunker_t *chunker, char *chunker_program));
-
-cmd_t getresult P((int fd, int show, int *result_argc, char **result_argv, int max_arg));
-int taper_cmd P((cmd_t cmd, void *ptr, char *destname, int level, char *datestamp));
-int dumper_cmd P((dumper_t *dumper, cmd_t cmd, disk_t *dp));
-int chunker_cmd P((chunker_t *chunker, cmd_t cmd, disk_t *dp));
-disk_t *serial2disk P((char *str));
-void free_serial P((char *str));
-void free_serial_dp P((disk_t *dp));
-void check_unfree_serial P(());
-char *disk2serial P((disk_t *dp));
-void update_info_dumper P((disk_t *dp, long origsize, long dumpsize, long dumptime));
-void update_info_taper P((disk_t *dp, char *label, int filenum, int level));
-void free_assignedhd P((assignedhd_t **holdp));
+void init_driverio(void);
+void startup_tape_process(char *taper_program);
+void startup_dump_process(dumper_t *dumper, char *dumper_program);
+void startup_dump_processes(char *dumper_program, int inparallel, char *timestamp);
+void startup_chunk_process(chunker_t *chunker, char *chunker_program);
+
+disk_t *serial2disk(char *str);
+void free_serial(char *str);
+void free_serial_dp(disk_t *dp);
+void check_unfree_serial(void);
+char *disk2serial(disk_t *dp);
+void update_info_dumper(disk_t *dp, off_t origsize, off_t dumpsize, time_t dumptime);
+void update_info_taper(disk_t *dp, char *label, off_t filenum, int level);
+void free_assignedhd(assignedhd_t **holdp);
+#endif /* !DRIVERIO_H */
* Authors: the Amanda Development Team. Its members are listed in a
* file named AUTHORS, in the root directory of this distribution.
*/
-/* $Id: dumper.c,v 1.170 2006/03/22 15:10:52 martinea Exp $
+/* $Id: dumper.c,v 1.190 2006/08/30 19:53:57 martinea Exp $
*
* requests remote amandad processes to dump filesystems
*/
static char *handle = NULL;
static char *errstr = NULL;
-static long dumpbytes;
-static long dumpsize, headersize, origsize;
+static off_t dumpbytes;
+static off_t dumpsize, headersize, origsize;
static comp_t srvcompress = COMP_NONE;
char *srvcompprog = NULL;
static char *hostname = NULL;
am_feature_t *their_features = NULL;
static char *diskname = NULL;
+static char *qdiskname = NULL;
static char *device = NULL;
static char *options = NULL;
static char *progname = NULL;
+static char *amandad_path=NULL;
+static char *client_username=NULL;
+static char *ssh_keys=NULL;
static int level;
static char *dumpdate = NULL;
-static char *datestamp;
-static int conf_dtimeout;
+static char *dumper_timestamp = NULL;
+static time_t conf_dtimeout;
static int indexfderror;
+static int set_datafd;
static dumpfile_t file;
#define INDEXFD 2
{ "INDEX", NULL },
};
-#define NSTREAMS (sizeof(streams) / sizeof(streams[0]))
+#define NSTREAMS (int)(sizeof(streams) / sizeof(streams[0]))
static am_feature_t *our_features = NULL;
static char *our_feature_string = NULL;
/* local functions */
-int main P((int, char **));
-static int do_dump P((struct databuf *));
-static void check_options P((char *));
-static void finish_tapeheader P((dumpfile_t *));
-static int write_tapeheader P((int, dumpfile_t *));
-static void databuf_init P((struct databuf *, int));
-static int databuf_write P((struct databuf *, const void *, int));
-static int databuf_flush P((struct databuf *));
-static void process_dumpeof P((void));
-static void process_dumpline P((const char *));
-static void add_msg_data P((const char *, size_t));
-static void parse_info_line P((char *));
-static void log_msgout P((logtype_t));
-
-static int runcompress P((int, pid_t *, comp_t));
-static int runencrypt P((int, pid_t *, encrypt_t));
-
-static void sendbackup_response P((void *, pkt_t *, security_handle_t *));
-static int startup_dump P((const char *, const char *, const char *, int,
- const char *, const char *, const char *));
-static void stop_dump P((void));
-
-static void read_indexfd P((void *, void *, ssize_t));
-static void read_datafd P((void *, void *, ssize_t));
-static void read_mesgfd P((void *, void *, ssize_t));
-static void timeout P((int));
-static void timeout_callback P((void *));
+int main(int, char **);
+static int do_dump(struct databuf *);
+static void check_options(char *);
+static void finish_tapeheader(dumpfile_t *);
+static ssize_t write_tapeheader(int, dumpfile_t *);
+static void databuf_init(struct databuf *, int);
+static int databuf_write(struct databuf *, const void *, size_t);
+static int databuf_flush(struct databuf *);
+static void process_dumpeof(void);
+static void process_dumpline(const char *);
+static void add_msg_data(const char *, size_t);
+static void parse_info_line(char *);
+static void log_msgout(logtype_t);
+static char * dumper_get_security_conf (char *, void *);
+
+static int runcompress(int, pid_t *, comp_t);
+static int runencrypt(int, pid_t *, encrypt_t);
+
+static void sendbackup_response(void *, pkt_t *, security_handle_t *);
+static int startup_dump(const char *, const char *, const char *, int,
+ const char *, const char *, const char *,
+ const char *, const char *, const char *);
+static void stop_dump(void);
+
+static void read_indexfd(void *, void *, ssize_t);
+static void read_datafd(void *, void *, ssize_t);
+static void read_mesgfd(void *, void *, ssize_t);
+static void timeout(time_t);
+static void timeout_callback(void *);
static void
-check_options(options)
- char *options;
-{
+check_options(
+ char *options)
+{
char *compmode = NULL;
char *compend = NULL;
char *encryptmode = NULL;
int
-main(main_argc, main_argv)
- int main_argc;
- char **main_argv;
+main(
+ int main_argc,
+ char ** main_argv)
{
static struct databuf db;
struct cmdargs cmdargs;
cmd_t cmd;
int outfd = -1;
- int taper_port, rc;
+ int rc;
+ in_port_t taper_port;
unsigned long malloc_hist_1, malloc_size_1;
unsigned long malloc_hist_2, malloc_size_2;
char *conffile;
char *q = NULL;
int a;
+ uid_t ruid;
+ int new_argc, my_argc;
+ char **new_argv, **my_argv;
safe_fd(-1, 0);
set_pname("dumper");
+ dbopen(DBG_SUBDIR_SERVER);
+
/* Don't die when child closes pipe */
signal(SIGPIPE, SIG_IGN);
erroutput_type = (ERR_AMANDALOG|ERR_INTERACTIVE);
set_logerror(logerror);
- if (main_argc > 1) {
- config_name = stralloc(main_argv[1]);
+ parse_server_conf(main_argc, main_argv, &new_argc, &new_argv);
+ my_argc = new_argc;
+ my_argv = new_argv;
+
+ if (my_argc > 1) {
+ config_name = stralloc(my_argv[1]);
config_dir = vstralloc(CONFIG_DIR, "/", config_name, "/", NULL);
} else {
char my_cwd[STR_SIZE];
- if (getcwd(my_cwd, sizeof(my_cwd)) == NULL) {
+ if (getcwd(my_cwd, SIZEOF(my_cwd)) == NULL) {
error("cannot determine current working directory");
+ /*NOTREACHED*/
}
config_dir = stralloc2(my_cwd, "/");
if ((config_name = strrchr(my_cwd, '/')) != NULL) {
conffile = stralloc2(config_dir, CONFFILE_NAME);
if(read_conffile(conffile)) {
error("errors processing config file \"%s\"", conffile);
+ /*NOTREACHED*/
}
amfree(conffile);
+ dbrename(config_name, DBG_SUBDIR_SERVER);
+
+ report_bad_conf_arg();
/*
- * Make our effective uid nonprivlidged, but keep our real uid as root
+ * Make our effective uid nonprivlidged, keeping save uid as root
* in case we need to get back (to bind privlidged ports, etc).
*/
+ ruid = getuid();
if(geteuid() == 0) {
- uid_t ruid = getuid();
- setuid(0);
seteuid(ruid);
setgid(getgid());
}
#if defined BSD_SECURITY && !defined SSH_SECURITY
- else error("must be run setuid root to communicate correctly");
+ else {
+ error("must be run setuid root to communicate correctly");
+ /*NOTREACHED*/
+ }
#endif
fprintf(stderr,
"%s: pid %ld executable %s version %s\n",
get_pname(), (long) getpid(),
- main_argv[0], version());
+ my_argv[0], version());
fflush(stderr);
/* now, make sure we are a valid user */
- if (getpwuid(getuid()) == NULL)
+ if (getpwuid(getuid()) == NULL) {
error("can't get login name for my uid %ld", (long)getuid());
+ /*NOTREACHED*/
+ }
signal(SIGPIPE, SIG_IGN);
- datestamp = construct_datestamp(NULL);
- conf_dtimeout = getconf_int(CNF_DTIMEOUT);
+ conf_dtimeout = getconf_time(CNF_DTIMEOUT);
protocol_init();
cmd = getcmd(&cmdargs);
switch(cmd) {
+ case START:
+ if(cmdargs.argc < 2)
+ error("error [dumper START: not enough args: timestamp]");
+ dumper_timestamp = newstralloc(dumper_timestamp, cmdargs.argv[2]);
+ break;
+
+ case ABORT:
+ break;
+
case QUIT:
break;
* level
* dumpdate
* progname
+ * amandad_path
+ * client_username
+ * ssh_keys
* options
*/
cmdargs.argc++; /* true count of args */
if(a >= cmdargs.argc) {
error("error [dumper PORT-DUMP: not enough args: handle]");
+ /*NOTREACHED*/
}
handle = newstralloc(handle, cmdargs.argv[a++]);
if(a >= cmdargs.argc) {
- error("error [dumper PORT-DUMP: not enough args: handle]");
+ error("error [dumper PORT-DUMP: not enough args: port]");
+ /*NOTREACHED*/
}
- taper_port = atoi(cmdargs.argv[a++]);
+ taper_port = (in_port_t)atoi(cmdargs.argv[a++]);
if(a >= cmdargs.argc) {
- error("error [dumper PORT-DUMP: not enough args: handle]");
+ error("error [dumper PORT-DUMP: not enough args: hostname]");
+ /*NOTREACHED*/
}
hostname = newstralloc(hostname, cmdargs.argv[a++]);
if(a >= cmdargs.argc) {
error("error [dumper PORT-DUMP: not enough args: features]");
+ /*NOTREACHED*/
}
am_release_feature_set(their_features);
their_features = am_string_to_feature(cmdargs.argv[a++]);
if(a >= cmdargs.argc) {
- error("error [dumper PORT-DUMP: not enough args: handle]");
+ error("error [dumper PORT-DUMP: not enough args: diskname]");
+ /*NOTREACHED*/
}
- diskname = newstralloc(diskname, cmdargs.argv[a++]);
+ qdiskname = newstralloc(qdiskname, cmdargs.argv[a++]);
+ if (diskname != NULL)
+ amfree(diskname);
+ diskname = unquote_string(qdiskname);
if(a >= cmdargs.argc) {
- error("error [dumper PORT-DUMP: not enough args: handle]");
+ error("error [dumper PORT-DUMP: not enough args: device]");
+ /*NOTREACHED*/
}
device = newstralloc(device, cmdargs.argv[a++]);
- if(strcmp(device,"NODEVICE") == 0) amfree(device);
+ if(strcmp(device,"NODEVICE") == 0)
+ amfree(device);
if(a >= cmdargs.argc) {
- error("error [dumper PORT-DUMP: not enough args: handle]");
+ error("error [dumper PORT-DUMP: not enough args: level]");
+ /*NOTREACHED*/
}
level = atoi(cmdargs.argv[a++]);
if(a >= cmdargs.argc) {
- error("error [dumper PORT-DUMP: not enough args: handle]");
+ error("error [dumper PORT-DUMP: not enough args: dumpdate]");
+ /*NOTREACHED*/
}
dumpdate = newstralloc(dumpdate, cmdargs.argv[a++]);
if(a >= cmdargs.argc) {
- error("error [dumper PORT-DUMP: not enough args: handle]");
+ error("error [dumper PORT-DUMP: not enough args: program]");
+ /*NOTREACHED*/
}
progname = newstralloc(progname, cmdargs.argv[a++]);
if(a >= cmdargs.argc) {
- error("error [dumper PORT-DUMP: not enough args: handle]");
+ error("error [dumper PORT-DUMP: not enough args: amandad_path]");
+ /*NOTREACHED*/
+ }
+ amandad_path = newstralloc(amandad_path, cmdargs.argv[a++]);
+
+ if(a >= cmdargs.argc) {
+ error("error [dumper PORT-DUMP: not enough args: client_username]");
+ }
+ client_username = newstralloc(client_username, cmdargs.argv[a++]);
+
+ if(a >= cmdargs.argc) {
+ error("error [dumper PORT-DUMP: not enough args: ssh_keys]");
+ }
+ ssh_keys = newstralloc(ssh_keys, cmdargs.argv[a++]);
+
+ if(a >= cmdargs.argc) {
+ error("error [dumper PORT-DUMP: not enough args: options]");
}
options = newstralloc(options, cmdargs.argv[a++]);
if(a != cmdargs.argc) {
error("error [dumper PORT-DUMP: too many args: %d != %d]",
cmdargs.argc, a);
+ /*NOTREACHED*/
}
- /* connect outf to taper port */
+ if ((gethostbyname("localhost")) == NULL) {
+ errstr = newstralloc(errstr,
+ "could not resolve localhost");
+ q = squotef(errstr);
+ putresult(FAILED, "%s %s\n", handle, q);
+ log_add(L_FAIL, "%s %s %s %d [%s]", hostname, qdiskname,
+ dumper_timestamp, level, errstr);
+ amfree(q);
+ break;
+ }
+ /* connect outf to chunker/taper port */
outfd = stream_client("localhost", taper_port,
- STREAM_BUFSIZE, -1, NULL, 0);
+ STREAM_BUFSIZE, 0, NULL, 0);
if (outfd == -1) {
- q = squotef("[taper port open: %s]", strerror(errno));
+
+ errstr = newvstralloc(errstr, "port open: ",
+ strerror(errno), NULL);
+ q = squotef(errstr);
putresult(FAILED, "%s %s\n", handle, q);
+ log_add(L_FAIL, "%s %s %s %d [%s]", hostname, qdiskname,
+ dumper_timestamp, level, errstr);
amfree(q);
break;
}
level,
dumpdate,
progname,
+ amandad_path,
+ client_username,
+ ssh_keys,
options);
if (rc != 0) {
q = squote(errstr);
putresult(rc == 2? FAILED : TRYAGAIN, "%s %s\n",
handle, q);
if (rc == 2)
- log_add(L_FAIL, "%s %s %s %d [%s]", hostname, diskname,
- datestamp, level, errstr);
+ log_add(L_FAIL, "%s %s %s %d [%s]", hostname, qdiskname,
+ dumper_timestamp, level, errstr);
amfree(q);
} else {
- if (do_dump(&db)) {
- }
+ do_dump(&db);
}
+
+ amfree(amandad_path);
+ amfree(client_username);
+
break;
default:
aclose(outfd);
} while(cmd != QUIT);
+ /* make sure root privilege is dropped */
+ if ( geteuid() == 0 ) {
+ setuid(ruid);
+ seteuid(ruid);
+ }
+
+ free_new_argv(new_argc, new_argv);
+ free_server_config();
+ am_release_feature_set(our_features);
+ amfree(our_feature_string);
amfree(errstr);
- amfree(datestamp);
+ amfree(dumper_timestamp);
amfree(handle);
amfree(hostname);
+ amfree(qdiskname);
amfree(diskname);
amfree(device);
amfree(dumpdate);
malloc_size_2 = malloc_inuse(&malloc_hist_2);
- if (malloc_size_1 != malloc_size_2)
+ if (malloc_size_1 != malloc_size_2) {
malloc_list(fileno(stderr), malloc_hist_1, malloc_hist_2);
+ }
- exit(0);
+ dbclose();
+ return (0); /* exit */
}
* Initialize a databuf. Takes a writeable file descriptor.
*/
static void
-databuf_init(db, fd)
- struct databuf *db;
- int fd;
+databuf_init(
+ struct databuf * db,
+ int fd)
{
db->fd = fd;
* any boundaries.
*/
static int
-databuf_write(db, buf, size)
- struct databuf *db;
- const void *buf;
- int size;
+databuf_write(
+ struct databuf * db,
+ const void * buf,
+ size_t size)
{
db->buf = (char *)buf;
db->datain = db->datalimit = db->buf + size;
* Write out the buffer to chunker.
*/
static int
-databuf_flush(db)
- struct databuf *db;
+databuf_flush(
+ struct databuf * db)
{
- int written;
+ ssize_t written;
/*
* If there's no data, do nothing.
/*
* Write out the buffer
*/
- written = fullwrite(db->fd, db->dataout, db->datain - db->dataout);
+ written = fullwrite(db->fd, db->dataout,
+ (size_t)(db->datain - db->dataout));
if (written > 0) {
db->dataout += written;
- dumpbytes += written;
+ dumpbytes += (off_t)written;
}
- if (dumpbytes >= 1024) {
- dumpsize += (dumpbytes / 1024);
- dumpbytes %= 1024;
+ if (dumpbytes >= (off_t)1024) {
+ dumpsize += (dumpbytes / (off_t)1024);
+ dumpbytes %= (off_t)1024;
}
if (written < 0) {
errstr = squotef("data write: %s", strerror(errno));
static void
-process_dumpeof()
+process_dumpeof(void)
{
/* process any partial line in msgbuf? !!! */
add_msg_data(NULL, 0);
* of any duplicates.
*/
static void
-parse_info_line(str)
- char *str;
+parse_info_line(
+ char *str)
{
static const struct {
const char *name;
char *value;
size_t len;
} fields[] = {
- { "BACKUP", file.program, sizeof(file.program) },
- { "RECOVER_CMD", file.recover_cmd, sizeof(file.recover_cmd) },
- { "COMPRESS_SUFFIX", file.comp_suffix, sizeof(file.comp_suffix) },
- { "SERVER_CUSTOM_COMPRESS", file.srvcompprog, sizeof(file.srvcompprog) },
- { "CLIENT_CUSTOM_COMPRESS", file.clntcompprog, sizeof(file.clntcompprog) },
- { "SERVER_ENCRYPT", file.srv_encrypt, sizeof(file.srv_encrypt) },
- { "CLIENT_ENCRYPT", file.clnt_encrypt, sizeof(file.clnt_encrypt) },
- { "SERVER_DECRYPT_OPTION", file.srv_decrypt_opt, sizeof(file.srv_decrypt_opt) },
- { "CLIENT_DECRYPT_OPTION", file.clnt_decrypt_opt, sizeof(file.clnt_decrypt_opt) }
+ { "BACKUP", file.program, SIZEOF(file.program) },
+ { "RECOVER_CMD", file.recover_cmd, SIZEOF(file.recover_cmd) },
+ { "COMPRESS_SUFFIX", file.comp_suffix, SIZEOF(file.comp_suffix) },
+ { "SERVER_CUSTOM_COMPRESS", file.srvcompprog, SIZEOF(file.srvcompprog) },
+ { "CLIENT_CUSTOM_COMPRESS", file.clntcompprog, SIZEOF(file.clntcompprog) },
+ { "SERVER_ENCRYPT", file.srv_encrypt, SIZEOF(file.srv_encrypt) },
+ { "CLIENT_ENCRYPT", file.clnt_encrypt, SIZEOF(file.clnt_encrypt) },
+ { "SERVER_DECRYPT_OPTION", file.srv_decrypt_opt, SIZEOF(file.srv_decrypt_opt) },
+ { "CLIENT_DECRYPT_OPTION", file.clnt_decrypt_opt, SIZEOF(file.clnt_decrypt_opt) }
};
char *name, *value;
- int i;
+ size_t i;
if (strcmp(str, "end") == 0) {
SET(status, GOT_INFO_ENDLINE);
if (value == NULL)
return;
- for (i = 0; i < sizeof(fields) / sizeof(fields[0]); i++) {
+ for (i = 0; i < SIZEOF(fields) / SIZEOF(fields[0]); i++) {
if (strcmp(name, fields[i].name) == 0) {
strncpy(fields[i].value, value, fields[i].len - 1);
fields[i].value[fields[i].len - 1] = '\0';
}
static void
-process_dumpline(str)
- const char *str;
+process_dumpline(
+ const char * str)
{
char *buf, *tok;
if (tok == NULL)
goto bad_line;
- if (strcmp(tok, "start") == 0)
+ if (strcmp(tok, "start") == 0) {
break;
+ }
if (strcmp(tok, "size") == 0) {
tok = strtok(NULL, "");
if (tok != NULL) {
- origsize = (long)atof(tok);
+ origsize = OFF_T_ATOI(tok);
SET(status, GOT_SIZELINE);
}
break;
}
static void
-add_msg_data(str, len)
- const char *str;
- size_t len;
+add_msg_data(
+ const char * str,
+ size_t len)
{
static struct {
char *buf; /* buffer holding msg data */
size_t size; /* size of alloced buffer */
} msg = { NULL, 0 };
- char *line, *nl;
+ char *line, *ch;
size_t buflen;
+ int in_quotes = 0;
if (msg.buf != NULL)
buflen = strlen(msg.buf);
if (str == NULL) {
if (buflen == 0)
return;
- fprintf(errf,"? %s: error [partial line in msgbuf: %ld bytes]\n",
- get_pname(), (long)buflen);
+ fprintf(errf,"? %s: error [partial line in msgbuf: "
+ SIZE_T_FMT " bytes]\n", get_pname(),
+ (SIZE_T_FMT_TYPE)buflen);
fprintf(errf,"? %s: error [partial line in msgbuf: \"%s\"]\n",
get_pname(), msg.buf);
msg.buf[0] = '\0';
/*
* Expand the buffer if it can't hold the new contents.
*/
- if (buflen + len + 1 > msg.size) {
+ if ((buflen + len + 1) > msg.size) {
char *newbuf;
size_t newsize;
/* round up to next y, where y is a power of 2 */
#define ROUND(x, y) (((x) + (y) - 1) & ~((y) - 1))
- newsize = ROUND(buflen + len + 1, 256);
+ newsize = ROUND(buflen + (ssize_t)len + 1, 256);
newbuf = alloc(newsize);
if (msg.buf != NULL) {
- strcpy(newbuf, msg.buf);
+ strncpy(newbuf, msg.buf, newsize);
amfree(msg.buf);
} else
newbuf[0] = '\0';
/*
* Process all lines in the buffer
+ * scanning line for unqouted newline.
*/
- for (line = msg.buf;;) {
- /*
- * If there's no newline, then we've only got a partial line.
- * We go back for more.
- */
- if ((nl = strchr(line, '\n')) == NULL)
- break;
- *nl = '\0';
- process_dumpline(line);
- line = nl + 1;
+ for (ch = line = msg.buf; *ch != '\0'; ch++) {
+ if (*ch == '"') {
+ in_quotes = !in_quotes;
+ } else if ((*ch == '\\') && (*(ch + 1) == '"')) {
+ ch++;
+ } else if (!in_quotes && (*ch == '\n')) {
+ /*
+ * Found an unqouted newline. Terminate and process line.
+ */
+ *ch = '\0';
+ process_dumpline(line);
+ line = ch + 1;
+ }
}
/*
*/
if (*line != '\0') {
buflen = strlen(line);
- memmove(msg.buf, line, buflen + 1);
+ memmove(msg.buf, line, (size_t)buflen + 1);
} else {
msg.buf[0] = '\0';
}
static void
-log_msgout(typ)
- logtype_t typ;
+log_msgout(
+ logtype_t typ)
{
char *line;
fflush(errf);
- (void) fseek(errf, 0L, SEEK_SET);
+ if (fseek(errf, 0L, SEEK_SET) < 0) {
+ dbprintf(("log_msgout: warning - seek failed: %s\n", strerror(errno)));
+ }
while ((line = agets(errf)) != NULL) {
- log_add(typ, "%s", line);
+ if (line[0] != '\0') {
+ log_add(typ, "%s", line);
+ }
amfree(line);
}
* Fill in the rest of the tape header
*/
static void
-finish_tapeheader(file)
- dumpfile_t *file;
+finish_tapeheader(
+ dumpfile_t *file)
{
assert(ISSET(status, HEADER_DONE));
file->type = F_DUMPFILE;
- strncpy(file->datestamp, datestamp, sizeof(file->datestamp) - 1);
- strncpy(file->name, hostname, sizeof(file->name) - 1);
- strncpy(file->disk, diskname, sizeof(file->disk) - 1);
+ strncpy(file->datestamp, dumper_timestamp, sizeof(file->datestamp) - 1);
+ strncpy(file->name, hostname, SIZEOF(file->name) - 1);
+ strncpy(file->disk, diskname, SIZEOF(file->disk) - 1);
file->dumplevel = level;
/*
#define UNCOMPRESS_OPT ""
#endif
if (srvcompress == COMP_SERV_CUST) {
- snprintf(file->uncompress_cmd, sizeof(file->uncompress_cmd),
+ snprintf(file->uncompress_cmd, SIZEOF(file->uncompress_cmd),
" %s %s |", srvcompprog, "-d");
- strcpy(file->comp_suffix, "cust");
- strncpy(file->srvcompprog, srvcompprog, sizeof(file->srvcompprog));
- file->srvcompprog[sizeof(file->srvcompprog)-1] = '\0';
+ strncpy(file->comp_suffix, "cust", SIZEOF(file->comp_suffix) - 1);
+ file->comp_suffix[SIZEOF(file->comp_suffix) - 1] = '\0';
+ strncpy(file->srvcompprog, srvcompprog, SIZEOF(file->srvcompprog) - 1);
+ file->srvcompprog[SIZEOF(file->srvcompprog) - 1] = '\0';
} else if ( srvcompress == COMP_CUST ) {
- snprintf(file->uncompress_cmd, sizeof(file->uncompress_cmd),
+ snprintf(file->uncompress_cmd, SIZEOF(file->uncompress_cmd),
" %s %s |", clntcompprog, "-d");
- strcpy(file->comp_suffix, "cust");
- strncpy(file->clntcompprog, clntcompprog, sizeof(file->clntcompprog));
- file->clntcompprog[sizeof(file->clntcompprog)-1] = '\0';
+ strncpy(file->comp_suffix, "cust", SIZEOF(file->comp_suffix) - 1);
+ file->comp_suffix[SIZEOF(file->comp_suffix) - 1] = '\0';
+ strncpy(file->clntcompprog, clntcompprog, SIZEOF(file->clntcompprog));
+ file->clntcompprog[SIZEOF(file->clntcompprog) - 1] = '\0';
} else {
- snprintf(file->uncompress_cmd, sizeof(file->uncompress_cmd),
+ snprintf(file->uncompress_cmd, SIZEOF(file->uncompress_cmd),
" %s %s |", UNCOMPRESS_PATH, UNCOMPRESS_OPT);
- strncpy(file->comp_suffix, COMPRESS_SUFFIX,sizeof(file->comp_suffix)-1);
- file->comp_suffix[sizeof(file->comp_suffix)-1] = '\0';
+ strncpy(file->comp_suffix, COMPRESS_SUFFIX,SIZEOF(file->comp_suffix) - 1);
+ file->comp_suffix[SIZEOF(file->comp_suffix) - 1] = '\0';
}
} else {
if (file->comp_suffix[0] == '\0') {
file->compressed = 0;
- assert(sizeof(file->comp_suffix) >= 2);
- strcpy(file->comp_suffix, "N");
+ assert(SIZEOF(file->comp_suffix) >= 2);
+ strncpy(file->comp_suffix, "N", SIZEOF(file->comp_suffix) - 1);
+ file->comp_suffix[SIZEOF(file->comp_suffix) - 1] = '\0';
} else {
file->compressed = 1;
}
if (srvencrypt != ENCRYPT_NONE) {
file->encrypted= 1;
if (srvencrypt == ENCRYPT_SERV_CUST) {
- snprintf(file->decrypt_cmd, sizeof(file->decrypt_cmd),
+ snprintf(file->decrypt_cmd, SIZEOF(file->decrypt_cmd),
" %s %s |", srv_encrypt, srv_decrypt_opt);
- strcpy(file->encrypt_suffix, "enc");
- strncpy(file->srv_encrypt, srv_encrypt, sizeof(file->srv_encrypt));
- file->srv_encrypt[sizeof(file->srv_encrypt)-1] = '\0';
- strncpy(file->srv_decrypt_opt, srv_decrypt_opt, sizeof(file->srv_decrypt_opt));
- file->srv_decrypt_opt[sizeof(file->srv_decrypt_opt)-1] = '\0';
+ strncpy(file->encrypt_suffix, "enc", SIZEOF(file->encrypt_suffix) - 1);
+ file->encrypt_suffix[SIZEOF(file->encrypt_suffix) - 1] = '\0';
+ strncpy(file->srv_encrypt, srv_encrypt, SIZEOF(file->srv_encrypt) - 1);
+ file->srv_encrypt[SIZEOF(file->srv_encrypt) - 1] = '\0';
+ strncpy(file->srv_decrypt_opt, srv_decrypt_opt, SIZEOF(file->srv_decrypt_opt) - 1);
+ file->srv_decrypt_opt[SIZEOF(file->srv_decrypt_opt) - 1] = '\0';
} else if ( srvencrypt == ENCRYPT_CUST ) {
- snprintf(file->decrypt_cmd, sizeof(file->decrypt_cmd),
+ snprintf(file->decrypt_cmd, SIZEOF(file->decrypt_cmd),
" %s %s |", clnt_encrypt, clnt_decrypt_opt);
- strcpy(file->encrypt_suffix, "enc");
- strncpy(file->clnt_encrypt, clnt_encrypt, sizeof(file->clnt_encrypt));
- file->clnt_encrypt[sizeof(file->clnt_encrypt)-1] = '\0';
- strncpy(file->clnt_decrypt_opt, clnt_decrypt_opt, sizeof(file->clnt_decrypt_opt));
- file->clnt_decrypt_opt[sizeof(file->clnt_decrypt_opt)-1] = '\0';
+ strncpy(file->encrypt_suffix, "enc", SIZEOF(file->encrypt_suffix) - 1);
+ file->encrypt_suffix[SIZEOF(file->encrypt_suffix) - 1] = '\0';
+ strncpy(file->clnt_encrypt, clnt_encrypt, SIZEOF(file->clnt_encrypt) - 1);
+ file->clnt_encrypt[SIZEOF(file->clnt_encrypt) - 1] = '\0';
+ strncpy(file->clnt_decrypt_opt, clnt_decrypt_opt, SIZEOF(file->clnt_decrypt_opt));
+ file->clnt_decrypt_opt[SIZEOF(file->clnt_decrypt_opt) - 1] = '\0';
}
} else {
if (file->encrypt_suffix[0] == '\0') {
file->encrypted = 0;
- assert(sizeof(file->encrypt_suffix) >= 2);
- strcpy(file->encrypt_suffix, "N");
+ assert(SIZEOF(file->encrypt_suffix) >= 2);
+ strncpy(file->encrypt_suffix, "N", SIZEOF(file->encrypt_suffix) - 1);
+ file->encrypt_suffix[SIZEOF(file->encrypt_suffix) - 1] = '\0';
} else {
file->encrypted= 1;
}
/*
* Send an Amanda dump header to the output file.
*/
-static int
-write_tapeheader(outfd, file)
- int outfd;
- dumpfile_t *file;
+static ssize_t
+write_tapeheader(
+ int outfd,
+ dumpfile_t *file)
{
char buffer[DISK_BLOCK_BYTES];
- int written;
+ ssize_t written;
- build_header(buffer, file, sizeof(buffer));
+ build_header(buffer, file, SIZEOF(buffer));
+
+ written = write(outfd, buffer, SIZEOF(buffer));
+ if(written == (ssize_t)sizeof(buffer))
+ return 0;
+ if(written < 0)
+ return written;
- written = write(outfd, buffer, sizeof(buffer));
- if(written == sizeof(buffer)) return 0;
- if(written < 0) return written;
errno = ENOSPC;
return -1;
}
static int
-do_dump(db)
- struct databuf *db;
+do_dump(
+ struct databuf *db)
{
char *indexfile_tmp = NULL;
char *indexfile_real = NULL;
startclock();
- dumpbytes = dumpsize = headersize = origsize = dump_result = 0;
status = 0;
+ dump_result = 0;
+ dumpbytes = dumpsize = headersize = origsize = (off_t)0;
fh_init(&file);
- snprintf(level_str, sizeof(level_str), "%d", level);
+ snprintf(level_str, SIZEOF(level_str), "%d", level);
fn = sanitise_filename(diskname);
errfname = newvstralloc(errfname,
AMANDA_TMPDIR,
amfree(errfname);
if (streams[INDEXFD].fd != NULL) {
- indexfile_real = getindexfname(hostname, diskname, datestamp, level);
+ indexfile_real = getindexfname(hostname, diskname, dumper_timestamp, level);
indexfile_tmp = stralloc2(indexfile_real, ".tmp");
if (mkpdir(indexfile_tmp, 02755, (uid_t)-1, (gid_t)-1) == -1) {
* the header, we will start processing data too.
*/
security_stream_read(streams[MESGFD].fd, read_mesgfd, db);
+ set_datafd = 0;
/*
* Setup a read timeout
goto failed;
runtime = stopclock();
- dumptime = runtime.r.tv_sec + runtime.r.tv_usec/1000000.0;
+ dumptime = (double)(runtime.r.tv_sec) +
+ ((double)(runtime.r.tv_usec) / 1000000.0);
dumpsize -= headersize; /* don't count the header */
- if (dumpsize < 0) dumpsize = 0; /* XXX - maybe this should be fatal? */
+ if (dumpsize < (off_t)0) /* XXX - maybe this should be fatal? */
+ dumpsize = (off_t)0;
amfree(errstr);
errstr = alloc(128);
- snprintf(errstr, 128, "sec %s kb %ld kps %3.1f orig-kb %ld",
- walltime_str(runtime), dumpsize,
- dumptime ? dumpsize / dumptime : 0.0, origsize);
+ snprintf(errstr, 128, "sec %s kb " OFF_T_FMT " kps %3.1lf orig-kb " OFF_T_FMT "",
+ walltime_str(runtime),
+ (OFF_T_FMT_TYPE)dumpsize,
+ (isnormal(dumptime) ? ((double)dumpsize / (double)dumptime) : 0.0),
+ (OFF_T_FMT_TYPE)origsize);
q = squotef("[%s]", errstr);
- putresult(DONE, "%s %ld %ld %ld %s\n", handle, origsize, dumpsize,
- (long)(dumptime+0.5), q);
+ putresult(DONE, "%s " OFF_T_FMT " " OFF_T_FMT " %lu %s\n", handle,
+ (OFF_T_FMT_TYPE)origsize,
+ (OFF_T_FMT_TYPE)dumpsize,
+ (unsigned long)((double)dumptime+0.5), q);
amfree(q);
switch(dump_result) {
case 0:
- log_add(L_SUCCESS, "%s %s %s %d [%s]", hostname, diskname, datestamp, level, errstr);
+ log_add(L_SUCCESS, "%s %s %s %d [%s]", hostname, qdiskname, dumper_timestamp, level, errstr);
break;
case 1:
log_start_multiline();
- log_add(L_STRANGE, "%s %s %d [%s]", hostname, diskname, level, errstr);
+ log_add(L_STRANGE, "%s %s %d [%s]", hostname, qdiskname, level, errstr);
log_msgout(L_STRANGE);
log_end_multiline();
if (indexfile_tmp) {
amwait_t index_status;
- aclose(indexout);
+ /*@i@*/ aclose(indexout);
waitpid(indexpid,&index_status,0);
if (rename(indexfile_tmp, indexfile_real) != 0) {
log_add(L_WARNING, "could not rename \"%s\" to \"%s\": %s",
}
log_start_multiline();
- log_add(L_FAIL, "%s %s %s %d [%s]", hostname, diskname, datestamp,
+ log_add(L_FAIL, "%s %s %s %d [%s]", hostname, qdiskname, dumper_timestamp,
level, errstr);
if (errf) {
log_msgout(L_FAIL);
* Callback for reads on the mesgfd stream
*/
static void
-read_mesgfd(cookie, buf, size)
- void *cookie, *buf;
- ssize_t size;
+read_mesgfd(
+ void * cookie,
+ void * buf,
+ ssize_t size)
{
struct databuf *db = cookie;
dump_result = 2;
stop_dump();
return;
+
case 0:
/*
* EOF. Just shut down the mesg stream.
/*
* If the data fd and index fd has also shut down, then we're done.
*/
- if (streams[DATAFD].fd == NULL && streams[INDEXFD].fd == NULL)
+ if ((set_datafd == 0 || streams[DATAFD].fd == NULL) &&
+ streams[INDEXFD].fd == NULL)
stop_dump();
return;
+
default:
assert(buf != NULL);
- add_msg_data(buf, size);
+ add_msg_data(buf, (size_t)size);
security_stream_read(streams[MESGFD].fd, read_mesgfd, cookie);
break;
}
stop_dump();
return;
}
- dumpsize += DISK_BLOCK_KB;
- headersize += DISK_BLOCK_KB;
+ dumpsize += (off_t)DISK_BLOCK_KB;
+ headersize += (off_t)DISK_BLOCK_KB;
if (srvencrypt == ENCRYPT_SERV_CUST) {
if (runencrypt(db->fd, &db->encryptpid, srvencrypt) < 0) {
}
}
security_stream_read(streams[DATAFD].fd, read_datafd, db);
+ set_datafd = 1;
}
}
* Callback for reads on the datafd stream
*/
static void
-read_datafd(cookie, buf, size)
- void *cookie, *buf;
- ssize_t size;
+read_datafd(
+ void * cookie,
+ void * buf,
+ ssize_t size)
{
struct databuf *db = cookie;
*/
if (size == 0) {
databuf_flush(db);
- if (dumpbytes) {
- dumpsize++;
+ if (dumpbytes != (off_t)0) {
+ dumpsize += (off_t)1;
}
security_stream_close(streams[DATAFD].fd);
streams[DATAFD].fd = NULL;
* more data.
*/
assert(buf != NULL);
- if (databuf_write(db, buf, size) < 0) {
+ if (databuf_write(db, buf, (size_t)size) < 0) {
errstr = newstralloc2(errstr, "data write: ", strerror(errno));
dump_result = 2;
stop_dump();
* Callback for reads on the index stream
*/
static void
-read_indexfd(cookie, buf, size)
- void *cookie, *buf;
- ssize_t size;
+read_indexfd(
+ void * cookie,
+ void * buf,
+ ssize_t size)
{
int fd;
/*
* If the mesg fd has also shut down, then we're done.
*/
- if (streams[DATAFD].fd == NULL && streams[MESGFD].fd == NULL)
+ if ((set_datafd == 0 || streams[DATAFD].fd == NULL) &&
+ streams[MESGFD].fd == NULL)
stop_dump();
return;
}
/*
* We ignore error while writing to the index file.
*/
- if (fullwrite(fd, buf, size) < 0) {
+ if (fullwrite(fd, buf, (size_t)size) < 0) {
/* Ignore error, but schedule another read. */
if(indexfderror == 0) {
indexfderror = 1;
- log_add(L_INFO, "Index corrupted for %s:%s", hostname, diskname);
+ log_add(L_INFO, "Index corrupted for %s:%s", hostname, qdiskname);
}
}
security_stream_read(streams[INDEXFD].fd, read_indexfd, cookie);
* then remove the timeout.
*/
static void
-timeout(seconds)
- int seconds;
+timeout(
+ time_t seconds)
{
static event_handle_t *ev_timeout = NULL;
* Now, schedule a new one if 'seconds' is greater than 0
*/
if (seconds > 0)
- ev_timeout = event_register(seconds, EV_TIME, timeout_callback, NULL);
+ ev_timeout = event_register((event_id_t)seconds, EV_TIME, timeout_callback, NULL);
}
/*
* have a data timeout.
*/
static void
-timeout_callback(unused)
- void *unused;
+timeout_callback(
+ void * unused)
{
+ (void)unused; /* Quiet unused parameter warning */
+
assert(unused == NULL);
errstr = newstralloc(errstr, "data timeout");
dump_result = 2;
* will exit.
*/
static void
-stop_dump()
+stop_dump(void)
{
int i;
* process.
*/
static int
-runcompress(outfd, pid, comptype)
- int outfd;
- pid_t *pid;
- comp_t comptype;
+runcompress(
+ int outfd,
+ pid_t * pid,
+ comp_t comptype)
{
int outpipe[2], rval;
aclose(outpipe[0]);
return (rval);
case 0:
- if (dup2(outpipe[0], 0) < 0)
+ if (dup2(outpipe[0], 0) < 0) {
error("err dup2 in: %s", strerror(errno));
- if (dup2(outfd, 1) == -1)
+ /*NOTREACHED*/
+ }
+ if (dup2(outfd, 1) == -1) {
error("err dup2 out: %s", strerror(errno));
+ /*NOTREACHED*/
+ }
safe_fd(-1, 0);
if (comptype != COMP_SERV_CUST) {
execlp(COMPRESS_PATH, COMPRESS_PATH, ( comptype == COMP_BEST ?
- COMPRESS_BEST_OPT : COMPRESS_FAST_OPT), NULL);
+ COMPRESS_BEST_OPT : COMPRESS_FAST_OPT), (char *)NULL);
error("error: couldn't exec %s: %s", COMPRESS_PATH, strerror(errno));
+ /*NOTREACHED*/
} else if (*srvcompprog) {
execlp(srvcompprog, srvcompprog, (char *)0);
error("error: couldn't exec server custom filter%s.\n", srvcompprog);
+ /*NOTREACHED*/
}
}
- /* NOTREACHED */
+ /*NOTREACHED*/
return (-1);
}
* process.
*/
static int
-runencrypt(outfd, pid, encrypttype)
- int outfd;
- pid_t *pid;
- encrypt_t encrypttype;
+runencrypt(
+ int outfd,
+ pid_t * pid,
+ encrypt_t encrypttype)
{
int outpipe[2], rval;
aclose(outpipe[0]);
return (rval);
case 0:
- if (dup2(outpipe[0], 0) < 0)
+ if (dup2(outpipe[0], 0) < 0) {
error("err dup2 in: %s", strerror(errno));
- if (dup2(outfd, 1) < 0 )
+ /*NOTREACHED*/
+ }
+ if (dup2(outfd, 1) < 0 ) {
error("err dup2 out: %s", strerror(errno));
+ /*NOTREACHED*/
+ }
safe_fd(-1, 0);
if ((encrypttype == ENCRYPT_SERV_CUST) && *srv_encrypt) {
execlp(srv_encrypt, srv_encrypt, (char *)0);
error("error: couldn't exec server encryption%s.\n", srv_encrypt);
+ /*NOTREACHED*/
}
}
- /* NOTREACHED */
+ /*NOTREACHED*/
return (-1);
}
/* -------------------- */
static void
-sendbackup_response(datap, pkt, sech)
- void *datap;
- pkt_t *pkt;
- security_handle_t *sech;
+sendbackup_response(
+ void * datap,
+ pkt_t * pkt,
+ security_handle_t * sech)
{
int ports[NSTREAMS], *response_error = datap, i;
char *p;
char *tok;
- char *tok_end;
- char *extra = NULL;
+ char *extra;
assert(response_error != NULL);
assert(sech != NULL);
+ security_close_connection(sech, hostname);
+
if (pkt == NULL) {
errstr = newvstralloc(errstr, "[request failed: ",
security_geterror(sech), "]", NULL);
return;
}
+ extra = NULL;
+ memset(ports, 0, SIZEOF(ports));
if (pkt->type == P_NAK) {
#if defined(PACKET_DEBUG)
fprintf(stderr, "got nak response:\n----\n%s\n----\n\n", pkt->body);
return;
}
-#if defined(PACKET_DEBUG)
+#if 1
+//#if defined(PACKET_DEBUG)
fprintf(stderr, "got response:\n----\n%s\n----\n\n", pkt->body);
#endif
extra = stralloc("OPTIONS token is missing");
goto parse_error;
}
- tok_end = tok + strlen(tok);
while((p = strchr(tok, ';')) != NULL) {
*p++ = '\0';
#define sc "features="
- if(strncmp(tok, sc, sizeof(sc)-1) == 0) {
- tok += sizeof(sc) - 1;
+ if(strncmp(tok, sc, SIZEOF(sc) - 1) == 0) {
+ tok += SIZEOF(sc) - 1;
#undef sc
am_release_feature_set(their_features);
if((their_features = am_string_to_feature(tok)) == NULL) {
/* everything worked */
*response_error = 0;
+ security_close_connection(sech, hostname);
return;
parse_error:
NULL);
amfree(extra);
*response_error = 2;
+ security_close_connection(sech, hostname);
return;
connect_error:
stop_dump();
*response_error = 1;
+ security_close_connection(sech, hostname);
+}
+
+static char *
+dumper_get_security_conf(
+ char * string,
+ void * arg)
+{
+ (void)arg; /* Quiet unused parameter warning */
+
+ if(!string || !*string)
+ return(NULL);
+
+ if(strcmp(string, "krb5principal")==0) {
+ return(getconf_str(CNF_KRB5PRINCIPAL));
+ } else if(strcmp(string, "krb5keytab")==0) {
+ return(getconf_str(CNF_KRB5KEYTAB));
+ } else if(strcmp(string, "amandad_path")==0) {
+ return (amandad_path);
+ } else if(strcmp(string, "client_username")==0) {
+ return (client_username);
+ } else if(strcmp(string, "ssh_keys")==0) {
+ return (ssh_keys);
+ }
+ return(NULL);
}
static int
-startup_dump(hostname, disk, device, level, dumpdate, progname, options)
- const char *hostname, *disk, *device, *dumpdate, *progname, *options;
- int level;
+startup_dump(
+ const char *hostname,
+ const char *disk,
+ const char *device,
+ int level,
+ const char *dumpdate,
+ const char *progname,
+ const char *amandad_path,
+ const char *client_username,
+ const char *ssh_keys,
+ const char *options)
{
char level_string[NUM_STR_SIZE];
char *req = NULL;
- char *authopt, *endauthopt, authoptbuf[64];
+ char *authopt, *endauthopt, authoptbuf[80];
int response_error;
const security_driver_t *secdrv;
char *dumper_api;
+ int has_features;
+ int has_hostname;
+ int has_device;
+ int has_config;
+
+ (void)disk; /* Quiet unused parameter warning */
+ (void)amandad_path; /* Quiet unused parameter warning */
+ (void)client_username; /* Quiet unused parameter warning */
+ (void)ssh_keys; /* Quiet unused parameter warning */
- int has_features = am_has_feature(their_features, fe_req_options_features);
- int has_hostname = am_has_feature(their_features, fe_req_options_hostname);
- int has_device = am_has_feature(their_features, fe_sendbackup_req_device);
+ has_features = am_has_feature(their_features, fe_req_options_features);
+ has_hostname = am_has_feature(their_features, fe_req_options_hostname);
+ has_config = am_has_feature(their_features, fe_req_options_config);
+ has_device = am_has_feature(their_features, fe_sendbackup_req_device);
/*
* Default to bsd authentication if none specified. This is gross.
* Options really need to be pre-parsed into some sort of structure
* much earlier, and then flattened out again before transmission.
*/
- if ((authopt = strstr(options, "auth=")) == NULL
- || (endauthopt = strchr(authopt, ';')) == NULL
- || (sizeof(authoptbuf) - 1 < endauthopt - authopt)) {
+ authopt = strstr(options, "auth=");
+ if (authopt == NULL) {
authopt = "BSD";
} else {
- authopt += strlen("auth=");
- strncpy(authoptbuf, authopt, endauthopt - authopt);
- authoptbuf[endauthopt - authopt] = '\0';
- authopt = authoptbuf;
+ endauthopt = strchr(authopt, ';');
+ if ((endauthopt == NULL) ||
+ ((sizeof(authoptbuf) - 1) < (size_t)(endauthopt - authopt))) {
+ authopt = "BSD";
+ } else {
+ authopt += strlen("auth=");
+ strncpy(authoptbuf, authopt, (size_t)(endauthopt - authopt));
+ authoptbuf[endauthopt - authopt] = '\0';
+ authopt = authoptbuf;
+ }
}
- snprintf(level_string, sizeof(level_string), "%d", level);
+ snprintf(level_string, SIZEOF(level_string), "%d", level);
if(strncmp(progname, "DUMP", 4) == 0
|| strncmp(progname, "GNUTAR", 6) == 0) {
dumper_api = "";
has_hostname ? "hostname=" : "",
has_hostname ? hostname : "",
has_hostname ? ";" : "",
+ has_config ? "config=" : "",
+ has_config ? config_name : "",
+ has_config ? ";" : "",
"\n",
dumper_api, progname,
- " ", disk,
+ " ", qdiskname,
" ", device && has_device ? device : "",
" ", level_string,
" ", dumpdate,
"\n",
NULL);
+fprintf(stderr, "send request:\n----\n%s\n----\n\n", req);
secdrv = security_getdriver(authopt);
if (secdrv == NULL) {
error("no '%s' security driver available for host '%s'",
authopt, hostname);
+ /*NOTREACHED*/
}
- protocol_sendreq(hostname, secdrv, generic_get_security_conf, req,
+ protocol_sendreq(hostname, secdrv, dumper_get_security_conf, req,
STARTUP_TIMEOUT, sendbackup_response, &response_error);
amfree(req);
* University of Maryland at College Park
*/
/*
- * $Id: find.c,v 1.23 2006/01/15 21:01:00 martinea Exp $
+ * $Id: find.c,v 1.33 2006/07/06 13:13:15 martinea Exp $
*
* controlling process for the Amanda backup system
*/
#include "holding.h"
#include "find.h"
-void find P((int argc, char **argv));
-int find_match P((char *host, char *disk));
-int search_logfile P((find_result_t **output_find, char *label, int datestamp, int datestamp_aux, char *logfile));
-void search_holding_disk P((find_result_t **output_find));
-void strip_failed_chunks P((find_result_t *output_find));
-char *find_nicedate P((int datestamp));
-static int find_compare P((const void *, const void *));
-static int parse_taper_datestamp_log P((char *, int *, char **));
+int find_match(char *host, char *disk);
+int search_logfile(find_result_t **output_find, char *label, char *datestamp, char *logfile);
+void search_holding_disk(find_result_t **output_find);
+void strip_failed_chunks(find_result_t **output_find);
+char *find_nicedate(char *datestamp);
+static int find_compare(const void *, const void *);
+static int parse_taper_datestamp_log(char *logline, char **datestamp, char **level);
+static int seen_chunk_of(find_result_t *output_find, char *date, char *host, char *disk, int level);
static char *find_sort_order = NULL;
int dynamic_disklist = 0;
disklist_t* find_diskqp = NULL;
-find_result_t *find_dump(dyna_disklist, diskqp)
-int dyna_disklist;
-disklist_t* diskqp;
+find_result_t *
+find_dump(
+ int dyna_disklist,
+ disklist_t* diskqp)
{
char *conf_logdir, *logfile = NULL;
- int tape, maxtape, seq, logs;
+ int tape, maxtape, logs;
+ unsigned seq;
tape_t *tp;
find_result_t *output_find = NULL;
maxtape = lookup_nb_tape();
for(tape = 1; tape <= maxtape; tape++) {
- char ds_str[NUM_STR_SIZE];
tp = lookup_tapepos(tape);
if(tp == NULL) continue;
- snprintf(ds_str, sizeof(ds_str), "%d", tp->datestamp);
/* search log files */
for(seq = 0; 1; seq++) {
char seq_str[NUM_STR_SIZE];
- snprintf(seq_str, sizeof(seq_str), "%d", seq);
+ snprintf(seq_str, SIZEOF(seq_str), "%u", seq);
logfile = newvstralloc(logfile,
- conf_logdir, "/log.", ds_str, ".", seq_str, NULL);
+ conf_logdir, "/log.", tp->datestamp, ".", seq_str, NULL);
if(access(logfile, R_OK) != 0) break;
- logs += search_logfile(&output_find, tp->label, tp->datestamp, seq, logfile);
+ logs += search_logfile(&output_find, tp->label, tp->datestamp, logfile);
}
/* search old-style amflush log, if any */
logfile = newvstralloc(logfile,
- conf_logdir, "/log.", ds_str, ".amflush", NULL);
+ conf_logdir, "/log.", tp->datestamp, ".amflush", NULL);
if(access(logfile,R_OK) == 0) {
- logs += search_logfile(&output_find, tp->label, tp->datestamp, 1000, logfile);
+ logs += search_logfile(&output_find, tp->label, tp->datestamp, logfile);
}
/* search old-style main log, if any */
- logfile = newvstralloc(logfile, conf_logdir, "/log.", ds_str, NULL);
+ logfile = newvstralloc(logfile, conf_logdir, "/log.", tp->datestamp, NULL);
if(access(logfile,R_OK) == 0) {
- logs += search_logfile(&output_find, tp->label, tp->datestamp, -1, logfile);
+ logs += search_logfile(&output_find, tp->label, tp->datestamp, logfile);
}
- if(logs == 0 && tp->datestamp != 0)
+ if(logs == 0 && strcmp(tp->datestamp,"0") != 0)
printf("Warning: no log files found for tape %s written %s\n",
tp->label, find_nicedate(tp->datestamp));
}
search_holding_disk(&output_find);
- strip_failed_chunks(output_find);
+ strip_failed_chunks(&output_find);
return(output_find);
}
-char **find_log()
+char **
+find_log(void)
{
char *conf_logdir, *logfile = NULL;
- int tape, maxtape, seq, logs;
+ int tape, maxtape, logs;
+ unsigned seq;
tape_t *tp;
char **output_find_log = NULL;
char **current_log;
}
maxtape = lookup_nb_tape();
- output_find_log = alloc((maxtape*5+10) * sizeof(char *));
+ output_find_log = alloc((maxtape*5+10) * SIZEOF(char *));
current_log = output_find_log;
for(tape = 1; tape <= maxtape; tape++) {
- char ds_str[NUM_STR_SIZE];
tp = lookup_tapepos(tape);
if(tp == NULL) continue;
- snprintf(ds_str, sizeof(ds_str), "%d", tp->datestamp);
/* search log files */
for(seq = 0; 1; seq++) {
char seq_str[NUM_STR_SIZE];
- snprintf(seq_str, sizeof(seq_str), "%d", seq);
+ snprintf(seq_str, SIZEOF(seq_str), "%u", seq);
logfile = newvstralloc(logfile,
- conf_logdir, "/log.", ds_str, ".", seq_str, NULL);
+ conf_logdir, "/log.", tp->datestamp, ".", seq_str, NULL);
if(access(logfile, R_OK) != 0) break;
- if( search_logfile(NULL, tp->label, tp->datestamp, seq, logfile)) {
- *current_log = vstralloc("log.", ds_str, ".", seq_str, NULL);
+ if( search_logfile(NULL, tp->label, tp->datestamp, logfile)) {
+ *current_log = vstralloc("log.", tp->datestamp, ".", seq_str, NULL);
current_log++;
logs++;
break;
/* search old-style amflush log, if any */
logfile = newvstralloc(logfile,
- conf_logdir, "/log.", ds_str, ".amflush", NULL);
+ conf_logdir, "/log.", tp->datestamp, ".amflush", NULL);
if(access(logfile,R_OK) == 0) {
- if( search_logfile(NULL, tp->label, tp->datestamp, 1000, logfile)) {
- *current_log = vstralloc("log.", ds_str, ".amflush", NULL);
+ if( search_logfile(NULL, tp->label, tp->datestamp, logfile)) {
+ *current_log = vstralloc("log.", tp->datestamp, ".amflush", NULL);
current_log++;
logs++;
}
/* search old-style main log, if any */
- logfile = newvstralloc(logfile, conf_logdir, "/log.", ds_str, NULL);
+ logfile = newvstralloc(logfile, conf_logdir, "/log.", tp->datestamp, NULL);
if(access(logfile,R_OK) == 0) {
- if(search_logfile(NULL, tp->label, tp->datestamp, -1, logfile)) {
- *current_log = vstralloc("log.", ds_str, NULL);
+ if(search_logfile(NULL, tp->label, tp->datestamp, logfile)) {
+ *current_log = vstralloc("log.", tp->datestamp, NULL);
current_log++;
logs++;
}
}
- if(logs == 0 && tp->datestamp != 0)
+ if(logs == 0 && strcmp(tp->datestamp,"0") != 0)
printf("Warning: no log files found for tape %s written %s\n",
tp->label, find_nicedate(tp->datestamp));
}
/*
* Remove CHUNK entries from dumps that ultimately failed from our report.
*/
-void strip_failed_chunks(output_find)
-find_result_t *output_find;
+void strip_failed_chunks(
+ find_result_t **output_find)
{
find_result_t *cur, *prev = NULL, *failed = NULL, *failures = NULL;
/* Generate a list of failures */
- for(cur=output_find; cur; cur=cur->next) {
- if(!cur->hostname || !cur->diskname) continue;
+ for(cur=*output_find; cur; cur=cur->next) {
+ if(!cur->hostname || !cur->diskname ||
+ !cur->timestamp || !cur->label)
+ continue;
if(strcmp(cur->status, "OK")){
- failed = alloc(sizeof(find_result_t));
- memcpy(failed, cur, sizeof(find_result_t));
+ failed = alloc(SIZEOF(find_result_t));
+ memcpy(failed, cur, SIZEOF(find_result_t));
failed->next = failures;
- failed->diskname = stralloc(cur->diskname);
- failed->hostname = stralloc(cur->hostname);
failures = failed;
}
}
/* Now if a CHUNK matches the parameters of a failed dump, remove it */
for(failed=failures; failed; failed=failed->next) {
prev = NULL;
- for(cur=output_find; cur; cur=cur->next) {
- if(!cur->hostname || !cur->diskname ||
- !strcmp(cur->partnum, "--") || strcmp(cur->status, "OK")){
+ cur = *output_find;
+ while (cur != NULL) {
+ find_result_t *next = cur->next;
+ if(!cur->hostname || !cur->diskname ||
+ !cur->timestamp || !cur->label || !cur->partnum ||
+ !strcmp(cur->partnum, "--") || strcmp(cur->status, "OK")) {
prev = cur;
- continue;
+ cur = next;
}
-
- if(!strcmp(cur->hostname, failed->hostname) &&
+ else if(!strcmp(cur->hostname, failed->hostname) &&
!strcmp(cur->diskname, failed->diskname) &&
- cur->datestamp == failed->datestamp &&
- cur->datestamp_aux == failed->datestamp_aux &&
+ !strcmp(cur->timestamp, failed->timestamp) &&
+ !strcmp(cur->label, failed->label) &&
cur->level == failed->level){
- find_result_t *next = cur->next;
amfree(cur->diskname);
amfree(cur->hostname);
- next = cur->next;
- amfree(cur);
- if(prev){
+ amfree(cur->label);
+ amfree(cur->timestamp);
+ amfree(cur->partnum);
+ amfree(cur->status);
+ cur = next;
+ if (prev) {
+ amfree(prev->next);
prev->next = next;
- cur = prev;
+ } else {
+ amfree(*output_find);
+ *output_find = next;
}
- else output_find = next;
}
- else prev = cur;
+ else {
+ prev = cur;
+ cur = next;
+ }
+
}
}
for(failed=failures; failed;) {
find_result_t *fai = failed->next;
- amfree(failed->diskname);
- amfree(failed->hostname);
fai = failed->next;
amfree(failed);
failed=fai;
}
}
-void search_holding_disk(output_find)
-find_result_t **output_find;
+void
+search_holding_disk(
+ find_result_t **output_find)
{
holdingdisk_t *hdisk;
sl_t *holding_list;
char *diskname = NULL;
DIR *workdir;
struct dirent *entry;
- int level;
+ int level = 0;
disk_t *dp;
+ int fd;
+ ssize_t result;
+ char buf[DISK_BLOCK_BYTES];
+ dumpfile_t file;
holding_list = pick_all_datestamp(1);
for(hdisk = getconf_holdingdisks(); hdisk != NULL; hdisk = hdisk->next) {
for(dir = holding_list->first; dir != NULL; dir = dir->next) {
sdirname = newvstralloc(sdirname,
- hdisk->diskdir, "/", dir->name,
+ holdingdisk_get_diskdir(hdisk), "/", dir->name,
NULL);
if((workdir = opendir(sdirname)) == NULL) {
continue;
}
if(level < 0 || level > 9)
continue;
+ if ((fd = open(destname, O_RDONLY)) == -1) {
+ continue;
+ }
+ if((result = read(fd, &buf, DISK_BLOCK_BYTES)) <= 0) {
+ continue;
+ }
+ close(fd);
+
+ parse_file_header(buf, &file, (size_t)result);
+ if (strcmp(file.name, hostname) != 0 ||
+ strcmp(file.disk, diskname) != 0 ||
+ file.dumplevel != level ||
+ !match_datestamp(file.datestamp, dir->name)) {
+ continue;
+ }
dp = NULL;
for(;;) {
if(find_match(hostname,diskname)) {
find_result_t *new_output_find =
- alloc(sizeof(find_result_t));
+ alloc(SIZEOF(find_result_t));
new_output_find->next=*output_find;
- if(strlen(dir->name) == 8) {
- new_output_find->datestamp=atoi(dir->name);
- new_output_find->timestamp=stralloc2(dir->name, "000000");
- }
- else if(strlen(dir->name) == 14) {
- char *name = stralloc(dir->name);
- name[8] = '\0';
- new_output_find->datestamp=atoi(name);
- new_output_find->timestamp=stralloc(dir->name);
- amfree(name);
- }
- else {
- error("Bad date\n");
- }
- new_output_find->datestamp_aux=1001;
+ new_output_find->timestamp=stralloc(file.datestamp);
new_output_find->hostname=hostname;
hostname = NULL;
new_output_find->diskname=diskname;
amfree(diskname);
}
-static int find_compare(i1, j1)
-const void *i1;
-const void *j1;
+static int
+find_compare(
+ const void *i1,
+ const void *j1)
{
int compare=0;
find_result_t **i = (find_result_t **)i1;
find_result_t **j = (find_result_t **)j1;
- int nb_compare=strlen(find_sort_order);
- int k;
+ size_t nb_compare=strlen(find_sort_order);
+ size_t k;
for(k=0;k<nb_compare;k++) {
switch (find_sort_order[k]) {
break;
case 'K' : compare=strcmp((*j)->diskname,(*i)->diskname);
break;
- case 'd' : compare=(*i)->datestamp - (*j)->datestamp;
- if (compare == 0)
- compare = (*i)->datestamp_aux - (*j)->datestamp_aux;
+ case 'd' : compare=strcmp((*i)->timestamp,(*j)->timestamp);
break;
- case 'D' : compare=(*j)->datestamp - (*i)->datestamp;
- if (compare == 0)
- compare = (*j)->datestamp_aux - (*i)->datestamp_aux;
+ case 'D' : compare=strcmp((*j)->timestamp,(*i)->timestamp);
break;
case 'l' : compare=(*j)->level - (*i)->level;
break;
- case 'f' : compare=(*i)->filenum - (*j)->filenum;
+ case 'f' : compare=((*i)->filenum == (*j)->filenum) ? 0 :
+ (((*i)->filenum < (*j)->filenum) ? -1 : 1);
break;
- case 'F' : compare=(*j)->filenum - (*i)->filenum;
+ case 'F' : compare=((*j)->filenum == (*i)->filenum) ? 0 :
+ (((*j)->filenum < (*i)->filenum) ? -1 : 1);
break;
case 'L' : compare=(*i)->level - (*j)->level;
break;
return 0;
}
-void sort_find_result(sort_order, output_find)
-char *sort_order;
-find_result_t **output_find;
+void
+sort_find_result(
+ char *sort_order,
+ find_result_t **output_find)
{
find_result_t *output_find_result;
find_result_t **array_find_result = NULL;
- int nb_result=0;
- int no_result;
+ size_t nb_result=0;
+ size_t no_result;
find_sort_order = sort_order;
/* qsort core dump if nothing to sort */
}
/* put the list in an array */
- array_find_result=alloc(nb_result * sizeof(find_result_t *));
+ array_find_result=alloc(nb_result * SIZEOF(find_result_t *));
for(output_find_result=*output_find,no_result=0;
output_find_result;
output_find_result=output_find_result->next,no_result++) {
}
/* sort the array */
- qsort(array_find_result,nb_result,sizeof(find_result_t *),
+ qsort(array_find_result,nb_result,SIZEOF(find_result_t *),
find_compare);
/* put the sorted result in the list */
amfree(array_find_result);
}
-void print_find_result(output_find)
-find_result_t *output_find;
+void
+print_find_result(
+ find_result_t *output_find)
{
find_result_t *output_find_result;
int max_len_datestamp = 4;
int max_len_filenum = 4;
int max_len_part = 4;
int max_len_status = 6;
- int len;
+ size_t len;
for(output_find_result=output_find;
output_find_result;
output_find_result=output_find_result->next) {
- len=strlen(find_nicedate(output_find_result->datestamp));
- if(len>max_len_datestamp) max_len_datestamp=len;
+ len=strlen(find_nicedate(output_find_result->timestamp));
+ if((int)len > max_len_datestamp)
+ max_len_datestamp=(int)len;
len=strlen(output_find_result->hostname);
- if(len>max_len_hostname) max_len_hostname=len;
+ if((int)len > max_len_hostname)
+ max_len_hostname = (int)len;
len=strlen(output_find_result->diskname);
- if(len>max_len_diskname) max_len_diskname=len;
+ if((int)len > max_len_diskname)
+ max_len_diskname = (int)len;
len=strlen(output_find_result->label);
- if(len>max_len_label) max_len_label=len;
+ if((int)len > max_len_label)
+ max_len_label = (int)len;
len=strlen(output_find_result->status);
- if(len>max_len_status) max_len_status=len;
+ if((int)len > max_len_status)
+ max_len_status = (int)len;
len=strlen(output_find_result->partnum);
- if(len>max_len_part) max_len_part=len;
+ if((int)len > max_len_part)
+ max_len_part = (int)len;
}
/*
for(output_find_result=output_find;
output_find_result;
output_find_result=output_find_result->next) {
+ char *qdiskname;
- printf("%-*s %-*s %-*s %*d %-*s %*d %*s %-*s\n",
+ qdiskname = quote_string(output_find_result->diskname);
+ /*@ignore@*/
+ printf("%-*s %-*s %-*s %*d %-*s %*" OFF_T_RFMT " %*s %-*s\n",
max_len_datestamp,
- find_nicedate(output_find_result->datestamp),
+ find_nicedate(output_find_result->timestamp),
max_len_hostname, output_find_result->hostname,
- max_len_diskname, output_find_result->diskname,
+ max_len_diskname, qdiskname,
max_len_level, output_find_result->level,
max_len_label, output_find_result->label,
- max_len_filenum, output_find_result->filenum,
+ max_len_filenum, (OFF_T_FMT_TYPE)output_find_result->filenum,
max_len_part, output_find_result->partnum,
max_len_status, output_find_result->status
);
+ /*@end@*/
+ amfree(qdiskname);
}
}
}
-void free_find_result(output_find)
-find_result_t **output_find;
+void
+free_find_result(
+ find_result_t **output_find)
{
find_result_t *output_find_result, *prev;
for(output_find_result=*output_find;
output_find_result;
output_find_result=output_find_result->next) {
- if(prev != NULL) amfree(prev);
+ amfree(prev);
+ amfree(output_find_result->timestamp);
amfree(output_find_result->hostname);
amfree(output_find_result->diskname);
amfree(output_find_result->label);
amfree(output_find_result->timestamp);
prev = output_find_result;
}
- if(prev != NULL) amfree(prev);
- output_find = NULL;
+ amfree(prev);
+ *output_find = NULL;
}
-int find_match(host, disk)
-char *host, *disk;
+int
+find_match(
+ char *host,
+ char *disk)
{
disk_t *dp = lookup_disk(host,disk);
return (dp && dp->todo);
}
-char *find_nicedate(datestamp)
-int datestamp;
+char *
+find_nicedate(
+ char *datestamp)
{
static char nice[20];
int year, month, day;
-
- year = datestamp / 10000;
- month = (datestamp / 100) % 100;
- day = datestamp % 100;
-
- snprintf(nice, sizeof(nice), "%4d-%02d-%02d", year, month, day);
+ int hours, minutes, seconds;
+ char date[9], atime[7];
+ int numdate, numtime;
+
+ strncpy(date, datestamp, 8);
+ date[8] = '\0';
+ numdate = atoi(date);
+ year = numdate / 10000;
+ month = (numdate / 100) % 100;
+ day = numdate % 100;
+
+ if(strlen(datestamp) <= 8) {
+ snprintf(nice, SIZEOF(nice), "%4d-%02d-%02d",
+ year, month, day);
+ }
+ else {
+ strncpy(atime, &(datestamp[8]), 6);
+ atime[6] = '\0';
+ numtime = atoi(atime);
+ hours = numtime / 10000;
+ minutes = (numtime / 100) % 100;
+ seconds = numtime % 100;
+
+ snprintf(nice, SIZEOF(nice), "%4d-%02d-%02d %02d:%02d:%02d",
+ year, month, day, hours, minutes, seconds);
+ }
return nice;
}
-static int parse_taper_datestamp_log(logline, datestamp, label)
-char *logline;
-int *datestamp;
-char **label;
+static int
+parse_taper_datestamp_log(
+ char *logline,
+ char **datestamp,
+ char **label)
{
char *s;
int ch;
return 0;
}
#define sc "datestamp"
- if(strncmp(s - 1, sc, sizeof(sc)-1) != 0) {
+ if(strncmp(s - 1, sc, SIZEOF(sc)-1) != 0) {
return 0;
}
- s += sizeof(sc)-1;
+ s += SIZEOF(sc)-1;
ch = s[-1];
#undef sc
skip_whitespace(s, ch);
- if(ch == '\0' || sscanf(s - 1, "%d", datestamp) != 1) {
+ if(ch == '\0') {
return 0;
}
- skip_integer(s, ch);
+ *datestamp = s - 1;
+ skip_non_whitespace(s, ch);
+ s[-1] = '\0';
skip_whitespace(s, ch);
if(ch == '\0') {
return 0;
}
#define sc "label"
- if(strncmp(s - 1, sc, sizeof(sc)-1) != 0) {
+ if(strncmp(s - 1, sc, SIZEOF(sc)-1) != 0) {
return 0;
}
- s += sizeof(sc)-1;
+ s += SIZEOF(sc)-1;
ch = s[-1];
#undef sc
* This is so we can interpret the final SUCCESS entry for a split dump as
* 'list its parts' instead. Return 1 if we have, 0 if not.
*/
-int seen_chunk_of(output_find, date, host, disk, level)
-find_result_t *output_find;
-int date, level;
-char *host, *disk;
+int
+seen_chunk_of(
+ find_result_t *output_find,
+ char *date,
+ char *host,
+ char *disk,
+ int level)
{
find_result_t *cur;
for(cur=output_find; cur; cur=cur->next) {
if(atoi(cur->partnum) < 1 || !cur->hostname || !cur->diskname) continue;
- if(cur->datestamp == date && strcmp(cur->hostname, host) == 0 &&
+ if(strcmp(cur->timestamp, date) == 0 && strcmp(cur->hostname, host) == 0 &&
strcmp(cur->diskname, disk) == 0 && cur->level == level){
return(1);
}
/* else */
/* add to output_find all the dump for this label */
/* return the number of dump added. */
-int search_logfile(output_find, label, datestamp, datestamp_aux, logfile)
-find_result_t **output_find;
-char *label, *logfile;
-int datestamp, datestamp_aux;
+int
+search_logfile(
+ find_result_t **output_find,
+ char *label,
+ char *datestamp,
+ char *logfile)
{
FILE *logf;
char *host, *host_undo;
- char *disk, *disk_undo;
+ char *disk, *qdisk, *disk_undo;
+ char *date, *date_undo;
char *partnum=NULL, *partnum_undo;
- int datestampI;
char *rest;
- char *ck_label;
- int level, filenum, ck_datestamp, tapematch;
- int passlabel, ck_datestamp2;
+ char *ck_label=NULL;
+ int level = 0;
+ int tapematch;
+ off_t filenum;
+ int passlabel;
+ char *ck_datestamp, *ck_datestamp2;
char *s;
int ch;
disk_t *dp;
- if((logf = fopen(logfile, "r")) == NULL)
+ if((logf = fopen(logfile, "r")) == NULL) {
error("could not open logfile %s: %s", logfile, strerror(errno));
+ /*NOTREACHED*/
+ }
/* check that this log file corresponds to the right tape */
tapematch = 0;
if(curlog == L_START && curprog == P_TAPER) {
if(parse_taper_datestamp_log(curstr,
&ck_datestamp, &ck_label) == 0) {
- printf("strange log line \"start taper %s\"\n", curstr);
- } else if(ck_datestamp == datestamp
+ printf("strange log line \"start taper %s\" curstr='%s'\n",
+ logfile, curstr);
+ } else if(strcmp(ck_datestamp, datestamp) == 0
&& strcmp(ck_label, label) == 0) {
tapematch = 1;
}
return 0;
}
- filenum = 0;
+ filenum = (off_t)0;
passlabel = 1;
while(get_logline(logf) && passlabel) {
if((curlog == L_SUCCESS || curlog == L_CHUNK) &&
if(curlog == L_START && curprog == P_TAPER) {
if(parse_taper_datestamp_log(curstr,
&ck_datestamp2, &ck_label) == 0) {
- printf("strange log line \"start taper %s\"\n", curstr);
+ printf("strange log line in %s \"start taper %s\"\n",
+ logfile, curstr);
} else if (strcmp(ck_label, label)) {
passlabel = !passlabel;
}
skip_whitespace(s, ch);
if(ch == '\0') {
- printf("strange log line \"%s\"\n", curstr);
+ printf("strange log line in %s \"%s\"\n",
+ logfile, curstr);
continue;
}
host = s - 1;
skip_whitespace(s, ch);
if(ch == '\0') {
- printf("strange log line \"%s\"\n", curstr);
+ printf("strange log line in %s \"%s\"\n",
+ logfile, curstr);
continue;
}
- disk = s - 1;
- skip_non_whitespace(s, ch);
+ qdisk = s - 1;
+ skip_quoted_string(s, ch);
disk_undo = s - 1;
*disk_undo = '\0';
+ disk = unquote_string(qdisk);
skip_whitespace(s, ch);
- if(ch == '\0' || sscanf(s - 1, "%d", &datestampI) != 1) {
- printf("strange log line \"%s\"\n", curstr);
+ if(ch == '\0') {
+ printf("strange log line in %s \"%s\"\n",
+ logfile, curstr);
continue;
}
- skip_integer(s, ch);
+ date = s - 1;
+ skip_non_whitespace(s, ch);
+ date_undo = s - 1;
+ *date_undo = '\0';
- if(datestampI < 100) { /* old log didn't have datestamp */
- level = datestampI;
- datestampI = datestamp;
+ if(strlen(date) < 3) { /* old log didn't have datestamp */
+ level = atoi(date);
+ date = stralloc(datestamp);
}
else {
if(curlog == L_CHUNK){
}
skip_whitespace(s, ch);
if(ch == '\0' || sscanf(s - 1, "%d", &level) != 1) {
- printf("strange log line \"%s\"\n", curstr);
+ printf("strange log line in %s \"%s\"\n",
+ logfile, curstr);
continue;
}
skip_integer(s, ch);
skip_whitespace(s, ch);
if(ch == '\0') {
- printf("strange log line \"%s\"\n", curstr);
+ printf("strange log line in %s \"%s\"\n",
+ logfile, curstr);
continue;
}
rest = s - 1;
enqueue_disk(find_diskqp, dp);
}
if(find_match(host, disk) && (curlog != L_SUCCESS ||
- !seen_chunk_of(*output_find,datestampI,host,disk,level))){
+ !seen_chunk_of(*output_find, date, host, disk, level))) {
if(curprog == P_TAPER) {
find_result_t *new_output_find =
- (find_result_t *)alloc(sizeof(find_result_t));
+ (find_result_t *)alloc(SIZEOF(find_result_t));
new_output_find->next=*output_find;
- new_output_find->datestamp=datestampI;
- new_output_find->timestamp = alloc(15);
- snprintf(new_output_find->timestamp, 15, "%d000000", datestampI);
- new_output_find->datestamp_aux=datestamp_aux;
+ new_output_find->timestamp = stralloc(date);
new_output_find->hostname=stralloc(host);
new_output_find->diskname=stralloc(disk);
new_output_find->level=level;
}
else if(curlog == L_FAIL) { /* print other failures too */
find_result_t *new_output_find =
- (find_result_t *)alloc(sizeof(find_result_t));
+ (find_result_t *)alloc(SIZEOF(find_result_t));
new_output_find->next=*output_find;
- new_output_find->datestamp=datestamp;
- new_output_find->datestamp_aux=datestamp_aux;
- new_output_find->timestamp = alloc(15);
- snprintf(new_output_find->timestamp, 15, "%d000000", datestamp);
+ new_output_find->timestamp = stralloc(date);
new_output_find->hostname=stralloc(host);
new_output_find->diskname=stralloc(disk);
new_output_find->level=level;
*output_find=new_output_find;
}
}
+ amfree(disk);
}
}
afclose(logf);
* an empty pattern to match .*, though). If 'ok' is true, will only match
* dumps with SUCCESS status.
*/
-find_result_t *dumps_match(output_find,hostname,diskname,datestamp,level,ok)
-find_result_t *output_find;
-char *hostname;
-char *diskname;
-char *datestamp;
-char *level;
-int ok;
+find_result_t *
+dumps_match(
+ find_result_t *output_find,
+ char *hostname,
+ char *diskname,
+ char *datestamp,
+ char *level,
+ int ok)
{
find_result_t *cur_result;
find_result_t *matches = NULL;
for(cur_result=output_find;
cur_result;
cur_result=cur_result->next) {
- char date_str[NUM_STR_SIZE];
char level_str[NUM_STR_SIZE];
- snprintf(date_str, sizeof(date_str), "%d", cur_result->datestamp);
- snprintf(level_str, sizeof(level_str), "%d", cur_result->level);
+ snprintf(level_str, SIZEOF(level_str), "%d", cur_result->level);
if((*hostname == '\0' || match_host(hostname, cur_result->hostname)) &&
(*diskname == '\0' || match_disk(diskname, cur_result->diskname)) &&
- (*datestamp== '\0' || match_datestamp(datestamp, date_str)) &&
+ (*datestamp== '\0' || match_datestamp(datestamp, cur_result->timestamp)) &&
(*level== '\0' || match_level(level, level_str)) &&
(!ok || !strcmp(cur_result->status, "OK"))){
- find_result_t *curmatch = alloc(sizeof(find_result_t));
- memcpy(curmatch, cur_result, sizeof(find_result_t));
+ find_result_t *curmatch = alloc(SIZEOF(find_result_t));
+ memcpy(curmatch, cur_result, SIZEOF(find_result_t));
/*
curmatch->hostname = stralloc(cur_result->hostname);
return(matches);
}
-find_result_t *dump_exist(output_find, hostname, diskname, datestamp, level)
-find_result_t *output_find;
-char *hostname;
-char *diskname;
-int datestamp;
-int level;
+find_result_t *
+dump_exist(
+ find_result_t *output_find,
+ char *hostname,
+ char *diskname,
+ char *datestamp,
+ int level)
{
find_result_t *output_find_result;
output_find_result=output_find_result->next) {
if( !strcmp(output_find_result->hostname, hostname) &&
!strcmp(output_find_result->diskname, diskname) &&
- output_find_result->datestamp == datestamp &&
+ !strcmp(output_find_result->timestamp, datestamp) &&
output_find_result->level == level) {
return output_find_result;
+#ifndef FIND_H
+#define FIND_H
+
#include "diskfile.h"
#define DEFAULT_SORT_ORDER "hkdlpb"
typedef struct find_result_s {
struct find_result_s *next;
- int datestamp;
- int datestamp_aux;
- /* aux is secondary key for intra-day comparisons -- could be timestamp,
- just use seq# */
char *timestamp;
char *hostname;
char *diskname;
int level;
char *label;
- int filenum;
+ off_t filenum;
char *status;
char *partnum;
void *user_ptr;
} find_result_t;
-find_result_t *find_dump P((int dyna_disklist, disklist_t* diskqp));
-char **find_log P((void));
-void sort_find_result P((char *sort_order, find_result_t **output_find));
-void print_find_result P((find_result_t *output_find));
-void free_find_result P((find_result_t **output_find));
-find_result_t *dump_exist P((find_result_t *output_find, char *hostname, char *diskname, int datestamp, int level));
-find_result_t *dumps_match P((find_result_t *output_find, char *hostname, char *diskname, char *datestamp, char *level, int ok));
+find_result_t *find_dump(int dyna_disklist, disklist_t* diskqp);
+char **find_log(void);
+void sort_find_result(char *sort_order, find_result_t **output_find);
+void print_find_result(find_result_t *output_find);
+void free_find_result(find_result_t **output_find);
+find_result_t *dump_exist(find_result_t *output_find, char *hostname, char *diskname, char *datestamp, int level);
+find_result_t *dumps_match(find_result_t *output_find, char *hostname, char *diskname, char *datestamp, char *level, int ok);
+#endif /* !FIND_H */
* University of Maryland at College Park
*/
/*
- * $Id: getconf.c,v 1.18 2006/01/14 04:37:19 paddy_s Exp $
+ * $Id: getconf.c,v 1.26 2006/07/25 19:00:56 martinea Exp $
*
* a little wrapper to extract config variables for shell scripts
*/
#include "genversion.h"
#include "conffile.h"
-int main P((int argc, char **argv));
+int main(int argc, char **argv);
+
+/*
+ * HOSTNAME_INSTANCE may not be defined at this point.
+ * We define it locally if it is needed...
+ *
+ * If CLIENT_HOST_PRINCIPLE is defined as HOSTNAME_INSTANCE
+ * then local host is the client host principle.
+ */
+#ifndef HOSTNAME_INSTANCE
+# define HOSTNAME_INSTANCE "localhost"
+#endif
+
+#ifndef KEYFILE
+# define KEYFILE "id_rsa"
+#endif
static struct build_info {
char *symbol;
{ "DEFAULT_SERVER", DEFAULT_SERVER },
{ "DEFAULT_CONFIG", DEFAULT_CONFIG },
{ "DEFAULT_TAPE_SERVER", DEFAULT_TAPE_SERVER },
- { "DEFAULT_TAPE_DEVICE", DEFAULT_TAPE_SERVER },
+#ifdef DEFAULT_TAPE_DEVICE
+ { "DEFAULT_TAPE_DEVICE", DEFAULT_TAPE_DEVICE },
+#endif
{ "CLIENT_LOGIN", CLIENT_LOGIN },
{ "BUILT_DATE",
#if defined(BUILT_DATE)
BUILT_DATE
+#else
+ NULL
#endif
},
{ "BUILT_MACH",
#if defined(BUILT_MACH)
BUILT_MACH
+#else
+ NULL
#endif
},
{ "CC",
#if defined(CC)
CC
+#else
+ NULL
#endif
},
{ "AMANDA_DBGDIR",
#if defined(AMANDA_DBGDIR)
AMANDA_DBGDIR
+#else
+ NULL
#endif
},
{ "DEV_PREFIX",
#if defined(DEV_PREFIX)
DEV_PREFIX
+#else
+ NULL
#endif
},
{ "RDEV_PREFIX",
#if defined(RDEV_PREFIX)
- RDEV_PREFIX },
+ RDEV_PREFIX
+#else
+ NULL
#endif
+ },
{ "DUMP",
#if defined(DUMP)
DUMP
+#else
+ NULL
#endif
},
{ "RESTORE",
#if defined(DUMP)
RESTORE
+#else
+ NULL
#endif
},
{ "VDUMP",
#if defined(VDUMP)
VDUMP
+#else
+ NULL
#endif
},
{ "VRESTORE",
#if defined(VDUMP)
VRESTORE
+#else
+ NULL
#endif
},
{ "XFSDUMP",
#if defined(XFSDUMP)
XFSDUMP
+#else
+ NULL
#endif
},
{ "XFSRESTORE",
#if defined(XFSDUMP)
XFSRESTORE
+#else
+ NULL
#endif
},
{ "VXDUMP",
#if defined(VXDUMP)
VXDUMP
+#else
+ NULL
#endif
},
{ "VXRESTORE",
#if defined(VXDUMP)
VXRESTORE
+#else
+ NULL
#endif
},
{ "SAMBA_CLIENT",
#if defined(SAMBA_CLIENT)
SAMBA_CLIENT
+#else
+ NULL
#endif
},
{ "GNUTAR",
#if defined(GNUTAR)
GNUTAR
+#else
+ NULL
#endif
},
{ "COMPRESS_PATH",
#if defined(COMPRESS_PATH)
COMPRESS_PATH
+#else
+ NULL
#endif
},
{ "UNCOMPRESS_PATH",
#if defined(UNCOMPRESS_PATH)
UNCOMPRESS_PATH
+#else
+ NULL
#endif
},
{ "listed_incr_dir",
#if defined(GNUTAR_LISTED_INCREMENTAL_DIR)
GNUTAR_LISTED_INCREMENTAL_DIR
+#else
+ NULL
#endif
},
{ "GNUTAR_LISTED_INCREMENTAL_DIR",
#if defined(GNUTAR_LISTED_INCREMENTAL_DIR)
GNUTAR_LISTED_INCREMENTAL_DIR
+#else
+ NULL
#endif
},
{ "AIX_BACKUP",
#if defined(AIX_BACKUP)
"1"
+#else
+ NULL
#endif
},
{ "AIX_TAPEIO",
#if defined(AIX_TAPEIO)
"1"
+#else
+ NULL
#endif
},
{ "DUMP_RETURNS_1",
#if defined(DUMP_RETURNS_1)
"1"
+#else
+ NULL
#endif
},
{ "STATFS_BSD",
#if defined(STATFS_BSD)
"1"
+#else
+ NULL
#endif
},
{ "STATFS_OSF1",
#if defined(STATFS_OSF1)
"1"
+#else
+ NULL
#endif
},
{ "STATFS_ULTRIX",
#if defined(STATFS_ULTRIX)
"1"
+#else
+ NULL
#endif
},
{ "ASSERTIONS",
#if defined(ASSERTIONS)
"1"
+#else
+ NULL
#endif
},
{ "DEBUG_CODE",
#if defined(DEBUG_CODE)
"1"
+#else
+ NULL
#endif
},
{ "BSD_SECURITY",
#if defined(BSD_SECURITY)
"1"
+#else
+ NULL
#endif
},
{ "USE_AMANDAHOSTS",
#if defined(USE_AMANDAHOSTS)
"1"
+#else
+ NULL
#endif
},
{ "USE_RUNDUMP",
#if defined(USE_RUNDUMP)
"1"
+#else
+ NULL
#endif
},
{ "FORCE_USERID",
#if defined(FORCE_USERID)
"1"
+#else
+ NULL
#endif
},
{ "USE_VERSION_SUFFIXES",
#if defined(USE_VERSION_SUFFIXES)
"1"
+#else
+ NULL
#endif
},
{ "HAVE_GZIP",
#if defined(HAVE_GZIP)
"1"
+#else
+ NULL
#endif
},
{ "KRB4_SECURITY",
#if defined(KRB4_SECURITY)
"1"
+#else
+ NULL
#endif
},
{ "SERVER_HOST_PRINCIPLE",
#if defined(KRB4_SECURITY)
SERVER_HOST_PRINCIPLE
+#else
+ NULL
#endif
},
{ "SERVER_HOST_INSTANCE",
#if defined(KRB4_SECURITY)
SERVER_HOST_INSTANCE
+#else
+ NULL
#endif
},
{ "SERVER_HOST_KEY_FILE",
#if defined(KRB4_SECURITY)
SERVER_HOST_KEY_FILE
+#else
+ NULL
#endif
},
{ "CLIENT_HOST_PRINCIPLE",
#if defined(KRB4_SECURITY)
CLIENT_HOST_PRINCIPLE
+#else
+ NULL
#endif
},
{ "CLIENT_HOST_INSTANCE",
#if defined(KRB4_SECURITY)
CLIENT_HOST_INSTANCE
+#else
+ NULL
#endif
},
{ "CLIENT_HOST_KEY_FILE",
#if defined(KRB4_SECURITY)
CLIENT_HOST_KEY_FILE
+#else
+ NULL
#endif
},
{ "COMPRESS_SUFFIX",
#if defined(COMPRESS_SUFFIX)
COMPRESS_SUFFIX
+#else
+ NULL
#endif
},
{ "COMPRESS_FAST_OPT",
#if defined(COMPRESS_FAST_OPT)
COMPRESS_FAST_OPT
+#else
+ NULL
#endif
},
{ "COMPRESS_BEST_OPT",
#if defined(COMPRESS_BEST_OPT)
COMPRESS_BEST_OPT
+#else
+ NULL
#endif
},
{ "UNCOMPRESS_OPT",
#if defined(UNCOMPRESS_OPT)
UNCOMPRESS_OPT
+#else
+ NULL
#endif
},
{ NULL, NULL }
};
-int main(argc, argv)
-int argc;
-char **argv;
+int
+main(
+ int argc,
+ char ** argv)
{
char *result;
unsigned long malloc_hist_1, malloc_size_1;
char *parmname;
int i;
char number[NUM_STR_SIZE];
+ int new_argc, my_argc;
+ char **new_argv, **my_argv;
safe_fd(-1, 0);
malloc_size_1 = malloc_inuse(&malloc_hist_1);
- if((pgm = strrchr(argv[0], '/')) == NULL) {
- pgm = argv[0];
+ parse_server_conf(argc, argv, &new_argc, &new_argv);
+ my_argc = new_argc;
+ my_argv = new_argv;
+
+ if((pgm = strrchr(my_argv[0], '/')) == NULL) {
+ pgm = my_argv[0];
} else {
pgm++;
}
/* Don't die when child closes pipe */
signal(SIGPIPE, SIG_IGN);
- if(argc < 2) {
- fprintf(stderr, "Usage: %s [config] <parmname>\n", pgm);
+ if(my_argc < 2) {
+ fprintf(stderr, "Usage: %s [config] <parmname> [-o configoption]*\n", pgm);
exit(1);
}
- if (argc > 2) {
- config_name = stralloc(argv[1]);
+ if (my_argc > 2) {
+ config_name = stralloc(my_argv[1]);
config_dir = vstralloc(CONFIG_DIR, "/", config_name, "/", NULL);
- parmname = argv[2];
+ parmname = my_argv[2];
} else {
char my_cwd[STR_SIZE];
- if (getcwd(my_cwd, sizeof(my_cwd)) == NULL) {
+ if (getcwd(my_cwd, SIZEOF(my_cwd)) == NULL) {
error("cannot determine current working directory");
+ /*NOTREACHED*/
}
config_dir = stralloc2(my_cwd, "/");
if ((config_name = strrchr(my_cwd, '/')) != NULL) {
config_name = stralloc(config_name + 1);
}
- parmname = argv[1];
+ parmname = my_argv[1];
}
safe_cd();
#else
i = -1;
#endif
- snprintf(number, sizeof(number), "%ld", (long)i);
+ snprintf(number, SIZEOF(number), "%ld", (long)i);
build_info[1].value = stralloc(number);
#if defined(KRB4_SECURITY)
i = TICKET_LIFETIME;
#else
i = -1;
#endif
- snprintf(number, sizeof(number), "%ld", (long)i);
+ snprintf(number, SIZEOF(number), "%ld", (long)i);
build_info[2].value = stralloc(number);
#undef p
#define p "build."
- if(strncmp(parmname, p, sizeof(p) - 1) == 0) {
+ if(strncmp(parmname, p, SIZEOF(p) - 1) == 0) {
char *s;
char *t;
- t = stralloc(parmname + sizeof(p) - 1);
+ t = stralloc(parmname + SIZEOF(p) - 1);
for(i = 0; (s = build_info[i].symbol) != NULL; i++) {
if(strcasecmp(s, t) == 0) {
break;
#undef p
#define p "dbopen."
- } else if(strncmp(parmname, p, sizeof(p) - 1) == 0) {
+ } else if(strncmp(parmname, p, SIZEOF(p) - 1) == 0) {
char *pname;
char *dbname;
- if((pname = strrchr(parmname + sizeof(p) - 1, '/')) == NULL) {
- pname = parmname + sizeof(p) - 1;
+ if((pname = strrchr(parmname + SIZEOF(p) - 1, '/')) == NULL) {
+ pname = parmname + SIZEOF(p) - 1;
} else {
pname++;
}
set_pname(pname);
- dbopen();
+ dbopen(DBG_SUBDIR_SERVER);
if((dbname = dbfn()) == NULL) {
result = stralloc("/dev/null");
} else {
#undef p
#define p "dbclose."
- } else if(strncmp(parmname, p, sizeof(p) - 1) == 0) {
+ } else if(strncmp(parmname, p, SIZEOF(p) - 1) == 0) {
char *t;
char *pname;
char *dbname;
- t = stralloc(parmname + sizeof(p) - 1);
+ t = stralloc(parmname + SIZEOF(p) - 1);
if((dbname = strchr(t, ':')) == NULL) {
error("cannot parse %s", parmname);
+ /*NOTREACHED*/
}
*dbname++ = '\0';
if((pname = strrchr(t, '/')) == NULL) {
conffile = stralloc2(config_dir, CONFFILE_NAME);
if(read_conffile(conffile)) {
error("errors processing config file \"%s\"", conffile);
+ /*NOTREACHED*/
}
amfree(conffile);
+ dbrename(config_name, DBG_SUBDIR_SERVER);
+ report_bad_conf_arg();
result = getconf_byname(parmname);
}
- if(result == NULL) {
- result = stralloc("BUGGY");
+
+ if (result == NULL) {
fprintf(stderr, "%s: no such parameter \"%s\"\n",
get_pname(), parmname);
fflush(stderr);
+ } else {
+ puts(result);
}
- puts(result);
-
+ free_new_argv(new_argc, new_argv);
+ free_server_config();
amfree(result);
amfree(config_dir);
amfree(config_name);
* file named AUTHORS, in the root directory of this distribution.
*/
/*
- * $Id: holding.c,v 1.52 2006/03/09 22:01:21 martinea Exp $
+ * $Id: holding.c,v 1.56 2006/06/09 23:07:26 martinea Exp $
*
* Functions to access holding disk
*/
#include "fileheader.h"
#include "logfile.h"
-static sl_t *scan_holdingdisk P((sl_t *holding_list, char *diskdir, int verbose));
+static sl_t *scan_holdingdisk(sl_t *holding_list, char *diskdir, int verbose);
+static sl_t *scan_holdingdir(sl_t *holding_list, holdingdisk_t *holdp, char *datestamp);
-int is_dir(fname)
-char *fname;
+int
+is_dir(
+ char *fname)
{
struct stat statbuf;
return (statbuf.st_mode & S_IFDIR) == S_IFDIR;
}
-int is_emptyfile(fname)
-char *fname;
+int
+is_emptyfile(
+ char *fname)
{
struct stat statbuf;
if(stat(fname, &statbuf) == -1) return 0;
- return (statbuf.st_mode & S_IFDIR) != S_IFDIR && statbuf.st_size == 0;
+ return ((statbuf.st_mode & S_IFDIR) != S_IFDIR) &&
+ (statbuf.st_size == (off_t)0);
}
-int is_datestr(fname)
-char *fname;
-/* sanity check on datestamp of the form YYYYMMDD or YYYYMMDDhhmmss*/
+
+/*
+ * sanity check on datestamp of the form YYYYMMDD or YYYYMMDDhhmmss
+ */
+
+int
+is_datestr(
+ char *fname)
{
char *cp;
int ch, num, date, year, month, hour, minute, second;
}
-int non_empty(fname)
-char *fname;
+int
+non_empty(
+ char * fname)
{
DIR *dir;
struct dirent *entry;
}
-static sl_t *scan_holdingdisk(holding_list, diskdir, verbose)
-sl_t *holding_list;
-char *diskdir;
-int verbose;
+static sl_t *
+scan_holdingdisk(
+ sl_t * holding_list,
+ char * diskdir,
+ int verbose)
{
DIR *topdir;
struct dirent *workdir;
}
-sl_t *scan_holdingdir(holding_list, holdp, datestamp)
-sl_t *holding_list;
-holdingdisk_t *holdp;
-char *datestamp;
+static sl_t *
+scan_holdingdir(
+ sl_t * holding_list,
+ holdingdisk_t * holdp,
+ char * datestamp)
{
DIR *workdir;
struct dirent *entry;
disk_t *dp;
dumpfile_t file;
- dirname = vstralloc(holdp->diskdir, "/", datestamp, NULL);
+ dirname = vstralloc(holdingdisk_get_diskdir(holdp), "/", datestamp, NULL);
if((workdir = opendir(dirname)) == NULL) {
if(errno != ENOENT)
log_add(L_INFO, "%s: could not open dir: %s",
amfree(dirname);
return holding_list;
}
- chdir(dirname);
+ if ((chdir(dirname)) == -1) {
+ log_add(L_INFO, "%s: could not chdir: %s",
+ dirname, strerror(errno));
+ amfree(dirname);
+ return holding_list;
+ }
+
while((entry = readdir(workdir)) != NULL) {
if(strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
continue;
-sl_t *get_flush(dateargs, datestamp, amflush, verbose)
-sl_t *dateargs;
-char *datestamp; /* don't do this date */
-int amflush, verbose;
+sl_t *
+get_flush(
+ sl_t *dateargs,
+ char *datestamp, /* don't do this date */
+ int amflush,
+ int verbose)
{
sl_t *holding_list;
sl_t *date_list;
sle_t *datearg;
sle_t *date, *next_date;
holdingdisk_t *hdisk;
- char current_dir[1000];
-
- getcwd(current_dir, 999);
+ char current_dir[PATH_MAX];
holding_list = new_sl();
+ if (getcwd(current_dir, SIZEOF(current_dir)-1) == NULL) {
+ log_add(L_INFO, "get_flush: could get current working directory: %s",
+ strerror(errno));
+ return holding_list;
+ }
+
if(dateargs) {
int ok;
free_sl(date_list);
date_list = NULL;
- chdir(current_dir);
+ if (chdir(current_dir) == -1) {
+ log_add(L_INFO, "%s: could not chdir: %s",
+ current_dir, strerror(errno));
+ }
return(holding_list);
}
-sl_t *pick_all_datestamp(verbose)
-int verbose;
+sl_t *
+pick_all_datestamp(
+ int verbose)
{
sl_t *holding_list = NULL;
holdingdisk_t *hdisk;
holding_list = new_sl();
for(hdisk = getconf_holdingdisks(); hdisk != NULL; hdisk = hdisk->next)
- holding_list = scan_holdingdisk(holding_list, hdisk->diskdir, verbose);
+ holding_list = scan_holdingdisk(holding_list, holdingdisk_get_diskdir(hdisk), verbose);
return holding_list;
}
-sl_t *pick_datestamp(verbose)
-int verbose;
+sl_t *
+pick_datestamp(
+ int verbose)
{
sl_t *holding_list;
sl_t *r_holding_list = NULL;
char **directories = NULL;
int i;
char *answer = NULL;
- char *a;
- int ch;
+ char *a = NULL;
+ int ch = 0;
char max_char = '\0', chupper = '\0';
holding_list = pick_all_datestamp(verbose);
return holding_list;
}
else {
- directories = alloc((holding_list->nb_element) * sizeof(char *));
+ directories = alloc((holding_list->nb_element) * SIZEOF(char *));
for(dir = holding_list->first, i=0; dir != NULL; dir = dir->next,i++) {
directories[i] = dir->name;
}
clearerr(stdin);
continue;
}
- a = answer;
- while ((ch = *a++) != '\0' && isspace(ch)) {}
- if(ch == '\0' || strncasecmp(a, "ALL", 3) == 0) {
+
+ if (*answer == '\0' || strncasecmp(answer, "ALL", 3) == 0) {
break;
}
+
+ a = answer;
+ while ((ch = *a++) != '\0') {
+ if (!isspace(ch))
+ break;
+ }
+
do {
if (isspace(ch) || ch == ',') {
continue;
}
- chupper = toupper(ch);
+ chupper = (char)toupper(ch);
if (chupper < 'A' || chupper > max_char) {
free_sl(r_holding_list);
r_holding_list = NULL;
}
-filetype_t get_amanda_names(fname, hostname, diskname, level)
-char *fname, **hostname, **diskname;
-int *level;
+filetype_t
+get_amanda_names( char * fname,
+ char ** hostname,
+ char ** diskname,
+ int * level)
{
dumpfile_t file;
char buffer[DISK_BLOCK_BYTES];
int fd;
*hostname = *diskname = NULL;
+ memset(buffer, 0, sizeof(buffer));
if((fd = open(fname, O_RDONLY)) == -1)
return F_UNKNOWN;
- if(fullread(fd, buffer, sizeof(buffer)) != sizeof(buffer)) {
+ if(fullread(fd, buffer, SIZEOF(buffer)) != (ssize_t)sizeof(buffer)) {
aclose(fd);
return F_UNKNOWN;
}
aclose(fd);
- parse_file_header(buffer,&file,sizeof(buffer));
+ parse_file_header(buffer, &file, SIZEOF(buffer));
if(file.type != F_DUMPFILE && file.type != F_CONT_DUMPFILE) {
return file.type;
}
}
-void get_dumpfile(fname, file)
-char *fname;
-dumpfile_t *file;
+void
+get_dumpfile(
+ char * fname,
+ dumpfile_t *file)
{
char buffer[DISK_BLOCK_BYTES];
int fd;
+ memset(buffer, 0, sizeof(buffer));
+
fh_init(file);
file->type = F_UNKNOWN;
if((fd = open(fname, O_RDONLY)) == -1)
return;
- if(fullread(fd, buffer, sizeof(buffer)) != sizeof(buffer)) {
+ if(fullread(fd, buffer, SIZEOF(buffer)) != (ssize_t)sizeof(buffer)) {
aclose(fd);
return;
}
aclose(fd);
- parse_file_header(buffer,file,sizeof(buffer));
+ parse_file_header(buffer, file, SIZEOF(buffer));
return;
}
-long size_holding_files(holding_file, strip_headers)
-char *holding_file;
-int strip_headers;
+off_t
+size_holding_files(
+ char * holding_file,
+ int strip_headers)
{
int fd;
- int buflen;
+ ssize_t buflen;
char buffer[DISK_BLOCK_BYTES];
dumpfile_t file;
char *filename;
- long size=0;
+ off_t size = (off_t)0;
struct stat finfo;
+ memset(buffer, 0, sizeof(buffer));
filename = stralloc(holding_file);
while(filename != NULL && filename[0] != '\0') {
if((fd = open(filename,O_RDONLY)) == -1) {
fprintf(stderr,"size_holding_files: open of %s failed: %s\n",filename,strerror(errno));
amfree(filename);
- return -1;
+ return (off_t)-1;
}
- if ((buflen = fullread(fd, buffer, sizeof(buffer))) > 0) {
- parse_file_header(buffer, &file, buflen);
+ if ((buflen = fullread(fd, buffer, SIZEOF(buffer))) > 0) {
+ parse_file_header(buffer, &file, (size_t)buflen);
}
close(fd);
if(stat(filename, &finfo) == -1) {
printf("stat %s: %s\n", filename, strerror(errno));
- finfo.st_size = 0;
+ finfo.st_size = (off_t)0;
}
- size += (finfo.st_size+1023)/1024;
- if(strip_headers) size -= DISK_BLOCK_BYTES/1024;
+ size += (finfo.st_size+(off_t)1023)/(off_t)1024;
+ if(strip_headers)
+ size -= (off_t)(DISK_BLOCK_BYTES / 1024);
if(buflen > 0) {
filename = newstralloc(filename, file.cont_filename);
}
}
-int unlink_holding_files( holding_file )
-char *holding_file;
+int
+unlink_holding_files(
+ char * holding_file)
{
int fd;
- int buflen;
+ ssize_t buflen;
char buffer[DISK_BLOCK_BYTES];
dumpfile_t file;
char *filename;
+ memset(buffer, 0, sizeof(buffer));
filename = stralloc(holding_file);
while(filename != NULL && filename[0] != '\0') {
if((fd = open(filename,O_RDONLY)) == -1) {
amfree(filename);
return 0;
}
- if ((buflen = fullread(fd, buffer, sizeof(buffer))) > 0) {
- parse_file_header(buffer, &file, buflen);
+ if ((buflen = fullread(fd, buffer, SIZEOF(buffer))) > 0) {
+ parse_file_header(buffer, &file, (size_t)buflen);
}
close(fd);
unlink(filename);
}
-int rename_tmp_holding( holding_file, complete )
-char *holding_file;
-int complete;
+int
+rename_tmp_holding(
+ char * holding_file,
+ int complete)
{
int fd;
- int buflen;
+ ssize_t buflen;
char buffer[DISK_BLOCK_BYTES];
dumpfile_t file;
char *filename;
char *filename_tmp = NULL;
+ memset(buffer, 0, sizeof(buffer));
filename = stralloc(holding_file);
while(filename != NULL && filename[0] != '\0') {
filename_tmp = newvstralloc(filename_tmp, filename, ".tmp", NULL);
amfree(filename_tmp);
return 0;
}
- buflen = fullread(fd, buffer, sizeof(buffer));
+ buflen = fullread(fd, buffer, SIZEOF(buffer));
close(fd);
if(rename(filename_tmp, filename) != 0) {
amfree(filename_tmp);
return 0;
}
- parse_file_header(buffer, &file, buflen);
+ parse_file_header(buffer, &file, (size_t)buflen);
if(complete == 0 ) {
if((fd = open(filename, O_RDWR)) == -1) {
fprintf(stderr, "rename_tmp_holdingX: open of %s failed: %s\n",
}
file.is_partial = 1;
- build_header(buffer, &file, sizeof(buffer));
- fullwrite(fd, buffer, sizeof(buffer));
+ build_header(buffer, &file, SIZEOF(buffer));
+ fullwrite(fd, buffer, SIZEOF(buffer));
close(fd);
}
filename = newstralloc(filename, file.cont_filename);
}
-void cleanup_holdingdisk(diskdir, verbose)
-char *diskdir;
-int verbose;
+void
+cleanup_holdingdisk(
+ char * diskdir,
+ int verbose)
{
DIR *topdir;
struct dirent *workdir;
if(verbose)
printf("Scanning %s...\n", diskdir);
- chdir(diskdir);
+ if ((chdir(diskdir)) == -1) {
+ log_add(L_INFO, "%s: could not chdir: %s",
+ diskdir, strerror(errno));
+ }
while((workdir = readdir(topdir)) != NULL) {
if(strcmp(workdir->d_name, ".") == 0
|| strcmp(workdir->d_name, "..") == 0
}
-int mkholdingdir(diskdir)
-char *diskdir;
+int
+mkholdingdir(
+ char * diskdir)
{
struct stat stat_hdp;
int success = 1;
* file named AUTHORS, in the root directory of this distribution.
*/
/*
- * $Id: holding.h,v 1.22 2005/10/11 01:17:01 vectro Exp $
+ * $Id: holding.h,v 1.23 2006/05/25 01:47:20 johnfranks Exp $
*
*/
#include "sl.h"
/* local functions */
-int is_dir P((char *fname));
-int is_emptyfile P((char *fname));
-int is_datestr P((char *fname));
-int non_empty P((char *fname));
-void free_holding_list P(( sl_t *holding_list));
+int is_dir(char *fname);
+int is_emptyfile(char *fname);
+int is_datestr(char *fname);
+int non_empty(char *fname);
+void free_holding_list( sl_t *holding_list);
sl_t *get_flush(sl_t *dateargs, char *datestamp, int amflush, int verbose);
-sl_t *pick_datestamp P((int verbose));
-sl_t *pick_all_datestamp P((int verbose));
-filetype_t get_amanda_names P((char *fname,
+sl_t *pick_datestamp(int verbose);
+sl_t *pick_all_datestamp(int verbose);
+filetype_t get_amanda_names(char *fname,
char **hostname,
char **diskname,
- int *level));
-void get_dumpfile P((char *fname, dumpfile_t *file));
-long size_holding_files P((char *holding_file, int strip_headers));
-int unlink_holding_files P((char *holding_file));
-int rename_tmp_holding P((char *holding_file, int complete));
-void cleanup_holdingdisk P((char *diskdir, int verbose));
-int mkholdingdir P((char *diskdir));
+ int *level);
+void get_dumpfile(char *fname, dumpfile_t *file);
+off_t size_holding_files(char *holding_file, int strip_headers);
+int unlink_holding_files(char *holding_file);
+int rename_tmp_holding(char *holding_file, int complete);
+void cleanup_holdingdisk(char *diskdir, int verbose);
+int mkholdingdir(char *diskdir);
#endif /* HOLDING_H */
* University of Maryland at College Park
*/
/*
- * $Id: infofile.c,v 1.57 2006/03/10 11:56:06 martinea Exp $
+ * $Id: infofile.c,v 1.64 2006/07/25 18:18:48 martinea Exp $
*
* manage current info file
*/
#include "infofile.h"
#include "token.h"
-static void zero_info P((info_t *));
+static void zero_info(info_t *);
#ifdef TEXTDB
static char *infodir = (char *)0;
static char *newinfofile;
static int writing;
- static FILE *open_txinfofile P((char *, char *, char *));
- static int close_txinfofile P((FILE *));
- static int read_txinfofile P((FILE *, info_t *));
- static int write_txinfofile P((FILE *, info_t *));
- static int delete_txinfofile P((char *, char *));
+ static FILE *open_txinfofile(char *, char *, char *);
+ static int close_txinfofile(FILE *);
+ static int read_txinfofile(FILE *, info_t *);
+ static int write_txinfofile(FILE *, info_t *);
+ static int delete_txinfofile(char *, char *);
#else
# define MAX_KEY 256
-/*# define HEADER (sizeof(info_t)-DUMP_LEVELS*sizeof(stats_t))*/
+/*# define HEADER (SIZEOF(info_t)-DUMP_LEVELS*SIZEOF(stats_t))*/
static DBM *infodb = NULL;
static lockfd = -1;
#ifdef TEXTDB
-static FILE *open_txinfofile(host, disk, mode)
-char *host;
-char *disk;
-char *mode;
+static FILE *
+open_txinfofile(
+ char * host,
+ char * disk,
+ char * mode)
{
FILE *infof;
+ char *myhost;
+ char *mydisk;
assert(infofile == (char *)0);
writing = (*mode == 'w');
- host = sanitise_filename(host);
- disk = sanitise_filename(disk);
+ myhost = sanitise_filename(host);
+ mydisk = sanitise_filename(disk);
infofile = vstralloc(infodir,
- "/", host,
- "/", disk,
+ "/", myhost,
+ "/", mydisk,
"/info",
NULL);
- amfree(host);
- amfree(disk);
+ amfree(myhost);
+ amfree(mydisk);
/* create the directory structure if in write mode */
if (writing) {
return infof;
}
-static int close_txinfofile(infof)
-FILE *infof;
+static int
+close_txinfofile(
+ FILE *infof)
{
int rc = 0;
return rc;
}
-static int read_txinfofile(infof, info) /* XXX - code assumes AVG_COUNT == 3 */
-FILE *infof;
-info_t *info;
+/* XXX - code assumes AVG_COUNT == 3 */
+static int
+read_txinfofile(
+ FILE * infof,
+ info_t * info)
{
char *line = NULL;
int version;
/* get version: command: lines */
- if((line = agets(infof)) == NULL) return -1;
+ while ((line = agets(infof)) != NULL) {
+ if (line[0] != '\0')
+ break;
+ amfree(line);
+ }
+ if (line == NULL) return -1;
rc = sscanf(line, "version: %d", &version);
amfree(line);
if(rc != 1) return -2;
- if((line = agets(infof)) == NULL) return -1;
- rc = sscanf(line, "command: %d", &info->command);
+ while ((line = agets(infof)) != NULL) {
+ if (line[0] != '\0')
+ break;
+ amfree(line);
+ }
+ if (line == NULL) return -1;
+ rc = sscanf(line, "command: %u", &info->command);
amfree(line);
if(rc != 1) return -2;
pp = &info->full;
- if((line = agets(infof)) == NULL) return -1;
- rc = sscanf(line, "full-rate: %f %f %f",
+ while ((line = agets(infof)) != NULL) {
+ if (line[0] != '\0')
+ break;
+ amfree(line);
+ }
+ if (line == NULL) return -1;
+ rc = sscanf(line, "full-rate: %lf %lf %lf",
&pp->rate[0], &pp->rate[1], &pp->rate[2]);
amfree(line);
if(rc > 3) return -2;
- if((line = agets(infof)) == NULL) return -1;
- rc = sscanf(line, "full-comp: %f %f %f",
+ while ((line = agets(infof)) != NULL) {
+ if (line[0] != '\0')
+ break;
+ amfree(line);
+ }
+ if (line == NULL) return -1;
+ rc = sscanf(line, "full-comp: %lf %lf %lf",
&pp->comp[0], &pp->comp[1], &pp->comp[2]);
amfree(line);
if(rc > 3) return -2;
pp = &info->incr;
- if((line = agets(infof)) == NULL) return -1;
- rc = sscanf(line, "incr-rate: %f %f %f",
+ while ((line = agets(infof)) != NULL) {
+ if (line[0] != '\0')
+ break;
+ amfree(line);
+ }
+ if (line == NULL) return -1;
+ rc = sscanf(line, "incr-rate: %lf %lf %lf",
&pp->rate[0], &pp->rate[1], &pp->rate[2]);
amfree(line);
if(rc > 3) return -2;
- if((line = agets(infof)) == NULL) return -1;
- rc = sscanf(line, "incr-comp: %f %f %f",
+ while ((line = agets(infof)) != NULL) {
+ if (line[0] != '\0')
+ break;
+ amfree(line);
+ }
+ if (line == NULL) return -1;
+ rc = sscanf(line, "incr-comp: %lf %lf %lf",
&pp->comp[0], &pp->comp[1], &pp->comp[2]);
amfree(line);
if(rc > 3) return -2;
for(rc = -2; (line = agets(infof)) != NULL; free(line)) {
stats_t onestat; /* one stat record */
- long date;
- int level;
+ time_t date = 0;
+ time_t *date_p = &date;
+ time_t *secs_p;
+ int level = 0;
+ if (line[0] == '\0')
+ continue;
if(line[0] == '/' && line[1] == '/') {
rc = 0;
amfree(line);
else if (strncmp(line,"history:",8) == 0) {
break; /* normal */
}
- memset(&onestat, 0, sizeof(onestat));
+ memset(&onestat, 0, SIZEOF(onestat));
s = line;
ch = *s++;
#define sc "stats:"
- if(strncmp(line, sc, sizeof(sc)-1) != 0) {
+ if(strncmp(line, sc, SIZEOF(sc)-1) != 0) {
break;
}
- s += sizeof(sc)-1;
+ s += SIZEOF(sc)-1;
ch = s[-1];
#undef sc
skip_integer(s, ch);
skip_whitespace(s, ch);
- if(ch == '\0' || sscanf((s - 1), "%ld", &onestat.size) != 1) {
+ if(ch == '\0' || sscanf((s - 1), OFF_T_FMT,
+ (OFF_T_FMT_TYPE *)&onestat.size) != 1) {
break;
}
skip_integer(s, ch);
skip_whitespace(s, ch);
- if(ch == '\0' || sscanf((s - 1), "%ld", &onestat.csize) != 1) {
+ if(ch == '\0' || sscanf((s - 1), OFF_T_FMT,
+ (OFF_T_FMT_TYPE *)&onestat.csize) != 1) {
break;
}
skip_integer(s, ch);
skip_whitespace(s, ch);
- if(ch == '\0' || sscanf((s - 1), "%ld", &onestat.secs) != 1) {
+ secs_p = &onestat.secs;
+ if(ch == '\0' || sscanf((s - 1), TIME_T_FMT,
+ (TIME_T_FMT_TYPE *)secs_p) != 1) {
break;
}
skip_integer(s, ch);
skip_whitespace(s, ch);
- if(ch == '\0' || sscanf((s - 1), "%ld", &date) != 1) {
+ if(ch == '\0' || sscanf((s - 1), TIME_T_FMT,
+ (TIME_T_FMT_TYPE *)date_p) != 1) {
break;
}
skip_integer(s, ch);
skip_whitespace(s, ch);
if(ch != '\0') {
- if(sscanf((s - 1), "%d", &onestat.filenum) != 1) {
+ if(sscanf((s - 1), OFF_T_FMT,
+ (OFF_T_FMT_TYPE *)&onestat.filenum) != 1) {
break;
}
skip_integer(s, ch);
if(ch == '\0') {
break;
}
- strncpy(onestat.label, s-1, sizeof(onestat.label)-1);
- onestat.label[sizeof(onestat.label)-1] = '\0';
+ strncpy(onestat.label, s-1, SIZEOF(onestat.label)-1);
+ onestat.label[SIZEOF(onestat.label)-1] = '\0';
}
onestat.date = date; /* time_t not guarranteed to be long */
for(rc = -2; (line = agets(infof)) != NULL; free(line)) {
history_t onehistory; /* one history record */
- long date;
+ time_t date;
+ time_t *date_p = &date;
+ time_t *secs_p;
+ if (line[0] == '\0')
+ continue;
+ date = 0L;
if(line[0] == '/' && line[1] == '/') {
info->history[nb_history].level = -2;
rc = 0;
return 0; /* normal end of record */
}
- memset(&onehistory, 0, sizeof(onehistory));
+ memset(&onehistory, 0, SIZEOF(onehistory));
s = line;
ch = *s++;
#define sc "history:"
- if(strncmp(line, sc, sizeof(sc)-1) != 0) {
+ if(strncmp(line, sc, SIZEOF(sc)-1) != 0) {
amfree(line);
break;
}
- s += sizeof(sc)-1;
+ s += SIZEOF(sc)-1;
ch = s[-1];
#undef sc
skip_integer(s, ch);
skip_whitespace(s, ch);
- if(ch == '\0' || sscanf((s - 1), "%ld", &onehistory.size) != 1) {
+ if(ch == '\0' || sscanf((s - 1), OFF_T_FMT,
+ (OFF_T_FMT_TYPE *)&onehistory.size) != 1) {
amfree(line);
break;
}
skip_integer(s, ch);
skip_whitespace(s, ch);
- if(ch == '\0' || sscanf((s - 1), "%ld", &onehistory.csize) != 1) {
+ if(ch == '\0' || sscanf((s - 1), OFF_T_FMT,
+ (OFF_T_FMT_TYPE *)&onehistory.csize) != 1) {
amfree(line);
break;
}
skip_integer(s, ch);
skip_whitespace(s, ch);
- if(ch == '\0' || sscanf((s - 1), "%ld", &date) != 1) {
+ if(ch == '\0' || sscanf((s - 1), TIME_T_FMT,
+ (TIME_T_FMT_TYPE *)date_p) != 1) {
amfree(line);
break;
}
skip_integer(s, ch);
- onehistory.date = date; /* time_t not guarranteed to be long */
+ onehistory.date = date; /* time_t not guaranteed to be long */
- onehistory.secs = -1;
+ onehistory.secs = (unsigned long)-1;
skip_whitespace(s, ch);
+ secs_p = &onehistory.secs;
if(ch != '\0') {
- if(sscanf((s - 1), "%ld", &onehistory.secs) != 1) {
+ if(sscanf((s - 1), TIME_T_FMT,
+ (TIME_T_FMT_TYPE *)secs_p) != 1) {
amfree(line);
break;
}
}
amfree(line);
- if((line = agets(infof)) == NULL) return -1; /* // line */
+ while ((line = agets(infof)) != NULL) {
+ if (line[0] != '\0')
+ break;
+ amfree(line);
+ }
+ if (line == NULL) return -1;
amfree(line);
return rc;
}
-static int write_txinfofile(infof, info)
-FILE *infof;
-info_t *info;
+static int
+write_txinfofile(
+ FILE * infof,
+ info_t * info)
{
int i;
stats_t *sp;
fprintf(infof, "version: %d\n", 0);
- fprintf(infof, "command: %d\n", info->command);
+ fprintf(infof, "command: %u\n", info->command);
pp = &info->full;
fprintf(infof, "full-rate:");
for(i=0; i<AVG_COUNT; i++)
if(pp->rate[i] >= 0.0)
- fprintf(infof, " %f", pp->rate[i]);
+ fprintf(infof, " %lf", pp->rate[i]);
fprintf(infof, "\n");
fprintf(infof, "full-comp:");
for(i=0; i<AVG_COUNT; i++)
if(pp->comp[i] >= 0.0)
- fprintf(infof, " %f", pp->comp[i]);
+ fprintf(infof, " %lf", pp->comp[i]);
fprintf(infof, "\n");
pp = &info->incr;
fprintf(infof, "incr-rate:");
for(i=0; i<AVG_COUNT; i++)
if(pp->rate[i] >= 0.0)
- fprintf(infof, " %f", pp->rate[i]);
+ fprintf(infof, " %lf", pp->rate[i]);
fprintf(infof, "\n");
fprintf(infof, "incr-comp:");
for(i=0; i<AVG_COUNT; i++)
if(pp->comp[i] >= 0.0)
- fprintf(infof, " %f", pp->comp[i]);
+ fprintf(infof, " %lf", pp->comp[i]);
fprintf(infof, "\n");
for(level=0; level<DUMP_LEVELS; level++) {
if(sp->date < (time_t)0 && sp->label[0] == '\0') continue;
- fprintf(infof, "stats: %d %ld %ld %ld %ld", level,
- sp->size, sp->csize, sp->secs, (long)sp->date);
+ fprintf(infof, "stats: %d " OFF_T_FMT " " OFF_T_FMT
+ " " TIME_T_FMT " " OFF_T_FMT,
+ level, (OFF_T_FMT_TYPE)sp->size, (OFF_T_FMT_TYPE)sp->csize,
+ (TIME_T_FMT_TYPE)sp->secs, (OFF_T_FMT_TYPE)sp->date);
if(sp->label[0] != '\0')
- fprintf(infof, " %d %s", sp->filenum, sp->label);
+ fprintf(infof, " " OFF_T_FMT " %s",
+ (OFF_T_FMT_TYPE)sp->filenum, sp->label);
fprintf(infof, "\n");
}
fprintf(infof, "last_level: %d %d\n", info->last_level, info->consecutive_runs);
for(i=0;info->history[i].level > -1;i++) {
- fprintf(infof, "history: %d %ld %ld %ld %ld\n",info->history[i].level,
- info->history[i].size, info->history[i].csize,
- info->history[i].date, info->history[i].secs);
+ fprintf(infof, "history: %d " OFF_T_FMT " " OFF_T_FMT
+ " " TIME_T_FMT " " TIME_T_FMT "\n",
+ info->history[i].level,
+ (OFF_T_FMT_TYPE)info->history[i].size,
+ (OFF_T_FMT_TYPE)info->history[i].csize,
+ (TIME_T_FMT_TYPE)info->history[i].date,
+ (TIME_T_FMT_TYPE)info->history[i].secs);
}
fprintf(infof, "//\n");
return 0;
}
-static int delete_txinfofile(host, disk)
-char *host;
-char *disk;
+static int
+delete_txinfofile(
+ char * host,
+ char * disk)
{
char *fn = NULL, *fn_new = NULL;
int rc;
+ char *myhost;
+ char *mydisk;
- host = sanitise_filename(host);
- disk = sanitise_filename(disk);
+ myhost = sanitise_filename(host);
+ mydisk = sanitise_filename(disk);
fn = vstralloc(infodir,
- "/", host,
- "/", disk,
+ "/", myhost,
+ "/", mydisk,
"/info",
NULL);
fn_new = stralloc2(fn, ".new");
- amfree(host);
- amfree(disk);
+ amfree(myhost);
+ amfree(mydisk);
unlink(fn_new);
amfree(fn_new);
static char *lockname = NULL;
#endif
-int open_infofile(filename)
-char *filename;
+int
+open_infofile(
+ char * filename)
{
#ifdef TEXTDB
assert(infodir == (char *)0);
#endif
}
-void close_infofile()
+void
+close_infofile(void)
{
#ifdef TEXTDB
assert(infodir != (char *)0);
#else
dbm_close(infodb);
- if(amfunlock(lockfd, "info") == -1)
+ if(amfunlock(lockfd, "info") == -1) {
error("could not unlock infofile: %s", strerror(errno));
+ /*NOTREACHED*/
+ }
aclose(lockfd);
lockfd = -1;
}
/* Convert a dump level to a GMT based time stamp */
-char *get_dumpdate(info, lev)
-info_t *info;
-int lev;
+char *
+get_dumpdate(
+ info_t * info,
+ int lev)
{
static char stamp[20]; /* YYYY:MM:DD:hh:mm:ss */
int l;
}
t = gmtime(&last);
- snprintf(stamp, sizeof(stamp), "%d:%d:%d:%d:%d:%d",
+ snprintf(stamp, SIZEOF(stamp), "%d:%d:%d:%d:%d:%d",
t->tm_year+1900, t->tm_mon+1, t->tm_mday,
t->tm_hour, t->tm_min, t->tm_sec);
return stamp;
}
-double perf_average(a, d)
-/* Weighted average */
-float *a; /* array of items to average */
-double d; /* default value */
+/*
+ * Weighted average
+ */
+double
+perf_average(
+ double * a, /* array of items to average */
+ double d) /* default value */
{
double sum; /* running total */
int n; /* number of items in sum */
return sum / n;
}
-static void zero_info(info)
-info_t *info;
+static void
+zero_info(
+ info_t *info)
{
int i;
- memset(info, '\0', sizeof(info_t));
+ memset(info, '\0', SIZEOF(info_t));
for(i = 0; i < AVG_COUNT; i++) {
info->full.comp[i] = info->incr.comp[i] = -1.0;
for(i=0;i<=NB_HISTORY;i++) {
info->history[i].level = -2;
- info->history[i].size = 0;
- info->history[i].csize = 0;
- info->history[i].date = 0;
+ info->history[i].size = (off_t)0;
+ info->history[i].csize = (off_t)0;
+ info->history[i].date = 0UL;
}
return;
}
-int get_info(hostname, diskname, info)
-char *hostname, *diskname;
-info_t *info;
+int
+get_info(
+ char * hostname,
+ char * diskname,
+ info_t * info)
{
int rc;
}
-int get_firstkey(hostname, hostname_size, diskname, diskname_size)
-char *hostname, *diskname;
-int hostname_size, diskname_size;
+int
+get_firstkey(
+ char * hostname,
+ int hostname_size,
+ char * diskname,
+ int diskname_size)
{
#ifdef TEXTDB
+ (void)hostname; /* Quiet unused parameter warning */
+ (void)hostname_size; /* Quiet unused parameter warning */
+ (void)diskname; /* Quiet unused parameter warning */
+ (void)diskname_size; /* Quiet unused parameter warning */
+
assert(0);
return 0;
#else
}
-int get_nextkey(hostname, hostname_size, diskname, diskname_size)
-char *hostname, *diskname;
-int hostname_size, diskname_size;
+int
+get_nextkey(
+ char * hostname,
+ int hostname_size,
+ char * diskname,
+ int diskname_size)
{
#ifdef TEXTDB
+ (void)hostname; /* Quiet unused parameter warning */
+ (void)hostname_size; /* Quiet unused parameter warning */
+ (void)diskname; /* Quiet unused parameter warning */
+ (void)diskname_size; /* Quiet unused parameter warning */
+
assert(0);
return 0;
#else
}
-int put_info(hostname, diskname, info)
- char *hostname, *diskname;
- info_t *info;
+int
+put_info(
+ char * hostname,
+ char * diskname,
+ info_t * info)
{
#ifdef TEXTDB
FILE *infof;
k.dsize = strlen(k.dptr)+1;
d.dptr = (char *)info;
- d.dsize = sizeof(info_t);
+ d.dsize = SIZEOF(info_t);
/* store record */
}
-int del_info(hostname, diskname)
-char *hostname, *diskname;
+int
+del_info(
+ char * hostname,
+ char * diskname)
{
#ifdef TEXTDB
return delete_txinfofile(hostname, diskname);
#ifdef TEST
-void dump_rec(info)
-info_t *info;
+void dump_rec(info_t *info);
+
+void
+dump_rec(
+ info_t * info)
{
int i;
stats_t *sp;
printf("command word: %d\n", info->command);
- printf("full dump rate (K/s) %5.1f, %5.1f, %5.1f\n",
+ printf("full dump rate (K/s) %5.1lf, %5.1lf, %5.1lf\n",
info->full.rate[0],info->full.rate[1],info->full.rate[2]);
- printf("full comp rate %5.1f, %5.1f, %5.1f\n",
+ printf("full comp rate %5.1lf, %5.1lf, %5.1lf\n",
info->full.comp[0]*100,info->full.comp[1]*100,info->full.comp[2]*100);
- printf("incr dump rate (K/s) %5.1f, %5.1f, %5.1f\n",
+ printf("incr dump rate (K/s) %5.1lf, %5.1lf, %5.1lf\n",
info->incr.rate[0],info->incr.rate[1],info->incr.rate[2]);
- printf("incr comp rate %5.1f, %5.1f, %5.1f\n",
+ printf("incr comp rate %5.1lf, %5.1lf, %5.1lf\n",
info->incr.comp[0]*100,info->incr.comp[1]*100,info->incr.comp[2]*100);
for(i = 0; i < DUMP_LEVELS; i++) {
sp = &info->inf[i];
if( sp->size != -1) {
- printf("lev %d date %ld tape %s filenum %d size %ld csize %ld secs %ld\n",
+ printf("lev %d date %ld tape %s filenum " OFF_T_FMT " size %ld csize %ld secs %ld\n",
i, (long)sp->date, sp->label, sp->filenum,
sp->size, sp->csize, sp->secs);
}
}
#ifdef TEXTDB
-void dump_db(host, disk)
-char *host, *disk;
+void dump_db( char *host, char *disk);
+
+void
+dump_db(
+ char * host,
+ char * disk)
{
info_t info;
int rc;
}
}
#else
-void dump_db(str)
-char *str;
+void
+dump_db(
+ char * str)
{
datum k,d;
int rec,r,num;
printf("%3d: KEY %s =\n", rec, k.dptr);
d = dbm_fetch(infodb, k);
- memset(&info, '\0', sizeof(info));
+ memset(&info, '\0', SIZEOF(info));
memcpy(&info, d.dptr, d.dsize);
- num = (d.dsize-HEADER)/sizeof(stats_t);
+ num = (d.dsize-HEADER)/SIZEOF(stats_t);
dump_rec(&info);
k = dbm_nextkey(infodb);
#endif
int
-main(argc, argv)
-int argc;
-char *argv[];
+main(
+ int argc,
+ char ** argv)
{
int i;
unsigned long malloc_hist_1, malloc_size_1;
set_pname("infofile");
+ dbopen(DBG_SUBDIR_SERVER);
+
malloc_size_1 = malloc_inuse(&malloc_hist_1);
for(i = 1; i < argc; ++i) {
* University of Maryland at College Park
*/
/*
- * $Id: infofile.h,v 1.13 2005/03/16 18:15:05 martinea Exp $
+ * $Id: infofile.h,v 1.14 2006/05/25 01:47:20 johnfranks Exp $
*
* interface for current info file reading code
*/
typedef struct stats_s {
/* fields updated by dumper */
- long size; /* original size of dump in kbytes */
- long csize; /* compressed size of dump in kbytes */
- long secs; /* time of dump in secs */
+ off_t size; /* original size of dump in kbytes */
+ off_t csize; /* compressed size of dump in kbytes */
+ time_t secs; /* time of dump in secs */
time_t date; /* end time of dump */
/* fields updated by taper */
- int filenum; /* file number on tape */
+ off_t filenum; /* file number on tape */
char label[MAX_LABEL]; /* tape label */
} stats_t;
typedef struct history_s {
int level; /* level of dump */
- long size; /* original size of dump in kbytes */
- long csize; /* compressed size of dump in kbytes */
+ off_t size; /* original size of dump in kbytes */
+ off_t csize; /* compressed size of dump in kbytes */
time_t date; /* time of dump */
- long secs; /* time of dump in secs */
+ time_t secs; /* time of dump in secs */
} history_t;
typedef struct perf_s {
- float rate[AVG_COUNT];
- float comp[AVG_COUNT];
+ double rate[AVG_COUNT];
+ double comp[AVG_COUNT];
} perf_t;
typedef struct info_s {
} info_t;
-int open_infofile P((char *infofile));
-void close_infofile P((void));
+int open_infofile(char *infofile);
+void close_infofile(void);
-char *get_dumpdate P((info_t *info, int level));
-double perf_average P((float *array, double def));
-int get_info P((char *hostname, char *diskname, info_t *info));
-int get_firstkey P((char *hostname, int hostname_size,
- char *diskname, int diskname_size));
-int get_nextkey P((char *hostname, int hostname_size,
- char *diskname, int diskname_size));
-int put_info P((char *hostname, char *diskname, info_t *info));
-int del_info P((char *hostname, char *diskname));
+char *get_dumpdate(info_t *info, int level);
+double perf_average(double *array, double def);
+int get_info(char *hostname, char *diskname, info_t *info);
+int get_firstkey(char *hostname, int hostname_size,
+ char *diskname, int diskname_size);
+int get_nextkey(char *hostname, int hostname_size,
+ char *diskname, int diskname_size);
+int put_info(char *hostname, char *diskname, info_t *info);
+int del_info(char *hostname, char *diskname);
#endif /* ! INFOFILE_H */
* Authors: the Amanda Development Team. Its members are listed in a
* file named AUTHORS, in the root directory of this distribution.
*/
-/* $Id: list_dir.c,v 1.17 2002/03/24 19:25:51 jrjackson Exp $
+/* $Id: list_dir.c,v 1.19 2006/07/05 11:22:49 martinea Exp $
*
* manage directory listings from index files
*/
DIR_ITEM *dir_last = NULL; /* last dir entry */
DIR_ITEM *cur_list = NULL; /* current dir entry,for speeding up search */
-DIR_ITEM *get_dir_list()
+DIR_ITEM *
+get_dir_list(void)
{
return dir_list;
}
-void clear_dir_list P((void))
+void
+clear_dir_list(void)
{
DIR_ITEM *this;
/* It's true because the output of the index file is sorted */
/* Maybe it could be more efficient if the index was sorted when */
/* it is generated */
-int add_dir_list_item(dump, path)
-DUMP_ITEM *dump;
-char *path;
+
+int
+add_dir_list_item(
+ DUMP_ITEM * dump,
+ const char *path)
{
DIR_ITEM *cur;
if (dir_list == NULL)
{
- dir_list = (DIR_ITEM *)alloc(sizeof(DIR_ITEM));
+ dir_list = (DIR_ITEM *)alloc(SIZEOF(DIR_ITEM));
dir_list->next = NULL;
dir_list->dump = dump;
dir_list->path = stralloc(path);
/* add at head of list */
if(strcmp(path,dir_list->path) < 0)
{
- cur_list = (DIR_ITEM *)alloc(sizeof(DIR_ITEM));
+ cur_list = (DIR_ITEM *)alloc(SIZEOF(DIR_ITEM));
cur_list->next = dir_list;
cur_list->dump = dump;
cur_list->path = stralloc(path);
cur_list=cur_list->next;
}
- if(strcmp(path,cur_list->next->path) == 0)
+ if (cur_list->next && strcmp(path, cur_list->next->path) == 0)
{
cur_list=cur_list->next;
return 0; /* found */
}
/* add at cur_list */
- cur = (DIR_ITEM *)alloc(sizeof(DIR_ITEM));
+ cur = (DIR_ITEM *)alloc(SIZEOF(DIR_ITEM));
cur->next = cur_list->next;
cur->dump = dump;
cur->path = stralloc(path);
}
else /* add at end of list */
{
- dir_last->next = (DIR_ITEM *)alloc(sizeof(DIR_ITEM));
+ dir_last->next = (DIR_ITEM *)alloc(SIZEOF(DIR_ITEM));
dir_last=dir_last->next;
dir_last->next = NULL;
dir_last->dump = dump;
* file named AUTHORS, in the root directory of this distribution.
*/
/*
- * $Id: list_dir.h,v 1.3 1999/02/15 02:30:26 martinea Exp $
+ * $Id: list_dir.h,v 1.4 2006/05/25 01:47:20 johnfranks Exp $
*
*/
+#ifndef LISTDIR_H
+#define LISTDIR_H
+
typedef struct DIR_ITEM {
DUMP_ITEM *dump;
struct DIR_ITEM *next;
} DIR_ITEM;
-
-extern DIR_ITEM *get_dir_list P((void));
-extern void clear_dir_list P((void));
-extern int add_dir_list_item P((DUMP_ITEM *dump, char *path));
+extern struct DIR_ITEM *get_dir_list(void);
+extern void clear_dir_list(void);
+extern int add_dir_list_item(DUMP_ITEM *dump, const char *path);
+#endif /* !LISTDIR_H */
* University of Maryland at College Park
*/
/*
- * $Id: logfile.c,v 1.29 2005/12/04 22:56:55 martinea Exp $
+ * $Id: logfile.c,v 1.31 2006/06/01 14:54:39 martinea Exp $
*
* common log file writing routine
*/
*/
/* local functions */
-static void open_log P((void));
-static void close_log P((void));
+static void open_log(void);
+static void close_log(void);
-void logerror(msg)
-char *msg;
+void
+logerror(
+ char * msg)
{
log_add(L_FATAL, "%s", msg);
}
}
arglist_start(argp, format);
- vsnprintf(linebuf, sizeof(linebuf)-1, format, argp);
+ vsnprintf(linebuf, SIZEOF(linebuf)-1, format, argp);
/* -1 to allow for '\n' */
return(vstralloc(leader, linebuf, "\n", NULL));
}
int saved_errout;
char *leader = NULL;
char linebuf[STR_SIZE];
- int n;
+ size_t n;
/* format error message */
}
arglist_start(argp, format);
- vsnprintf(linebuf, sizeof(linebuf)-1, format, argp);
+ vsnprintf(linebuf, SIZEOF(linebuf)-1, format, argp);
/* -1 to allow for '\n' */
arglist_end(argp);
if(multiline == -1) open_log();
- if (fullwrite(logfd, leader, strlen(leader)) < 0)
+ if (fullwrite(logfd, leader, strlen(leader)) < 0) {
error("log file write error: %s", strerror(errno));
+ /*NOTREACHED*/
+ }
amfree(leader);
if(n == 0 || linebuf[n-1] != '\n') linebuf[n++] = '\n';
linebuf[n] = '\0';
- if (fullwrite(logfd, linebuf, n) < 0)
+ if (fullwrite(logfd, linebuf, n) < 0) {
error("log file write error: %s", strerror(errno));
+ /*NOTREACHED*/
+ }
if(multiline != -1) multiline++;
else close_log();
erroutput_type = saved_errout;
}
-void log_start_multiline()
+void
+log_start_multiline(void)
{
assert(multiline == -1);
}
-void log_end_multiline()
+void
+log_end_multiline(void)
{
assert(multiline != -1);
multiline = -1;
}
-void log_rename(datestamp)
-char *datestamp;
+void
+log_rename(
+ char * datestamp)
{
char *conf_logdir;
char *logfile;
logfile = vstralloc(conf_logdir, "/log", NULL);
for(seq = 0; 1; seq++) { /* if you've got MAXINT files in your dir... */
- snprintf(seq_str, sizeof(seq_str), "%d", seq);
+ snprintf(seq_str, SIZEOF(seq_str), "%u", seq);
fname = newvstralloc(fname,
logfile,
".", datestamp,
if(stat(fname, &statbuf) == -1 && errno == ENOENT) break;
}
- if(rename(logfile, fname) == -1)
+ if(rename(logfile, fname) == -1) {
error("could not rename \"%s\" to \"%s\": %s",
logfile, fname, strerror(errno));
+ /*NOTREACHED*/
+ }
amfree(fname);
amfree(logfile);
}
-static void open_log()
+static void
+open_log(void)
{
char *conf_logdir;
logfd = open(logfile, O_WRONLY|O_CREAT|O_APPEND, 0600);
- if(logfd == -1)
+ if(logfd == -1) {
error("could not open log file %s: %s", logfile, strerror(errno));
+ /*NOTREACHED*/
+ }
- if(amflock(logfd, "log") == -1)
+ if(amflock(logfd, "log") == -1) {
error("could not lock log file %s: %s", logfile, strerror(errno));
+ /*NOTREACHED*/
+ }
}
-static void close_log()
+static void
+close_log(void)
{
- if(amfunlock(logfd, "log") == -1)
+ if(amfunlock(logfd, "log") == -1) {
error("could not unlock log file %s: %s", logfile, strerror(errno));
+ /*NOTREACHED*/
+ }
- if(close(logfd) == -1)
+ if(close(logfd) == -1) {
error("close log file: %s", strerror(errno));
+ /*NOTREACHED*/
+ }
logfd = -1;
amfree(logfile);
}
-int get_logline(logf)
-FILE *logf;
+int
+get_logline(
+ FILE * logf)
{
static char *logline = NULL;
char *logstr, *progstr;
int ch;
amfree(logline);
- if((logline = agets(logf)) == NULL) return 0;
+ while ((logline = agets(logf)) != NULL) {
+ if (logline[0] != '\0')
+ break;
+ amfree(logline);
+ }
+ if (logline == NULL) return 0;
curlinenum++;
s = logline;
ch = *s++;
* University of Maryland at College Park
*/
/*
- * $Id: logfile.h,v 1.12 2005/11/29 22:19:08 martinea Exp $
+ * $Id: logfile.h,v 1.13 2006/05/25 01:47:20 johnfranks Exp $
*
* interface to logfile module
*/
extern char *curstr;
extern char *program_str[];
-void logerror P((char *));
-void log_add P((logtype_t typ, char * format, ...))
+void logerror(char *);
+void log_add(logtype_t typ, char * format, ...)
__attribute__ ((format (printf, 2, 3)));
-char* log_genstring P((logtype_t typ, char *pname, char * format, ...));
+char* log_genstring(logtype_t typ, char *pname, char * format, ...);
/* __attribute__ ((format (printf, 3, 4))); */
-void log_start_multiline P((void));
-void log_end_multiline P((void));
-void log_rename P((char *datestamp));
-int get_logline P((FILE *));
+void log_start_multiline(void);
+void log_end_multiline(void);
+void log_rename(char *datestamp);
+int get_logline(FILE *);
#endif /* ! LOGFILE_H */
* file named AUTHORS, in the root directory of this distribution.
*/
/*
- * $Id: planner.c,v 1.180.2.1 2006/04/24 11:16:43 martinea Exp $
+ * $Id: planner.c,v 1.206 2006/08/10 23:57:27 paddy_s Exp $
*
* backup schedule planner for the Amanda backup system.
*/
/* configuration file stuff */
-char *conf_tapetype;
-am64_t conf_maxdumpsize;
-int conf_runtapes;
-int conf_dumpcycle;
-int conf_runspercycle;
-int conf_tapecycle;
-int conf_etimeout;
-int conf_reserve;
-int conf_autoflush;
+char * conf_tapetype;
+off_t conf_maxdumpsize;
+int conf_runtapes;
+int conf_dumpcycle;
+int conf_runspercycle;
+int conf_tapecycle;
+time_t conf_etimeout;
+int conf_reserve;
+int conf_autoflush;
+int conf_usetimestamps;
#define HOST_READY ((void *)0) /* must be 0 */
#define HOST_ACTIVE ((void *)1)
int got_estimate;
int dump_priority;
int dump_level;
- long dump_size;
+ off_t dump_nsize; /* native size */
+ off_t dump_csize; /* compressed size */
int degr_level; /* if dump_level == 0, what would be the inc level */
- long degr_size;
+ off_t degr_nsize; /* native degraded size */
+ off_t degr_csize; /* compressed degraded size */
int last_level;
- long last_lev0size;
+ off_t last_lev0size;
int next_level0;
int level_days;
int promote;
char *errstr;
int level[MAX_LEVELS];
char *dumpdate[MAX_LEVELS];
- long est_size[MAX_LEVELS];
+ off_t est_size[MAX_LEVELS];
} est_t;
#define est(dp) ((est_t *)(dp)->up)
/* pestq = partial estimate */
disklist_t startq, waitq, pestq, estq, failq, schedq;
-am64_t total_size;
+off_t total_size;
double total_lev0, balanced_size, balance_threshold;
-am64_t tape_length, tape_mark;
+off_t tape_length;
+size_t tape_mark;
tapetype_t *tape;
-long tt_blocksize;
-long tt_blocksize_kb;
+size_t tt_blocksize;
+size_t tt_blocksize_kb;
int runs_per_cycle = 0;
time_t today;
-char *datestamp = NULL;
+char *planner_timestamp = NULL;
static am_feature_t *our_features = NULL;
static char *our_feature_string = NULL;
int deleted; /* 0=modified, 1=deleted */
disk_t *dp; /* The disk that was changed */
int level; /* The original level */
- long size; /* The original size */
+ off_t nsize; /* The original native size */
+ off_t csize; /* The original compressed size */
char *errstr; /* A message describing why this disk is here */
} bi_t;
*
*/
-static void setup_estimate P((disk_t *dp));
-static void get_estimates P((void));
-static void analyze_estimate P((disk_t *dp));
-static void handle_failed P((disk_t *dp));
-static void delay_dumps P((void));
-static int promote_highest_priority_incremental P((void));
-static int promote_hills P((void));
-static void output_scheduleline P((disk_t *dp));
-int main P((int, char **));
-
-int main(argc, argv)
-int argc;
-char **argv;
+static void setup_estimate(disk_t *dp);
+static void get_estimates(void);
+static void analyze_estimate(disk_t *dp);
+static void handle_failed(disk_t *dp);
+static void delay_dumps(void);
+static int promote_highest_priority_incremental(void);
+static int promote_hills(void);
+static void output_scheduleline(disk_t *dp);
+int main(int, char **);
+
+int main(int argc, char **argv)
{
disklist_t origq;
disk_t *dp;
int moved_one;
unsigned long malloc_hist_1, malloc_size_1;
unsigned long malloc_hist_2, malloc_size_2;
- long initial_size;
+ off_t initial_size;
int i;
char *conffile;
char *conf_diskfile;
char *conf_tapelist;
char *conf_infofile;
times_t section_start;
+ uid_t ruid;
+ char *qname;
+ int new_argc, my_argc;
+ char **new_argv, **my_argv;
+ int nb_disk;
+ char *errstr;
safe_fd(-1, 0);
- setvbuf(stderr, (char *)NULL, _IOLBF, 0);
+ setvbuf(stderr, (char *)NULL, (int)_IOLBF, 0);
- if (argc > 1) {
- config_name = stralloc(argv[1]);
+ parse_server_conf(argc, argv, &new_argc, &new_argv);
+ my_argc = new_argc;
+ my_argv = new_argv;
+
+ if (my_argc > 1) {
+ config_name = stralloc(my_argv[1]);
config_dir = vstralloc(CONFIG_DIR, "/", config_name, "/", NULL);
} else {
char my_cwd[STR_SIZE];
- if (getcwd(my_cwd, sizeof(my_cwd)) == NULL) {
+ if (getcwd(my_cwd, SIZEOF(my_cwd)) == NULL) {
error("cannot determine current working directory");
+ /*NOTREACHED*/
}
config_dir = stralloc2(my_cwd, "/");
if ((config_name = strrchr(my_cwd, '/')) != NULL) {
set_pname("planner");
+ dbopen(DBG_SUBDIR_SERVER);
+
/* Don't die when child closes pipe */
signal(SIGPIPE, SIG_IGN);
our_feature_string = am_feature_to_string(our_features);
fprintf(stderr, "%s: pid %ld executable %s version %s\n",
- get_pname(), (long) getpid(), argv[0], version());
+ get_pname(), (long) getpid(), my_argv[0], version());
for (i = 0; version_info[i] != NULL; i++)
fprintf(stderr, "%s: %s", get_pname(), version_info[i]);
* 1. Networking Setup
*
* Planner runs setuid to get a priviledged socket for BSD security.
- * We get the socket right away as root, then setuid back to a normal
- * user. If we are not using BSD security, planner is not installed
- * setuid root.
+ * We get the socket right away as root, then set euid to normal
+ * user. Keeping saved uid as root.
*/
protocol_init();
+ ruid = getuid();
if(geteuid() == 0) {
- uid_t ruid = getuid();
- setuid(0);
seteuid(ruid);
setgid(getgid());
}
* are a valid user.
*/
- if(getpwuid(getuid()) == NULL)
+ if(getpwuid(getuid()) == NULL) {
error("can't get login name for my uid %ld", (long)getuid());
+ /*NOTREACHED*/
+ }
/*
* 2. Read in Configuration Information
conffile = stralloc2(config_dir, CONFFILE_NAME);
if(read_conffile(conffile)) {
error("errors processing config file \"%s\"", conffile);
+ /*NOTREACHED*/
}
amfree(conffile);
+ dbrename(config_name, DBG_SUBDIR_SERVER);
+
+ report_bad_conf_arg();
+
conf_diskfile = getconf_str(CNF_DISKFILE);
if (*conf_diskfile == '/') {
conf_diskfile = stralloc(conf_diskfile);
}
if (read_diskfile(conf_diskfile, &origq) < 0) {
error("could not load disklist \"%s\"", conf_diskfile);
+ /*NOTREACHED*/
}
- match_disklist(&origq, argc-2, argv+2);
+ if(origq.head == NULL) {
+ error("empty disklist \"%s\"", conf_diskfile);
+ /*NOTREACHED*/
+ }
+
+ errstr = match_disklist(&origq, my_argc-2, my_argv+2);
+ if (errstr) {
+ fprintf(stderr,"%s",errstr);
+ amfree(errstr);
+ }
+ nb_disk = 0;
for(dp = origq.head; dp != NULL; dp = dp->next) {
- if(dp->todo)
- log_add(L_DISK, "%s %s", dp->host->hostname, dp->name);
+ if(dp->todo) {
+ qname = quote_string(dp->name);
+ log_add(L_DISK, "%s %s", dp->host->hostname, qname);
+ amfree(qname);
+ nb_disk++;
+ }
+ }
+
+ if(nb_disk == 0) {
+ error("no DLE to backup");
+ /*NOTREACHED*/
}
amfree(conf_diskfile);
}
if(read_tapelist(conf_tapelist)) {
error("could not load tapelist \"%s\"", conf_tapelist);
+ /*NOTREACHED*/
}
amfree(conf_tapelist);
}
if(open_infofile(conf_infofile)) {
error("could not open info db \"%s\"", conf_infofile);
+ /*NOTREACHED*/
}
amfree(conf_infofile);
conf_dumpcycle = getconf_int(CNF_DUMPCYCLE);
conf_runspercycle = getconf_int(CNF_RUNSPERCYCLE);
conf_tapecycle = getconf_int(CNF_TAPECYCLE);
- conf_etimeout = getconf_int(CNF_ETIMEOUT);
+ conf_etimeout = getconf_time(CNF_ETIMEOUT);
conf_reserve = getconf_int(CNF_RESERVE);
- conf_autoflush = getconf_int(CNF_AUTOFLUSH);
+ conf_autoflush = getconf_boolean(CNF_AUTOFLUSH);
+ conf_usetimestamps = getconf_boolean(CNF_USETIMESTAMPS);
- amfree(datestamp);
+ amfree(planner_timestamp);
today = time(0);
- datestamp = construct_datestamp(NULL);
- log_add(L_START, "date %s", datestamp);
+ if(conf_usetimestamps == 0) {
+ planner_timestamp = construct_datestamp(NULL);
+ }
+ else {
+ planner_timestamp = construct_timestamp(NULL);
+ }
+ log_add(L_START, "date %s", planner_timestamp);
+ printf("DATE %s\n", planner_timestamp);
+ fflush(stdout);
+ fprintf(stderr, "%s: timestamp %s\n",
+ get_pname(), planner_timestamp);
/* some initializations */
}
tape = lookup_tapetype(conf_tapetype);
- if(conf_maxdumpsize > 0) {
- tape_length = conf_maxdumpsize;
+ if(conf_maxdumpsize > (off_t)0) {
+ tape_length = (off_t)conf_maxdumpsize;
}
else {
- tape_length = tape->length * conf_runtapes;
+ tape_length = tapetype_get_length(tape) * (off_t)conf_runtapes;
}
- tape_mark = tape->filemark;
- tt_blocksize_kb = tape->blocksize;
+ tape_mark = (size_t)tapetype_get_filemark(tape);
+ tt_blocksize_kb = (size_t)tapetype_get_blocksize(tape);
tt_blocksize = tt_blocksize_kb * 1024;
fprintf(stderr, "%s: time %s: startup took %s secs\n",
section_start = curclock();
/* an empty tape still has a label and an endmark */
- total_size = (tt_blocksize_kb + tape_mark) * 2;
+ total_size = ((off_t)tt_blocksize_kb + (off_t)tape_mark) * (off_t)2;
total_lev0 = 0.0;
balanced_size = 0.0;
{
disk_t *dp;
- fprintf(stderr, "INITIAL SCHEDULE (size " AM64_FMT "):\n", total_size);
+ fprintf(stderr, "INITIAL SCHEDULE (size " OFF_T_FMT "):\n",
+ (OFF_T_FMT_TYPE)total_size);
for(dp = schedq.head; dp != NULL; dp = dp->next) {
- fprintf(stderr, " %s %s pri %d lev %d size %ld\n",
- dp->host->hostname, dp->name, est(dp)->dump_priority,
- est(dp)->dump_level, est(dp)->dump_size);
+ qname = quote_string(dp->name);
+ fprintf(stderr, " %s %s pri %d lev %d nsize " OFF_T_FMT " csize " OFF_T_FMT "\n",
+ dp->host->hostname, qname, est(dp)->dump_priority,
+ est(dp)->dump_level,
+ (OFF_T_FMT_TYPE)est(dp)->dump_nsize,
+ (OFF_T_FMT_TYPE)est(dp)->dump_csize);
+ amfree(qname);
}
}
* until the dumps fit on the tape.
*/
- fprintf(stderr,
- "\nDELAYING DUMPS IF NEEDED, total_size " AM64_FMT ", tape length " AM64_FMT " mark " AM64_FMT "\n",
- total_size, tape_length, tape_mark);
+ fprintf(stderr, "\nDELAYING DUMPS IF NEEDED, total_size " OFF_T_FMT
+ ", tape length " OFF_T_FMT " mark " SIZE_T_FMT "\n",
+ (OFF_T_FMT_TYPE)total_size,
+ (OFF_T_FMT_TYPE)tape_length,
+ (SIZE_T_FMT_TYPE)tape_mark);
initial_size = total_size;
delay_dumps();
/* XXX - why bother checking this? */
- if(empty(schedq) && total_size < initial_size)
+ if(empty(schedq) && total_size < initial_size) {
error("cannot fit anything on tape, bailing out");
+ /*NOTREACHED*/
+ }
/*
*/
fprintf(stderr,
- "\nPROMOTING DUMPS IF NEEDED, total_lev0 %1.0f, balanced_size %1.0f...\n",
+ "\nPROMOTING DUMPS IF NEEDED, total_lev0 %1.0lf, balanced_size %1.0lf...\n",
total_lev0, balanced_size);
balance_threshold = balanced_size * PROMOTE_THRESHOLD;
walltime_str(timessub(curclock(), section_start)));
+ /* done with prvileged ops, make sure root privilege is dropped */
+ if ( geteuid() == 0 ) {
+ setuid(ruid);
+ seteuid(ruid);
+ }
+
/*
* 9. Output Schedule
*
fprintf(stderr, "--------\n");
close_infofile();
- log_add(L_FINISH, "date %s time %s", datestamp, walltime_str(curclock()));
+ log_add(L_FINISH, "date %s time %s", planner_timestamp, walltime_str(curclock()));
- amfree(datestamp);
+ clear_tapelist();
+ free_new_argv(new_argc, new_argv);
+ free_server_config();
+ amfree(planner_timestamp);
amfree(config_dir);
amfree(config_name);
amfree(our_feature_string);
malloc_list(fileno(stderr), malloc_hist_1, malloc_hist_2);
}
+ dbclose();
+
return 0;
}
*
*/
-static void askfor P((est_t *, int, int, info_t *));
-static int last_level P((info_t *info)); /* subroutines */
-static long est_size P((disk_t *dp, int level));
-static long est_tape_size P((disk_t *dp, int level));
-static int next_level0 P((disk_t *dp, info_t *info));
-static int runs_at P((info_t *info, int lev));
-static long bump_thresh P((int level, long size_level_0, int bumppercent, int bumpsize, double bumpmult));
-static int when_overwrite P((char *label));
-
-static void askfor(ep, seq, lev, info)
-est_t *ep; /* esimate data block */
-int seq; /* sequence number of request */
-int lev; /* dump level being requested */
-info_t *info; /* info block for disk */
+static void askfor(est_t *, int, int, info_t *);
+static int last_level(info_t *info); /* subroutines */
+static off_t est_size(disk_t *dp, int level);
+static off_t est_tape_size(disk_t *dp, int level);
+static int next_level0(disk_t *dp, info_t *info);
+static int runs_at(info_t *info, int lev);
+static off_t bump_thresh(int level, off_t size_level_0, int bumppercent, off_t bumpsize, double bumpmult);
+static int when_overwrite(char *label);
+
+static void askfor(
+ est_t *ep, /* esimate data block */
+ int seq, /* sequence number of request */
+ int lev, /* dump level being requested */
+ info_t *info) /* info block for disk */
{
if(seq < 0 || seq >= MAX_LEVELS) {
error("error [planner askfor: seq out of range 0..%d: %d]",
MAX_LEVELS, seq);
+ /*NOTREACHED*/
}
if(lev < -1 || lev >= DUMP_LEVELS) {
error("error [planner askfor: lev out of range -1..%d: %d]",
DUMP_LEVELS, lev);
+ /*NOTREACHED*/
}
if (lev == -1) {
ep->level[seq] = -1;
ep->dumpdate[seq] = (char *)0;
- ep->est_size[seq] = -2;
+ ep->est_size[seq] = (off_t)-2;
return;
}
ep->dumpdate[seq] = stralloc(get_dumpdate(info,lev));
malloc_mark(ep->dumpdate[seq]);
- ep->est_size[seq] = -2;
+ ep->est_size[seq] = (off_t)-2;
return;
}
static void
-setup_estimate(dp)
- disk_t *dp;
+setup_estimate(
+ disk_t *dp)
{
est_t *ep;
info_t info;
int i;
+ char *qname;
+ int overwrite_runs;
assert(dp && dp->host);
+
+ qname = quote_string(dp->name);
fprintf(stderr, "%s: time %s: setting up estimates for %s:%s\n",
get_pname(), walltime_str(curclock()),
- dp->host->hostname, dp->name);
+ dp->host->hostname, qname);
/* get current information about disk */
/* setup working data struct for disk */
- ep = alloc(sizeof(est_t));
+ ep = alloc(SIZEOF(est_t));
malloc_mark(ep);
dp->up = (void *) ep;
ep->state = DISK_READY;
- ep->dump_size = -1;
+ ep->dump_nsize = (off_t)-1;
+ ep->dump_csize = (off_t)-1;
ep->dump_priority = dp->priority;
ep->errstr = 0;
ep->promote = 0;
*/
log_add(L_ERROR,
"Cannot force full dump of %s:%s with no-full option.",
- dp->host->hostname, dp->name);
+ dp->host->hostname, qname);
/* clear force command */
CLR(info.command, FORCE_FULL);
- if(put_info(dp->host->hostname, dp->name, &info))
+ if(put_info(dp->host->hostname, dp->name, &info)) {
error("could not put info record for %s:%s: %s",
- dp->host->hostname, dp->name, strerror(errno));
+ dp->host->hostname, qname, strerror(errno));
+ /*NOTREACHED*/
+ }
ep->last_level = last_level(&info);
ep->next_level0 = next_level0(dp, &info);
}
ep->last_level = -1;
ep->next_level0 = -conf_dumpcycle;
log_add(L_INFO, "Forcing full dump of %s:%s as directed.",
- dp->host->hostname, dp->name);
+ dp->host->hostname, qname);
}
}
else if(dp->strategy == DS_NOFULL) {
/* adjust priority levels */
+ /* warn if dump will be overwritten */
+ if(ep->last_level > -1) {
+ overwrite_runs = when_overwrite(info.inf[0].label);
+ if(overwrite_runs == 0) {
+ log_add(L_WARNING, "Last full dump of %s:%s "
+ "on tape %s overwritten on this run.",
+ dp->host->hostname, qname, info.inf[0].label);
+ }
+ else if(overwrite_runs <= RUNS_REDZONE) {
+ log_add(L_WARNING, "Last full dump of %s:%s on "
+ "tape %s overwritten in %d run%s.",
+ dp->host->hostname, qname, info.inf[0].label,
+ overwrite_runs, overwrite_runs == 1? "" : "s");
+ }
+ }
+
if(ep->next_level0 < 0) {
fprintf(stderr,"%s:%s overdue %d day%s for level 0\n",
- dp->host->hostname, dp->name,
+ dp->host->hostname, qname,
- ep->next_level0, ((- ep->next_level0) == 1) ? "" : "s");
ep->dump_priority -= ep->next_level0;
- /* warn if dump will be overwritten */
- if(ep->last_level > -1) {
- int overwrite_runs = when_overwrite(info.inf[0].label);
- if(overwrite_runs == 0) {
- log_add(L_WARNING,
- "Last full dump of %s:%s on tape %s overwritten on this run.",
- dp->host->hostname, dp->name, info.inf[0].label);
- }
- else if(overwrite_runs < RUNS_REDZONE) {
- log_add(L_WARNING,
- "Last full dump of %s:%s on tape %s overwritten in %d run%s.",
- dp->host->hostname, dp->name, info.inf[0].label,
- overwrite_runs, overwrite_runs == 1? "" : "s");
- }
- }
}
else if (ISSET(info.command, FORCE_FULL))
ep->dump_priority += 1;
CLR(info.command, FORCE_FULL);
ep->next_level0 += conf_dumpcycle;
ep->last_level = 0;
- if(put_info(dp->host->hostname, dp->name, &info))
+ if(put_info(dp->host->hostname, dp->name, &info)) {
error("could not put info record for %s:%s: %s",
- dp->host->hostname, dp->name, strerror(errno));
+ dp->host->hostname, qname, strerror(errno));
+ /*NOTREACHED*/
+ }
log_add(L_INFO, "Skipping full dump of %s:%s today.",
- dp->host->hostname, dp->name);
+ dp->host->hostname, qname);
fprintf(stderr,"%s:%s lev 0 skipped due to skip-full flag\n",
- dp->host->hostname, dp->name);
+ dp->host->hostname, qname);
/* don't enqueue the disk */
askfor(ep, 0, -1, &info);
askfor(ep, 1, -1, &info);
askfor(ep, 2, -1, &info);
fprintf(stderr, "%s: SKIPPED %s %s 0 [skip-full]\n",
- get_pname(), dp->host->hostname, dp->name);
+ get_pname(), dp->host->hostname, qname);
log_add(L_SUCCESS, "%s %s %s 0 [skipped: skip-full]",
- dp->host->hostname, dp->name, datestamp);
+ dp->host->hostname, qname, planner_timestamp);
+ amfree(qname);
return;
}
if(ep->next_level0 == 1) {
log_add(L_WARNING, "Skipping full dump of %s:%s tomorrow.",
- dp->host->hostname, dp->name);
+ dp->host->hostname, qname);
}
}
askfor(ep, 1, -1, &info);
askfor(ep, 2, -1, &info);
log_add(L_FAIL, "%s %s 19000101 1 [Skipping incronly because no full dump were done]",
- dp->host->hostname, dp->name);
+ dp->host->hostname, qname);
fprintf(stderr,"%s:%s lev 1 skipped due to strategy incronly and no full dump were done\n",
- dp->host->hostname, dp->name);
+ dp->host->hostname, qname);
+ amfree(qname);
return;
}
if(dp->skip_incr && ep->next_level0 > 0) {
fprintf(stderr,"%s:%s lev 1 skipped due to skip-incr flag\n",
- dp->host->hostname, dp->name);
+ dp->host->hostname, qname);
/* don't enqueue the disk */
askfor(ep, 0, -1, &info);
askfor(ep, 1, -1, &info);
askfor(ep, 2, -1, &info);
fprintf(stderr, "%s: SKIPPED %s %s 1 [skip-incr]\n",
- get_pname(), dp->host->hostname, dp->name);
+ get_pname(), dp->host->hostname, qname);
log_add(L_SUCCESS, "%s %s %s 1 [skipped: skip-incr]",
- dp->host->hostname, dp->name, datestamp);
+ dp->host->hostname, qname, planner_timestamp);
+ amfree(qname);
return;
}
if( ep->last_level == -1 && ep->next_level0 > 0 &&
dp->strategy != DS_NOFULL && dp->strategy != DS_INCRONLY &&
conf_reserve == 100) {
- log_add(L_WARNING,
- "%s:%s mismatch: no tapelist record, but curinfo next_level0: %d.",
- dp->host->hostname, dp->name, ep->next_level0);
+ log_add(L_WARNING, "%s:%s mismatch: no tapelist record, "
+ "but curinfo next_level0: %d.",
+ dp->host->hostname, qname, ep->next_level0);
ep->next_level0 = 0;
}
if(info.command & FORCE_BUMP && ep->last_level == -1) {
log_add(L_INFO,
"Remove force-bump command of %s:%s because it's a new disk.",
- dp->host->hostname, dp->name);
+ dp->host->hostname, qname);
}
switch (dp->strategy) {
case DS_STANDARD:
case DS_NOINC:
askfor(ep, i++, 0, &info);
if(dp->skip_full) {
- log_add(L_INFO,
- "Ignoring skip_full for %s:%s because the strategy is NOINC.",
- dp->host->hostname, dp->name);
+ log_add(L_INFO, "Ignoring skip_full for %s:%s "
+ "because the strategy is NOINC.",
+ dp->host->hostname, qname);
}
if(info.command & FORCE_BUMP) {
log_add(L_INFO,
"Ignoring FORCE_BUMP for %s:%s because the strategy is NOINC.",
- dp->host->hostname, dp->name);
+ dp->host->hostname, qname);
}
break;
askfor(ep, i++, curr_level, &info);
}
log_add(L_INFO,"Preventing bump of %s:%s as directed.",
- dp->host->hostname, dp->name);
+ dp->host->hostname, qname);
} else if (ISSET(info.command, FORCE_BUMP)
&& curr_level + 1 < DUMP_LEVELS) {
askfor(ep, i++, curr_level+1, &info);
log_add(L_INFO,"Bumping of %s:%s at level %d as directed.",
- dp->host->hostname, dp->name, curr_level+1);
+ dp->host->hostname, qname, curr_level+1);
} else if (curr_level == 0) {
askfor(ep, i++, 1, &info);
} else {
* if we haven't been at this level 2 days, or the dump failed
* last night, we can't bump.
*/
- if((info.inf[curr_level].size == 0 || /* no data, try it anyway */
+ if((info.inf[curr_level].size == (off_t)0 || /* no data, try it anyway */
(((info.inf[curr_level].size > bump_thresh(curr_level, info.inf[0].size,dp->bumppercent, dp->bumpsize, dp->bumpmult)))
&& ep->level_days >= dp->bumpdays))
&& curr_level + 1 < DUMP_LEVELS) {
/* debug output */
- fprintf(stderr, "setup_estimate: %s:%s: command %d, options: %s last_level %d next_level0 %d level_days %d getting estimates %d (%ld) %d (%ld) %d (%ld)\n",
- dp->host->hostname, dp->name, info.command,
+ fprintf(stderr, "setup_estimate: %s:%s: command %u, options: %s "
+ "last_level %d next_level0 %d level_days %d getting estimates "
+ "%d (" OFF_T_FMT ") %d (" OFF_T_FMT ") %d (" OFF_T_FMT ")\n",
+ dp->host->hostname, qname, info.command,
dp->strategy == DS_NOFULL ? "no-full" :
dp->strategy == DS_INCRONLY ? "incr-only" :
dp->skip_full ? "skip-full" :
dp->skip_incr ? "skip-incr" : "none",
ep->last_level, ep->next_level0, ep->level_days,
- ep->level[0], ep->est_size[0],
- ep->level[1], ep->est_size[1],
- ep->level[2], ep->est_size[2]);
+ ep->level[0], (OFF_T_FMT_TYPE)ep->est_size[0],
+ ep->level[1], (OFF_T_FMT_TYPE)ep->est_size[1],
+ ep->level[2], (OFF_T_FMT_TYPE)ep->est_size[2]);
assert(ep->level[0] != -1);
enqueue_disk(&startq, dp);
+ amfree(qname);
}
-static int when_overwrite(label)
-char *label;
+static int when_overwrite(
+ char *label)
{
tape_t *tp;
int runtapes;
if((tp = lookup_tapelabel(label)) == NULL)
return 1; /* "shouldn't happen", but trigger warning message */
- else if(!reusable_tape(tp))
+ else if(tp->reuse == 0)
return 1024;
else if(lookup_nb_tape() > conf_tapecycle)
return (lookup_nb_tape() - tp->position) / runtapes;
}
/* Return the estimated size for a particular dump */
-static long est_size(dp, level)
-disk_t *dp;
-int level;
+static off_t est_size(
+ disk_t *dp,
+ int level)
{
int i;
if(level == est(dp)->level[i])
return est(dp)->est_size[i];
}
- return -1;
+ return (off_t)-1;
}
/* Return the estimated on-tape size of a particular dump */
-static long est_tape_size(dp, level)
-disk_t *dp;
-int level;
+static off_t est_tape_size(
+ disk_t *dp,
+ int level)
{
- long size;
+ off_t size;
double ratio;
size = est_size(dp, level);
- if(size == -1) return size;
+ if(size == (off_t)-1) return size;
if(dp->compress == COMP_NONE)
return size;
if(ratio > 1.1) ratio = 1.1;
- size *= ratio;
+ size = (off_t)((double)size * ratio);
/*
* Ratio can be very small in some error situations, so make sure
* size goes back greater than zero. It may not be right, but
* indicates we did get an estimate.
*/
- if(size <= 0) {
- size = 1;
+ if(size <= (off_t)0) {
+ size = (off_t)1;
}
return size;
/* what was the level of the last successful dump to tape? */
-static int last_level(info)
-info_t *info;
+static int last_level(
+ info_t *info)
{
int min_pos, min_level, i;
time_t lev0_date, last_date;
/* when is next level 0 due? 0 = today, 1 = tomorrow, etc*/
static int
-next_level0(dp, info)
- disk_t *dp;
- info_t *info;
+next_level0(
+ disk_t *dp,
+ info_t *info)
{
if(dp->strategy == DS_NOFULL || dp->strategy == DS_INCRONLY)
return 1; /* fake it */
}
/* how many runs at current level? */
-static int runs_at(info, lev)
-info_t *info;
-int lev;
+static int runs_at(
+ info_t *info,
+ int lev)
{
tape_t *cur_tape, *old_tape;
int last, nb_runs;
}
-static long bump_thresh(level, size_level_0, bumppercent, bumpsize, bumpmult)
-int level;
-long size_level_0;
-int bumppercent;
-int bumpsize;
-double bumpmult;
+static off_t bump_thresh(
+ int level,
+ off_t size_level_0,
+ int bumppercent,
+ off_t bumpsize,
+ double bumpmult)
{
double bump;
- if(bumppercent != 0 && size_level_0 > 1024) {
- bump = (size_level_0 * bumppercent)/100.0;
+ if ((bumppercent != 0) && (size_level_0 > (off_t)1024)) {
+ bump = ((double)size_level_0 * (double)bumppercent) / 100.0;
}
else {
- bump = bumpsize;
+ bump = (double)bumpsize;
}
while(--level) bump = bump * bumpmult;
- return (long)bump;
+ return (off_t)bump;
}
*
*/
-static void getsize P((am_host_t *hostp));
-static disk_t *lookup_hostdisk P((am_host_t *hp, char *str));
-static void handle_result P((void *datap, pkt_t *pkt, security_handle_t *sech));
+static void getsize(am_host_t *hostp);
+static disk_t *lookup_hostdisk(am_host_t *hp, char *str);
+static void handle_result(void *datap, pkt_t *pkt, security_handle_t *sech);
-static void get_estimates P((void))
+static void get_estimates(void)
{
am_host_t *hostp;
disk_t *dp;
while(!empty(pestq)) {
disk_t *dp = dequeue_disk(&pestq);
-
- if(est(dp)->level[0] != -1 && est(dp)->est_size[0] < 0) {
- if(est(dp)->est_size[0] == -1) {
- log_add(L_WARNING,
- "disk %s:%s, estimate of level %d failed.",
- dp->host->hostname, dp->name,
- est(dp)->level[0]);
+ char * qname = quote_string(dp->name);
+
+ if(est(dp)->level[0] != -1 && est(dp)->est_size[0] < (off_t)0) {
+ if(est(dp)->est_size[0] == (off_t)-1) {
+ log_add(L_WARNING, "disk %s:%s, estimate of level %d failed.",
+ dp->host->hostname, qname, est(dp)->level[0]);
}
else {
log_add(L_WARNING,
"disk %s:%s, estimate of level %d timed out.",
- dp->host->hostname, dp->name,
- est(dp)->level[0]);
+ dp->host->hostname, qname, est(dp)->level[0]);
}
est(dp)->level[0] = -1;
}
- if(est(dp)->level[1] != -1 && est(dp)->est_size[1] < 0) {
- if(est(dp)->est_size[1] == -1) {
+ if(est(dp)->level[1] != -1 && est(dp)->est_size[1] < (off_t)0) {
+ if(est(dp)->est_size[1] == (off_t)-1) {
log_add(L_WARNING,
"disk %s:%s, estimate of level %d failed.",
- dp->host->hostname, dp->name,
- est(dp)->level[1]);
+ dp->host->hostname, qname, est(dp)->level[1]);
}
else {
log_add(L_WARNING,
"disk %s:%s, estimate of level %d timed out.",
- dp->host->hostname, dp->name,
- est(dp)->level[1]);
+ dp->host->hostname, qname, est(dp)->level[1]);
}
est(dp)->level[1] = -1;
}
- if(est(dp)->level[2] != -1 && est(dp)->est_size[2] < 0) {
- if(est(dp)->est_size[2] == -1) {
+ if(est(dp)->level[2] != -1 && est(dp)->est_size[2] < (off_t)0) {
+ if(est(dp)->est_size[2] == (off_t)-1) {
log_add(L_WARNING,
"disk %s:%s, estimate of level %d failed.",
- dp->host->hostname, dp->name,
- est(dp)->level[2]);
+ dp->host->hostname, qname, est(dp)->level[2]);
}
else {
log_add(L_WARNING,
"disk %s:%s, estimate of level %d timed out.",
- dp->host->hostname, dp->name,
- est(dp)->level[2]);
+ dp->host->hostname, qname, est(dp)->level[2]);
}
est(dp)->level[2] = -1;
}
- if((est(dp)->level[0] != -1 && est(dp)->est_size[0] > 0) ||
- (est(dp)->level[1] != -1 && est(dp)->est_size[1] > 0) ||
- (est(dp)->level[2] != -1 && est(dp)->est_size[2] > 0)) {
+ if((est(dp)->level[0] != -1 && est(dp)->est_size[0] > (off_t)0) ||
+ (est(dp)->level[1] != -1 && est(dp)->est_size[1] > (off_t)0) ||
+ (est(dp)->level[2] != -1 && est(dp)->est_size[2] > (off_t)0)) {
enqueue_disk(&estq, dp);
}
else {
- est(dp)->errstr = vstralloc("disk ", dp->name,
+ est(dp)->errstr = vstralloc("disk ", qname,
", all estimate timed out", NULL);
enqueue_disk(&failq, dp);
}
+ amfree(qname);
}
}
-static void getsize(hostp)
-am_host_t *hostp;
+static void getsize(
+ am_host_t *hostp)
{
- char number[NUM_STR_SIZE], *req;
- disk_t *dp;
- int i, estimates, timeout, req_len;
- const security_driver_t *secdrv;
- char *dumper;
- char *calcsize;
+ char number[NUM_STR_SIZE], *req;
+ disk_t * dp;
+ int i;
+ time_t estimates, timeout;
+ size_t req_len;
+ const security_driver_t *secdrv;
+ char * dumper;
+ char * calcsize;
+ char * qname;
assert(hostp->disks != NULL);
fe_req_options_hostname);
int has_maxdumps = am_has_feature(hostp->features,
fe_req_options_maxdumps);
+ int has_config = am_has_feature(hostp->features,
+ fe_req_options_config);
- snprintf(number, sizeof(number), "%d", hostp->maxdumps);
+ snprintf(number, SIZEOF(number), "%d", hostp->maxdumps);
req = vstralloc("SERVICE ", "sendsize", "\n",
"OPTIONS ",
has_features ? "features=" : "",
has_hostname ? "hostname=" : "",
has_hostname ? hostp->hostname : "",
has_hostname ? ";" : "",
+ has_config ? "config=" : "",
+ has_config ? config_name : "",
+ has_config ? ";" : "",
"\n",
NULL);
req_len = strlen(req);
- req_len += 128; /* room for SECURITY ... */
+ req_len += 128; /* room for SECURITY ... */
estimates = 0;
for(dp = hostp->disks; dp != NULL; dp = dp->hostnext) {
char *s = NULL;
- int s_len = 0;
+ size_t s_len = 0;
if(dp->todo == 0) continue;
continue;
}
+ qname = quote_string(dp->name);
if(dp->estimate == ES_CLIENT ||
dp->estimate == ES_CALCSIZE) {
nb_client++;
char *exclude1 = "";
char *exclude2 = "";
char *excludefree = NULL;
+ char *include1 = "";
+ char *include2 = "";
+ char *includefree = NULL;
char spindle[NUM_STR_SIZE];
char level[NUM_STR_SIZE];
int lev = est(dp)->level[i];
if(lev == -1) break;
- snprintf(level, sizeof(level), "%d", lev);
- snprintf(spindle, sizeof(spindle), "%d", dp->spindle);
+ snprintf(level, SIZEOF(level), "%d", lev);
+ snprintf(spindle, SIZEOF(spindle), "%d", dp->spindle);
if(am_has_feature(hostp->features,fe_sendsize_req_options)){
exclude1 = " OPTIONS |";
exclude2 = optionstr(dp, hostp->features, NULL);
+ if ( exclude2 == NULL ) {
+ error("problem with option string, check the dumptype definition.\n");
+ }
excludefree = exclude2;
+ includefree = NULL;
}
else {
if(dp->exclude_file &&
dp->exclude_file->nb_element == 1) {
exclude1 = " exclude-file=";
- exclude2 = dp->exclude_file->first->name;
+ exclude2 =
+ quote_string(dp->exclude_file->first->name);
+ excludefree = exclude2;
}
else if(dp->exclude_list &&
dp->exclude_list->nb_element == 1) {
exclude1 = " exclude-list=";
- exclude2 = dp->exclude_list->first->name;
+ exclude2 =
+ quote_string(dp->exclude_list->first->name);
+ excludefree = exclude2;
+ }
+ if(dp->include_file &&
+ dp->include_file->nb_element == 1) {
+ include1 = " include-file=";
+ include2 =
+ quote_string(dp->include_file->first->name);
+ includefree = include2;
+ }
+ else if(dp->include_list &&
+ dp->include_list->nb_element == 1) {
+ include1 = " include-list=";
+ include2 =
+ quote_string(dp->include_list->first->name);
+ includefree = include2;
}
}
if(dp->estimate == ES_CALCSIZE &&
!am_has_feature(hostp->features, fe_calcsize_estimate)) {
log_add(L_WARNING,"%s:%s does not support CALCSIZE for estimate, using CLIENT.\n",
- hostp->hostname, dp->name);
+ hostp->hostname, qname);
dp->estimate = ES_CLIENT;
}
if(dp->estimate == ES_CLIENT)
l = vstralloc(calcsize,
dumper,
dp->program,
- " ", dp->name,
+ " ", qname,
" ", dp->device ? dp->device : "",
" ", level,
" ", est(dp)->dumpdate[i],
" ", spindle,
" ", exclude1, exclude2,
+ ((includefree != NULL) ? " " : ""),
+ include1, include2,
"\n",
NULL);
strappend(s, l);
s_len += strlen(l);
amfree(l);
+ amfree(includefree);
amfree(excludefree);
}
- /*
- * Allow 2X for err response.
- */
- if(req_len + s_len > MAX_PACKET / 2) {
- amfree(s);
- break;
- }
if (s != NULL) {
estimates += i;
strappend(req, s);
if(lev == -1) break;
if(lev == 0) { /* use latest level 0, should do extrapolation */
- long est_size = 0;
+ off_t est_size = (off_t)0;
int nb_est = 0;
for(j=NB_HISTORY-2;j>=0;j--) {
if(info.history[j].level == 0) {
- if(info.history[j].size < 0) continue;
+ if(info.history[j].size < (off_t)0) continue;
est_size = info.history[j].size;
nb_est++;
}
if(nb_est > 0) {
est(dp)->est_size[i] = est_size;
}
- else if(info.inf[lev].size > 1000) { /* stats */
+ else if(info.inf[lev].size > (off_t)1000) { /* stats */
est(dp)->est_size[i] = info.inf[lev].size;
}
else {
- est(dp)->est_size[i] = 1000000;
+ est(dp)->est_size[i] = (off_t)1000000;
}
}
else if(lev == est(dp)->last_level) {
/* means of all X day at the same level */
#define NB_DAY 30
int nb_day = 0;
- long est_size_day[NB_DAY];
+ off_t est_size_day[NB_DAY];
int nb_est_day[NB_DAY];
for(j=0;j<NB_DAY;j++) {
- est_size_day[j]=0;
+ est_size_day[j]=(off_t)0;
nb_est_day[j]=0;
}
for(j=NB_HISTORY-2;j>=0;j--) {
if(info.history[j].level <= 0) continue;
- if(info.history[j].size < 0) continue;
+ if(info.history[j].size < (off_t)0) continue;
if(info.history[j].level==info.history[j+1].level) {
if(nb_day <NB_DAY-1) nb_day++;
est_size_day[nb_day] += info.history[j].size;
while(nb_day > 0 && nb_est_day[nb_day] == 0) nb_day--;
if(nb_est_day[nb_day] > 0) {
- est(dp)->est_size[i] =
- est_size_day[nb_day] / nb_est_day[nb_day];
+ est(dp)->est_size[i] = est_size_day[nb_day] /
+ (off_t)nb_est_day[nb_day];
}
- else if(info.inf[lev].size > 1000) { /* stats */
+ else if(info.inf[lev].size > (off_t)1000) { /* stats */
est(dp)->est_size[i] = info.inf[lev].size;
}
else {
- est(dp)->est_size[i] = 10000;
+ est(dp)->est_size[i] = (off_t)10000;
}
}
else if(lev == est(dp)->last_level + 1) {
/* means of all first day at a new level */
- long est_size = 0;
+ off_t est_size = (off_t)0;
int nb_est = 0;
for(j=NB_HISTORY-2;j>=0;j--) {
if(info.history[j].level <= 0) continue;
- if(info.history[j].size < 0) continue;
+ if(info.history[j].size < (off_t)0) continue;
if(info.history[j].level == info.history[j+1].level + 1 ) {
est_size += info.history[j].size;
nb_est++;
}
}
if(nb_est > 0) {
- est(dp)->est_size[i] = est_size / nb_est;
+ est(dp)->est_size[i] = est_size / (off_t)nb_est;
}
- else if(info.inf[lev].size > 1000) { /* stats */
+ else if(info.inf[lev].size > (off_t)1000) { /* stats */
est(dp)->est_size[i] = info.inf[lev].size;
}
else {
- est(dp)->est_size[i] = 100000;
+ est(dp)->est_size[i] = (off_t)100000;
}
}
- }
+ }
fprintf(stderr,"%s time %s: got result for host %s disk %s:",
get_pname(), walltime_str(curclock()),
- dp->host->hostname, dp->name);
- fprintf(stderr," %d -> %ldK, %d -> %ldK, %d -> %ldK\n",
- est(dp)->level[0], est(dp)->est_size[0],
- est(dp)->level[1], est(dp)->est_size[1],
- est(dp)->level[2], est(dp)->est_size[2]);
+ dp->host->hostname, qname);
+ fprintf(stderr," %d -> " OFF_T_FMT "K, %d -> " OFF_T_FMT "K, %d -> " OFF_T_FMT "K\n",
+ est(dp)->level[0], (OFF_T_FMT_TYPE)est(dp)->est_size[0],
+ est(dp)->level[1], (OFF_T_FMT_TYPE)est(dp)->est_size[1],
+ est(dp)->level[2], (OFF_T_FMT_TYPE)est(dp)->est_size[2]);
est(dp)->state = DISK_DONE;
remove_disk(&startq, dp);
enqueue_disk(&estq, dp);
}
+ amfree(qname);
}
if(estimates == 0) {
* We use ctimeout for the "noop" request because it should be
* very fast and etimeout has other side effects.
*/
- timeout = getconf_int(CNF_CTIMEOUT);
+ timeout = getconf_time(CNF_CTIMEOUT);
}
secdrv = security_getdriver(hostp->disks->security_driver);
if (secdrv == NULL) {
error("could not find security driver '%s' for host '%s'",
hostp->disks->security_driver, hostp->hostname);
+ /*NOTREACHED*/
}
hostp->up = HOST_ACTIVE;
}
}
- protocol_sendreq(hostp->hostname, secdrv, generic_get_security_conf,
+ protocol_sendreq(hostp->hostname, secdrv, amhost_get_security_conf,
req, timeout, handle_result, hostp);
amfree(req);
}
-static disk_t *lookup_hostdisk(hp, str)
-am_host_t *hp;
-char *str;
+static disk_t *lookup_hostdisk(
+ /*@keep@*/ am_host_t *hp,
+ char *str)
{
disk_t *dp;
}
-static void handle_result(datap, pkt, sech)
-void *datap;
-pkt_t *pkt;
-security_handle_t *sech;
+static void handle_result(
+ void *datap,
+ pkt_t *pkt,
+ security_handle_t *sech)
{
int level, i;
- long size;
+ off_t size;
disk_t *dp;
am_host_t *hostp;
char *msgdisk=NULL, *msgdisk_undo=NULL, msgdisk_undo_ch = '\0';
char *line;
int ch;
int tch;
+ char *qname;
+ char *disk;
hostp = (am_host_t *)datap;
hostp->up = HOST_READY;
}
if (pkt->type == P_NAK) {
#define sc "ERROR "
- if(strncmp(pkt->body, sc, sizeof(sc)-1) == 0) {
- s = pkt->body + sizeof(sc)-1;
+ if(strncmp(pkt->body, sc, SIZEOF(sc)-1) == 0) {
+ s = pkt->body + SIZEOF(sc)-1;
ch = *s++;
#undef sc
} else {
*s = '\0';
}
if (strcmp(remoterr, "unknown service: noop") != 0
- && strcmp(remoterr, "noop: invalid service") != 0) {
+ && strcmp(remoterr, "noop: invalid service") != 0) {
errbuf = vstralloc(hostp->hostname, " NAK: ", remoterr, NULL);
if(s) *s = '\n';
goto error_return;
ch = *s++;
while(ch) {
line = s - 1;
- skip_line(s, ch);
- if (s[-2] == '\n') {
- s[-2] = '\0';
- }
#define sc "OPTIONS "
- if(strncmp(line, sc, sizeof(sc)-1) == 0) {
+ if(strncmp(line, sc, SIZEOF(sc)-1) == 0) {
#undef sc
#define sc "features="
t = strstr(line, sc);
if(t != NULL && (isspace((int)t[-1]) || t[-1] == ';')) {
- t += sizeof(sc)-1;
+ t += SIZEOF(sc)-1;
#undef sc
am_release_feature_set(hostp->features);
if((hostp->features = am_string_to_feature(t)) == NULL) {
goto error_return;
}
}
-
+ skip_quoted_line(s, ch);
continue;
}
#define sc "ERROR "
- if(strncmp(line, sc, sizeof(sc)-1) == 0) {
- t = line + sizeof(sc)-1;
+ if(strncmp(line, sc, SIZEOF(sc) - 1) == 0) {
+ t = line + SIZEOF(sc) - 1;
tch = t[-1];
#undef sc
if (tch == '\n') {
t[-1] = '\0';
}
+
/*
* If the "error" is that the "noop" service is unknown, it
* just means the client is "old" (does not support the servie).
if(hostp->features == NULL
&& pkt->type == P_NAK
&& (strcmp(t - 1, "unknown service: noop") == 0
- || strcmp(t - 1, "noop: invalid service") == 0)) {
+ || strcmp(t - 1, "noop: invalid service") == 0)) {
continue;
- } else {
- errbuf = vstralloc(hostp->hostname,
- (pkt->type == P_NAK) ? "NAK " : "",
- ": ",
- fp,
- NULL);
- goto error_return;
}
+ errbuf = vstralloc(hostp->hostname,
+ (pkt->type == P_NAK) ? "NAK " : "",
+ ": ",
+ fp,
+ NULL);
+ goto error_return;
}
msgdisk = t = line;
- tch = *t++;
- skip_non_whitespace(t, tch);
+ tch = *(t++);
+ skip_quoted_string(t, tch);
msgdisk_undo = t - 1;
msgdisk_undo_ch = *msgdisk_undo;
*msgdisk_undo = '\0';
-
+ disk = unquote_string(msgdisk);
skip_whitespace(t, tch);
- if (sscanf(t - 1, "%d SIZE %ld", &level, &size) != 2) {
+ s = t;
+ ch = tch;
+
+ if (sscanf(t - 1, "%d SIZE " OFF_T_FMT , &level,
+ (OFF_T_FMT_TYPE *)&size) != 2) {
goto bad_msg;
}
-
- dp = lookup_hostdisk(hostp, msgdisk);
+ dp = lookup_hostdisk(hostp, disk);
+ amfree(disk);
*msgdisk_undo = msgdisk_undo_ch; /* for error message */
msgdisk_undo = NULL;
}
est(dp)->got_estimate++;
}
+ skip_quoted_line(s, ch);
}
if(hostp->up == HOST_READY && hostp->features == NULL) {
hostp->features = am_set_default_feature_set();
}
+ security_close_connection(sech, hostp->hostname);
/* XXX what about disks that only got some estimates... do we care? */
/* XXX amanda 2.1 treated that case as a bad msg */
if(est(dp)->level[0] == -1) continue; /* ignore this disk */
+ qname = quote_string(dp->name);
if(pkt->type == P_PREP) {
fprintf(stderr,"%s: time %s: got partial result for host %s disk %s:",
get_pname(), walltime_str(curclock()),
- dp->host->hostname, dp->name);
- fprintf(stderr," %d -> %ldK, %d -> %ldK, %d -> %ldK\n",
- est(dp)->level[0], est(dp)->est_size[0],
- est(dp)->level[1], est(dp)->est_size[1],
- est(dp)->level[2], est(dp)->est_size[2]);
+ dp->host->hostname, qname);
+ fprintf(stderr," %d -> " OFF_T_FMT "K, %d -> " OFF_T_FMT "K, %d -> " OFF_T_FMT "K\n",
+ est(dp)->level[0], (OFF_T_FMT_TYPE)est(dp)->est_size[0],
+ est(dp)->level[1], (OFF_T_FMT_TYPE)est(dp)->est_size[1],
+ est(dp)->level[2], (OFF_T_FMT_TYPE)est(dp)->est_size[2]);
enqueue_disk(&pestq, dp);
}
else if(pkt->type == P_REP) {
fprintf(stderr,"%s: time %s: got result for host %s disk %s:",
get_pname(), walltime_str(curclock()),
- dp->host->hostname, dp->name);
- fprintf(stderr," %d -> %ldK, %d -> %ldK, %d -> %ldK\n",
- est(dp)->level[0], est(dp)->est_size[0],
- est(dp)->level[1], est(dp)->est_size[1],
- est(dp)->level[2], est(dp)->est_size[2]);
- if((est(dp)->level[0] != -1 && est(dp)->est_size[0] > 0) ||
- (est(dp)->level[1] != -1 && est(dp)->est_size[1] > 0) ||
- (est(dp)->level[2] != -1 && est(dp)->est_size[2] > 0)) {
-
- if(est(dp)->level[2] != -1 && est(dp)->est_size[2] < 0) {
+ dp->host->hostname, qname);
+ fprintf(stderr," %d -> " OFF_T_FMT "K, %d -> " OFF_T_FMT "K, %d -> " OFF_T_FMT "K\n",
+ est(dp)->level[0], (OFF_T_FMT_TYPE)est(dp)->est_size[0],
+ est(dp)->level[1], (OFF_T_FMT_TYPE)est(dp)->est_size[1],
+ est(dp)->level[2], (OFF_T_FMT_TYPE)est(dp)->est_size[2]);
+ if((est(dp)->level[0] != -1 && est(dp)->est_size[0] > (off_t)0) ||
+ (est(dp)->level[1] != -1 && est(dp)->est_size[1] > (off_t)0) ||
+ (est(dp)->level[2] != -1 && est(dp)->est_size[2] > (off_t)0)) {
+
+ if(est(dp)->level[2] != -1 && est(dp)->est_size[2] < (off_t)0) {
log_add(L_WARNING,
"disk %s:%s, estimate of level %d failed.",
- dp->host->hostname, dp->name,
- est(dp)->level[2]);
+ dp->host->hostname, qname, est(dp)->level[2]);
est(dp)->level[2] = -1;
}
- if(est(dp)->level[1] != -1 && est(dp)->est_size[1] < 0) {
+ if(est(dp)->level[1] != -1 && est(dp)->est_size[1] < (off_t)0) {
log_add(L_WARNING,
"disk %s:%s, estimate of level %d failed.",
- dp->host->hostname, dp->name,
+ dp->host->hostname, qname,
est(dp)->level[1]);
est(dp)->level[1] = -1;
}
- if(est(dp)->level[0] != -1 && est(dp)->est_size[0] < 0) {
+ if(est(dp)->level[0] != -1 && est(dp)->est_size[0] < (off_t)0) {
log_add(L_WARNING,
"disk %s:%s, estimate of level %d failed.",
- dp->host->hostname, dp->name,
- est(dp)->level[0]);
+ dp->host->hostname, qname, est(dp)->level[0]);
est(dp)->level[0] = -1;
}
enqueue_disk(&estq, dp);
else {
enqueue_disk(&failq, dp);
if(est(dp)->got_estimate) {
- est(dp)->errstr = vstralloc("disk ", dp->name,
+ est(dp)->errstr = vstralloc("disk ", qname,
", all estimate failed", NULL);
}
else {
fprintf(stderr, "error result for host %s disk %s: missing estimate\n",
- dp->host->hostname, dp->name);
- est(dp)->errstr = vstralloc("missing result for ", dp->name,
+ dp->host->hostname, qname);
+ est(dp)->errstr = vstralloc("missing result for ", qname,
" in ", dp->host->hostname,
" response",
NULL);
}
}
}
+ amfree(qname);
}
getsize(hostp);
return;
goto error_return;
bad_msg:
-
if(msgdisk_undo) {
*msgdisk_undo = msgdisk_undo_ch;
msgdisk_undo = NULL;
}
fprintf(stderr,"got a bad message, stopped at:\n");
+ /*@ignore@*/
fprintf(stderr,"----\n%s----\n\n", line);
errbuf = stralloc2("badly formatted response from ", hostp->hostname);
- /* fall through to ... */
+ /*@end@*/
error_return:
-
i = 0;
for(dp = hostp->disks; dp != NULL; dp = dp->hostnext) {
if(est(dp)->state != DISK_ACTIVE) continue;
+ qname = quote_string(dp->name);
est(dp)->state = DISK_DONE;
if(est(dp)->state == DISK_ACTIVE) {
est(dp)->state = DISK_DONE;
est(dp)->errstr = stralloc(errbuf);
fprintf(stderr, "error result for host %s disk %s: %s\n",
- dp->host->hostname, dp->name, errbuf);
+ dp->host->hostname, qname, errbuf);
}
+ amfree(qname);
}
if(i == 0) {
/*
*
*/
-static int schedule_order P((disk_t *a, disk_t *b)); /* subroutines */
-static int pick_inclevel P((disk_t *dp));
+static int schedule_order(disk_t *a, disk_t *b); /* subroutines */
+static int pick_inclevel(disk_t *dp);
-static void analyze_estimate(dp)
-disk_t *dp;
+static void analyze_estimate(
+ disk_t *dp)
{
est_t *ep;
info_t info;
int have_info = 0;
+ char *qname = quote_string(dp->name);
ep = est(dp);
fprintf(stderr, "pondering %s:%s... ",
- dp->host->hostname, dp->name);
+ dp->host->hostname, qname);
fprintf(stderr, "next_level0 %d last_level %d ",
ep->next_level0, ep->last_level);
}
ep->degr_level = -1;
- ep->degr_size = -1;
+ ep->degr_nsize = (off_t)-1;
+ ep->degr_csize = (off_t)-1;
- if(ep->next_level0 <= 0
- || (have_info && ep->last_level == 0 && (info.command & FORCE_NO_BUMP))) {
+ if(ep->next_level0 <= 0 || (have_info && ep->last_level == 0
+ && (info.command & FORCE_NO_BUMP))) {
if(ep->next_level0 <= 0) {
fprintf(stderr,"(due for level 0) ");
}
ep->dump_level = 0;
- ep->dump_size = est_tape_size(dp, 0);
- if(ep->dump_size <= 0) {
+ ep->dump_nsize = est_size(dp, 0);
+ ep->dump_csize = est_tape_size(dp, 0);
+ if(ep->dump_csize <= (off_t)0) {
fprintf(stderr,
"(no estimate for level 0, picking an incr level)\n");
ep->dump_level = pick_inclevel(dp);
- ep->dump_size = est_tape_size(dp, ep->dump_level);
+ ep->dump_nsize = est_size(dp, ep->dump_level);
+ ep->dump_csize = est_tape_size(dp, ep->dump_level);
- if(ep->dump_size == -1) {
+ if(ep->dump_nsize == (off_t)-1) {
ep->dump_level = ep->dump_level + 1;
- ep->dump_size = est_tape_size(dp, ep->dump_level);
+ ep->dump_nsize = est_size(dp, ep->dump_level);
+ ep->dump_csize = est_tape_size(dp, ep->dump_level);
}
}
else {
- total_lev0 += (double) ep->dump_size;
+ total_lev0 += (double) ep->dump_csize;
if(ep->last_level == -1 || dp->skip_incr) {
fprintf(stderr,"(%s disk, can't switch to degraded mode)\n",
dp->skip_incr? "skip-incr":"new");
ep->degr_level = -1;
- ep->degr_size = -1;
+ ep->degr_nsize = (off_t)-1;
+ ep->degr_csize = (off_t)-1;
}
else {
/* fill in degraded mode info */
fprintf(stderr,"(picking inclevel for degraded mode)");
ep->degr_level = pick_inclevel(dp);
- ep->degr_size = est_tape_size(dp, ep->degr_level);
- if(ep->degr_size == -1) {
+ ep->degr_nsize = est_size(dp, ep->degr_level);
+ ep->degr_csize = est_tape_size(dp, ep->degr_level);
+ if(ep->degr_csize == (off_t)-1) {
ep->degr_level = ep->degr_level + 1;
- ep->degr_size = est_tape_size(dp, ep->degr_level);
+ ep->degr_nsize = est_size(dp, ep->degr_level);
+ ep->degr_csize = est_tape_size(dp, ep->degr_level);
}
- if(ep->degr_size == -1) {
+ if(ep->degr_csize == (off_t)-1) {
fprintf(stderr,"(no inc estimate)");
ep->degr_level = -1;
}
fprintf(stderr,"(not due for a full dump, picking an incr level)\n");
/* XXX - if this returns -1 may be we should force a total? */
ep->dump_level = pick_inclevel(dp);
- ep->dump_size = est_tape_size(dp, ep->dump_level);
+ ep->dump_nsize = est_size(dp, ep->dump_level);
+ ep->dump_csize = est_tape_size(dp, ep->dump_level);
- if(ep->dump_size == -1) {
+ if(ep->dump_csize == (off_t)-1) {
ep->dump_level = ep->last_level;
- ep->dump_size = est_tape_size(dp, ep->dump_level);
+ ep->dump_nsize = est_size(dp, ep->dump_level);
+ ep->dump_csize = est_tape_size(dp, ep->dump_level);
}
- if(ep->dump_size == -1) {
+ if(ep->dump_csize == (off_t)-1) {
ep->dump_level = ep->last_level + 1;
- ep->dump_size = est_tape_size(dp, ep->dump_level);
+ ep->dump_nsize = est_size(dp, ep->dump_level);
+ ep->dump_csize = est_tape_size(dp, ep->dump_level);
}
- if(ep->dump_size == -1) {
+ if(ep->dump_csize == (off_t)-1) {
ep->dump_level = 0;
- ep->dump_size = est_tape_size(dp, ep->dump_level);
+ ep->dump_nsize = est_size(dp, ep->dump_level);
+ ep->dump_csize = est_tape_size(dp, ep->dump_level);
}
}
- fprintf(stderr," curr level %d size %ld ", ep->dump_level, ep->dump_size);
+ fprintf(stderr," curr level %d nsize " OFF_T_FMT " csize " OFF_T_FMT " ",
+ ep->dump_level, (OFF_T_FMT_TYPE)ep->dump_nsize,
+ (OFF_T_FMT_TYPE)ep->dump_csize);
insert_disk(&schedq, dp, schedule_order);
- total_size += tt_blocksize_kb + ep->dump_size + tape_mark;
+ total_size += (off_t)tt_blocksize_kb + ep->dump_csize + tape_mark;
/* update the balanced size */
if(!(dp->skip_full || dp->strategy == DS_NOFULL ||
dp->strategy == DS_INCRONLY)) {
- long lev0size;
+ off_t lev0size;
lev0size = est_tape_size(dp, 0);
- if(lev0size == -1) lev0size = ep->last_lev0size;
+ if(lev0size == (off_t)-1) lev0size = ep->last_lev0size;
- balanced_size += lev0size / runs_per_cycle;
+ balanced_size += (double)(lev0size / (off_t)runs_per_cycle);
}
- fprintf(stderr,"total size " AM64_FMT " total_lev0 %1.0f balanced-lev0size %1.0f\n",
- total_size, total_lev0, balanced_size);
+ fprintf(stderr,"total size " OFF_T_FMT " total_lev0 %1.0lf balanced-lev0size %1.0lf\n",
+ (OFF_T_FMT_TYPE)total_size, total_lev0, balanced_size);
+ amfree(qname);
}
-static void handle_failed(dp)
-disk_t *dp;
+static void handle_failed(
+ disk_t *dp)
{
char *errstr;
+ char *qname = quote_string(dp->name);
/*
* From George Scott <George.Scott@cc.monash.edu.au>:
#ifdef old_behavior
if(est(dp)->last_level != -1) {
log_add(L_WARNING,
- "Could not get estimate for %s:%s, using historical data.",
- dp->host->hostname, dp->name);
+ "Could not get estimate for %s:%s, using historical data.",
+ dp->host->hostname, qname);
analyze_estimate(dp);
+ amfree(qname);
return;
}
#endif
errstr = est(dp)->errstr? est(dp)->errstr : "hmm, no error indicator!";
fprintf(stderr, "%s: FAILED %s %s %s 0 [%s]\n",
- get_pname(), dp->host->hostname, dp->name, datestamp, errstr);
+ get_pname(), dp->host->hostname, qname, planner_timestamp, errstr);
- log_add(L_FAIL, "%s %s %s 0 [%s]", dp->host->hostname, dp->name,
- datestamp, errstr);
+ log_add(L_FAIL, "%s %s %s 0 [%s]", dp->host->hostname, qname,
+ planner_timestamp, errstr);
+ amfree(qname);
/* XXX - memory leak with *dp */
}
-static int schedule_order(a, b)
-disk_t *a, *b;
/*
* insert-sort by decreasing priority, then
* by decreasing size within priority levels.
*/
+
+static int schedule_order(
+ disk_t *a,
+ disk_t *b)
{
int diff;
- long ldiff;
+ off_t ldiff;
diff = est(b)->dump_priority - est(a)->dump_priority;
if(diff != 0) return diff;
- ldiff = est(b)->dump_size - est(a)->dump_size;
- if(ldiff < 0) return -1; /* XXX - there has to be a better way to dothis */
- if(ldiff > 0) return 1;
+ ldiff = est(b)->dump_csize - est(a)->dump_csize;
+ if(ldiff < (off_t)0) return -1; /* XXX - there has to be a better way to dothis */
+ if(ldiff > (off_t)0) return 1;
return 0;
}
-static int pick_inclevel(dp)
-disk_t *dp;
+static int pick_inclevel(
+ disk_t *dp)
{
int base_level, bump_level;
- long base_size, bump_size;
- long thresh;
+ off_t base_size, bump_size;
+ off_t thresh;
+ char *qname;
base_level = est(dp)->last_level;
base_size = est_size(dp, base_level);
/* if we didn't get an estimate, we can't do an inc */
- if(base_size == -1) {
+ if(base_size == (off_t)-1) {
base_size = est_size(dp, base_level+1);
- if(base_size > 0) /* FORCE_BUMP */
+ if(base_size > (off_t)0) /* FORCE_BUMP */
return base_level+1;
fprintf(stderr," picklev: no estimate for level %d, so no incs\n", base_level);
return base_level;
thresh = bump_thresh(base_level, est_size(dp, 0), dp->bumppercent, dp->bumpsize, dp->bumpmult);
fprintf(stderr,
- " pick: size %ld level %d days %d (thresh %ldK, %d days)\n",
- base_size, base_level, est(dp)->level_days,
- thresh, dp->bumpdays);
+ " pick: size " OFF_T_FMT " level %d days %d (thresh " OFF_T_FMT "K, %d days)\n",
+ (OFF_T_FMT_TYPE)base_size, base_level, est(dp)->level_days,
+ (OFF_T_FMT_TYPE)thresh, dp->bumpdays);
if(base_level == 9
|| est(dp)->level_days < dp->bumpdays
bump_level = base_level + 1;
bump_size = est_size(dp, bump_level);
- if(bump_size == -1) return base_level;
+ if(bump_size == (off_t)-1) return base_level;
- fprintf(stderr, " pick: next size %ld... ", bump_size);
+ fprintf(stderr, " pick: next size " OFF_T_FMT "... ",
+ (OFF_T_FMT_TYPE)bump_size);
if(base_size - bump_size < thresh) {
fprintf(stderr, "not bumped\n");
return base_level;
}
+ qname = quote_string(dp->name);
fprintf(stderr, "BUMPED\n");
log_add(L_INFO, "Incremental of %s:%s bumped to level %d.",
- dp->host->hostname, dp->name, bump_level);
+ dp->host->hostname, qname, bump_level);
+ amfree(qname);
return bump_level;
}
** more balanced cycle.
*/
-static void delay_one_dump P((disk_t *dp, int delete, ...));
+static void delay_one_dump(disk_t *dp, int delete, ...);
+static int promote_highest_priority_incremental(void);
+static int promote_hills(void);
-static void delay_dumps P((void))
/* delay any dumps that will not fit */
+static void delay_dumps(void)
{
- disk_t *dp, *ndp, *preserve;
- bi_t *bi, *nbi;
- am64_t new_total; /* New total_size */
- char est_kb[20]; /* Text formatted dump size */
- int nb_forced_level_0;
- info_t info;
- int delete;
- char *message;
+ disk_t * dp;
+ disk_t * ndp;
+ disk_t * preserve;
+ bi_t * bi;
+ bi_t * nbi;
+ off_t new_total; /* New total_size */
+ char est_kb[20]; /* Text formatted dump size */
+ int nb_forced_level_0;
+ info_t info;
+ int delete;
+ char * message;
+ off_t full_size;
biq.head = biq.tail = NULL;
for(dp = schedq.head; dp != NULL; dp = ndp) {
int avail_tapes = 1;
- if (dp->tape_splitsize > 0)
+ if (dp->tape_splitsize > (off_t)0)
avail_tapes = conf_runtapes;
ndp = dp->next; /* remove_disk zaps this */
- if (est(dp)->dump_size == -1 ||
- est(dp)->dump_size <= tape->length * avail_tapes) {
+ full_size = est_tape_size(dp, 0);
+ if (full_size > tapetype_get_length(tape) * (off_t)avail_tapes) {
+ char *qname = quote_string(dp->name);
+ log_add(L_WARNING, "disk %s:%s, full dump (" OFF_T_FMT
+ "KB) will be larger than available tape space",
+ dp->host->hostname, qname,
+ (OFF_T_FMT_TYPE)full_size);
+ amfree(qname);
+ }
+
+ if (est(dp)->dump_csize == (off_t)-1 ||
+ est(dp)->dump_csize <= tapetype_get_length(tape) * (off_t)avail_tapes) {
continue;
}
- /* Format dumpsize for messages */
- snprintf(est_kb, 20, "%ld KB,", est(dp)->dump_size);
+ /* Format dumpsize for messages */
+ snprintf(est_kb, 20, OFF_T_FMT " KB,",
+ (OFF_T_FMT_TYPE)est(dp)->dump_csize);
if(est(dp)->dump_level == 0) {
if(dp->skip_incr) {
delete = 1;
message = "but no incremental estimate";
}
- else if (est(dp)->degr_size > tape->length) {
+ else if (est(dp)->degr_csize > tapetype_get_length(tape)) {
delete = 1;
message = "incremental dump also larger than tape";
}
delete = 1;
message = "skipping incremental";
}
- delay_one_dump(dp, delete, "dump larger than available tape space,", est_kb,
- message, NULL);
+ delay_one_dump(dp, delete, "dump larger than available tape space,",
+ est_kb, message, NULL);
}
/*
if(dp != preserve) {
- /* Format dumpsize for messages */
- snprintf(est_kb, 20, "%ld KB,", est(dp)->dump_size);
+ /* Format dumpsize for messages */
+ snprintf(est_kb, 20, OFF_T_FMT " KB,",
+ (OFF_T_FMT_TYPE)est(dp)->dump_csize);
if(dp->skip_incr) {
delete = 1;
if(est(dp)->dump_level == 0 && dp != preserve) {
/* Format dumpsize for messages */
- snprintf(est_kb, 20, "%ld KB,", est(dp)->dump_size);
+ snprintf(est_kb, 20, OFF_T_FMT " KB,",
+ (OFF_T_FMT_TYPE)est(dp)->dump_csize);
if(dp->skip_incr) {
delete = 1;
if(est(dp)->dump_level != 0) {
- /* Format dumpsize for messages */
- snprintf(est_kb, 20, "%ld KB,", est(dp)->dump_size);
+ /* Format dumpsize for messages */
+ snprintf(est_kb, 20, OFF_T_FMT " KB,",
+ (OFF_T_FMT_TYPE)est(dp)->dump_csize);
delay_one_dump(dp, 1,
"dumps way too big,",
** in but why complicate the code?
*/
- for(bi = biq.tail; bi != NULL; bi = nbi) {
+/*@i@*/ for(bi = biq.tail; bi != NULL; bi = nbi) {
int avail_tapes = 1;
nbi = bi->prev;
dp = bi->dp;
- if(dp->tape_splitsize > 0) avail_tapes = conf_runtapes;
-
- if(bi->deleted)
- new_total = total_size + tt_blocksize_kb + bi->size + tape_mark;
- else
- new_total = total_size - est(dp)->dump_size + bi->size;
+ if(dp->tape_splitsize > (off_t)0)
+ avail_tapes = conf_runtapes;
- if(new_total <= tape_length && bi->size < tape->length * avail_tapes) {
+ if(bi->deleted) {
+ new_total = total_size + (off_t)tt_blocksize_kb +
+ bi->csize + (off_t)tape_mark;
+ } else {
+ new_total = total_size - est(dp)->dump_csize + bi->csize;
+ }
+ if((new_total <= tape_length) &&
+ (bi->csize < (tapetype_get_length(tape) * (off_t)avail_tapes))) {
/* reinstate it */
total_size = new_total;
if(bi->deleted) {
if(bi->level == 0) {
- total_lev0 += (double) bi->size;
+ total_lev0 += (double) bi->csize;
}
insert_disk(&schedq, dp, schedule_order);
}
else {
est(dp)->dump_level = bi->level;
- est(dp)->dump_size = bi->size;
+ est(dp)->dump_nsize = bi->nsize;
+ est(dp)->dump_csize = bi->csize;
}
/* Keep it clean */
biq.head = bi->next;
else
(bi->prev)->next = bi->next;
+
amfree(bi->errstr);
amfree(bi);
}
** now.
*/
- for(bi = biq.head; bi != NULL; bi = nbi) {
+/*@i@*/ for(bi = biq.head; bi != NULL; bi = nbi) {
nbi = bi->next;
-
if(bi->deleted) {
fprintf(stderr, "%s: FAILED %s\n", get_pname(), bi->errstr);
log_add(L_FAIL, "%s", bi->errstr);
bi->errstr, est(dp)->dump_level);
log_add(L_INFO, "%s", bi->errstr);
}
-
- /* Clean up - dont be too fancy! */
+ /*@ignore@*/
amfree(bi->errstr);
amfree(bi);
+ /*@end@*/
}
- fprintf(stderr, " delay: Total size now " AM64_FMT ".\n", total_size);
+ fprintf(stderr, " delay: Total size now " OFF_T_FMT ".\n",
+ (OFF_T_FMT_TYPE)total_size);
return;
}
* Remove a dump or modify it from full to incremental.
* Keep track of it on the bi q in case we can add it back later.
*/
-arglist_function1(static void delay_one_dump,
- disk_t *, dp,
- int, delete)
+arglist_function1(
+ static void delay_one_dump,
+ disk_t *, dp,
+ int, delete)
{
bi_t *bi;
va_list argp;
char level_str[NUM_STR_SIZE];
char *sep;
char *next;
+ char *qname = quote_string(dp->name);
arglist_start(argp, delete);
- total_size -= tt_blocksize_kb + est(dp)->dump_size + tape_mark;
+ total_size -= (off_t)tt_blocksize_kb + est(dp)->dump_csize + (off_t)tape_mark;
if(est(dp)->dump_level == 0) {
- total_lev0 -= (double) est(dp)->dump_size;
+ total_lev0 -= (double) est(dp)->dump_csize;
}
- bi = alloc(sizeof(bi_t));
+ bi = alloc(SIZEOF(bi_t));
bi->next = NULL;
bi->prev = biq.tail;
if(biq.tail == NULL)
bi->deleted = delete;
bi->dp = dp;
bi->level = est(dp)->dump_level;
- bi->size = est(dp)->dump_size;
+ bi->nsize = est(dp)->dump_nsize;
+ bi->csize = est(dp)->dump_csize;
- snprintf(level_str, sizeof(level_str), "%d", est(dp)->dump_level);
+ snprintf(level_str, SIZEOF(level_str), "%d", est(dp)->dump_level);
bi->errstr = vstralloc(dp->host->hostname,
- " ", dp->name,
- " ", datestamp ? datestamp : "?",
+ " ", qname,
+ " ", planner_timestamp ? planner_timestamp : "?",
" ", level_str,
NULL);
sep = " [";
remove_disk(&schedq, dp);
} else {
est(dp)->dump_level = est(dp)->degr_level;
- est(dp)->dump_size = est(dp)->degr_size;
- total_size += tt_blocksize_kb + est(dp)->dump_size + tape_mark;
+ est(dp)->dump_nsize = est(dp)->degr_nsize;
+ est(dp)->dump_csize = est(dp)->degr_csize;
+ total_size += (off_t)tt_blocksize_kb + est(dp)->dump_csize + (off_t)tape_mark;
}
-
+ amfree(qname);
return;
}
-static int promote_highest_priority_incremental P((void))
+static int promote_highest_priority_incremental(void)
{
disk_t *dp, *dp1, *dp_promote;
- long new_size, new_total, new_lev0;
+ off_t new_size, new_total, new_lev0;
int check_days;
int nb_today, nb_same_day, nb_today2;
int nb_disk_today, nb_disk_same_day;
+ char *qname;
/*
* return 1 if did so; must update total_size correctly; must not
est(dp)->promote = -1000;
- if(est_size(dp,0) <= 0)
+ if(est_size(dp,0) <= (off_t)0)
continue;
if(est(dp)->next_level0 <= 0)
continue;
new_size = est_tape_size(dp, 0);
- new_total = total_size - est(dp)->dump_size + new_size;
- new_lev0 = total_lev0 + new_size;
+ new_total = total_size - est(dp)->dump_csize + new_size;
+ new_lev0 = (off_t)total_lev0 + new_size;
nb_today = 0;
nb_same_day = 0;
nb_disk_today = 0;
nb_disk_same_day = 0;
- for(dp1 = schedq.head; dp1 != NULL; dp1 = dp1->next) {
+ for(dp1 = schedq.head; dp1 != NULL; dp1 = dp1->next) {
if(est(dp1)->dump_level == 0)
nb_disk_today++;
else if(est(dp1)->next_level0 == est(dp)->next_level0)
}
/* do not promote if overflow tape */
- if(new_total > tape_length) continue;
+ if(new_total > tape_length)
+ continue;
/* do not promote if overflow balanced size and something today */
/* promote if nothing today */
- if(new_lev0 > balanced_size+balance_threshold && nb_disk_today > 0)
+ if((new_lev0 > (off_t)(balanced_size + balance_threshold)) &&
+ (nb_disk_today > 0))
continue;
/* do not promote if only one disk due that day and nothing today */
- if(nb_disk_same_day == 1 && nb_disk_today == 0) continue;
+ if(nb_disk_same_day == 1 && nb_disk_today == 0)
+ continue;
nb_today2 = nb_today*nb_today;
- if(nb_today == 0 && nb_same_day > 1) nb_same_day++;
+ if(nb_today == 0 && nb_same_day > 1)
+ nb_same_day++;
if(nb_same_day >= nb_today2) {
est(dp)->promote = ((nb_same_day - nb_today2)*(nb_same_day - nb_today2)) +
conf_dumpcycle - est(dp)->next_level0;
}
- if(!dp_promote || est(dp_promote)->promote < est(dp)->promote) {
+ qname = quote_string(dp->name);
+ if(!dp_promote || est(dp_promote)->promote < est(dp)->promote) {
dp_promote = dp;
fprintf(stderr," try %s:%s %d %d %d = %d\n",
- dp->host->hostname, dp->name, nb_same_day, nb_today, est(dp)->next_level0, est(dp)->promote);
+ dp->host->hostname, qname, nb_same_day, nb_today, est(dp)->next_level0, est(dp)->promote);
}
- else {
+ else {
fprintf(stderr,"no try %s:%s %d %d %d = %d\n",
- dp->host->hostname, dp->name, nb_same_day, nb_today, est(dp)->next_level0, est(dp)->promote);
+ dp->host->hostname, qname, nb_same_day, nb_today, est(dp)->next_level0, est(dp)->promote);
}
+ amfree(qname);
}
if(dp_promote) {
dp = dp_promote;
+ qname = quote_string(dp->name);
new_size = est_tape_size(dp, 0);
- new_total = total_size - est(dp)->dump_size + new_size;
- new_lev0 = total_lev0 + new_size;
+ new_total = total_size - est(dp)->dump_csize + new_size;
+ new_lev0 = (off_t)total_lev0 + new_size;
total_size = new_total;
- total_lev0 = new_lev0;
+ total_lev0 = (double)new_lev0;
check_days = est(dp)->next_level0;
est(dp)->degr_level = est(dp)->dump_level;
- est(dp)->degr_size = est(dp)->dump_size;
+ est(dp)->degr_nsize = est(dp)->dump_nsize;
+ est(dp)->degr_csize = est(dp)->dump_csize;
est(dp)->dump_level = 0;
- est(dp)->dump_size = new_size;
+ est(dp)->dump_nsize = est_size(dp, 0);
+ est(dp)->dump_csize = new_size;
est(dp)->next_level0 = 0;
fprintf(stderr,
- " promote: moving %s:%s up, total_lev0 %1.0f, total_size " AM64_FMT "\n",
- dp->host->hostname, dp->name,
- total_lev0, total_size);
+ " promote: moving %s:%s up, total_lev0 %1.0lf, total_size " OFF_T_FMT "\n",
+ dp->host->hostname, qname,
+ total_lev0, (OFF_T_FMT_TYPE)total_size);
log_add(L_INFO,
"Full dump of %s:%s promoted from %d day%s ahead.",
- dp->host->hostname, dp->name,
+ dp->host->hostname, qname,
check_days, (check_days == 1) ? "" : "s");
+ amfree(qname);
return 1;
}
return 0;
}
-static int promote_hills P((void))
+static int promote_hills(void)
{
disk_t *dp;
struct balance_stats {
int disks;
- long size;
+ off_t size;
} *sp = NULL;
int days;
int hill_days = 0;
- long hill_size;
- long new_size;
- long new_total;
+ off_t hill_size;
+ off_t new_size;
+ off_t new_total;
int my_dumpcycle;
+ char *qname;
/* If we are already doing a level 0 don't bother */
if(total_lev0 > 0)
if(my_dumpcycle > 10000) my_dumpcycle = 10000;
sp = (struct balance_stats *)
- alloc(sizeof(struct balance_stats) * my_dumpcycle);
+ alloc(SIZEOF(struct balance_stats) * my_dumpcycle);
- for(days = 0; days < my_dumpcycle; days++)
- sp[days].disks = sp[days].size = 0;
+ for(days = 0; days < my_dumpcycle; days++) {
+ sp[days].disks = 0;
+ sp[days].size = (off_t)0;
+ }
for(dp = schedq.head; dp != NULL; dp = dp->next) {
days = est(dp)->next_level0; /* This is > 0 by definition */
/* Search for a suitable big hill and cut it down */
while(1) {
/* Find the tallest hill */
- hill_size = 0;
+ hill_size = (off_t)0;
for(days = 0; days < my_dumpcycle; days++) {
if(sp[days].disks > 1 && sp[days].size > hill_size) {
hill_size = sp[days].size;
}
}
- if(hill_size <= 0) break; /* no suitable hills */
+ if(hill_size <= (off_t)0) break; /* no suitable hills */
/* Find all the dumps in that hill and try and remove one */
for(dp = schedq.head; dp != NULL; dp = dp->next) {
dp->strategy == DS_INCRONLY)
continue;
new_size = est_tape_size(dp, 0);
- new_total = total_size - est(dp)->dump_size + new_size;
+ new_total = total_size - est(dp)->dump_csize + new_size;
if(new_total > tape_length)
continue;
/* We found a disk we can promote */
+ qname = quote_string(dp->name);
total_size = new_total;
- total_lev0 += new_size;
+ total_lev0 += (double)new_size;
est(dp)->degr_level = est(dp)->dump_level;
- est(dp)->degr_size = est(dp)->dump_size;
+ est(dp)->degr_nsize = est(dp)->dump_nsize;
+ est(dp)->degr_csize = est(dp)->dump_csize;
est(dp)->dump_level = 0;
est(dp)->next_level0 = 0;
- est(dp)->dump_size = new_size;
+ est(dp)->dump_nsize = est_size(dp, 0);
+ est(dp)->dump_csize = new_size;
fprintf(stderr,
- " promote: moving %s:%s up, total_lev0 %1.0f, total_size " AM64_FMT "\n",
- dp->host->hostname, dp->name,
- total_lev0, total_size);
+ " promote: moving %s:%s up, total_lev0 %1.0lf, total_size " OFF_T_FMT "\n",
+ dp->host->hostname, qname,
+ total_lev0, (OFF_T_FMT_TYPE)total_size);
log_add(L_INFO,
"Full dump of %s:%s specially promoted from %d day%s ahead.",
- dp->host->hostname, dp->name,
+ dp->host->hostname, qname,
hill_days, (hill_days == 1) ? "" : "s");
+ amfree(qname);
amfree(sp);
return 1;
}
*
* XXX - memory leak - we shouldn't just throw away *dp
*/
-static void output_scheduleline(dp)
- disk_t *dp;
+static void output_scheduleline(
+ disk_t *dp)
{
est_t *ep;
- long dump_time = 0, degr_time = 0;
+ time_t dump_time = 0, degr_time = 0;
+ double dump_kps = 0, degr_kps = 0;
char *schedline = NULL, *degr_str = NULL;
char dump_priority_str[NUM_STR_SIZE];
char dump_level_str[NUM_STR_SIZE];
- char dump_size_str[NUM_STR_SIZE];
+ char dump_nsize_str[NUM_STR_SIZE];
+ char dump_csize_str[NUM_STR_SIZE];
char dump_time_str[NUM_STR_SIZE];
+ char dump_kps_str[NUM_STR_SIZE];
char degr_level_str[NUM_STR_SIZE];
- char degr_size_str[NUM_STR_SIZE];
+ char degr_nsize_str[NUM_STR_SIZE];
+ char degr_csize_str[NUM_STR_SIZE];
char degr_time_str[NUM_STR_SIZE];
+ char degr_kps_str[NUM_STR_SIZE];
char *dump_date, *degr_date;
char *features;
int i;
+ char *qname = quote_string(dp->name);
ep = est(dp);
- if(ep->dump_size == -1) {
+ if(ep->dump_csize == (off_t)-1) {
/* no estimate, fail the disk */
fprintf(stderr,
"%s: FAILED %s %s %s %d [no estimate]\n",
get_pname(),
- dp->host->hostname, dp->name, datestamp, ep->dump_level);
+ dp->host->hostname, qname, planner_timestamp, ep->dump_level);
log_add(L_FAIL, "%s %s %s %d [no estimate]",
- dp->host->hostname, dp->name, datestamp, ep->dump_level);
+ dp->host->hostname, qname, planner_timestamp, ep->dump_level);
+ amfree(qname);
return;
}
#define fix_rate(rate) (rate < 1.0 ? DEFAULT_DUMPRATE : rate)
if(ep->dump_level == 0) {
- dump_time = ep->dump_size / fix_rate(ep->fullrate);
+ dump_kps = fix_rate(ep->fullrate);
+ dump_time = (time_t)((double)ep->dump_csize / dump_kps);
- if(ep->degr_size != -1) {
- degr_time = ep->degr_size / fix_rate(ep->incrrate);
+ if(ep->degr_csize != (off_t)-1) {
+ degr_kps = fix_rate(ep->incrrate);
+ degr_time = (time_t)((double)ep->degr_csize / degr_kps);
}
}
else {
- dump_time = ep->dump_size / fix_rate(ep->incrrate);
+ dump_kps = fix_rate(ep->incrrate);
+ dump_time = (time_t)((double)ep->dump_csize / dump_kps);
}
- if(ep->dump_level == 0 && ep->degr_size != -1) {
+ if(ep->dump_level == 0 && ep->degr_csize != (off_t)-1) {
snprintf(degr_level_str, sizeof(degr_level_str),
"%d", ep->degr_level);
- snprintf(degr_size_str, sizeof(degr_size_str),
- "%ld", ep->degr_size);
+ snprintf(degr_nsize_str, sizeof(degr_nsize_str),
+ OFF_T_FMT, (OFF_T_FMT_TYPE)ep->degr_nsize);
+ snprintf(degr_csize_str, sizeof(degr_csize_str),
+ OFF_T_FMT, (OFF_T_FMT_TYPE)ep->degr_csize);
snprintf(degr_time_str, sizeof(degr_time_str),
- "%ld", degr_time);
+ OFF_T_FMT, (OFF_T_FMT_TYPE)degr_time);
+ snprintf(degr_kps_str, sizeof(degr_kps_str),
+ "%.0lf", degr_kps);
degr_str = vstralloc(" ", degr_level_str,
" ", degr_date,
- " ", degr_size_str,
+ " ", degr_nsize_str,
+ " ", degr_csize_str,
" ", degr_time_str,
+ " ", degr_kps_str,
NULL);
}
- snprintf(dump_priority_str, sizeof(dump_priority_str),
+ snprintf(dump_priority_str, SIZEOF(dump_priority_str),
"%d", ep->dump_priority);
- snprintf(dump_level_str, sizeof(dump_level_str),
+ snprintf(dump_level_str, SIZEOF(dump_level_str),
"%d", ep->dump_level);
- snprintf(dump_size_str, sizeof(dump_size_str),
- "%ld", ep->dump_size);
+ snprintf(dump_nsize_str, sizeof(dump_nsize_str),
+ OFF_T_FMT, (OFF_T_FMT_TYPE)ep->dump_nsize);
+ snprintf(dump_csize_str, sizeof(dump_csize_str),
+ OFF_T_FMT, (OFF_T_FMT_TYPE)ep->dump_csize);
snprintf(dump_time_str, sizeof(dump_time_str),
- "%ld", dump_time);
+ OFF_T_FMT, (OFF_T_FMT_TYPE)dump_time);
+ snprintf(dump_kps_str, sizeof(dump_kps_str),
+ "%.0lf", dump_kps);
features = am_feature_to_string(dp->host->features);
schedline = vstralloc("DUMP ",dp->host->hostname,
" ", features,
- " ", dp->name,
- " ", datestamp,
+ " ", qname,
+ " ", planner_timestamp,
" ", dump_priority_str,
" ", dump_level_str,
" ", dump_date,
- " ", dump_size_str,
+ " ", dump_nsize_str,
+ " ", dump_csize_str,
" ", dump_time_str,
+ " ", dump_kps_str,
degr_str ? degr_str : "",
"\n", NULL);
amfree(features);
amfree(schedline);
amfree(degr_str);
+ amfree(qname);
}
* University of Maryland at College Park
*/
/*
- * $Id: reporter.c,v 1.105 2006/03/09 16:51:42 martinea Exp $
+ * $Id: reporter.c,v 1.132 2006/08/28 17:02:48 martinea Exp $
*
* nightly Amanda Report generator
*/
/*
-report format
- tape label message
- error messages
- summary stats
- details for errors
- notes
- success summary
-*/
+ * report format
+ * tape label message
+ * error messages
+ * summary stats
+ * details for errors
+ * notes
+ * success summary
+ */
#include "amanda.h"
#include "conffile.h"
typedef struct timedata_s {
logtype_t result;
- float origsize, outsize;
+ double origsize, outsize;
char *datestamp;
- float sec, kps;
+ double sec, kps;
int filenum;
char *tapelabel;
} timedata_t;
typedef struct repdata_s {
disk_t *disk;
char *datestamp;
+ double est_nsize, est_csize;
timedata_t taper;
timedata_t dumper;
timedata_t chunker;
char *label;
double taper_time;
double coutsize, corigsize;
- int tapedisks, tapechunks;
+ int tapedisks, tapechunks;
struct taper_s *next;
} taper_t;
static strange_t *first_strange=NULL, *last_strange=NULL;
-static float total_time, startup_time, planner_time;
+static double total_time, startup_time, planner_time;
/* count files to tape */
static int tapefcount = 0;
static char *run_datestamp;
-static char *today_datestamp;
static char *tape_labels = NULL;
static int last_run_tapes = 0;
static int degraded_mode = 0; /* defined in driverio too */
long int unitdivisor;
/* local functions */
-static int contline_next P((void));
-static void addline P((line_t **lp, char *str));
-static void usage P((void));
-int main P((int argc, char **argv));
-
-static void copy_template_file P((char *lbl_templ));
-static void do_postscript_output P((void));
-static void handle_start P((void));
-static void handle_finish P((void));
-static void handle_note P((void));
-static void handle_summary P((void));
-static void handle_stats P((void));
-static void handle_error P((void));
-static void handle_disk P((void));
-static repdata_t *handle_success P((logtype_t logtype));
-static repdata_t *handle_chunk P((void));
-static void handle_partial P((void));
-static void handle_strange P((void));
-static void handle_failed P((void));
-static void generate_missing P((void));
-static void output_tapeinfo P((void));
-static void output_lines P((line_t *lp, FILE *f));
-static void output_stats P((void));
-static void output_summary P((void));
-static void output_strange P((void));
-static void sort_disks P((void));
-static int sort_by_name P((disk_t *a, disk_t *b));
-static void bogus_line P((void));
-static char *nicedate P((int datestamp));
-static char *prefix P((char *host, char *disk, int level));
-static char *prefixstrange P((char *host, char *disk, int level, int len_host, int len_disk));
-static void addtostrange P((char *host, char *disk, int level, char *str));
-static repdata_t *find_repdata P((disk_t *dp, char *datestamp, int level));
-
+int main(int argc, char **argv);
+
+static char * nicedate(const char * datestamp);
+static char * prefix(char *host, char *disk, int level);
+static char * prefixstrange(char *host, char *disk, int level,
+ size_t len_host, size_t len_disk);
+static char * Rule(int From, int To);
+static char * sDivZero(double a, double b, int cn);
+static char * TextRule(int From, int To, char *s);
+static int ColWidth(int From, int To);
+static int contline_next(void);
+static int sort_by_name(disk_t *a, disk_t *b);
+static repdata_t *find_repdata(disk_t *dp, char *datestamp, int level);
+static repdata_t *handle_chunk(void);
+static repdata_t *handle_success(logtype_t logtype);
+static void addline(line_t **lp, char *str);
+static void addtostrange(char *host, char *disk, int level, char *str);
+static void bogus_line(const char *);
+static void CalcMaxWidth(void);
+static void CheckFloatMax(ColumnInfo *cd, double d);
+static void CheckIntMax(ColumnInfo *cd, int n);
+static void CheckStringMax(ColumnInfo *cd, char *s);
+static void copy_template_file(char *lbl_templ);
+static void do_postscript_output(void);
+static void generate_missing(void);
+static void generate_bad_estimate(void);
+static void handle_disk(void);
+static void handle_error(void);
+static void handle_failed(void);
+static void handle_finish(void);
+static void handle_note(void);
+static void handle_partial(void);
+static void handle_start(void);
+static void handle_stats(void);
+static void handle_strange(void);
+static void handle_summary(void);
+static void output_lines(line_t *lp, FILE *f);
+static void output_stats(void);
+static void output_strange(void);
+static void output_summary(void);
+static void output_tapeinfo(void);
+static void sort_disks(void);
+static void usage(void);
static int
-ColWidth(From, To)
- int From, To;
+ColWidth(
+ int From,
+ int To)
{
int i, Width= 0;
for (i=From; i<=To && ColumnData[i].Name != NULL; i++) {
}
static char *
-Rule(From, To)
- int From, To;
+Rule(
+ int From,
+ int To)
{
int i, ThisLeng;
int Leng= ColWidth(0, ColumnDataCount());
- char *RuleSpace= alloc(Leng+1);
+ char *RuleSpace= alloc((size_t)(Leng+1));
ThisLeng= ColWidth(From, To);
for (i=0;i<ColumnData[From].PrefixSpace; i++)
RuleSpace[i]= ' ';
}
static char *
-TextRule(From, To, s)
- int From, To;
- char *s;
+TextRule(
+ int From,
+ int To,
+ char * s)
{
ColumnInfo *cd= &ColumnData[From];
- int leng, nbrules, i, txtlength;
+ int leng;
+ int nbrules, i, txtlength;
int RuleSpaceSize= ColWidth(0, ColumnDataCount());
- char *RuleSpace= alloc(RuleSpaceSize), *tmp;
+ char *RuleSpace= alloc((size_t)RuleSpaceSize), *tmp;
- leng= strlen(s);
+ leng = (int)strlen(s);
if(leng >= (RuleSpaceSize - cd->PrefixSpace))
leng = RuleSpaceSize - cd->PrefixSpace - 1;
- snprintf(RuleSpace, RuleSpaceSize, "%*s%*.*s ", cd->PrefixSpace, "",
+ snprintf(RuleSpace, (size_t)RuleSpaceSize, "%*s%*.*s ", cd->PrefixSpace, "",
leng, leng, s);
txtlength = cd->PrefixSpace + leng + 1;
nbrules = ColWidth(From,To) - txtlength;
}
static char *
-sDivZero(a, b, cn)
- double a, b;
- int cn;
+sDivZero(
+ double a,
+ double b,
+ int cn)
{
ColumnInfo *cd= &ColumnData[cn];
static char PrtBuf[256];
- if (b == 0.0)
- snprintf(PrtBuf, sizeof(PrtBuf),
+ if (!isnormal(b))
+ snprintf(PrtBuf, SIZEOF(PrtBuf),
"%*s", cd->Width, "-- ");
else
- snprintf(PrtBuf, sizeof(PrtBuf),
+ snprintf(PrtBuf, SIZEOF(PrtBuf),
cd->Format, cd->Width, cd->Precision, a/b);
return PrtBuf;
}
static int
-contline_next()
+contline_next(void)
{
int ch;
- ch = getc(logfile);
- ungetc(ch, logfile);
-
+ if ((ch = getc(logfile)) != EOF) {
+ if (ungetc(ch, logfile) == EOF) {
+ if (ferror(logfile)) {
+ error("ungetc failed: %s\n", strerror(errno));
+ /*NOTREACHED*/
+ }
+ error("ungetc failed: EOF\n");
+ /*NOTREACHED*/
+ }
+ }
return ch == ' ';
}
static void
-addline(lp, str)
- line_t **lp;
- char *str;
+addline(
+ line_t ** lp,
+ char * str)
{
- line_t *new, *p, *q;
+ line_t *new, *p;
/* allocate new line node */
- new = (line_t *) alloc(sizeof(line_t));
+ new = (line_t *) alloc(SIZEOF(line_t));
new->next = NULL;
new->str = stralloc(str);
/* add to end of list */
- for(p = *lp, q = NULL; p != NULL; q = p, p = p->next);
- if(q == NULL) *lp = new;
- else q->next = new;
+ p = *lp;
+ if (p == NULL) {
+ *lp = new;
+ } else {
+ while (p->next != NULL)
+ p = p->next;
+ p->next = new;
+ }
}
static void
-usage()
+usage(void)
{
- error("Usage: amreport conf [-f output-file] [-l logfile] [-p postscript-file]");
+ error("Usage: amreport conf [-i] [-M address] [-f output-file] [-l logfile] [-p postscript-file] [-o configoption]*");
+ /*NOTREACHED*/
}
int
-main(argc, argv)
- int argc;
- char **argv;
+main(
+ int argc,
+ char ** argv)
{
char *conffile;
char *conf_diskfile;
char *ColumnSpec = "";
char *errstr = NULL;
int cn;
+ int mailout = 1;
+ char *mailto = NULL;
+ int new_argc, my_argc;
+ char **new_argv, **my_argv;
+ char *lbl_templ = NULL;
safe_fd(-1, 0);
set_pname("amreport");
+ dbopen(DBG_SUBDIR_SERVER);
+
/* Don't die when child closes pipe */
signal(SIGPIPE, SIG_IGN);
psfname = NULL;
logfname = NULL;
- if (getcwd(my_cwd, sizeof(my_cwd)) == NULL) {
+ if (getcwd(my_cwd, SIZEOF(my_cwd)) == NULL) {
error("cannot determine current working directory");
+ /*NOTREACHED*/
}
- if (argc < 2) {
+ parse_server_conf(argc, argv, &new_argc, &new_argv);
+ my_argc = new_argc;
+ my_argv = new_argv;
+
+ if (my_argc < 2) {
config_dir = stralloc2(my_cwd, "/");
if ((config_name = strrchr(my_cwd, '/')) != NULL) {
config_name = stralloc(config_name + 1);
}
} else {
- if (argv[1][0] == '-') {
+ if (my_argv[1][0] == '-') {
usage();
return 1;
}
- config_name = stralloc(argv[1]);
+ config_name = stralloc(my_argv[1]);
config_dir = vstralloc(CONFIG_DIR, "/", config_name, "/", NULL);
- --argc; ++argv;
- while((opt = getopt(argc, argv, "f:l:p:")) != EOF) {
+ --my_argc; ++my_argv;
+ while((opt = getopt(my_argc, my_argv, "M:f:l:p:i")) != EOF) {
switch(opt) {
+ case 'i':
+ mailout = 0;
+ break;
+ case 'M':
+ if (mailto != NULL) {
+ error("you may specify at most one -M");
+ /*NOTREACHED*/
+ }
+ mailto = stralloc(optarg);
+ if(!validate_mailto(mailto)) {
+ error("mail address has invalid characters");
+ /*NOTREACHED*/
+ }
+ break;
case 'f':
if (outfname != NULL) {
error("you may specify at most one -f");
+ /*NOTREACHED*/
}
if (*optarg == '/') {
outfname = stralloc(optarg);
case 'l':
if (logfname != NULL) {
error("you may specify at most one -l");
+ /*NOTREACHED*/
}
if (*optarg == '/') {
logfname = stralloc(optarg);
case 'p':
if (psfname != NULL) {
error("you may specify at most one -p");
+ /*NOTREACHED*/
}
if (*optarg == '/') {
psfname = stralloc(optarg);
}
break;
case '?':
- default:
usage();
return 1;
+ default:
+ break;
}
}
- argc -= optind;
- argv += optind;
-
- if (argc > 1) {
- usage();
- return 1;
- }
+ my_argc -= optind;
+ my_argv += optind;
+ }
+ if( !mailout && mailto ){
+ printf("You cannot specify both -i & -M at the same time\n");
+ exit(1);
}
+
#if !defined MAILER
if(!outfname) {
printf("You must run amreport with '-f <output file>' because configure\n");
/* read configuration files */
conffile = stralloc2(config_dir, CONFFILE_NAME);
- if(read_conffile(conffile)) {
- error("errors processing config file \"%s\"", conffile);
- }
+ /* Ignore error from read_conffile */
+ read_conffile(conffile);
amfree(conffile);
+
+ dbrename(config_name, DBG_SUBDIR_SERVER);
+
+ report_bad_conf_arg();
conf_diskfile = getconf_str(CNF_DISKFILE);
if (*conf_diskfile == '/') {
conf_diskfile = stralloc(conf_diskfile);
} else {
conf_diskfile = stralloc2(config_dir, conf_diskfile);
}
- if(read_diskfile(conf_diskfile, &diskq) < 0) {
- error("could not load disklist \"%s\"", conf_diskfile);
- }
+ /* Ignore error from read_diskfile */
+ read_diskfile(conf_diskfile, &diskq);
amfree(conf_diskfile);
+ if(mailout && !mailto &&
+ getconf_seen(CNF_MAILTO) && strlen(getconf_str(CNF_MAILTO)) > 0) {
+ mailto = getconf_str(CNF_MAILTO);
+ if(!validate_mailto(mailto)){
+ mailto = NULL;
+ }
+ }
+
conf_tapelist = getconf_str(CNF_TAPELIST);
if (*conf_tapelist == '/') {
conf_tapelist = stralloc(conf_tapelist);
} else {
conf_tapelist = stralloc2(config_dir, conf_tapelist);
}
- if(read_tapelist(conf_tapelist)) {
- error("could not read tapelist \"%s\"", conf_tapelist);
- }
+ /* Ignore error from read_tapelist */
+ read_tapelist(conf_tapelist);
amfree(conf_tapelist);
conf_infofile = getconf_str(CNF_INFOFILE);
if (*conf_infofile == '/') {
}
if(open_infofile(conf_infofile)) {
error("could not open info db \"%s\"", conf_infofile);
+ /*NOTREACHED*/
}
amfree(conf_infofile);
- today_datestamp = construct_datestamp(NULL);
-
displayunit = getconf_str(CNF_DISPLAYUNIT);
unitdivisor = getconf_unit_divisor();
}
afclose(logfile);
close_infofile();
- if(!amflush_run)
+ if(!amflush_run) {
generate_missing();
+ generate_bad_estimate();
+ }
subj_str = vstralloc(getconf_str(CNF_ORG),
" ", amflush_run ? "AMFLUSH" : "AMANDA",
" ", "MAIL REPORT FOR",
- " ", nicedate(run_datestamp ? atoi(run_datestamp) : 0),
+ " ", nicedate(run_datestamp ? run_datestamp : "0"),
NULL);
/* lookup the tapetype and printer type from the amanda.conf file. */
/* output to a file */
if((mailf = fopen(outfname,"w")) == NULL) {
error("could not open output file: %s %s", outfname, strerror(errno));
+ /*NOTREACHED*/
}
- fprintf(mailf, "To: %s\n", getconf_str(CNF_MAILTO));
+ fprintf(mailf, "To: %s\n", mailto);
fprintf(mailf, "Subject: %s\n\n", subj_str);
} else {
#ifdef MAILER
- mail_cmd = vstralloc(MAILER,
+ if(mailto) {
+ mail_cmd = vstralloc(MAILER,
" -s", " \"", subj_str, "\"",
- " ", getconf_str(CNF_MAILTO),
- NULL);
- if((mailf = popen(mail_cmd, "w")) == NULL)
- error("could not open pipe to \"%s\": %s",
- mail_cmd, strerror(errno));
+ " ", mailto, NULL);
+ if((mailf = popen(mail_cmd, "w")) == NULL) {
+ error("could not open pipe to \"%s\": %s",
+ mail_cmd, strerror(errno));
+ /*NOTREACHED*/
+ }
+ }
+ else {
+ if(mailout) {
+ printf("No mail sent! ");
+ printf("No valid mail address has been specified in amanda.conf or on the commmand line\n");
+ }
+ mailf = NULL;
+ }
#endif
}
/* if the postscript_label_template (tp->lbl_templ) field is not */
/* the empty string (i.e. it is set to something), open the */
/* postscript debugging file for writing. */
- if ((strcmp(tp->lbl_templ, "")) != 0) {
+ if (tp)
+ lbl_templ = tapetype_get_lbl_templ(tp);
+ if (tp && lbl_templ && strcmp(lbl_templ, "") != 0) {
if ((postscript = fopen(psfname, "w")) == NULL) {
curlog = L_ERROR;
curprog = P_REPORTER;
/* print to the default printer */
printer_cmd = vstralloc(LPRCMD, NULL);
#endif
-
- if ((strcmp(tp->lbl_templ, "")) != 0) {
+ if (tp)
+ lbl_templ = tapetype_get_lbl_templ(tp);
+ if (tp && lbl_templ && strcmp(lbl_templ, "") != 0) {
#ifdef LPRCMD
if ((postscript = popen(printer_cmd, "w")) == NULL) {
curlog = L_ERROR;
amfree(subj_str);
+ if(mailf) {
- if(!got_finish) fputs("*** THE DUMPS DID NOT FINISH PROPERLY!\n\n", mailf);
-
- output_tapeinfo();
-
- if(first_strange || errsum) {
- fprintf(mailf,"\nFAILURE AND STRANGE DUMP SUMMARY:\n");
- if(first_strange) output_strange();
- if(errsum) output_lines(errsum, mailf);
- }
- fputs("\n\n", mailf);
+ if(!got_finish) fputs("*** THE DUMPS DID NOT FINISH PROPERLY!\n\n", mailf);
- output_stats();
+ output_tapeinfo();
- if(errdet) {
- fprintf(mailf,"\n\014\nFAILED AND STRANGE DUMP DETAILS:\n");
- output_lines(errdet, mailf);
- }
- if(notes) {
- fprintf(mailf,"\n\014\nNOTES:\n");
- output_lines(notes, mailf);
- }
- sort_disks();
- if(sortq.head != NULL) {
- fprintf(mailf,"\n\014\nDUMP SUMMARY:\n");
- output_summary();
+ if(first_strange || errsum) {
+ fprintf(mailf,"\nFAILURE AND STRANGE DUMP SUMMARY:\n");
+ if(first_strange) output_strange();
+ if(errsum) output_lines(errsum, mailf);
+ }
+ fputs("\n\n", mailf);
+
+ output_stats();
+
+ if(errdet) {
+ fprintf(mailf,"\n\014\nFAILED AND STRANGE DUMP DETAILS:\n");
+ output_lines(errdet, mailf);
+ }
+ if(notes) {
+ fprintf(mailf,"\n\014\nNOTES:\n");
+ output_lines(notes, mailf);
+ }
+ sort_disks();
+ if(sortq.head != NULL) {
+ fprintf(mailf,"\n\014\nDUMP SUMMARY:\n");
+ output_summary();
+ }
+ fprintf(mailf,"\n(brought to you by Amanda version %s)\n",
+ version());
}
- fprintf(mailf,"\n(brought to you by Amanda version %s)\n",
- version());
if (postscript) {
do_postscript_output();
afclose(postscript);
}
else {
- if (postscript != NULL && pclose(postscript) != 0)
+ if (postscript != NULL && pclose(postscript) != 0) {
error("printer command failed: %s", printer_cmd);
+ /*NOTREACHED*/
+ }
postscript = NULL;
}
if(outfname) {
afclose(mailf);
}
- else {
- if(pclose(mailf) != 0)
+ else if(mailf) {
+ if(pclose(mailf) != 0) {
error("mail command failed: %s", mail_cmd);
+ /*NOTREACHED*/
+ }
mailf = NULL;
}
+ clear_tapelist();
+ free_disklist(&diskq);
+ free_new_argv(new_argc, new_argv);
+ free_server_config();
amfree(run_datestamp);
amfree(tape_labels);
amfree(config_dir);
malloc_list(fileno(stderr), malloc_hist_1, malloc_hist_2);
}
+ dbclose();
return 0;
}
#define divzero(fp,a,b) \
do { \
double q = (b); \
- if (q == 0.0) \
+ if (!isnormal(q)) \
fprintf((fp)," -- "); \
else if ((q = (a)/q) >= 999.95) \
fprintf((fp), "###.#"); \
else \
- fprintf((fp), "%5.1f",q); \
+ fprintf((fp), "%5.1lf",q); \
} while(0)
#define divzero_wide(fp,a,b) \
do { \
double q = (b); \
- if (q == 0.0) \
+ if (!isnormal(q)) \
fprintf((fp)," -- "); \
else if ((q = (a)/q) >= 99999.95) \
fprintf((fp), "#####.#"); \
else \
- fprintf((fp), "%7.1f",q); \
+ fprintf((fp), "%7.1lf",q); \
} while(0)
static void
-output_stats()
+output_stats(void)
{
double idle_time;
tapetype_t *tp = lookup_tapetype(getconf_str(CNF_TAPETYPE));
- int tapesize, marksize, lv, first;
+ off_t tapesize;
+ off_t marksize;
+ int lv, first;
- tapesize = tp->length;
- marksize = tp->filemark;
+ if (tp) {
+ tapesize = tapetype_get_length(tp);
+ marksize = tapetype_get_filemark(tp);
+ } else {
+ tapesize = 100 * 1024 * 1024;
+ marksize = 1 * 1024 * 1024;
+ }
stats[2].dumpdisks = stats[0].dumpdisks + stats[1].dumpdisks;
stats[2].tapedisks = stats[0].tapedisks + stats[1].tapedisks;
hrmn(stats[1].dumper_time));
fprintf(mailf,
- "Output Size (meg) %8.1f %8.1f %8.1f\n",
+ "Output Size (meg) %8.1lf %8.1lf %8.1lf\n",
mb(stats[2].outsize), mb(stats[0].outsize), mb(stats[1].outsize));
fprintf(mailf,
- "Original Size (meg) %8.1f %8.1f %8.1f\n",
+ "Original Size (meg) %8.1lf %8.1lf %8.1lf\n",
mb(stats[2].origsize), mb(stats[0].origsize),
mb(stats[1].origsize));
hrmn(stats[1].taper_time));
fprintf(mailf,
- "Tape Size (meg) %8.1f %8.1f %8.1f\n",
+ "Tape Size (meg) %8.1lf %8.1lf %8.1lf\n",
mb(stats[2].tapesize), mb(stats[0].tapesize),
mb(stats[1].tapesize));
fprintf(mailf, "Tape Used (%%) ");
- divzero(mailf, pct(stats[2].tapesize+marksize*(stats[2].tapedisks+stats[2].tapechunks)),tapesize);
+ divzero(mailf, pct(stats[2].tapesize+marksize*(stats[2].tapedisks+stats[2].tapechunks)),(double)tapesize);
fputs(" ", mailf);
- divzero(mailf, pct(stats[0].tapesize+marksize*(stats[0].tapedisks+stats[0].tapechunks)),tapesize);
+ divzero(mailf, pct(stats[0].tapesize+marksize*(stats[0].tapedisks+stats[0].tapechunks)),(double)tapesize);
fputs(" ", mailf);
- divzero(mailf, pct(stats[1].tapesize+marksize*(stats[1].tapedisks+stats[1].tapechunks)),tapesize);
+ divzero(mailf, pct(stats[1].tapesize+marksize*(stats[1].tapedisks+stats[1].tapechunks)),(double)tapesize);
if(stats[1].tapedisks > 0) fputs(" (level:#disks ...)", mailf);
putc('\n', mailf);
putc('\n', mailf);
if(stats_by_tape) {
- int label_length = strlen(stats_by_tape->label) + 5;
+ int label_length = (int)strlen(stats_by_tape->label) + 5;
fprintf(mailf,"\nUSAGE BY TAPE:\n");
fprintf(mailf," %-*s Time Size %% Nb Nc\n",
label_length, "Label");
current_tape = current_tape->next) {
fprintf(mailf, " %-*s", label_length, current_tape->label);
fprintf(mailf, " %2d:%02d", hrmn(current_tape->taper_time));
- fprintf(mailf, " %8.0f%s ", du(current_tape->coutsize), displayunit);
- divzero(mailf, pct(current_tape->coutsize +
- marksize * (current_tape->tapedisks+current_tape->tapechunks)),
- tapesize);
+ fprintf(mailf, " %8.0lf%s ", du(current_tape->coutsize), displayunit);
+ divzero(mailf, pct(current_tape->coutsize + marksize *
+ (current_tape->tapedisks+current_tape->tapechunks)),
+ (double)tapesize);
fprintf(mailf, " %4d", current_tape->tapedisks);
fprintf(mailf, " %4d\n", current_tape->tapechunks);
}
}
-
}
/* ----- */
static void
-output_tapeinfo()
+output_tapeinfo(void)
{
tape_t *tp, *lasttp;
int run_tapes;
run_tapes);
while(run_tapes > 0) {
- if(tp != NULL)
+ if(tp != NULL) {
fprintf(mailf, "%s", tp->label);
- else
- fputs("a new tape", mailf);
+ } else {
+ if (run_tapes == 1)
+ fprintf(mailf, "a new tape");
+ else
+ fprintf(mailf, "%d new tapes", run_tapes);
+ run_tapes = 1;
+ }
if(run_tapes > 1) fputs(", ", mailf);
lasttp = lookup_tapepos(lookup_nb_tape());
run_tapes = getconf_int(CNF_RUNTAPES);
- if(lasttp && run_tapes > 0 && lasttp->datestamp == 0) {
+ if(lasttp && run_tapes > 0 && strcmp(lasttp->datestamp,"0") == 0) {
int c = 0;
- while(lasttp && run_tapes > 0 && lasttp->datestamp == 0) {
+ while(lasttp && run_tapes > 0 && strcmp(lasttp->datestamp,"0") == 0) {
c++;
lasttp = lasttp->prev;
run_tapes--;
lasttp->label);
lasttp = lasttp->prev;
c--;
- while(lasttp && c > 0 && lasttp->datestamp == 0) {
+ while(lasttp && c > 0 && strcmp(lasttp->datestamp,"0") == 0) {
fprintf(mailf, ", %s", lasttp->label);
lasttp = lasttp->prev;
c--;
}
/* ----- */
-static void output_strange()
+static void
+output_strange(void)
{
- int len_host=0, len_disk=0;
+ size_t len_host=0, len_disk=0;
strange_t *strange;
char *str = NULL;
str = vstralloc(" ", prefixstrange(strange->hostname, strange->diskname, strange->level, len_host, len_disk),
" ", strange->str, NULL);
fprintf(mailf, "%s\n", str);
+ amfree(str);
}
}
static void
-output_lines(lp, f)
- line_t *lp;
- FILE *f;
+output_lines(
+ line_t * lp,
+ FILE * f)
{
line_t *next;
/* ----- */
static int
-sort_by_name(a, b)
- disk_t *a, *b;
+sort_by_name(
+ disk_t * a,
+ disk_t * b)
{
int rc;
}
static void
-sort_disks()
+sort_disks(void)
{
disk_t *dp;
}
static void
-CheckStringMax(cd, s)
- ColumnInfo *cd;
- char *s;
+CheckStringMax(
+ ColumnInfo *cd,
+ char * s)
{
if (cd->MaxWidth) {
- int l= strlen(s);
+ int l = (int)strlen(s);
+
if (cd->Width < l)
cd->Width= l;
}
}
static void
-CheckIntMax(cd, n)
- ColumnInfo *cd;
- int n;
+CheckIntMax(
+ ColumnInfo *cd,
+ int n)
{
if (cd->MaxWidth) {
char testBuf[200];
int l;
- snprintf(testBuf, sizeof(testBuf),
+
+ snprintf(testBuf, SIZEOF(testBuf),
cd->Format, cd->Width, cd->Precision, n);
- l= strlen(testBuf);
+ l = (int)strlen(testBuf);
if (cd->Width < l)
cd->Width= l;
}
}
static void
-CheckFloatMax(cd, d)
- ColumnInfo *cd;
- double d;
+CheckFloatMax(
+ ColumnInfo *cd,
+ double d)
{
if (cd->MaxWidth) {
char testBuf[200];
int l;
- snprintf(testBuf, sizeof(testBuf),
+ snprintf(testBuf, SIZEOF(testBuf),
cd->Format, cd->Width, cd->Precision, d);
- l= strlen(testBuf);
+ l = (int)strlen(testBuf);
if (cd->Width < l)
cd->Width= l;
}
static int TapeRate;
static void
-CalcMaxWidth()
+CalcMaxWidth(void)
{
/* we have to look for columspec's, that require the recalculation.
* we do here the same loops over the sortq as is done in
* ElB, 1999-02-24.
*/
disk_t *dp;
- float f;
+ double f;
repdata_t *repdata;
for(dp = sortq.head; dp != NULL; dp = dp->next) {
if(dp->todo) {
for(repdata = data(dp); repdata != NULL; repdata = repdata->next) {
- ColumnInfo *cd;
char TimeRateBuffer[40];
CheckStringMax(&ColumnData[HostName], dp->host->hostname);
CheckIntMax(&ColumnData[Level], repdata->level);
if(repdata->dumper.result == L_SUCCESS ||
repdata->dumper.result == L_CHUNKSUCCESS) {
- CheckFloatMax(&ColumnData[OrigKB], du(repdata->dumper.origsize));
- CheckFloatMax(&ColumnData[OutKB], du(repdata->dumper.outsize));
+ CheckFloatMax(&ColumnData[OrigKB],
+ (double)du(repdata->dumper.origsize));
+ CheckFloatMax(&ColumnData[OutKB],
+ (double)du(repdata->dumper.outsize));
if(dp->compress == COMP_NONE)
f = 0.0;
else
sDivZero(pct(repdata->dumper.outsize), f, Compress));
if(!amflush_run)
- snprintf(TimeRateBuffer, sizeof(TimeRateBuffer),
+ snprintf(TimeRateBuffer, SIZEOF(TimeRateBuffer),
"%3d:%02d", mnsc(repdata->dumper.sec));
else
- snprintf(TimeRateBuffer, sizeof(TimeRateBuffer),
+ snprintf(TimeRateBuffer, SIZEOF(TimeRateBuffer),
"N/A ");
CheckStringMax(&ColumnData[DumpTime], TimeRateBuffer);
CheckFloatMax(&ColumnData[DumpRate], repdata->dumper.kps);
}
- cd= &ColumnData[TapeTime];
if(repdata->taper.result == L_FAIL) {
- CheckStringMax(cd, "FAILED");
+ CheckStringMax(&ColumnData[TapeTime], "FAILED");
continue;
}
if(repdata->taper.result == L_SUCCESS ||
repdata->taper.result == L_CHUNKSUCCESS)
- snprintf(TimeRateBuffer, sizeof(TimeRateBuffer),
+ snprintf(TimeRateBuffer, SIZEOF(TimeRateBuffer),
"%3d:%02d", mnsc(repdata->taper.sec));
else
- snprintf(TimeRateBuffer, sizeof(TimeRateBuffer),
+ snprintf(TimeRateBuffer, SIZEOF(TimeRateBuffer),
"N/A ");
- CheckStringMax(cd, TimeRateBuffer);
+ CheckStringMax(&ColumnData[TapeTime], TimeRateBuffer);
- cd= &ColumnData[TapeRate];
if(repdata->taper.result == L_SUCCESS ||
repdata->taper.result == L_CHUNKSUCCESS)
- CheckFloatMax(cd, repdata->taper.kps);
+ CheckFloatMax(&ColumnData[TapeRate], repdata->taper.kps);
else
- CheckStringMax(cd, "N/A ");
+ CheckStringMax(&ColumnData[TapeRate], "N/A ");
}
}
}
}
static void
-output_summary()
+output_summary(void)
{
disk_t *dp;
repdata_t *repdata;
char *tmp;
int i, h, w1, wDump, wTape;
- float outsize, origsize;
- float f;
+ double outsize, origsize;
+ double f;
HostName = StringToColumn("HostName");
Disk = StringToColumn("Disk");
wTape= ColWidth(TapeTime, TapeRate);
/* print centered top titles */
- h= strlen(ds);
+ h = (int)strlen(ds);
if (h > wDump) {
- h= 0;
+ h = 0;
} else {
- h= (wDump-h)/2;
+ h = (wDump-h)/2;
}
fprintf(mailf, "%*s", w1+h, "");
fprintf(mailf, "%-*s", wDump-h, ds);
- h= strlen(ts);
+ h = (int)strlen(ts);
if (h > wTape) {
- h= 0;
+ h = 0;
} else {
- h= (wTape-h)/2;
+ h = (wTape-h)/2;
}
fprintf(mailf, "%*s", h, "");
fprintf(mailf, "%-*s", wTape-h, ts);
ColumnInfo *cd;
char TimeRateBuffer[40];
for(repdata = data(dp); repdata != NULL; repdata = repdata->next) {
- int devlen;
+ char *devname;
+ size_t devlen;
cd= &ColumnData[HostName];
fprintf(mailf, "%*s", cd->PrefixSpace, "");
cd= &ColumnData[Disk];
fprintf(mailf, "%*s", cd->PrefixSpace, "");
- devlen= strlen(dp->name);
- if (devlen > cd->Width) {
+ devname = sanitize_string(dp->name);
+ devlen = strlen(devname);
+ if (devlen > (size_t)cd->Width) {
fputc('-', mailf);
fprintf(mailf, cd->Format, cd->Width-1, cd->Precision-1,
- dp->name+devlen - (cd->Width-1) );
+ devname+devlen - (cd->Width-1) );
}
else
- fprintf(mailf, cd->Format, cd->Width, cd->Width, dp->name);
-
+ fprintf(mailf, cd->Format, cd->Width, cd->Width, devname);
+ amfree(devname);
cd= &ColumnData[Level];
if (repdata->dumper.result == L_BOGUS &&
repdata->taper.result == L_BOGUS) {
cd= &ColumnData[OrigKB];
fprintf(mailf, "%*s", cd->PrefixSpace, "");
- if(origsize != 0.0)
+ if(isnormal(origsize))
fprintf(mailf, cd->Format, cd->Width, cd->Precision, du(origsize));
else
fprintf(mailf, "%*.*s", cd->Width, cd->Width, "N/A");
fprintf(mailf, "%*s", cd->PrefixSpace, "");
if(repdata->dumper.result == L_SUCCESS ||
repdata->dumper.result == L_CHUNKSUCCESS)
- snprintf(TimeRateBuffer, sizeof(TimeRateBuffer),
+ snprintf(TimeRateBuffer, SIZEOF(TimeRateBuffer),
"%3d:%02d", mnsc(repdata->dumper.sec));
else
- snprintf(TimeRateBuffer, sizeof(TimeRateBuffer),
+ snprintf(TimeRateBuffer, SIZEOF(TimeRateBuffer),
"N/A ");
fprintf(mailf, cd->Format, cd->Width, cd->Width, TimeRateBuffer);
if(repdata->taper.result == L_SUCCESS ||
repdata->taper.result == L_PARTIAL ||
repdata->taper.result == L_CHUNKSUCCESS)
- snprintf(TimeRateBuffer, sizeof(TimeRateBuffer),
+ snprintf(TimeRateBuffer, SIZEOF(TimeRateBuffer),
"%3d:%02d", mnsc(repdata->taper.sec));
else
- snprintf(TimeRateBuffer, sizeof(TimeRateBuffer),
+ snprintf(TimeRateBuffer, SIZEOF(TimeRateBuffer),
"N/A ");
fprintf(mailf, cd->Format, cd->Width, cd->Width, TimeRateBuffer);
}
static void
-bogus_line()
+bogus_line(
+ const char *err_text)
{
- printf("line %d of log is bogus\n", curlinenum);
+ printf("line %d of log is bogus: <%s>\n", curlinenum, curstr);
+ printf(" Scan failed at: <%s>\n", err_text);
}
-static char *
-nicedate(datestamp)
- int datestamp;
/*
- * Formats an integer of the form YYYYMMDD into the string
+ * Formats an integer of the form YYYYMMDDHHMMSS into the string
* "Monthname DD, YYYY". A pointer to the statically allocated string
* is returned, so it must be copied to other storage (or just printed)
* before calling nicedate() again.
*/
+static char *
+nicedate(
+ const char *datestamp)
{
static char nice[64];
+ char date[9];
+ int numdate;
static char *months[13] = { "BogusMonth",
"January", "February", "March", "April", "May", "June",
"July", "August", "September", "October", "November", "December"
};
int year, month, day;
- year = datestamp / 10000;
- day = datestamp % 100;
- month = (datestamp / 100) % 100;
+ strncpy(date, datestamp, 8);
+ date[8] = '\0';
+ numdate = atoi(date);
+ year = numdate / 10000;
+ day = numdate % 100;
+ month = (numdate / 100) % 100;
+ if (month > 12 )
+ month = 0;
- snprintf(nice, sizeof(nice), "%s %d, %d", months[month], day, year);
+ snprintf(nice, SIZEOF(nice), "%s %d, %d", months[month], day, year);
return nice;
}
static void
-handle_start()
+handle_start(void)
{
static int started = 0;
char *label;
skip_whitespace(s, ch);
#define sc "datestamp"
- if(ch == '\0' || strncmp(s - 1, sc, sizeof(sc)-1) != 0) {
- bogus_line();
+ if(ch == '\0' || strncmp(s - 1, sc, SIZEOF(sc)-1) != 0) {
+ bogus_line(s - 1);
return;
}
- s += sizeof(sc)-1;
+ s += SIZEOF(sc)-1;
ch = s[-1];
#undef sc
skip_whitespace(s, ch);
if(ch == '\0') {
- bogus_line();
+ bogus_line(s - 1);
return;
}
fp = s - 1;
skip_non_whitespace(s, ch);
s[-1] = '\0';
run_datestamp = newstralloc(run_datestamp, fp);
- s[-1] = ch;
+ s[-1] = (char)ch;
skip_whitespace(s, ch);
#define sc "label"
- if(ch == '\0' || strncmp(s - 1, sc, sizeof(sc)-1) != 0) {
- bogus_line();
+ if(ch == '\0' || strncmp(s - 1, sc, SIZEOF(sc)-1) != 0) {
+ bogus_line(s - 1);
return;
}
- s += sizeof(sc)-1;
+ s += SIZEOF(sc)-1;
ch = s[-1];
#undef sc
skip_whitespace(s, ch);
if(ch == '\0') {
- bogus_line();
+ bogus_line(s - 1);
return;
}
fp = s - 1;
s[-1] = '\0';
label = stralloc(fp);
- s[-1] = ch;
+ s[-1] = (char)ch;
if(tape_labels) {
fp = vstralloc(tape_labels, ", ", label, NULL);
last_run_tapes++;
if(stats_by_tape == NULL) {
- stats_by_tape = current_tape = (taper_t *)alloc(sizeof(taper_t));
+ stats_by_tape = current_tape = (taper_t *)alloc(SIZEOF(taper_t));
}
else {
- current_tape->next = (taper_t *)alloc(sizeof(taper_t));
+ current_tape->next = (taper_t *)alloc(SIZEOF(taper_t));
current_tape = current_tape->next;
}
current_tape->label = label;
skip_whitespace(s, ch);
#define sc "date"
- if(ch == '\0' || strncmp(s - 1, sc, sizeof(sc)-1) != 0) {
+ if(ch == '\0' || strncmp(s - 1, sc, SIZEOF(sc)-1) != 0) {
return; /* ignore bogus line */
}
- s += sizeof(sc)-1;
+ s += SIZEOF(sc)-1;
ch = s[-1];
#undef sc
skip_whitespace(s, ch);
if(ch == '\0') {
- bogus_line();
+ bogus_line(s - 1);
return;
}
fp = s - 1;
skip_non_whitespace(s, ch);
s[-1] = '\0';
run_datestamp = newstralloc(run_datestamp, fp);
- s[-1] = ch;
+ s[-1] = (char)ch;
started = 1;
}
static void
-handle_finish()
+handle_finish(void)
{
char *s;
int ch;
- float a_time;
+ double a_time;
if(curprog == P_DRIVER || curprog == P_AMFLUSH || curprog == P_PLANNER) {
s = curstr;
skip_whitespace(s, ch);
#define sc "date"
- if(ch == '\0' || strncmp(s - 1, sc, sizeof(sc)-1) != 0) {
- bogus_line();
+ if(ch == '\0' || strncmp(s - 1, sc, SIZEOF(sc)-1) != 0) {
+ bogus_line(s - 1);
return;
}
- s += sizeof(sc)-1;
+ s += SIZEOF(sc)-1;
ch = s[-1];
#undef sc
skip_whitespace(s, ch);
if(ch == '\0') {
- bogus_line();
+ bogus_line(s - 1);
return;
}
skip_non_whitespace(s, ch); /* ignore the date string */
skip_whitespace(s, ch);
#define sc "time"
- if(ch == '\0' || strncmp(s - 1, sc, sizeof(sc)-1) != 0) {
+ if(ch == '\0' || strncmp(s - 1, sc, SIZEOF(sc)-1) != 0) {
/* older planner doesn't write time */
if(curprog == P_PLANNER) return;
- bogus_line();
+ bogus_line(s - 1);
return;
}
- s += sizeof(sc)-1;
+ s += SIZEOF(sc)-1;
ch = s[-1];
#undef sc
skip_whitespace(s, ch);
if(ch == '\0') {
- bogus_line();
+ bogus_line(s - 1);
return;
}
- if(sscanf(s - 1, "%f", &a_time) != 1) {
- bogus_line();
+ if(sscanf(s - 1, "%lf", &a_time) != 1) {
+ bogus_line(s - 1);
return;
}
if(curprog == P_PLANNER) {
}
static void
-handle_stats()
+handle_stats(void)
{
- char *s;
+ char *s, *fp;
int ch;
+ char *hostname, *diskname, *datestamp;
+ int level = 0;
+ double sec, kps, nbytes, cbytes;
+ repdata_t *repdata;
+ disk_t *dp;
if(curprog == P_DRIVER) {
s = curstr;
skip_whitespace(s, ch);
#define sc "startup time"
- if(ch == '\0' || strncmp(s - 1, sc, sizeof(sc)-1) != 0) {
- bogus_line();
- return;
+ if(ch != '\0' && strncmp(s - 1, sc, sizeof(sc)-1) == 0) {
+ s += sizeof(sc)-1;
+ ch = s[-1];
+#undef sc
+
+ skip_whitespace(s, ch);
+ if(ch == '\0') {
+ bogus_line(s - 1);
+ return;
+ }
+ if(sscanf(s - 1, "%lf", &startup_time) != 1) {
+ bogus_line(s - 1);
+ return;
+ }
+ planner_time = startup_time;
}
- s += sizeof(sc)-1;
- ch = s[-1];
+#define sc "estimate"
+ else if(ch != '\0' && strncmp(s - 1, sc, sizeof(sc)-1) == 0) {
+ s += sizeof(sc)-1;
+ ch = s[-1];
#undef sc
- skip_whitespace(s, ch);
- if(ch == '\0') {
- bogus_line();
- return;
+ skip_whitespace(s, ch);
+ if(ch == '\0') {
+ bogus_line(s - 1);
+ return;
+ }
+ fp = s - 1;
+ skip_non_whitespace(s, ch);
+ s[-1] = '\0';
+ hostname = stralloc(fp);
+ s[-1] = (char)ch;
+
+ skip_whitespace(s, ch);
+ if(ch == '\0') {
+ bogus_line(s - 1);
+ amfree(hostname);
+ return;
+ }
+ fp = s - 1;
+ skip_non_whitespace(s, ch);
+ s[-1] = '\0';
+ diskname = stralloc(fp);
+ s[-1] = (char)ch;
+
+ skip_whitespace(s, ch);
+ if(ch == '\0') {
+ bogus_line(s - 1);
+ amfree(hostname);
+ amfree(diskname);
+ return;
+ }
+ fp = s - 1;
+ skip_non_whitespace(s, ch);
+ s[-1] = '\0';
+ datestamp = stralloc(fp);
+ s[-1] = (char)ch;
+
+ skip_whitespace(s, ch);
+ if(ch == '\0' || sscanf(s - 1, "%d", &level) != 1) {
+ bogus_line(s - 1);
+ amfree(hostname);
+ amfree(diskname);
+ amfree(datestamp);
+ return;
+ }
+ skip_integer(s, ch);
+ if(level < 0 || level > 9) {
+ amfree(hostname);
+ amfree(diskname);
+ amfree(datestamp);
+ return;
+ }
+
+ skip_whitespace(s, ch);
+
+ if(sscanf(s - 1,"[sec %lf nkb %lf ckb %lf kps %lf",
+ &sec, &nbytes, &cbytes, &kps) != 4) {
+ bogus_line(s - 1);
+ amfree(hostname);
+ amfree(diskname);
+ amfree(datestamp);
+ return;
+ }
+
+ dp = lookup_disk(hostname, diskname);
+ if(dp == NULL) {
+ addtostrange(hostname, diskname, level,
+ "ERROR [not in disklist]");
+ amfree(hostname);
+ amfree(diskname);
+ amfree(datestamp);
+ return;
+ }
+
+ repdata = find_repdata(dp, datestamp, level);
+
+ repdata->est_nsize = nbytes;
+ repdata->est_csize = cbytes;
+
+ amfree(hostname);
+ amfree(diskname);
+ amfree(datestamp);
}
- if(sscanf(s - 1, "%f", &startup_time) != 1) {
- bogus_line();
+ else {
+ bogus_line(s - 1);
return;
}
- planner_time = startup_time;
+#undef sc
+
}
}
static void
-handle_note()
+handle_note(void)
{
char *str = NULL;
/* ----- */
static void
-handle_error()
+handle_error(void)
{
char *s = NULL, *nl;
int ch;
skip_whitespace(s, ch);
#define sc "no-tape"
- if(ch != '\0' && strncmp(s - 1, sc, sizeof(sc)-1) == 0) {
- s += sizeof(sc)-1;
+ if(ch != '\0' && strncmp(s - 1, sc, SIZEOF(sc)-1) == 0) {
+ s += SIZEOF(sc)-1;
ch = s[-1];
#undef sc
/* ----- */
static void
-handle_summary()
+handle_summary(void)
{
- bogus_line();
+ bogus_line(curstr);
}
/* ----- */
static int nb_disk=0;
static void
-handle_disk()
+handle_disk(void)
{
disk_t *dp;
- char *s, *fp;
+ char *s, *fp, *qdiskname;
int ch;
char *hostname = NULL, *diskname = NULL;
if(curprog != P_PLANNER && curprog != P_AMFLUSH) {
- bogus_line();
+ bogus_line(curstr);
return;
}
skip_whitespace(s, ch);
if(ch == '\0') {
- bogus_line();
+ bogus_line(s - 1);
return;
}
fp = s - 1;
skip_non_whitespace(s, ch);
s[-1] = '\0';
hostname = newstralloc(hostname, fp);
- s[-1] = ch;
+ s[-1] = (char)ch;
skip_whitespace(s, ch);
if(ch == '\0') {
- bogus_line();
+ bogus_line(s - 1);
amfree(hostname);
return;
}
- fp = s - 1;
- skip_non_whitespace(s, ch);
+ qdiskname = s - 1;
+ skip_quoted_string(s, ch);
s[-1] = '\0';
- diskname = newstralloc(diskname, fp);
- s[-1] = ch;
+ diskname = unquote_string(qdiskname);
+ s[-1] = (char)ch;
dp = lookup_disk(hostname, diskname);
if(dp == NULL) {
* for a split chunk of the overall dumpfile.
*/
static repdata_t *
-handle_chunk()
+handle_chunk(void)
{
disk_t *dp;
- float sec, kps, kbytes;
+ double sec, kps, kbytes;
timedata_t *sp;
int i;
char *s, *fp;
char *datestamp;
if(curprog != P_TAPER) {
- bogus_line();
+ bogus_line(curstr);
return NULL;
}
skip_whitespace(s, ch);
if(ch == '\0') {
- bogus_line();
+ bogus_line(s - 1);
return NULL;
}
fp = s - 1;
skip_non_whitespace(s, ch);
s[-1] = '\0';
hostname = stralloc(fp);
- s[-1] = ch;
+ s[-1] = (char)ch;
skip_whitespace(s, ch);
if(ch == '\0') {
- bogus_line();
+ bogus_line(s - 1);
amfree(hostname);
return NULL;
}
fp = s - 1;
- skip_non_whitespace(s, ch);
+ skip_quoted_string(s, ch);
s[-1] = '\0';
- diskname = stralloc(fp);
- s[-1] = ch;
+ diskname = unquote_string(fp);
+ s[-1] = (char)ch;
skip_whitespace(s, ch);
if(ch == '\0') {
- bogus_line();
+ bogus_line(s - 1);
amfree(hostname);
amfree(diskname);
return NULL;
skip_non_whitespace(s, ch);
s[-1] = '\0';
datestamp = stralloc(fp);
- s[-1] = ch;
-
- level = atoi(datestamp);
- if(level < 100) {
- datestamp = newstralloc(datestamp, run_datestamp);
- }
- else {
- skip_whitespace(s, ch);
- if(ch == '\0' || sscanf(s - 1, "%d", &chunk) != 1) {
- bogus_line();
- amfree(hostname);
- amfree(diskname);
- amfree(datestamp);
- return NULL;
- }
- skip_integer(s, ch);
-
- skip_whitespace(s, ch);
- if(ch == '\0' || sscanf(s - 1, "%d", &level) != 1) {
- bogus_line();
- amfree(hostname);
- amfree(diskname);
- amfree(datestamp);
- return NULL;
- }
- skip_integer(s, ch);
+ s[-1] = (char)ch;
+
+ skip_whitespace(s, ch);
+ if(ch == '\0' || sscanf(s - 1, "%d", &chunk) != 1) {
+ bogus_line(s - 1);
+ amfree(hostname);
+ amfree(diskname);
+ amfree(datestamp);
+ return NULL;
}
+ skip_integer(s, ch);
+
skip_whitespace(s, ch);
+ if(ch == '\0' || sscanf(s - 1, "%d", &level) != 1) {
+ bogus_line(s - 1);
+ amfree(hostname);
+ amfree(diskname);
+ amfree(datestamp);
+ return NULL;
+ }
+ skip_integer(s, ch);
+ /*@ignore@*/
if(level < 0 || level > 9) {
amfree(hostname);
amfree(diskname);
amfree(datestamp);
return NULL;
}
-
- if(sscanf(s - 1,"[sec %f kb %f kps %f", &sec, &kbytes, &kps) != 3) {
- bogus_line();
+ /*@end@*/
+
+ skip_whitespace(s, ch);
+ if(sscanf(s - 1,"[sec %lf kb %lf kps %lf", &sec, &kbytes, &kps) != 3) {
+ bogus_line(s - 1);
amfree(hostname);
amfree(diskname);
amfree(datestamp);
}
static repdata_t *
-handle_success(logtype_t logtype)
+handle_success(
+ logtype_t logtype)
{
disk_t *dp;
- float sec, kps, kbytes, origkb;
+ double sec = 0.0;
+ double kps = 0.0;
+ double kbytes = 0.0;
+ double origkb = 0.0;
timedata_t *sp;
int i;
- char *s, *fp;
+ char *s, *fp, *qdiskname;
int ch;
char *hostname = NULL;
char *diskname = NULL;
repdata_t *repdata;
- int level;
+ int level = 0;
char *datestamp;
if(curprog != P_TAPER && curprog != P_DUMPER && curprog != P_PLANNER &&
curprog != P_CHUNKER) {
- bogus_line();
+ bogus_line(curstr);
return NULL;
}
skip_whitespace(s, ch);
if(ch == '\0') {
- bogus_line();
+ bogus_line(s - 1);
return NULL;
}
fp = s - 1;
skip_non_whitespace(s, ch);
s[-1] = '\0';
hostname = stralloc(fp);
- s[-1] = ch;
+ s[-1] = (char)ch;
skip_whitespace(s, ch);
if(ch == '\0') {
- bogus_line();
+ bogus_line(s - 1);
amfree(hostname);
return NULL;
}
- fp = s - 1;
- skip_non_whitespace(s, ch);
+ qdiskname = s - 1;
+ skip_quoted_string(s, ch);
s[-1] = '\0';
- diskname = stralloc(fp);
- s[-1] = ch;
+ diskname = unquote_string(qdiskname);
skip_whitespace(s, ch);
if(ch == '\0') {
- bogus_line();
+ bogus_line(s - 1);
amfree(hostname);
amfree(diskname);
return NULL;
skip_non_whitespace(s, ch);
s[-1] = '\0';
datestamp = stralloc(fp);
- s[-1] = ch;
+ s[-1] = (char)ch;
- level = atoi(datestamp);
- if(level < 100) {
+ if(strlen(datestamp) < 3) {
+ level = atoi(datestamp);
datestamp = newstralloc(datestamp, run_datestamp);
}
else {
skip_whitespace(s, ch);
if(ch == '\0' || sscanf(s - 1, "%d", &level) != 1) {
- bogus_line();
+ bogus_line(s - 1);
amfree(hostname);
amfree(diskname);
amfree(datestamp);
}
skip_integer(s, ch);
}
+
if(level < 0 || level > 9) {
amfree(hostname);
amfree(diskname);
/* Planner success messages (for skipped
dumps) do not contain statistics */
if(curprog != P_PLANNER) {
- if(curprog != P_DUMPER ||
- sscanf(s - 1,"[sec %f kb %f kps %f orig-kb %f",
- &sec, &kbytes, &kps, &origkb) != 4) {
+ if(*(s - 1) == '"')
+ s++;
+ if((curprog != P_DUMPER)
+ || (sscanf(s - 1,"[sec %lf kb %lf kps %lf orig-kb %lf",
+ &sec, &kbytes, &kps, &origkb) != 4)) {
origkb = -1;
- if(sscanf(s - 1,"[sec %f kb %f kps %f",
+ if(sscanf(s - 1,"[sec %lf kb %lf kps %lf",
&sec, &kbytes, &kps) != 3) {
- bogus_line();
+ bogus_line(s - 1);
amfree(hostname);
amfree(diskname);
amfree(datestamp);
}
}
else {
- if(origkb == 0.0) origkb = 0.1;
+ if(!isnormal(origkb))
+ origkb = 0.1;
}
}
dp = lookup_disk(hostname, diskname);
if(dp == NULL) {
- addtostrange(hostname, diskname, level, "ERROR [not in disklist]");
+ addtostrange(hostname, qdiskname, level, "ERROR [not in disklist]");
amfree(hostname);
amfree(diskname);
amfree(datestamp);
i = level > 0;
- if(origkb == -1) {
+ if(origkb < 0.0) {
info_t inf;
struct tm *tm;
int Idatestamp;
get_info(hostname, diskname, &inf);
tm = localtime(&inf.inf[level].date);
- Idatestamp = 10000*(tm->tm_year+1900) +
- 100*(tm->tm_mon+1) + tm->tm_mday;
+ if (tm) {
+ Idatestamp = 10000*(tm->tm_year+1900) +
+ 100*(tm->tm_mon+1) + tm->tm_mday;
+ } else {
+ Idatestamp = 19000101;
+ }
if(atoi(datestamp) == Idatestamp) {
/* grab original size from record */
else
origkb = 0.0;
}
+
+ if (curprog == P_DUMPER &&
+ (sp->result == L_FAIL || sp->result == L_PARTIAL)) {
+ addtostrange(hostname, qdiskname, level, "was successfully retried");
+ }
+
amfree(hostname);
amfree(diskname);
amfree(datestamp);
if(curprog == P_TAPER) {
if(current_tape == NULL) {
error("current_tape == NULL");
+ /*NOTREACHED*/
}
stats[i].taper_time += sec;
sp->filenum = ++tapefcount;
stats[i].tapedisks +=1;
stats[i].tapesize += kbytes;
sp->outsize = kbytes;
- if(repdata->chunker.outsize == 0.0 && repdata->dumper.outsize != 0.0) { /* dump to tape */
+ if(!isnormal(repdata->chunker.outsize) && isnormal(repdata->dumper.outsize)) { /* dump to tape */
stats[i].outsize += kbytes;
if(dp->compress != COMP_NONE) {
stats[i].coutsize += kbytes;
}
static void
-handle_partial()
+handle_partial(void)
{
repdata_t *repdata;
timedata_t *sp;
repdata = handle_success(L_PARTIAL);
+ if (!repdata)
+ return;
if(curprog == P_TAPER)
sp = &(repdata->taper);
}
static void
-handle_strange()
+handle_strange(void)
{
char *str = NULL;
char *strangestr = NULL;
repdata_t *repdata;
+ char *qdisk;
repdata = handle_success(L_SUCCESS);
+ if (!repdata)
+ return;
+
+ qdisk = quote_string(repdata->disk->name);
addline(&errdet,"");
str = vstralloc("/-- ", prefix(repdata->disk->host->hostname,
- repdata->disk->name, repdata->level),
+ qdisk, repdata->level),
" ", "STRANGE",
NULL);
addline(&errdet, str);
while(contline_next()) {
get_logline(logfile);
#define sc "sendbackup: warning "
- if(strncmp(curstr, sc, sizeof(sc)-1) == 0) {
- strangestr = newstralloc(strangestr, curstr+sizeof(sc)-1);
+ if(strncmp(curstr, sc, SIZEOF(sc)-1) == 0) {
+ strangestr = newstralloc(strangestr, curstr+SIZEOF(sc)-1);
}
addline(&errdet, curstr);
}
addline(&errdet,"\\--------");
str = vstralloc("STRANGE", " ", strangestr, NULL);
- addtostrange(repdata->disk->host->hostname, repdata->disk->name, repdata->level,
- str);
+ addtostrange(repdata->disk->host->hostname, qdisk, repdata->level, str);
+ amfree(qdisk);
amfree(str);
amfree(strangestr);
}
static void
-handle_failed()
+handle_failed(void)
{
disk_t *dp;
char *hostname;
char *diskname;
char *datestamp;
char *errstr;
- int level;
- char *s, *fp;
+ int level = 0;
+ char *s, *fp, *qdiskname;
int ch;
char *str = NULL;
repdata_t *repdata;
skip_whitespace(s, ch);
if(ch == '\0') {
- bogus_line();
+ bogus_line(s - 1);
return;
}
hostname = s - 1;
skip_whitespace(s, ch);
if(ch == '\0') {
- bogus_line();
+ bogus_line(s - 1);
return;
}
- diskname = s - 1;
- skip_non_whitespace(s, ch);
+ qdiskname = s - 1;
+ skip_quoted_string(s, ch);
s[-1] = '\0';
+ diskname = unquote_string(qdiskname);
skip_whitespace(s, ch);
if(ch == '\0') {
- bogus_line();
+ bogus_line(s - 1);
+ amfree(diskname);
return;
}
fp = s - 1;
else { /* read the level */
skip_whitespace(s, ch);
if(ch == '\0' || sscanf(s - 1, "%d", &level) != 1) {
- bogus_line();
+ bogus_line(s - 1);
amfree(datestamp);
+ amfree(diskname);
return;
}
skip_integer(s, ch);
skip_whitespace(s, ch);
if(ch == '\0') {
- bogus_line();
+ bogus_line(s - 1);
amfree(datestamp);
+ amfree(diskname);
return;
}
errstr = s - 1;
}
dp = lookup_disk(hostname, diskname);
+ amfree(diskname);
if(dp == NULL) {
- addtostrange(hostname, diskname, level, "ERROR [not in disklist]");
+ addtostrange(hostname, qdiskname, level, "ERROR [not in disklist]");
} else {
repdata = find_repdata(dp, datestamp, level);
amfree(datestamp);
str = vstralloc("FAILED", " ", errstr, NULL);
- addtostrange(hostname, diskname, level, str);
+ addtostrange(hostname, qdiskname, level, str);
amfree(str);
if(curprog == P_DUMPER) {
addline(&errdet,"");
- str = vstralloc("/-- ", prefix(hostname, diskname, level),
+ str = vstralloc("/-- ", prefix(hostname, qdiskname, level),
" ", "FAILED",
" ", errstr,
NULL);
static void
-generate_missing()
+generate_missing(void)
{
disk_t *dp;
+ char *qdisk;
for(dp = diskq.head; dp != NULL; dp = dp->next) {
if(dp->todo && data(dp) == NULL) {
- addtostrange(dp->host->hostname, dp->name, -987, "RESULTS MISSING");
+ qdisk = quote_string(dp->name);
+ addtostrange(dp->host->hostname, qdisk, -987, "RESULTS MISSING");
+ amfree(qdisk);
}
}
}
+static void
+generate_bad_estimate(void)
+{
+ disk_t *dp;
+ repdata_t *repdata;
+ char s[1000];
+ double outsize;
+
+ for(dp = diskq.head; dp != NULL; dp = dp->next) {
+ if(dp->todo) {
+ for(repdata = data(dp); repdata != NULL; repdata = repdata->next) {
+ if(repdata->est_csize >= 0.1) {
+ if(repdata->taper.result == L_SUCCESS ||
+ repdata->taper.result == L_PARTIAL ||
+ repdata->taper.result == L_CHUNKSUCCESS)
+ outsize = repdata->taper.outsize;
+ else if(repdata->chunker.result == L_SUCCESS ||
+ repdata->chunker.result == L_PARTIAL ||
+ repdata->chunker.result == L_CHUNKSUCCESS)
+ outsize = repdata->chunker.outsize;
+ else
+ outsize = repdata->dumper.outsize;
+
+ if(repdata->est_csize * 0.9 > outsize) {
+ snprintf(s, 1000,
+ " big estimate: %s %s %d",
+ repdata->disk->host->hostname,
+ repdata->disk->name,
+ repdata->level);
+ s[999] = '\0';
+ addline(¬es, s);
+ snprintf(s, 1000,
+ " est: %.0lf%s out %.0lf%s",
+ du(repdata->est_csize), displayunit,
+ du(outsize), displayunit);
+ s[999] = '\0';
+ addline(¬es, s);
+ }
+ else if(repdata->est_csize * 1.1 < outsize) {
+ snprintf(s, 1000,
+ " small estimate: %s %s %d",
+ repdata->disk->host->hostname,
+ repdata->disk->name,
+ repdata->level);
+ s[999] = '\0';
+ addline(¬es, s);
+ snprintf(s, 1000,
+ " est: %.0lf%s out %.0lf%s",
+ du(repdata->est_csize), displayunit,
+ du(outsize), displayunit);
+ s[999] = '\0';
+ addline(¬es, s);
+ }
+ }
+ }
+ }
+ }
+}
static char *
-prefix (host, disk, level)
- char *host;
- char *disk;
- int level;
+prefix (
+ char * host,
+ char * disk,
+ int level)
{
char number[NUM_STR_SIZE];
static char *str = NULL;
- snprintf(number, sizeof(number), "%d", level);
+ snprintf(number, SIZEOF(number), "%d", level);
str = newvstralloc(str,
" ", host ? host : "(host?)",
" ", disk ? disk : "(disk?)",
static char *
-prefixstrange (host, disk, level, len_host, len_disk)
- char *host;
- char *disk;
- int level;
- int len_host, len_disk;
+prefixstrange (
+ char * host,
+ char * disk,
+ int level,
+ size_t len_host,
+ size_t len_disk)
{
char *h, *d;
- int l;
+ size_t l;
char number[NUM_STR_SIZE];
static char *str = NULL;
- snprintf(number, sizeof(number), "%d", level);
- h=malloc(len_host+1);
+ snprintf(number, SIZEOF(number), "%d", level);
+ h=alloc(len_host+1);
if(host) {
strncpy(h, host, len_host);
} else {
for(l = strlen(h); l < len_host; l++) {
h[l] = ' ';
}
- d=malloc(len_disk+1);
+ d=alloc(len_disk+1);
if(disk) {
strncpy(d, disk, len_disk);
} else {
static void
-addtostrange (host, disk, level, str)
- char *host;
- char *disk;
- int level;
- char *str;
+addtostrange (
+ char * host,
+ char * disk,
+ int level,
+ char * str)
{
strange_t *strange;
- strange = malloc(sizeof(strange_t));
+ strange = alloc(SIZEOF(strange_t));
strange->hostname = stralloc(host);
strange->diskname = stralloc(disk);
strange->level = level;
static void
-copy_template_file(lbl_templ)
- char *lbl_templ;
+copy_template_file(
+ char * lbl_templ)
{
char buf[BUFSIZ];
int fd;
- int numread;
+ ssize_t numread;
if (strchr(lbl_templ, '/') == NULL) {
lbl_templ = stralloc2(config_dir, lbl_templ);
afclose(postscript);
return;
}
- while ((numread = read(fd, buf, sizeof(buf))) > 0) {
- if (fwrite(buf, numread, 1, postscript) != 1) {
+ while ((numread = read(fd, buf, SIZEOF(buf))) > 0) {
+ if (fwrite(buf, (size_t)numread, 1, postscript) != 1) {
curlog = L_ERROR;
curprog = P_REPORTER;
curstr = vstralloc("error copying PostScript template file ",
}
static repdata_t *
-find_repdata(dp, datestamp, level)
- disk_t *dp;
- char *datestamp;
- int level;
+find_repdata(
+ /*@keep@*/ disk_t *dp,
+ char * datestamp,
+ int level)
{
repdata_t *repdata, *prev;
prev = repdata;
}
if(!repdata) {
- repdata = (repdata_t *)alloc(sizeof(repdata_t));
- memset(repdata, '\0',sizeof(repdata_t));
+ repdata = (repdata_t *)alloc(SIZEOF(repdata_t));
+ memset(repdata, '\0', SIZEOF(repdata_t));
repdata->disk = dp;
repdata->datestamp = stralloc(datestamp ? datestamp : "");
repdata->level = level;
}
-static void do_postscript_output()
+static void
+do_postscript_output(void)
{
tapetype_t *tp = lookup_tapetype(getconf_str(CNF_TAPETYPE));
disk_t *dp;
repdata_t *repdata;
- float outsize, origsize;
- int tapesize, marksize;
+ double outsize, origsize;
+ off_t tapesize;
+ off_t marksize;
+
+ if (!tp)
+ return;
- tapesize = tp->length;
- marksize = tp->filemark;
+ tapesize = tapetype_get_length(tp);
+ marksize = tapetype_get_filemark(tp);
for(current_tape = stats_by_tape; current_tape != NULL;
current_tape = current_tape->next) {
break;
}
- copy_template_file(tp->lbl_templ);
+ copy_template_file(tapetype_get_lbl_templ(tp));
/* generate a few elements */
fprintf(postscript,"(%s) DrawDate\n\n",
- nicedate(run_datestamp ? atoi(run_datestamp) : 0));
+ nicedate(run_datestamp ? run_datestamp : "0"));
fprintf(postscript,"(Amanda Version %s) DrawVers\n",version());
fprintf(postscript,"(%s) DrawTitle\n", current_tape->label);
/* Stats */
- fprintf(postscript, "(Total Size: %6.1f MB) DrawStat\n",
+ fprintf(postscript, "(Total Size: %6.1lf MB) DrawStat\n",
mb(current_tape->coutsize));
fprintf(postscript, "(Tape Used (%%) ");
divzero(postscript, pct(current_tape->coutsize +
marksize * (current_tape->tapedisks + current_tape->tapechunks)),
- tapesize);
+ (double)tapesize);
fprintf(postscript," %%) DrawStat\n");
fprintf(postscript, "(Compression Ratio: ");
divzero(postscript, pct(current_tape->coutsize),current_tape->corigsize);
if (repdata->taper.result == L_SUCCESS ||
repdata->taper.result == L_PARTIAL) {
- if(origsize != 0.0) {
- fprintf(postscript,"(%s) (%s) (%d) (%3.0d) (%8.0f) (%8.0f) DrawHost\n",
+ if(isnormal(origsize)) {
+ fprintf(postscript,"(%s) (%s) (%d) (%3.0d) (%8.0lf) (%8.0lf) DrawHost\n",
dp->host->hostname, dp->name, repdata->level,
repdata->taper.filenum, origsize,
outsize);
}
else {
- fprintf(postscript,"(%s) (%s) (%d) (%3.0d) (%8s) (%8.0f) DrawHost\n",
+ fprintf(postscript,"(%s) (%s) (%d) (%3.0d) (%8s) (%8.0lf) DrawHost\n",
dp->host->hostname, dp->name, repdata->level,
repdata->taper.filenum, "N/A",
outsize);
* file named AUTHORS, in the root directory of this distribution.
*/
/*
- * $Id: server_util.c,v 1.13.2.1 2006/04/23 18:52:04 martinea Exp $
+ * $Id: server_util.c,v 1.17 2006/05/25 01:47:20 johnfranks Exp $
*
*/
#include "server_util.h"
#include "arglist.h"
#include "token.h"
+#include "logfile.h"
+#include "util.h"
+#include "conffile.h"
+#include "diskfile.h"
const char *cmdstr[] = {
"BOGUS", "QUIT", "QUITTING", "DONE", "PARTIAL",
- "START", "FILE-DUMP", "PORT-DUMP", "CONTINUE", "ABORT", /* dumper cmds */
+ "START", "FILE-DUMP", "PORT-DUMP", "CONTINUE", "ABORT",/* dumper cmds */
"FAILED", "TRY-AGAIN", "NO-ROOM", "RQ-MORE-DISK", /* dumper results */
"ABORT-FINISHED", "BAD-COMMAND", /* dumper results */
"START-TAPER", "FILE-WRITE", "PORT-WRITE", /* taper cmds */
};
-cmd_t getcmd(cmdargs)
-struct cmdargs *cmdargs;
+cmd_t
+getcmd(
+ struct cmdargs * cmdargs)
{
char *line;
cmd_t cmd_i;
if (isatty(0)) {
printf("%s> ", get_pname());
fflush(stdout);
+ line = readline(NULL);
+ } else {
+ line = agets(stdin);
}
-
- if ((line = agets(stdin)) == NULL) {
+ if (line == NULL) {
line = stralloc("QUIT");
}
cmdargs->argc = split(line, cmdargs->argv,
- sizeof(cmdargs->argv) / sizeof(cmdargs->argv[0]), " ");
+ (int)(sizeof(cmdargs->argv) / sizeof(cmdargs->argv[0])), " ");
amfree(line);
#if DEBUG
fflush(stdout);
arglist_end(argp);
}
+
+char *
+amhost_get_security_conf(
+ char * string,
+ void * arg)
+{
+ if(!string || !*string)
+ return(NULL);
+
+ if(strcmp(string, "krb5principal")==0)
+ return(getconf_str(CNF_KRB5PRINCIPAL));
+ else if(strcmp(string, "krb5keytab")==0)
+ return(getconf_str(CNF_KRB5KEYTAB));
+
+ if(!arg || !((am_host_t *)arg)->disks) return(NULL);
+
+ if(strcmp(string, "amandad_path")==0)
+ return ((am_host_t *)arg)->disks->amandad_path;
+ else if(strcmp(string, "client_username")==0)
+ return ((am_host_t *)arg)->disks->client_username;
+ else if(strcmp(string, "ssh_keys")==0)
+ return ((am_host_t *)arg)->disks->ssh_keys;
+
+ return(NULL);
+}
* file named AUTHORS, in the root directory of this distribution.
*/
/*
- * $Id: server_util.h,v 1.8.2.1 2006/04/23 18:52:04 martinea Exp $
+ * $Id: server_util.h,v 1.11 2006/05/25 01:47:20 johnfranks Exp $
*
*/
#ifndef SERVER_UTIL_H
#define MAX_ARGS 32
-typedef enum {
+/*
+ * Some lints are confused by: typedef enum (...) xxx_t;
+ * So here we use an equivalent of type int and an unnamed enum for constants.
+ */
+typedef int cmd_t;
+enum {
BOGUS, QUIT, QUITTING, DONE, PARTIAL,
START, FILE_DUMP, PORT_DUMP, CONTINUE, ABORT, /* dumper cmds */
FAILED, TRYAGAIN, NO_ROOM, RQ_MORE_DISK, /* dumper results */
PORT, TAPE_ERROR, TAPER_OK, SPLIT_NEEDNEXT, /* taper results */
SPLIT_CONTINUE,
LAST_TOK
-} cmd_t;
+};
extern const char *cmdstr[];
struct cmdargs {
char *argv[MAX_ARGS + 1];
};
-cmd_t getcmd P((struct cmdargs *cmdargs));
-void putresult P((cmd_t result, const char *, ...))
+cmd_t getcmd(struct cmdargs *cmdargs);
+cmd_t getresult(int fd, int show, int *result_argc, char **result_argv, int max_arg);
+void putresult(cmd_t result, const char *, ...)
__attribute__ ((format (printf, 2, 3)));
+int taper_cmd(cmd_t cmd, void *ptr, char *destname, int level, char *datestamp);
+
+struct disk_s;
+struct chunker_s;
+int chunker_cmd(struct chunker_s *chunker, cmd_t cmd, struct disk_s *dp);
+
+struct dumper_s;
+int dumper_cmd(struct dumper_s *dumper, cmd_t cmd, struct disk_s *dp);
+
+char *amhost_get_security_conf(char *string, void *arg);
#endif /* SERVER_UTIL_H */
* file named AUTHORS, in the root directory of this distribution.
*/
/*
- * $Id: tapefile.c,v 1.28 2003/10/24 13:44:35 martinea Exp $
+ * $Id: tapefile.c,v 1.37 2006/07/21 00:25:52 martinea Exp $
*
* routines to read and write the amanda active tape list
*/
static tape_t *tape_list = NULL;
/* local functions */
-static tape_t *parse_tapeline P((int *status, char *line));
-static tape_t *insert P((tape_t *list, tape_t *tp));
-static time_t stamp2time P((int datestamp));
+static tape_t *parse_tapeline(int *status, char *line);
+static tape_t *insert(tape_t *list, tape_t *tp);
+static time_t stamp2time(char *datestamp);
-
-
-int read_tapelist(tapefile)
-char *tapefile;
+int
+read_tapelist(
+ char *tapefile)
{
tape_t *tp;
FILE *tapef;
int pos;
char *line = NULL;
- int status;
+ int status = 0;
tape_list = NULL;
if((tapef = fopen(tapefile,"r")) == NULL) {
}
while((line = agets(tapef)) != NULL) {
+ if (line[0] == '\0') {
+ amfree(line);
+ continue;
+ }
tp = parse_tapeline(&status, line);
amfree(line);
- if(tp == NULL && status != 0) return 1;
- if(tp != NULL) tape_list = insert(tape_list, tp);
+ if(tp == NULL && status != 0)
+ return 1;
+ if(tp != NULL)
+ tape_list = insert(tape_list, tp);
}
afclose(tapef);
return 0;
}
-int write_tapelist(tapefile)
-char *tapefile;
+int
+write_tapelist(
+ char *tapefile)
{
tape_t *tp;
FILE *tapef;
}
for(tp = tape_list; tp != NULL; tp = tp->next) {
- fprintf(tapef, "%d %s", tp->datestamp, tp->label);
+ fprintf(tapef, "%s %s", tp->datestamp, tp->label);
if(tp->reuse) fprintf(tapef, " reuse");
else fprintf(tapef, " no-reuse");
fprintf(tapef, "\n");
if (fclose(tapef) == EOF) {
fprintf(stderr,"error [closing %s: %s]", newtapefile, strerror(errno));
+ amfree(newtapefile);
return 1;
}
rc = rename(newtapefile, tapefile);
return(rc != 0);
}
-void clear_tapelist()
+void
+clear_tapelist(void)
{
tape_t *tp, *next;
for(tp = tape_list; tp; tp = next) {
amfree(tp->label);
+ amfree(tp->datestamp);
next = tp->next;
amfree(tp);
}
tape_list = NULL;
}
-tape_t *lookup_tapelabel(label)
-char *label;
+tape_t *
+lookup_tapelabel(
+ char *label)
{
tape_t *tp;
-tape_t *lookup_tapepos(pos)
-int pos;
+tape_t *
+lookup_tapepos(
+ int pos)
{
tape_t *tp;
}
-tape_t *lookup_tapedate(datestamp)
-int datestamp;
+tape_t *
+lookup_tapedate(
+ char *datestamp)
{
tape_t *tp;
for(tp = tape_list; tp != NULL; tp = tp->next) {
- if(tp->datestamp == datestamp) return tp;
+ if(strcmp(tp->datestamp, datestamp) == 0) return tp;
}
return NULL;
}
-int lookup_nb_tape()
+int
+lookup_nb_tape(void)
{
tape_t *tp;
int pos=0;
return pos;
}
-tape_t *lookup_last_reusable_tape(skip)
- int skip;
+tape_t *
+lookup_last_reusable_tape(
+ int skip)
{
tape_t *tp, **tpsave;
int count=0;
* caller. If skip is zero, the oldest is returned, if it is
* one, the next oldest, two, the next to next oldest and so on.
*/
- tpsave = alloc((skip + 1) * sizeof (*tpsave));
+ tpsave = alloc((skip + 1) * SIZEOF(*tpsave));
for(s = 0; s <= skip; s++) {
tpsave[s] = NULL;
}
for(tp = tape_list; tp != NULL; tp = tp->next) {
- if(tp->reuse == 1 && tp->datestamp > 0 && match (labelstr, tp->label)) {
+ if(tp->reuse == 1 && strcmp(tp->datestamp,"0") != 0 && match (labelstr, tp->label)) {
count++;
for(s = skip; s > 0; s--) {
tpsave[s] = tpsave[s - 1];
return tp;
}
-int reusable_tape(tp)
- tape_t *tp;
+int
+reusable_tape(
+ tape_t *tp)
{
int count = 0;
if(tp == NULL) return 0;
if(tp->reuse == 0) return 0;
- if(tp->datestamp == 0) return 1;
+ if( strcmp(tp->datestamp,"0") == 0) return 1;
while(tp != NULL) {
if(tp->reuse == 1) count++;
tp = tp->prev;
return (count >= getconf_int(CNF_TAPECYCLE));
}
-void remove_tapelabel(label)
-char *label;
+void
+remove_tapelabel(
+ char *label)
{
tape_t *tp, *prev, *next;
if(tp != NULL) {
prev = tp->prev;
next = tp->next;
+ /*@ignore@*/
if(prev != NULL)
prev->next = next;
else /* begin of list */
tape_list = next;
if(next != NULL)
next->prev = prev;
+ /*@end@*/
while (next != NULL) {
next->position--;
next = next->next;
}
+ amfree(tp->datestamp);
amfree(tp->label);
amfree(tp);
}
}
-tape_t *add_tapelabel(datestamp, label)
-int datestamp;
-char *label;
+tape_t *
+add_tapelabel(
+ char *datestamp,
+ char *label)
{
tape_t *cur, *new;
/* insert a new record to the front of the list */
- new = (tape_t *) alloc(sizeof(tape_t));
+ new = (tape_t *) alloc(SIZEOF(tape_t));
- new->datestamp = datestamp;
+ new->datestamp = stralloc(datestamp);
new->position = 0;
new->reuse = 1;
new->label = stralloc(label);
return new;
}
-int guess_runs_from_tapelist()
+int
+guess_runs_from_tapelist(void)
{
tape_t *tp;
int i, ntapes, tape_ndays, dumpcycle, runtapes, runs;
if((tp = lookup_tapepos(i)) == NULL) break;
tape_time = stamp2time(tp->datestamp);
- tape_ndays = days_diff(tape_time, today);
+ tape_ndays = (int)days_diff(tape_time, today);
if(tape_ndays < dumpcycle) ntapes++;
else break;
return runs;
}
-static tape_t *parse_tapeline(status, line)
-int *status;
-char *line;
+static tape_t *
+parse_tapeline(
+ int *status,
+ char *line)
{
tape_t *tp = NULL;
char *s, *s1;
int ch;
*status = 0;
- tp = (tape_t *) alloc(sizeof(tape_t));
+ tp = (tape_t *) alloc(SIZEOF(tape_t));
tp->prev = NULL;
tp->next = NULL;
amfree(tp);
return NULL;
}
- if (sscanf(s - 1, "%d", &tp->datestamp) != 1) {
- amfree(tp);
- *status = 1;
- return NULL;
- }
- skip_integer(s, ch);
+ s1 = s - 1;
+ skip_non_whitespace(s, ch);
+ s[-1] = '\0';
+ tp->datestamp = stralloc(s1);
skip_whitespace(s, ch);
s1 = s - 1;
skip_non_whitespace(s, ch);
s[-1] = '\0';
tp->label = stralloc(s1);
+
skip_whitespace(s, ch);
tp->reuse = 1;
#define sc "reuse"
- if(strncmp(s - 1, sc, sizeof(sc)-1) == 0)
+ if(strncmp(s - 1, sc, SIZEOF(sc)-1) == 0)
tp->reuse = 1;
#undef sc
#define sc "no-reuse"
- if(strncmp(s - 1, sc, sizeof(sc)-1) == 0)
+ if(strncmp(s - 1, sc, SIZEOF(sc)-1) == 0)
tp->reuse = 0;
#undef sc
/* insert in reversed datestamp order */
-static tape_t *insert(list, tp)
-tape_t *list, *tp;
+/*@ignore@*/
+static tape_t *
+insert(
+ tape_t *list,
+ tape_t *tp)
{
tape_t *prev, *cur;
prev = NULL;
cur = list;
- while(cur != NULL && cur->datestamp >= tp->datestamp) {
+ while(cur != NULL && strcmp(cur->datestamp, tp->datestamp) >= 0) {
prev = cur;
cur = cur->next;
}
tp->prev = prev;
tp->next = cur;
- if(prev == NULL) list = tp;
- else prev->next = tp;
- if(cur !=NULL) cur->prev = tp;
+ if(prev == NULL) {
+ list = tp;
+#ifndef __lint
+ } else {
+ prev->next = tp;
+#endif
+ }
+ if(cur !=NULL)
+ cur->prev = tp;
return list;
}
+/*@end@*/
-
-static time_t stamp2time(datestamp)
-int datestamp;
/*
- * Converts datestamp (an int of the form YYYYMMDD) into a real time_t value.
+ * Converts datestamp (an char of the form YYYYMMDD or YYYYMMDDHHMMSS) into a real
+ * time_t value.
* Since the datestamp contains no timezone or hh/mm/ss information, the
* value is approximate. This is ok for our purposes, since we round off
* scheduling calculations to the nearest day.
*/
+
+static time_t
+stamp2time(
+ char *datestamp)
{
- struct tm tm;
+ struct tm *tm;
time_t now;
+ char date[9];
+ int dateint;
+ strncpy(date, datestamp, 8);
+ date[8] = '\0';
+ dateint = atoi(date);
now = time(0);
- tm = *localtime(&now); /* initialize sec/min/hour & gmtoff */
+ tm = localtime(&now); /* initialize sec/min/hour & gmtoff */
+
+ if (!tm) {
+ tm = alloc(SIZEOF(struct tm));
+ tm->tm_sec = 0;
+ tm->tm_min = 0;
+ tm->tm_hour = 0;
+ tm->tm_wday = 0;
+ tm->tm_yday = 0;
+ tm->tm_isdst = 0;
+ }
+
- tm.tm_year = ( datestamp / 10000) - 1900;
- tm.tm_mon = ((datestamp % 10000) / 100) - 1;
- tm.tm_mday = ((datestamp % 100) );
+ tm->tm_year = ( dateint / 10000) - 1900;
+ tm->tm_mon = ((dateint % 10000) / 100) - 1;
+ tm->tm_mday = ((dateint % 100) );
- return mktime(&tm);
+ return mktime(tm);
}
* University of Maryland at College Park
*/
/*
- * $Id: tapefile.h,v 1.7 1999/05/14 21:40:21 kashmir Exp $
+ * $Id: tapefile.h,v 1.9 2006/05/25 01:47:20 johnfranks Exp $
*
* interface for active tape list manipulation routines
*/
typedef struct tape_s {
struct tape_s *next, *prev;
int position;
- int datestamp;
+ char * datestamp;
int reuse;
char *label;
} tape_t;
-int read_tapelist P((char *tapefile));
-int write_tapelist P((char *tapefile));
-void clear_tapelist P((void));
-tape_t *lookup_tapelabel P((char *label));
-tape_t *lookup_tapepos P((int pos));
-tape_t *lookup_tapedate P((int datestamp));
-int lookup_nb_tape P((void));
-tape_t *lookup_last_reusable_tape P((int skip));
-void remove_tapelabel P((char *label));
-tape_t *add_tapelabel P((int datestamp, char *label));
-int reusable_tape P((tape_t *tp));
+int read_tapelist(char *tapefile);
+int write_tapelist(char *tapefile);
+void clear_tapelist(void);
+tape_t *lookup_tapelabel(char *label);
+tape_t *lookup_tapepos(int pos);
+tape_t *lookup_tapedate(char *datestamp);
+int lookup_nb_tape(void);
+tape_t *lookup_last_reusable_tape(int skip);
+void remove_tapelabel(char *label);
+tape_t *add_tapelabel(char *datestamp, char *label);
+int reusable_tape(tape_t *tp);
-int guess_runs_from_tapelist P((void));
+int guess_runs_from_tapelist(void);
#endif /* !TAPEFILE_H */
* Authors: the Amanda Development Team. Its members are listed in a
* file named AUTHORS, in the root directory of this distribution.
*/
-/* $Id: taper.c,v 1.118.2.1 2006/05/04 21:31:15 martinea Exp $
+/* $Id: taper.c,v 1.144 2006/08/24 11:23:32 martinea Exp $
*
* moves files from holding disk to tape, or from a socket to tape
*/
static int offset = 0;
static char *datestr = NULL;
static char start_datestr[20];
-time_t raw_time;
-struct tm tape_time;
-struct tm backup_time;
-struct tm *tape_timep = &tape_time;
+static time_t raw_time;
+static struct tm tape_time;
+static struct tm backup_time;
+static struct tm *tape_timep = &tape_time;
typedef struct vtbl_lbls {
u_int8_t label[45];
u_int8_t date[20];
* XXX advance to next tape first in next_tape
* XXX label is being read twice?
*/
-long splitsize = 0; /* max size of dumpfile before split (Kb) */
-char *splitbuf = NULL;
-char *splitbuf_wr_ptr = NULL; /* the number of Kb we've written into splitbuf */
+static off_t splitsize = (off_t)0; /* max size of dumpfile before split (Kb) */
+static off_t mmap_splitsize = (off_t)0;
+static char *mmap_filename = NULL;
+static char *mmap_splitbuf = NULL;
+static char *mem_splitbuf = NULL;
+static char *splitbuf = NULL;
+static off_t mem_splitsize = (off_t)0;
+static char *splitbuf_wr_ptr = NULL; /* the number of Kb we've written into splitbuf */
int orig_holdfile = -1;
/* NBUFS replaced by conf_tapebufs */
/* #define NBUFS 20 */
-int conf_tapebufs;
+static int conf_tapebufs;
-off_t maxseek = (off_t)1 << ((sizeof(off_t) * 8) - 11);
+static off_t maxseek = (off_t)1 << ((SIZEOF(off_t) * 8) - 11);
-char *holdfile_path = NULL;
-char *holdfile_path_thischunk = NULL;
-int num_holdfile_chunks = 0;
-dumpfile_t holdfile_hdr;
-dumpfile_t holdfile_hdr_thischunk;
-off_t holdfile_offset_thischunk = (off_t)0;
-int splitbuffer_fd = -1;
-char *splitbuffer_path = NULL;
+static char *holdfile_path = NULL;
+static char *holdfile_path_thischunk = NULL;
+static int num_holdfile_chunks = 0;
+static off_t holdfile_offset_thischunk = (off_t)0;
+static int mmap_splitbuffer_fd = -1;
#define MODE_NONE 0
#define MODE_FILE_WRITE 1
#define MODE_PORT_WRITE 2
-int mode = MODE_NONE;
+static mode_t mode = MODE_NONE;
/* This is now the number of empties, not full bufs */
#define THRESHOLD 1
#define CONNECT_TIMEOUT 2*60
-
-
#define EMPTY 1
#define FILLING 2
#define FULL 3
typedef struct buffer_s {
long status;
- unsigned int size;
+ ssize_t size;
char *buffer;
} buffer_t;
#define prevbuf(p) ((p) == buftable? buftable+conf_tapebufs-1 : (p)-1)
/* major modules */
-int main P((int main_argc, char **main_argv));
-void file_reader_side P((int rdpipe, int wrpipe));
-void tape_writer_side P((int rdpipe, int wrpipe));
+int main(int main_argc, char **main_argv);
+void file_reader_side(int rdpipe, int wrpipe);
+void tape_writer_side(int rdpipe, int wrpipe);
+void put_syncpipe_fault_result(char *handle);
/* shared-memory routines */
-char *attach_buffers P((unsigned int size));
-void detach_buffers P((char *bufp));
-void destroy_buffers P((void));
+char *attach_buffers(size_t size);
+void detach_buffers(char *bufp);
+void destroy_buffers(void);
#define REMOVE_SHARED_MEMORY() \
detach_buffers(buffers); \
if (strcmp(procname, "reader") == 0) { \
}
/* synchronization pipe routines */
-void syncpipe_init P((int rd, int wr));
-char syncpipe_get P((int *intp));
-int syncpipe_getint P((void));
-char *syncpipe_getstr P((void));
-void syncpipe_put P((int ch, int intval));
-void syncpipe_putint P((int i));
-void syncpipe_putstr P((const char *str));
+void syncpipe_init(int rd, int wr);
+void syncpipe_read_error(ssize_t rc, ssize_t expected);
+void syncpipe_write_error(ssize_t rc, ssize_t expected);
+int syncpipe_get(int *intp);
+int syncpipe_getint(void);
+char *syncpipe_getstr(void);
+int syncpipe_put(int ch, int intval);
+int syncpipe_putint(int i);
+int syncpipe_putstr(const char *str);
/* tape manipulation subsystem */
-int first_tape P((char *new_datestamp));
-int next_tape P((int writerr));
-int end_tape P((int writerr));
-int write_filemark P((void));
+int first_tape(char *new_datestamp);
+int next_tape(int writerr);
+int end_tape(int writerr);
+int write_filemark(void);
/* support crap */
-int seek_holdfile P((int fd, buffer_t *bp, long kbytes));
+int seek_holdfile(int fd, buffer_t *bp, off_t kbytes);
/* signal handling */
-static void install_signal_handlers P((void));
-static void signal_handler P((int));
+static void install_signal_handlers(void);
+static void signal_handler(int);
/* exit routine */
-static void cleanup P((void));
+static void cleanup(void);
/*
* ========================================================================
*
*/
int interactive;
-int writerpid;
+pid_t writerpid;
times_t total_wait;
#ifdef TAPER_DEBUG
int bufdebug = 1;
char *procname = "parent";
-char *taper_datestamp = NULL;
+char *taper_timestamp = NULL;
char *label = NULL;
int filenum;
char *errstr = NULL;
char *tapedev = NULL;
char *tapetype = NULL;
tapetype_t *tt = NULL;
-long tt_blocksize;
-long tt_blocksize_kb;
-long buffer_size;
+size_t tt_blocksize;
+size_t tt_blocksize_kb;
+size_t buffer_size;
int tt_file_pad;
static unsigned long malloc_hist_1, malloc_size_1;
static unsigned long malloc_hist_2, malloc_size_2;
dumpfile_t file;
dumpfile_t *save_holdfile = NULL;
-long cur_span_chunkstart = 0; /* start of current split dump chunk (Kb) */
+off_t cur_span_chunkstart = (off_t)0; /* start of current split dump chunk (Kb) */
char *holdfile_name;
int num_splits = 0;
int expected_splits = 0;
* MAIN PROGRAM
*
*/
-int main(main_argc, main_argv)
-int main_argc;
-char **main_argv;
+int
+main(
+ int main_argc,
+ char **main_argv)
{
int p2c[2], c2p[2]; /* parent-to-child, child-to-parent pipes */
char *conffile;
- unsigned int size;
+ size_t size;
int i;
- int j;
- int page_size;
+ size_t j;
+ size_t page_size;
char *first_buffer;
+ int new_argc, my_argc;
+ char **new_argv, **my_argv;
safe_fd(-1, 0);
set_pname("taper");
+ dbopen("server");
+
/* Don't die when child closes pipe */
signal(SIGPIPE, SIG_IGN);
malloc_size_1 = malloc_inuse(&malloc_hist_1);
+ parse_server_conf(main_argc, main_argv, &new_argc, &new_argv);
+ my_argc = new_argc;
+ my_argv = new_argv;
+
fprintf(stderr, "%s: pid %ld executable %s version %s\n",
- get_pname(), (long) getpid(), main_argv[0], version());
+ get_pname(), (long) getpid(), my_argv[0], version());
+ dbprintf(("%s: pid %ld executable %s version %s\n",
+ get_pname(), (long) getpid(), my_argv[0], version()));
fflush(stderr);
- if (main_argc > 1 && main_argv[1][0] != '-') {
- config_name = stralloc(main_argv[1]);
- config_dir = vstralloc(CONFIG_DIR, "/", main_argv[1], "/", NULL);
- main_argc--;
- main_argv++;
+ if (my_argc > 1 && my_argv[1][0] != '-') {
+ config_name = stralloc(my_argv[1]);
+ config_dir = vstralloc(CONFIG_DIR, "/", my_argv[1], "/", NULL);
+ my_argc--;
+ my_argv++;
} else {
char my_cwd[STR_SIZE];
- if (getcwd(my_cwd, sizeof(my_cwd)) == NULL) {
+ if (getcwd(my_cwd, SIZEOF(my_cwd)) == NULL) {
error("cannot determine current working directory");
+ /*NOTREACHED*/
}
config_dir = stralloc2(my_cwd, "/");
if ((config_name = strrchr(my_cwd, '/')) != NULL) {
/* print prompts and debug messages if running interactive */
- interactive = (main_argc > 1 && strcmp(main_argv[1],"-t") == 0);
- if(interactive) {
+ interactive = (my_argc > 1 && strcmp(my_argv[1],"-t") == 0);
+ if (interactive) {
erroutput_type = ERR_INTERACTIVE;
} else {
erroutput_type = ERR_AMANDALOG;
set_logerror(logerror);
}
+ free_new_argv(new_argc, new_argv);
+
conffile = stralloc2(config_dir, CONFFILE_NAME);
- if(read_conffile(conffile)) {
+ if (read_conffile(conffile)) {
error("errors processing config file \"%s\"", conffile);
+ /*NOTREACHED*/
}
amfree(conffile);
+ dbrename(config_name, DBG_SUBDIR_SERVER);
+
+ report_bad_conf_arg();
+
conf_tapelist = getconf_str(CNF_TAPELIST);
if (*conf_tapelist == '/') {
conf_tapelist = stralloc(conf_tapelist);
} else {
conf_tapelist = stralloc2(config_dir, conf_tapelist);
}
- if(read_tapelist(conf_tapelist)) {
+ if (read_tapelist(conf_tapelist)) {
error("could not load tapelist \"%s\"", conf_tapelist);
+ /*NOTREACHED*/
}
- tapedev = getconf_str(CNF_TAPEDEV);
+ tapedev = stralloc(getconf_str(CNF_TAPEDEV));
tapetype = getconf_str(CNF_TAPETYPE);
tt = lookup_tapetype(tapetype);
#ifdef HAVE_LIBVTBLC
- rawtapedev = getconf_str(CNF_RAWTAPEDEV);
+ rawtapedev = stralloc(getconf_str(CNF_RAWTAPEDEV));
#endif /* HAVE_LIBVTBLC */
tapedays = getconf_int(CNF_TAPECYCLE);
labelstr = getconf_str(CNF_LABELSTR);
conf_tapebufs = getconf_int(CNF_TAPEBUFS);
- tt_blocksize_kb = tt->blocksize;
+ tt_blocksize_kb = (size_t)tapetype_get_blocksize(tt);
tt_blocksize = tt_blocksize_kb * 1024;
- tt_file_pad = tt->file_pad;
+ tt_file_pad = tapetype_get_file_pad(tt);
- if(interactive) {
+ if (interactive) {
fprintf(stderr,"taper: running in interactive test mode\n");
+ dbprintf(("taper: running in interactive test mode\n"));
fflush(stderr);
}
/* create read/write syncronization pipes */
- if(pipe(p2c) || pipe(c2p))
+ if (pipe(p2c)) {
+ error("creating sync pipes: %s", strerror(errno));
+ /*NOTREACHED*/
+ }
+ if (pipe(c2p)) {
error("creating sync pipes: %s", strerror(errno));
+ /*NOTREACHED*/
+ }
/* create shared memory segment */
#if defined(HAVE_GETPAGESIZE)
- page_size = getpagesize();
- fprintf(stderr, "%s: page size is %d\n", get_pname(), page_size);
+ page_size = (size_t)getpagesize();
+ fprintf(stderr, "%s: page size = " SIZE_T_FMT "\n",
+ get_pname(), (SIZE_T_FMT_TYPE)page_size);
+ dbprintf(("%s: page size = " SIZE_T_FMT "\n", get_pname(),
+ (SIZE_T_FMT_TYPE)page_size));
#else
page_size = 1024;
- fprintf(stderr, "%s: getpagesize() not available, using %d\n",
- get_pname(),
- page_size);
+ fprintf(stderr, "%s: getpagesize() not available, using " SIZE_T_FMT "\n",
+ get_pname(), page_size);
+ dbprintf((stderr, "%s: getpagesize() not available, using " SIZE_T_FMT "\n",
+ get_pname(), page_size));
#endif
buffer_size = am_round(tt_blocksize, page_size);
- fprintf(stderr, "%s: buffer size is %ld\n", get_pname(), buffer_size);
- while(conf_tapebufs > 0) {
+ fprintf(stderr, "%s: buffer size is " SIZE_T_FMT "\n",
+ get_pname(), (SIZE_T_FMT_TYPE)buffer_size);
+ dbprintf(("%s: buffer size is " SIZE_T_FMT "\n",
+ get_pname(), (SIZE_T_FMT_TYPE)buffer_size));
+ while (conf_tapebufs > 0) {
size = page_size;
size += conf_tapebufs * buffer_size;
- size += conf_tapebufs * sizeof(buffer_t);
- if((buffers = attach_buffers(size)) != NULL) {
+ size += conf_tapebufs * SIZEOF(buffer_t);
+ if ((buffers = attach_buffers(size)) != NULL) {
break;
}
log_add(L_INFO, "attach_buffers: (%d tapebuf%s: %d bytes) %s",
strerror(errno));
conf_tapebufs--;
}
- if(buffers == NULL) {
+ if (buffers == NULL) {
error("cannot allocate shared memory");
+ /*NOTREACHED*/
}
- i = (buffers - (char *)0) & (page_size - 1); /* page boundary offset */
- if(i != 0) {
+
+ /* page boundary offset */
+ i = (int)((buffers - (char *)0) & (page_size - 1));
+ if (i != 0) {
first_buffer = buffers + page_size - i;
- fprintf(stderr, "%s: shared memory at %p, first buffer at %p\n",
+ dbprintf(("%s: shared memory at %p, first buffer at %p\n",
get_pname(),
- buffers,
- first_buffer);
+ (void *)buffers,
+ (void *)first_buffer));
} else {
first_buffer = buffers;
}
- buftable = (buffer_t *)(first_buffer + conf_tapebufs * buffer_size);
- memset(buftable, 0, conf_tapebufs * sizeof(buffer_t));
- if(conf_tapebufs < 10) {
+
+ /*LINTED first_buffer, conf_tapebufs and buffer size are all * pagesize */
+ buftable = (buffer_t *)(first_buffer + (conf_tapebufs * buffer_size));
+ memset(buftable, 0, conf_tapebufs * SIZEOF(buffer_t));
+ if (conf_tapebufs < 10) {
j = 1;
- } else if(conf_tapebufs < 100) {
+ } else if (conf_tapebufs < 100) {
j = 2;
} else {
j = 3;
}
- for(i = 0; i < conf_tapebufs; i++) {
+ for (i = 0; i < conf_tapebufs; i++) {
buftable[i].buffer = first_buffer + i * buffer_size;
- fprintf(stderr, "%s: buffer[%0*d] at %p\n",
+ dbprintf(("%s: buffer[%0*d] at %p\n",
get_pname(),
- j, i,
- buftable[i].buffer);
+ (int)j, i,
+ (void *)buftable[i].buffer));
}
- fprintf(stderr, "%s: buffer structures at %p for %d bytes\n",
+ dbprintf(("%s: buffer structures at %p for %d bytes\n",
get_pname(),
- buftable,
- (int)(conf_tapebufs * sizeof(buffer_t)));
+ (void *)buftable,
+ (int)(conf_tapebufs * SIZEOF(buffer_t))));
/* fork off child writer process, parent becomes reader process */
-
switch(writerpid = fork()) {
case -1:
error("fork: %s", strerror(errno));
+ /*NOTREACHED*/
case 0: /* child */
aclose(p2c[1]);
tape_writer_side(p2c[0], c2p[1]);
error("tape writer terminated unexpectedly");
+ /*NOTREACHED*/
default: /* parent */
aclose(p2c[0]);
file_reader_side(c2p[0], p2c[1]);
error("file reader terminated unexpectedly");
+ /*NOTREACHED*/
}
- /* NOTREACHED */
+ /*NOTREACHED*/
return 0;
}
* FILE READER SIDE
*
*/
-int read_file P((int fd, char *handle,
+int read_file(int fd, char *handle,
char *host, char *disk, char *datestamp,
- int level));
-int taper_fill_buffer P((int fd, buffer_t *bp, int buflen));
-void dumpbufs P((char *str1));
-void dumpstatus P((buffer_t *bp));
-int get_next_holding_file P((int fd, buffer_t *bp, char *strclosing, int rc));
-int predict_splits P((char *filename));
-void create_split_buffer P((char *split_diskbuffer, long fallback_splitsize, char *id_string));
-void free_split_buffer P(());
+ int level);
+ssize_t taper_fill_buffer(int fd, buffer_t *bp, size_t buflen);
+void dumpbufs(char *str1);
+void dumpstatus(buffer_t *bp);
+ssize_t get_next_holding_file(int fd, buffer_t *bp, char **strclosing, size_t rc);
+int predict_splits(char *filename);
+void create_split_buffer(char *split_diskbuffer, size_t fallback_splitsize, char *id_string);
+void free_split_buffer(void);
/*
* Create a buffer, either in an mmapped file or in memory, where PORT-WRITE
* dumps can buffer the current split chunk in case of retry.
*/
-void create_split_buffer(split_diskbuffer, fallback_splitsize, id_string)
-char *split_diskbuffer;
-long fallback_splitsize;
-char *id_string;
+void
+create_split_buffer(
+ char *split_diskbuffer,
+ size_t fallback_splitsize,
+ char *id_string)
{
char *buff_err = NULL;
- void *nulls = NULL;
- int c;
+ off_t offset;
+ char *splitbuffer_path = NULL;
/* don't bother if we're not actually splitting */
- if(splitsize <= 0){
+ if (splitsize <= (off_t)0) {
splitbuf = NULL;
splitbuf_wr_ptr = NULL;
return;
#ifdef HAVE_MMAP
#ifdef HAVE_SYS_MMAN_H
- if(strcmp(split_diskbuffer, "NULL")){
+ if (strcmp(split_diskbuffer, "NULL")) {
+ void *nulls = NULL;
+ char *quoted;
+ off_t c;
+
splitbuffer_path = vstralloc(split_diskbuffer,
- "/splitdump_buffer_XXXXXX",
+ "/splitdump_buffer",
NULL);
-#ifdef HAVE_MKSTEMP
- splitbuffer_fd = mkstemp(splitbuffer_path);
-#else
- log_add(L_INFO, "mkstemp not available, using plain open() for split buffer- make sure %s has safe permissions", split_diskbuffer);
- splitbuffer_fd = open(splitbuffer_path, O_RDWR|O_CREAT, 0600);
-#endif
- if(splitbuffer_fd == -1){
- buff_err = newvstralloc(buff_err, "mkstemp/open of ",
- splitbuffer_path, "failed (",
- strerror(errno), ")", NULL);
- goto fallback;
+ /* different file, munmap the previous */
+ if (mmap_filename && strcmp(mmap_filename, splitbuffer_path) != 0) {
+ dbprintf(("create_split_buffer: new file %s\n", splitbuffer_path));
+ munmap(splitbuf, (size_t)mmap_splitsize);
+ aclose(mmap_splitbuffer_fd);
+ mmap_splitbuf = NULL;
+ amfree(mmap_filename);
+ mmap_splitsize = 0;
}
- nulls = alloc(1024); /* lame */
- memset(nulls, 0, 1024);
- for(c = 0; c < splitsize ; c++) {
- if(fullwrite(splitbuffer_fd, nulls, 1024) < 1024){
- buff_err = newvstralloc(buff_err, "write to ", splitbuffer_path,
- "failed (", strerror(errno), ")", NULL);
- free_split_buffer();
+ if (!mmap_filename) {
+ dbprintf(("create_split_buffer: open file %s\n",
+ splitbuffer_path));
+ mmap_splitbuffer_fd = open(splitbuffer_path, O_RDWR|O_CREAT, 0600);
+ if (mmap_splitbuffer_fd == -1) {
+ buff_err = newvstralloc(buff_err, "open of ",
+ splitbuffer_path, "failed (",
+ strerror(errno), ")", NULL);
goto fallback;
}
}
+ offset = lseek(mmap_splitbuffer_fd, (off_t)0, SEEK_END) / 1024;
+ if (offset < splitsize) { /* Increase file size */
+ dbprintf(("create_split_buffer: increase file size of %s to "
+ OFF_T_FMT "kb\n",
+ splitbuffer_path, (OFF_T_FMT_TYPE)splitsize));
+ if (mmap_filename) {
+ dbprintf(("create_split_buffer: munmap old file %s\n",
+ mmap_filename));
+ munmap(splitbuf, (size_t)mmap_splitsize);
+ mmap_splitsize = 0;
+ mmap_splitbuf = NULL;
+ }
+ nulls = alloc(1024); /* lame */
+ memset(nulls, 0, 1024);
+ for (c = offset; c < splitsize ; c += (off_t)1) {
+ if (fullwrite(mmap_splitbuffer_fd, nulls, 1024) < 1024) {
+ buff_err = newvstralloc(buff_err, "write to ",
+ splitbuffer_path,
+ "failed (", strerror(errno),
+ ")", NULL);
+ c -= 1;
+ if (c <= (off_t)fallback_splitsize) {
+ goto fallback;
+ }
+ splitsize = c;
+ break;
+ }
+ }
+ }
amfree(nulls);
- splitbuf = mmap(NULL, (size_t)splitsize*1024, PROT_READ|PROT_WRITE,
- MAP_SHARED, splitbuffer_fd, (off_t)0);
- if(splitbuf == (char*)-1){
- buff_err = newvstralloc(buff_err, "mmap failed (", strerror(errno),
- ")", NULL);
- free_split_buffer();
- goto fallback;
+ if (mmap_splitsize < splitsize*1024) {
+ mmap_splitsize = splitsize*1024;
+ mmap_filename = stralloc(splitbuffer_path);
+ dbprintf(("create_split_buffer: mmap file %s for " OFF_T_FMT "kb\n",
+ mmap_filename,(OFF_T_FMT_TYPE)splitsize));
+ mmap_splitbuf = mmap(NULL, (size_t)mmap_splitsize,
+ PROT_READ|PROT_WRITE,
+ MAP_SHARED, mmap_splitbuffer_fd, (off_t)0);
+ if (mmap_splitbuf == (char*)-1) {
+ buff_err = newvstralloc(buff_err, "mmap failed (",
+ strerror(errno), ")", NULL);
+ aclose(mmap_splitbuffer_fd);
+ amfree(mmap_filename);
+ mmap_splitsize = 0;
+ mmap_splitbuf = NULL;
+ goto fallback;
+ }
}
+ quoted = quote_string(splitbuffer_path);
fprintf(stderr,
- "taper: r: buffering %ldkb split chunks in mmapped file %s\n",
- splitsize, splitbuffer_path);
+ "taper: r: buffering " OFF_T_FMT
+ "kb split chunks in mmapped file %s\n",
+ (OFF_T_FMT_TYPE)splitsize, quoted);
+ dbprintf(("taper: r: buffering " OFF_T_FMT
+ "kb split chunks in mmapped file %s\n",
+ (OFF_T_FMT_TYPE)splitsize, quoted));
+ amfree(splitbuffer_path);
+ amfree(quoted);
+ amfree(buff_err);
+ splitbuf = mmap_splitbuf;
splitbuf_wr_ptr = splitbuf;
return;
- }
- else{
+ } else {
buff_err = stralloc("no split_diskbuffer specified");
}
#else
+ (void)split_diskbuffer; /* Quite unused parameter warning */
buff_err = stralloc("mman.h not available");
goto fallback;
#endif
#else
+ (void)split_diskbuffer; /* Quite unused parameter warning */
buff_err = stralloc("mmap not available");
goto fallback;
#endif
Buffer split dumps in memory, if we can't use a file.
*/
fallback:
- splitsize = fallback_splitsize;
+ amfree(splitbuffer_path);
+ splitsize = (off_t)fallback_splitsize;
+ dbprintf(("create_split_buffer: fallback size " OFF_T_FMT "\n",
+ (OFF_T_FMT_TYPE)splitsize));
log_add(L_INFO,
"%s: using fallback split size of %dkb to buffer %s in-memory",
buff_err, splitsize, id_string);
- splitbuf = alloc(splitsize * 1024);
+ amfree(buff_err);
+ if (splitsize > mem_splitsize) {
+ amfree(mem_splitbuf);
+ mem_splitbuf = alloc(fallback_splitsize * 1024);
+ mem_splitsize = fallback_splitsize;
+ dbprintf(("create_split_buffer: alloc buffer size " OFF_T_FMT "\n",
+ (OFF_T_FMT_TYPE)splitsize *1024));
+ }
+ splitbuf = mem_splitbuf;
splitbuf_wr_ptr = splitbuf;
}
/*
* Free up resources that create_split_buffer eats.
*/
-void free_split_buffer()
+void
+free_split_buffer(void)
{
- if(splitbuffer_fd != -1){
+ if (mmap_splitbuffer_fd != -1) {
#ifdef HAVE_MMAP
#ifdef HAVE_SYS_MMAN_H
- if(splitbuf != NULL) munmap(splitbuf, splitsize);
+ if (splitbuf != NULL)
+ munmap(splitbuf, (size_t)mmap_splitsize);
#endif
#endif
- aclose(splitbuffer_fd);
- splitbuffer_fd = -1;
-
- if(unlink(splitbuffer_path) == -1){
- log_add(L_WARNING, "Failed to unlink %s: %s",
- splitbuffer_path, strerror(errno));
- }
- amfree(splitbuffer_path);
- splitbuffer_path = NULL;
+ aclose(mmap_splitbuffer_fd);
+ amfree(mmap_filename);
+ mmap_splitsize = 0;
}
- else if(splitbuf){
+ if (mem_splitbuf) {
amfree(splitbuf);
- splitbuf = NULL;
+ mem_splitsize = 0;
}
}
+void
+put_syncpipe_fault_result(
+ char * handle)
+{
+ char *q;
+
+ if (handle == NULL)
+ handle = "<nohandle>";
+
+ q = squotef("[Taper syncpipe fault]");
+ putresult(TAPE_ERROR, "%s %s\n", handle, q);
+ log_add(L_ERROR, "tape-error %s %s", handle, q);
+ amfree(q);
+}
-void file_reader_side(rdpipe, wrpipe)
-int rdpipe, wrpipe;
+void
+file_reader_side(
+ int rdpipe,
+ int wrpipe)
{
cmd_t cmd;
struct cmdargs cmdargs;
char *handle = NULL;
char *filename = NULL;
+ char *qfilename = NULL;
char *hostname = NULL;
char *diskname = NULL;
+ char *qdiskname = NULL;
char *result = NULL;
char *datestamp = NULL;
char *split_diskbuffer = NULL;
char *id_string = NULL;
- char tok;
+ int tok;
char *q = NULL;
- int level, fd, data_port, data_socket, wpid;
+ int level, fd;
+ in_port_t data_port;
+ int data_socket;
+ pid_t wpid;
char level_str[64];
struct stat stat_file;
int tape_started;
int a;
- long fallback_splitsize = 0;
+ size_t fallback_splitsize = 0;
int tmpint;
+ char *c, *c1;
procname = "reader";
syncpipe_init(rdpipe, wrpipe);
cmd = getcmd(&cmdargs);
total_wait = stopclock();
- if(cmd != START_TAPER || cmdargs.argc != 2) {
+ if (cmd != START_TAPER || cmdargs.argc != 2) {
error("error [file_reader_side cmd %d argc %d]", cmd, cmdargs.argc);
+ /*NOTREACHED*/
}
/* pass start command on to tape writer */
- taper_datestamp = newstralloc(taper_datestamp, cmdargs.argv[2]);
+ taper_timestamp = newstralloc(taper_timestamp, cmdargs.argv[2]);
tape_started = 0;
- syncpipe_put('S', 0);
- syncpipe_putstr(taper_datestamp);
+ if (syncpipe_put('S', 0) == -1) {
+ put_syncpipe_fault_result(NULL);
+ }
+
+ if (syncpipe_putstr(taper_timestamp) == -1) {
+ put_syncpipe_fault_result(NULL);
+ }
/* get result of start command */
tok = syncpipe_get(&tmpint);
switch(tok) {
+ case -1:
+ put_syncpipe_fault_result(NULL);
+ break;
+
case 'S':
putresult(TAPER_OK, "\n");
tape_started = 1;
/* start is logged in writer */
break;
+
case 'E':
/* no tape, bail out */
- result = syncpipe_getstr();
- q = squotef("[%s]", result ? result : "(null)");
- putresult(TAPE_ERROR, "%s\n", q);
- amfree(q);
- log_add(L_ERROR,"no-tape [%s]", "No writable valid tape found");
- amfree(result);
- syncpipe_put('e', 0); /* ACK error */
+ if ((result = syncpipe_getstr()) == NULL) {
+ put_syncpipe_fault_result(NULL);
+ } else {
+ q = squotef("[%s]", result);
+ putresult(TAPE_ERROR, "<nohandle> %s\n", q);
+ amfree(q);
+ log_add(L_ERROR,"no-tape [%s]", "No writable valid tape found");
+ c = c1 = result;
+ while (*c != '\0') {
+ if (*c == '\n') {
+ *c = '\0';
+ log_add(L_WARNING,"%s", c1);
+ c1 = c+1;
+ }
+ c++;
+ }
+ if (strlen(c1) > 1 )
+ log_add(L_WARNING,"%s", c1);
+ amfree(result);
+ (void)syncpipe_put('e', 0); /* ACK error */
+ }
+ break;
+
+ case 'H': /* Syncpipe I/O error */
+ /* No ACK syncpipe is down just exit */
+ put_syncpipe_fault_result(handle);
break;
+
+ case 'X':
+ /*
+ * Pipe read error: Communications is severed at least
+ * back to us. We send a blind 'Q' (quit) and we don't
+ * wait for a response...
+ */
+ syncpipe_put('Q', 0); /* ACK error */
+ error("error [communications pipe from writer severed]");
+ /*NOTREACHED*/
+
default:
- error("expected 'S' or 'E' for START-TAPER, got '%c'", tok);
+ q = squotef("[syncpipe sequence fault: Expected 'S' or 'E']");
+ putresult(TAPE_ERROR, "<nohandle> %s\n", q);
+ log_add(L_ERROR, "no-tape %s]", q);
+ amfree(q);
}
- /* process further commands */
-
- while(1) {
+ /* process further driver commands */
+ while (1) {
startclock();
cmd = getcmd(&cmdargs);
- if(cmd != QUIT && !tape_started) {
+ if (cmd != QUIT && !tape_started) {
error("error [file_reader_side cmd %d without tape ready]", cmd);
+ /*NOTREACHED*/
}
total_wait = timesadd(total_wait, stopclock());
cmdargs.argc++; /* true count of args */
a = 2;
- if(a >= cmdargs.argc) {
+ if (a >= cmdargs.argc) {
error("error [taper PORT-WRITE: not enough args: handle]");
+ /*NOTREACHED*/
}
handle = newstralloc(handle, cmdargs.argv[a++]);
- if(a >= cmdargs.argc) {
+ if (a >= cmdargs.argc) {
error("error [taper PORT-WRITE: not enough args: hostname]");
+ /*NOTREACHED*/
}
hostname = newstralloc(hostname, cmdargs.argv[a++]);
- if(a >= cmdargs.argc) {
+ if (a >= cmdargs.argc) {
error("error [taper PORT-WRITE: not enough args: features]");
+ /*NOTREACHED*/
}
am_release_feature_set(their_features);
their_features = am_string_to_feature(cmdargs.argv[a++]);
- if(a >= cmdargs.argc) {
+ if (a >= cmdargs.argc) {
error("error [taper PORT-WRITE: not enough args: diskname]");
+ /*NOTREACHED*/
}
- diskname = newstralloc(diskname, cmdargs.argv[a++]);
+ qdiskname = newstralloc(qdiskname, cmdargs.argv[a++]);
+ if (diskname != NULL)
+ amfree(diskname);
+ diskname = unquote_string(qdiskname);
- if(a >= cmdargs.argc) {
+ if (a >= cmdargs.argc) {
error("error [taper PORT-WRITE: not enough args: level]");
+ /*NOTREACHED*/
}
level = atoi(cmdargs.argv[a++]);
- if(a >= cmdargs.argc) {
+ if (a >= cmdargs.argc) {
error("error [taper PORT-WRITE: not enough args: datestamp]");
+ /*NOTREACHED*/
}
datestamp = newstralloc(datestamp, cmdargs.argv[a++]);
- if(a >= cmdargs.argc) {
+ if (a >= cmdargs.argc) {
error("error [taper PORT-WRITE: not enough args: splitsize]");
+ /*NOTREACHED*/
}
- splitsize = atoi(cmdargs.argv[a++]);
+ splitsize = OFF_T_ATOI(cmdargs.argv[a++]);
- if(a >= cmdargs.argc) {
+ if (a >= cmdargs.argc) {
error("error [taper PORT-WRITE: not enough args: split_diskbuffer]");
+ /*NOTREACHED*/
}
split_diskbuffer = newstralloc(split_diskbuffer, cmdargs.argv[a++]);
- if(a >= cmdargs.argc) {
+ if (a >= cmdargs.argc) {
error("error [taper PORT-WRITE: not enough args: fallback_splitsize]");
+ /*NOTREACHED*/
}
- fallback_splitsize = atoi(cmdargs.argv[a++]);
+ /* Must fit in memory... */
+ fallback_splitsize = (size_t)atoi(cmdargs.argv[a++]);
- if(a != cmdargs.argc) {
+ if (a != cmdargs.argc) {
error("error [taper file_reader_side PORT-WRITE: too many args: %d != %d]",
cmdargs.argc, a);
+ /*NOTREACHED*/
}
- snprintf(level_str, sizeof(level_str), "%d", level);
- id_string = newvstralloc(id_string, hostname, ":", diskname, ".",
+ if (fallback_splitsize < 128 ||
+ fallback_splitsize > 64 * 1024 * 1024) {
+ error("error [bad value for fallback_splitsize]");
+ /*NOTREACHED*/
+ }
+ snprintf(level_str, SIZEOF(level_str), "%d", level);
+ id_string = newvstralloc(id_string, hostname, ":", qdiskname, ".",
level_str, NULL);
create_split_buffer(split_diskbuffer, fallback_splitsize, id_string);
amfree(id_string);
data_port = 0;
- data_socket = stream_server(&data_port, -1, STREAM_BUFSIZE);
- if(data_socket < 0) {
+ data_socket = stream_server(&data_port, 0, STREAM_BUFSIZE, 0);
+ if (data_socket < 0) {
char *m;
m = vstralloc("[port create failure: ",
}
putresult(PORT, "%d\n", data_port);
- if((fd = stream_accept(data_socket, CONNECT_TIMEOUT,
- -1, NETWORK_BLOCK_BYTES)) == -1) {
+ if ((fd = stream_accept(data_socket, CONNECT_TIMEOUT,
+ 0, STREAM_BUFSIZE)) == -1) {
q = squote("[port connect timeout]");
putresult(TAPE_ERROR, "%s %s\n", handle, q);
aclose(data_socket);
}
expected_splits = -1;
- while(read_file(fd,handle,hostname,diskname,datestamp,level));
+ while(read_file(fd, handle, hostname, qdiskname, datestamp, level))
+ (void)fd; /* Quiet lint */
aclose(data_socket);
- free_split_buffer();
break;
case FILE_WRITE:
cmdargs.argc++; /* true count of args */
a = 2;
- if(a >= cmdargs.argc) {
+ if (a >= cmdargs.argc) {
error("error [taper FILE-WRITE: not enough args: handle]");
+ /*NOTREACHED*/
}
handle = newstralloc(handle, cmdargs.argv[a++]);
- if(a >= cmdargs.argc) {
+ if (a >= cmdargs.argc) {
error("error [taper FILE-WRITE: not enough args: filename]");
+ /*NOTREACHED*/
}
- filename = newstralloc(filename, cmdargs.argv[a++]);
+ qfilename = newstralloc(qfilename, cmdargs.argv[a++]);
+ if (filename != NULL)
+ amfree(filename);
+ filename = unquote_string(qfilename);
- if(a >= cmdargs.argc) {
+ if (a >= cmdargs.argc) {
error("error [taper FILE-WRITE: not enough args: hostname]");
+ /*NOTREACHED*/
}
hostname = newstralloc(hostname, cmdargs.argv[a++]);
- if(a >= cmdargs.argc) {
+ if (a >= cmdargs.argc) {
error("error [taper FILE-WRITE: not enough args: features]");
+ /*NOTREACHED*/
}
am_release_feature_set(their_features);
their_features = am_string_to_feature(cmdargs.argv[a++]);
- if(a >= cmdargs.argc) {
+ if (a >= cmdargs.argc) {
error("error [taper FILE-WRITE: not enough args: diskname]");
+ /*NOTREACHED*/
}
- diskname = newstralloc(diskname, cmdargs.argv[a++]);
+ qdiskname = newstralloc(qdiskname, cmdargs.argv[a++]);
+ if (diskname != NULL)
+ amfree(diskname);
+ diskname = unquote_string(qdiskname);
- if(a >= cmdargs.argc) {
+ if (a >= cmdargs.argc) {
error("error [taper FILE-WRITE: not enough args: level]");
+ /*NOTREACHED*/
}
level = atoi(cmdargs.argv[a++]);
- if(a >= cmdargs.argc) {
+ if (a >= cmdargs.argc) {
error("error [taper FILE-WRITE: not enough args: datestamp]");
+ /*NOTREACHED*/
}
datestamp = newstralloc(datestamp, cmdargs.argv[a++]);
- if(a >= cmdargs.argc) {
+ if (a >= cmdargs.argc) {
error("error [taper FILE-WRITE: not enough args: splitsize]");
+ /*NOTREACHED*/
}
- splitsize = atoi(cmdargs.argv[a++]);
+ splitsize = OFF_T_ATOI(cmdargs.argv[a++]);
- if(a != cmdargs.argc) {
+ if (a != cmdargs.argc) {
error("error [taper file_reader_side FILE-WRITE: too many args: %d != %d]",
cmdargs.argc, a);
+ /*NOTREACHED*/
}
- if(holdfile_name != NULL) {
+ if (holdfile_name != NULL) {
filename = newstralloc(filename, holdfile_name);
}
- if((expected_splits = predict_splits(filename)) < 0) {
+ if ((expected_splits = predict_splits(filename)) < 0) {
break;
}
- if(stat(filename, &stat_file)!=0) {
+ if (stat(filename, &stat_file)!=0) {
q = squotef("[%s]", strerror(errno));
putresult(TAPE_ERROR, "%s %s\n", handle, q);
amfree(q);
break;
}
- if((fd = open(filename, O_RDONLY)) == -1) {
+ if ((fd = open(filename, O_RDONLY)) == -1) {
q = squotef("[%s]", strerror(errno));
putresult(TAPE_ERROR, "%s %s\n", handle, q);
amfree(q);
holdfile_path_thischunk = stralloc(filename);
holdfile_offset_thischunk = (off_t)0;
- while(read_file(fd,handle,hostname,diskname,datestamp,level)){
- if(splitsize > 0 && holdfile_path_thischunk)
+ while (read_file(fd,handle,hostname,qdiskname,datestamp,level)) {
+ if (splitsize > (off_t)0 && holdfile_path_thischunk)
filename = newstralloc(filename, holdfile_path_thischunk);
- if((fd = open(filename, O_RDONLY)) == -1) {
+ if ((fd = open(filename, O_RDONLY)) == -1) {
q = squotef("[%s]", strerror(errno));
putresult(TAPE_ERROR, "%s %s\n", handle, q);
amfree(q);
break;
}
}
-
break;
case QUIT:
fprintf(stderr,"taper: DONE [idle wait: %s secs]\n",
walltime_str(total_wait));
fflush(stderr);
- syncpipe_put('Q', 0); /* tell writer we're exiting gracefully */
+ (void)syncpipe_put('Q', 0); /* tell writer we're exiting gracefully */
aclose(wrpipe);
- if((wpid = wait(NULL)) != writerpid) {
+ if ((wpid = wait(NULL)) != writerpid) {
+ dbprintf(("taper: writer wait returned %u instead of %u: %s\n",
+ (unsigned)wpid, (unsigned)writerpid, strerror(errno)));
fprintf(stderr,
- "taper: writer wait returned %d instead of %d: %s\n",
- wpid, writerpid, strerror(errno));
+ "taper: writer wait returned %u instead of %u: %s\n",
+ (unsigned)wpid, (unsigned)writerpid, strerror(errno));
fflush(stderr);
}
- if (datestamp != NULL)
- amfree(datestamp);
+ free_split_buffer();
+ amfree(datestamp);
+ clear_tapelist();
+ free_server_config();
+ amfree(taper_timestamp);
amfree(label);
amfree(errstr);
amfree(changer_resultstr);
amfree(tapedev);
- amfree(conf_tapelist);
amfree(filename);
+ amfree(conf_tapelist);
amfree(config_dir);
amfree(config_name);
- if(holdfile_name != NULL) amfree(holdfile_name);
+ amfree(holdfile_name);
malloc_size_2 = malloc_inuse(&malloc_hist_2);
- if(malloc_size_1 != malloc_size_2) {
+ if (malloc_size_1 != malloc_size_2) {
malloc_list(fileno(stderr), malloc_hist_1, malloc_hist_2);
}
-
exit(0);
+ /*NOTREACHED*/
default:
- if(cmdargs.argc >= 1) {
+ if (cmdargs.argc >= 1) {
q = squote(cmdargs.argv[1]);
- } else if(cmdargs.argc >= 0) {
+ } else if (cmdargs.argc >= 0) {
q = squote(cmdargs.argv[0]);
} else {
q = stralloc("(no input?)");
break;
}
}
- amfree(handle);
- am_release_feature_set(their_features);
- amfree(hostname);
- amfree(diskname);
- fprintf(stderr, "TAPER AT END OF READER SIDE\n");
+ /* NOTREACHED */
}
-void dumpbufs(str1)
-char *str1;
+void
+dumpbufs(
+ char *str1)
{
int i,j;
long v;
fprintf(stderr, "%s: state", str1);
- for(i = j = 0; i < conf_tapebufs; i = j+1) {
+ for (i = j = 0; i < conf_tapebufs; i = j+1) {
v = buftable[i].status;
- for(j = i; j < conf_tapebufs && buftable[j].status == v; j++);
+ for(j = i; j < conf_tapebufs && buftable[j].status == v; j++)
+ (void)j; /* Quiet lint */
j--;
- if(i == j) fprintf(stderr, " %d:", i);
- else fprintf(stderr, " %d-%d:", i, j);
+ if (i == j) {
+ fprintf(stderr, " %d:", i);
+ } else {
+ fprintf(stderr, " %d-%d:", i, j);
+ }
switch(v) {
- case FULL: fputc('F', stderr); break;
- case FILLING: fputc('f', stderr); break;
- case EMPTY: fputc('E', stderr); break;
+ case FULL:
+ fputc('F', stderr);
+ break;
+
+ case FILLING:
+ fputc('f', stderr);
+ break;
+
+ case EMPTY:
+ fputc('E', stderr);
+ break;
+
default:
fprintf(stderr, "%ld", v);
break;
}
-
}
fputc('\n', stderr);
fflush(stderr);
}
-void dumpstatus(bp)
-buffer_t *bp;
+void
+dumpstatus(
+ buffer_t *bp)
{
char pn[2];
char bt[NUM_STR_SIZE];
pn[0] = procname[0];
pn[1] = '\0';
- snprintf(bt, sizeof(bt), "%d", (int)(bp-buftable));
+ snprintf(bt, SIZEOF(bt), "%d", (int)(bp-buftable));
switch(bp->status) {
- case FULL: snprintf(status, sizeof(status), "F%d", bp->size);
- break;
- case FILLING: status[0] = 'f'; status[1] = '\0'; break;
- case EMPTY: status[0] = 'E'; status[1] = '\0'; break;
+ case FULL:
+ snprintf(status, SIZEOF(status), "F" SIZE_T_FMT,
+ (SIZE_T_FMT_TYPE)bp->size);
+ break;
+
+ case FILLING:
+ snprintf(status, SIZEOF(status), "f");
+ break;
+
+ case EMPTY:
+ snprintf(status, SIZEOF(status), "E");
+ break;
+
default:
- snprintf(status, sizeof(status), "%ld", bp->status);
+ snprintf(status, SIZEOF(status), "%ld", bp->status);
break;
}
be another global. What is rc anyway, 'read count?' I keep thinking it
should be 'return code')
*/
-int get_next_holding_file(fd, bp, strclosing, rc)
- int fd;
- buffer_t *bp;
- char *strclosing;
+ssize_t
+get_next_holding_file(
+ int fd,
+ buffer_t *bp,
+ char **strclosing,
+ size_t rc)
{
- int save_fd, rc1;
+ int save_fd;
+ ssize_t rc1;
struct stat stat_file;
- int ret = -1;
+ ssize_t ret = -1;
save_fd = fd;
close(fd);
/* see if we're fresh out of file */
- if(file.cont_filename[0] == '\0') {
+ if (file.cont_filename[0] == '\0') {
err = 0;
ret = 0;
- } else if(stat(file.cont_filename, &stat_file) != 0) {
+ } else if (stat(file.cont_filename, &stat_file) != 0) {
err = errno;
ret = -1;
- strclosing = newvstralloc(strclosing,"can't stat: ",file.cont_filename,NULL);
- } else if((fd = open(file.cont_filename,O_RDONLY)) == -1) {
+ *strclosing = newvstralloc(*strclosing, "can't stat: ",
+ file.cont_filename, NULL);
+ } else if ((fd = open(file.cont_filename,O_RDONLY)) == -1) {
err = errno;
ret = -1;
- strclosing = newvstralloc(strclosing,"can't open: ",file.cont_filename,NULL);
- } else if((fd != save_fd) && dup2(fd, save_fd) == -1) {
+ *strclosing = newvstralloc(*strclosing, "can't open: ",
+ file.cont_filename, NULL);
+ } else if ((fd != save_fd) && dup2(fd, save_fd) == -1) {
err = errno;
ret = -1;
- strclosing = newvstralloc(strclosing,"can't dup2: ",file.cont_filename,NULL);
+ *strclosing = newvstralloc(*strclosing, "can't dup2: ",
+ file.cont_filename, NULL);
} else {
buffer_t bp1;
+ char *quoted;
+
holdfile_path = stralloc(file.cont_filename);
-
- fprintf(stderr, "taper: r: switching to next holding chunk '%s'\n", file.cont_filename);
+ quoted = quote_string(holdfile_path);
+ fprintf(stderr, "taper: r: switching to next holding chunk '%s'\n",
+ quoted);
+ amfree(quoted);
num_holdfile_chunks++;
bp1.status = EMPTY;
bp1.size = DISK_BLOCK_BYTES;
- bp1.buffer = malloc(DISK_BLOCK_BYTES);
+ bp1.buffer = alloc(DISK_BLOCK_BYTES);
- if(fd != save_fd) {
+ if (fd != save_fd) {
close(fd);
fd = save_fd;
}
rc1 = taper_fill_buffer(fd, &bp1, DISK_BLOCK_BYTES);
- if(rc1 <= 0) {
+ if (rc1 <= 0) {
amfree(bp1.buffer);
err = (rc1 < 0) ? errno : 0;
ret = -1;
- strclosing = newvstralloc(strclosing,
- "Can't read header: ",
- file.cont_filename,
- NULL);
+ *strclosing = newvstralloc(*strclosing,
+ "Can't read header: ",
+ file.cont_filename,
+ NULL);
} else {
- parse_file_header(bp1.buffer, &file, rc1);
+ parse_file_header(bp1.buffer, &file, (size_t)rc1);
amfree(bp1.buffer);
bp1.buffer = bp->buffer + rc;
- rc1 = taper_fill_buffer(fd, &bp1, tt_blocksize - rc);
- if(rc1 <= 0) {
+ rc1 = taper_fill_buffer(fd, &bp1, (size_t)tt_blocksize - rc);
+ if (rc1 <= 0) {
err = (rc1 < 0) ? errno : 0;
ret = -1;
- if(rc1 < 0) {
- strclosing = newvstralloc(strclosing,
- "Can't read data: ",
- file.cont_filename,
- NULL);
+ if (rc1 < 0) {
+ *strclosing = newvstralloc(*strclosing,
+ "Can't read data: ",
+ file.cont_filename,
+ NULL);
}
- }
- else {
+ } else {
ret = rc1;
num_holdfiles++;
}
}
}
-
+
return(ret);
}
-int read_file(fd, handle, hostname, diskname, datestamp, level)
- int fd, level;
- char *handle, *hostname, *diskname, *datestamp;
+int
+read_file(
+ int fd,
+ char * handle,
+ char * hostname,
+ char * qdiskname,
+ char * datestamp,
+ int level)
{
buffer_t *bp;
- char tok;
- int rc, opening, closing, bufnum, need_closing, nexting;
- long filesize;
+ int tok;
+ ssize_t rc;
+#ifdef ASSERTIONS
+ int opening;
+#endif
+ int closing, bufnum, need_closing, nexting;
+ off_t filesize;
times_t runtime;
char *strclosing = NULL;
char seekerrstr[STR_SIZE];
char *str;
int header_written = 0;
- int buflen;
+ size_t buflen;
dumpfile_t first_file;
dumpfile_t cur_holdfile;
- long kbytesread = 0;
+ off_t kbytesread = (off_t)0;
int header_read = 0;
char *cur_filename = NULL;
int retry_from_splitbuf = 0;
char *splitbuf_rd_ptr = NULL;
-
char *q = NULL;
#ifdef HAVE_LIBVTBLC
/* initialize */
+ memset(&first_file, 0, SIZEOF(first_file));
+ memset(&cur_holdfile, 0, SIZEOF(cur_holdfile));
- filesize = 0;
+ filesize = (off_t)0;
closing = 0;
need_closing = 0;
nexting = 0;
err = 0;
/* don't break this if we're still on the same file as a previous init */
- if(cur_span_chunkstart <= 0){
- fh_init(&file);
- header_read = 0;
- }
- else if(mode == MODE_FILE_WRITE){
- memcpy(&file, save_holdfile, sizeof(dumpfile_t));
- memcpy(&cur_holdfile, save_holdfile, sizeof(dumpfile_t));
+ if (cur_span_chunkstart <= (off_t)0) {
+ fh_init(&file);
+ header_read = 0;
+ } else if(mode == MODE_FILE_WRITE){
+ memcpy(&file, save_holdfile, SIZEOF(dumpfile_t));
+ memcpy(&cur_holdfile, save_holdfile, SIZEOF(dumpfile_t));
}
- if(bufdebug) {
+ if (bufdebug) {
fprintf(stderr, "taper: r: start file\n");
fflush(stderr);
}
- for(bp = buftable; bp < buftable + conf_tapebufs; bp++) {
+ for (bp = buftable; bp < buftable + conf_tapebufs; bp++) {
bp->status = EMPTY;
}
bp = buftable;
- if(interactive || bufdebug) dumpstatus(bp);
+ if (interactive || bufdebug)
+ dumpstatus(bp);
- if(cur_span_chunkstart >= 0 && splitsize > 0){
+ if ((cur_span_chunkstart >= (off_t)0) && (splitsize > (off_t)0)) {
/* We're supposed to start at some later part of the file, not read the
whole thing. "Seek" forward to where we want to be. */
- if(label) putresult(SPLIT_CONTINUE, "%s %s\n", handle, label);
- if(mode == MODE_FILE_WRITE && cur_span_chunkstart > 0){
+ if (label)
+ putresult(SPLIT_CONTINUE, "%s %s\n", handle, label);
+ if ((mode == MODE_FILE_WRITE) && (cur_span_chunkstart > (off_t)0)) {
+ char *quoted = quote_string(holdfile_path_thischunk);
fprintf(stderr, "taper: r: seeking %s to " OFF_T_FMT " kb\n",
- holdfile_path_thischunk, holdfile_offset_thischunk);
+ quoted,
+ (OFF_T_FMT_TYPE)holdfile_offset_thischunk);
fflush(stderr);
- if(holdfile_offset_thischunk > maxseek){
- snprintf(seekerrstr, sizeof(seekerrstr), "Can't seek by " OFF_T_FMT " kb (compiled for %d-bit file offsets), recompile with large file support or set holdingdisk chunksize to <%ld Mb", holdfile_offset_thischunk, (int)(sizeof(off_t) * 8), (long)(maxseek/1024));
- log_add(L_ERROR, "%s", seekerrstr);
- fprintf(stderr, "taper: r: FATAL: %s\n", seekerrstr);
- fflush(stderr);
- syncpipe_put('X', 0);
- return -1;
+ if (holdfile_offset_thischunk > maxseek) {
+ snprintf(seekerrstr, SIZEOF(seekerrstr), "Can't seek by "
+ OFF_T_FMT " kb (compiled for %d-bit file offsets), "
+ "recompile with large file support or "
+ "set holdingdisk chunksize to <" OFF_T_FMT " Mb",
+ (OFF_T_FMT_TYPE)holdfile_offset_thischunk,
+ (int)(sizeof(off_t) * 8),
+ (OFF_T_FMT_TYPE)(maxseek/(off_t)1024));
+ log_add(L_ERROR, "%s", seekerrstr);
+ fprintf(stderr, "taper: r: FATAL: %s\n", seekerrstr);
+ fflush(stderr);
+ if (syncpipe_put('X', 0) == -1) {
+ put_syncpipe_fault_result(handle);
+ }
+ amfree(quoted);
+ return -1;
}
- if(lseek(fd, holdfile_offset_thischunk*1024, SEEK_SET) == (off_t)-1){
- fprintf(stderr, "taper: r: FATAL: seek_holdfile lseek error while seeking into %s by " OFF_T_FMT "kb: %s\n", holdfile_path_thischunk, holdfile_offset_thischunk, strerror(errno));
- fflush(stderr);
- syncpipe_put('X', 0);
- return -1;
+ if (lseek(fd, holdfile_offset_thischunk*(off_t)1024, SEEK_SET) == (off_t)-1) {
+ fprintf(stderr, "taper: r: FATAL: seek_holdfile lseek error "
+ "while seeking into %s by "
+ OFF_T_FMT "kb: %s\n", quoted,
+ (OFF_T_FMT_TYPE)holdfile_offset_thischunk,
+ strerror(errno));
+ fflush(stderr);
+ if (syncpipe_put('X', 0) == -1) {
+ put_syncpipe_fault_result(handle);
+ }
+ amfree(quoted);
+ return -1;
}
- }
- else if(mode == MODE_PORT_WRITE){
+ amfree(quoted);
+ } else if (mode == MODE_PORT_WRITE) {
fprintf(stderr, "taper: r: re-reading split dump piece from buffer\n");
fflush(stderr);
retry_from_splitbuf = 1;
splitbuf_rd_ptr = splitbuf;
- if(splitbuf_rd_ptr >= splitbuf_wr_ptr) retry_from_splitbuf = 0;
+ if (splitbuf_rd_ptr >= splitbuf_wr_ptr)
+ retry_from_splitbuf = 0;
}
- if(cur_span_chunkstart > 0) header_read = 1; /* really initialized in prior run */
+ if (cur_span_chunkstart > (off_t)0)
+ header_read = 1; /* really initialized in prior run */
}
/* tell writer to open tape */
+#ifdef ASSERTIONS
opening = 1;
- syncpipe_put('O', 0);
- syncpipe_putstr(datestamp);
- syncpipe_putstr(hostname);
- syncpipe_putstr(diskname);
- syncpipe_putint(level);
+#endif
+
+ if (syncpipe_put('O', 0) == -1) {
+ put_syncpipe_fault_result(handle);
+ return -1;
+ }
+ if (syncpipe_putstr(datestamp) == -1) {
+ put_syncpipe_fault_result(handle);
+ return -1;
+ }
+ if (syncpipe_putstr(hostname) == -1) {
+ put_syncpipe_fault_result(handle);
+ return -1;
+ }
+ if (syncpipe_putstr(qdiskname) == -1) {
+ put_syncpipe_fault_result(handle);
+ return -1;
+ }
+ if (syncpipe_putint(level) == -1) {
+ put_syncpipe_fault_result(handle);
+ return -1;
+ }
startclock();
/* read file in loop */
- while(1) {
- tok = syncpipe_get(&bufnum);
+ while (1) {
+ if ((tok = syncpipe_get(&bufnum)) == -1) {
+ put_syncpipe_fault_result(handle);
+ return -1;
+ }
+
switch(tok) {
-
case 'O':
+#ifdef ASSERTIONS
assert(opening);
opening = 0;
+#endif
err = 0;
break;
case 'R':
- if(bufdebug) {
+ if (bufdebug) {
fprintf(stderr, "taper: r: got R%d\n", bufnum);
fflush(stderr);
}
- if(need_closing) {
- syncpipe_put('C', 0);
+ if (need_closing) {
+ if (syncpipe_put('C', 0) == -1) {
+ put_syncpipe_fault_result(handle);
+ return (-1);
+ }
closing = 1;
need_closing = 0;
break;
}
- if(closing) break; /* ignore extra read tokens */
+ if (closing)
+ break; /* ignore extra read tokens */
+#ifdef ASSERTIONS
assert(!opening);
- if(bp->status != EMPTY || bufnum != bp-buftable) {
+#endif
+ if(bp->status != EMPTY || bufnum != (int)(bp - buftable)) {
/* XXX this SHOULD NOT HAPPEN. Famous last words. */
- fprintf(stderr,"taper: panic: buffer mismatch at ofs %ld:\n",
- filesize);
- if(bufnum != bp-buftable) {
+ fprintf(stderr,"taper: panic: buffer mismatch at ofs "
+ OFF_T_FMT ":\n", (OFF_T_FMT_TYPE)filesize);
+ if(bufnum != (int)(bp - buftable)) {
fprintf(stderr, " my buf %d but writer buf %d\n",
(int)(bp-buftable), bufnum);
- }
- else {
+ } else {
fprintf(stderr,"buf %d state %s (%ld) instead of EMPTY\n",
(int)(bp-buftable),
bp->status == FILLING? "FILLING" :
dumpbufs("taper");
sleep(1);
dumpbufs("taper: after 1 sec");
- if(bp->status == EMPTY)
+ if (bp->status == EMPTY)
fprintf(stderr, "taper: result now correct!\n");
fflush(stderr);
"[fatal buffer mismanagement bug]");
q = squote(errstr);
putresult(TRYAGAIN, "%s %s\n", handle, q);
- cur_span_chunkstart = 0;
+ cur_span_chunkstart = (off_t)0;
amfree(q);
log_add(L_INFO, "retrying %s:%s.%d on new tape due to: %s",
- hostname, diskname, level, errstr);
+ hostname, qdiskname, level, errstr);
closing = 1;
- syncpipe_put('X', 0); /* X == buffer snafu, bail */
+ if (syncpipe_put('X', 0) == -1) {/* X == buffer snafu, bail */
+ put_syncpipe_fault_result(handle);
+ return (-1);
+ }
do {
- tok = syncpipe_get(&bufnum);
- } while(tok != 'x');
+ if ((tok = syncpipe_get(&bufnum)) == -1) {
+ put_syncpipe_fault_result(handle);
+ return (-1);
+ }
+ } while (tok != 'x');
aclose(fd);
return -1;
- } /* end 'if (bf->status != EMPTY || bufnum != bp-buftable)' */
+ } /* end 'if (bf->status != EMPTY || bufnum != (int)(bp-buftable))' */
bp->status = FILLING;
- buflen = header_read ? tt_blocksize : DISK_BLOCK_BYTES;
- if(interactive || bufdebug) dumpstatus(bp);
- if(header_written == 0 && (header_read == 1 || cur_span_chunkstart > 0)){
+ buflen = header_read ? (size_t)tt_blocksize : DISK_BLOCK_BYTES;
+ if (interactive || bufdebug)
+ dumpstatus(bp);
+ if (header_written == 0 &&
+ (header_read == 1 || cur_span_chunkstart > (off_t)0)) {
/* for split dumpfiles, modify headers for the second - nth
pieces that signify that they're continuations of the last
normal one */
file.type = F_SPLIT_DUMPFILE;
file.partnum = num_splits + 1;
file.totalparts = expected_splits;
- cont_filename = stralloc(file.cont_filename);
+ cont_filename = stralloc(file.cont_filename);
file.cont_filename[0] = '\0';
build_header(bp->buffer, &file, tt_blocksize);
- if(cont_filename[0] != '\0') {
+ if (cont_filename[0] != '\0') {
file.type = F_CONT_DUMPFILE;
strncpy(file.cont_filename, cont_filename,
- sizeof(file.cont_filename));
+ SIZEOF(file.cont_filename));
}
- memcpy(&cur_holdfile, &file, sizeof(dumpfile_t));
+ memcpy(&cur_holdfile, &file, SIZEOF(dumpfile_t));
- if(interactive || bufdebug) dumpstatus(bp);
- bp->size = tt_blocksize;
- rc = tt_blocksize;
+ if (interactive || bufdebug)
+ dumpstatus(bp);
+ bp->size = (ssize_t)tt_blocksize;
+ rc = (ssize_t)tt_blocksize;
header_written = 1;
amfree(cont_filename);
- }
- else if(retry_from_splitbuf){
+ } else if (retry_from_splitbuf) {
/* quietly pull dump data from our in-memory cache, and the
writer side need never know the wiser */
memcpy(bp->buffer, splitbuf_rd_ptr, tt_blocksize);
- bp->size = tt_blocksize;
- rc = tt_blocksize;
+ bp->size = (ssize_t)tt_blocksize;
+ rc = (ssize_t)tt_blocksize;
splitbuf_rd_ptr += tt_blocksize;
- if(splitbuf_rd_ptr >= splitbuf_wr_ptr) retry_from_splitbuf = 0;
- }
- else if((rc = taper_fill_buffer(fd, bp, buflen)) < 0) {
+ if (splitbuf_rd_ptr >= splitbuf_wr_ptr)
+ retry_from_splitbuf = 0;
+ } else if ((rc = taper_fill_buffer(fd, bp, buflen)) < 0) {
err = errno;
closing = 1;
- strclosing = newvstralloc(strclosing,"Can't read data: ",NULL);
- syncpipe_put('C', 0);
+ strclosing = newvstralloc(strclosing,"Can't read data: ",
+ NULL);
+ if (syncpipe_put('C', 0) == -1) {
+ put_syncpipe_fault_result(handle);
+ return (-1);
+ }
}
- if(!closing) {
- if(rc < buflen) { /* switch to next holding file */
- int ret;
- if(file.cont_filename[0] != '\0'){
- cur_filename = newvstralloc(cur_filename, file.cont_filename, NULL);
- }
- ret = get_next_holding_file(fd, bp, strclosing, rc);
- if(ret <= 0){
+ if (!closing) {
+ if (rc < (ssize_t)buflen) { /* switch to next holding file */
+ ssize_t ret;
+
+ if (file.cont_filename[0] != '\0') {
+ cur_filename = newvstralloc(cur_filename, file.cont_filename, NULL);
+ }
+ ret = get_next_holding_file(fd, bp, &strclosing, (size_t)rc);
+ if (ret <= 0) {
need_closing = 1;
- }
- else {
- memcpy(&cur_holdfile, &file, sizeof(dumpfile_t));
+ } else {
+ memcpy(&cur_holdfile, &file, SIZEOF(dumpfile_t));
rc += ret;
- bp->size = rc;
- }
- }
- if(rc > 0) {
+ bp->size = rc;
+ }
+ }
+ if (rc > 0) {
bp->status = FULL;
/* rebuild the header block, which might have CONT junk */
- if(header_read == 0) {
+ if (header_read == 0) {
char *cont_filename;
/* write the "real" filename if the holding-file
is a partial one */
- parse_file_header(bp->buffer, &file, rc);
- parse_file_header(bp->buffer, &first_file, rc);
+ parse_file_header(bp->buffer, &file, (size_t)rc);
+ parse_file_header(bp->buffer, &first_file, (size_t)rc);
cont_filename = stralloc(file.cont_filename);
file.cont_filename[0] = '\0';
- if(splitsize > 0){
+ if (splitsize > (off_t)0) {
file.type = F_SPLIT_DUMPFILE;
file.partnum = 1;
file.totalparts = expected_splits;
}
file.blocksize = tt_blocksize;
build_header(bp->buffer, &file, tt_blocksize);
- kbytesread += tt_blocksize/1024; /* XXX shady */
+ kbytesread += (off_t)(tt_blocksize/1024); /* XXX shady */
file.type = F_CONT_DUMPFILE;
/* add CONT_FILENAME back to in-memory header */
strncpy(file.cont_filename, cont_filename,
- sizeof(file.cont_filename));
- if(interactive || bufdebug) dumpstatus(bp);
- bp->size = tt_blocksize; /* output a full tape block */
+ SIZEOF(file.cont_filename));
+ if (interactive || bufdebug)
+ dumpstatus(bp);
+ bp->size = (ssize_t)tt_blocksize; /* output a full tape block */
/* save the header, we'll need it if we jump tapes */
- memcpy(&cur_holdfile, &file, sizeof(dumpfile_t));
+ memcpy(&cur_holdfile, &file, SIZEOF(dumpfile_t));
header_read = 1;
header_written = 1;
amfree(cont_filename);
- }
- else {
+ } else {
filesize = kbytesread;
}
- if(bufdebug) {
+ if (bufdebug) {
fprintf(stderr,"taper: r: put W%d\n",(int)(bp-buftable));
fflush(stderr);
}
- syncpipe_put('W', bp-buftable);
+ if (syncpipe_put('W', (int)(bp-buftable)) == -1) {
+ put_syncpipe_fault_result(handle);
+ return (-1);
+ }
bp = nextbuf(bp);
}
- if(kbytesread + DISK_BLOCK_BYTES/1024 >= splitsize && splitsize > 0 && !need_closing){
+ if (((kbytesread + (off_t)(DISK_BLOCK_BYTES/1024)) >= splitsize)
+ && (splitsize > (off_t)0) && !need_closing) {
- if(mode == MODE_PORT_WRITE){
+ if (mode == MODE_PORT_WRITE) {
splitbuf_wr_ptr = splitbuf;
splitbuf_rd_ptr = splitbuf;
- memset(splitbuf, 0, sizeof(splitbuf));
+ memset(splitbuf, 0, SIZEOF(splitbuf));
retry_from_splitbuf = 0;
}
- fprintf(stderr,"taper: r: end %s.%s.%s.%d part %d, splitting chunk that started at %ldkb after %ldkb (next chunk will start at %ldkb)\n", hostname, diskname, datestamp, level, num_splits+1, cur_span_chunkstart, kbytesread, cur_span_chunkstart+kbytesread);
+ fprintf(stderr,"taper: r: end %s.%s.%s.%d part %d, "
+ "splitting chunk that started at "
+ OFF_T_FMT "kb after " OFF_T_FMT
+ "kb (next chunk will start at "
+ OFF_T_FMT "kb)\n",
+ hostname, qdiskname, datestamp, level,
+ num_splits+1,
+ (OFF_T_FMT_TYPE)cur_span_chunkstart,
+ (OFF_T_FMT_TYPE)kbytesread,
+ (OFF_T_FMT_TYPE)(cur_span_chunkstart+kbytesread));
fflush(stderr);
nexting = 1;
need_closing = 1;
} /* end '(kbytesread >= splitsize && splitsize > 0)' */
- if(need_closing && rc <= 0) {
- syncpipe_put('C', 0);
+ if (need_closing && rc <= 0) {
+ if (syncpipe_put('C', 0) == -1) {
+ put_syncpipe_fault_result(handle);
+ return (-1);
+ }
need_closing = 0;
closing = 1;
}
- kbytesread += rc/1024;
- } /* end the 'if(!closing)' (successful buffer fill) */
+ kbytesread += (off_t)(rc / 1024);
+ } /* end the 'if (!closing)' (successful buffer fill) */
break;
case 'T':
case 'E':
- syncpipe_put('e', 0); /* ACK error */
+ case 'H':
+ if (syncpipe_put('e', 0) == -1) { /* ACK error */
+ put_syncpipe_fault_result(handle);
+ return (-1);
+ }
- str = syncpipe_getstr();
- errstr = newvstralloc(errstr, "[", str ? str : "(null)", "]", NULL);
+ if ((str = syncpipe_getstr()) == NULL) {
+ put_syncpipe_fault_result(handle);
+ return (-1);
+ }
+
+ errstr = newvstralloc(errstr, "[", str, "]", NULL);
amfree(str);
q = squote(errstr);
- if(tok == 'T') {
- if(splitsize > 0){
+ if (tok == 'T') {
+ if (splitsize > (off_t)0) {
/* we'll be restarting this chunk on the next tape */
- if(mode == MODE_FILE_WRITE){
+ if (mode == MODE_FILE_WRITE) {
aclose(fd);
}
- putresult(SPLIT_NEEDNEXT, "%s %ld\n", handle, cur_span_chunkstart);
- log_add(L_INFO, "continuing %s:%s.%d on new tape from %ldkb mark: %s",
- hostname, diskname, level, cur_span_chunkstart, errstr);
+ putresult(SPLIT_NEEDNEXT, "%s " OFF_T_FMT "\n", handle,
+ (OFF_T_FMT_TYPE)cur_span_chunkstart);
+ log_add(L_INFO, "continuing %s:%s.%d on new tape from "
+ OFF_T_FMT "kb mark: %s",
+ hostname, qdiskname, level,
+ (OFF_T_FMT_TYPE)cur_span_chunkstart, errstr);
return 1;
- }
- else{
+ } else {
/* restart the entire dump (failure propagates to driver) */
aclose(fd);
putresult(TRYAGAIN, "%s %s\n", handle, q);
- cur_span_chunkstart = 0;
+ cur_span_chunkstart = (off_t)0;
log_add(L_INFO, "retrying %s:%s.%d on new tape due to: %s",
- hostname, diskname, level, errstr);
+ hostname, qdiskname, level, errstr);
}
} else {
aclose(fd);
putresult(TAPE_ERROR, "%s %s\n", handle, q);
log_add(L_FAIL, "%s %s %s %d [out of tape]",
- hostname, diskname, datestamp, level);
+ hostname, qdiskname, datestamp, level);
log_add(L_ERROR,"no-tape [%s]", "No more writable valid tape found");
}
amfree(q);
-
return 0;
case 'C':
+#ifdef ASSERTIONS
assert(!opening);
+#endif
assert(closing);
- if(nexting){
+ if (nexting) {
cur_span_chunkstart += kbytesread; /* XXX possibly wrong */
- holdfile_name = newvstralloc(holdfile_name, cur_filename, NULL);
-
- kbytesread = 0;
- if(cur_filename != NULL) amfree(cur_filename);
+ if (cur_filename)
+ holdfile_name = newvstralloc(holdfile_name, cur_filename,
+ NULL);
+ else
+ amfree(holdfile_name);
+
+ kbytesread = (off_t)0;
+ amfree(cur_filename);
}
+ if ((str = syncpipe_getstr()) == NULL) {
+ put_syncpipe_fault_result(handle);
+ return (-1);
+ }
- str = syncpipe_getstr();
label = newstralloc(label, str ? str : "(null)");
amfree(str);
- str = syncpipe_getstr();
+ if ((str = syncpipe_getstr()) == NULL) {
+ put_syncpipe_fault_result(handle);
+ return (-1);
+ }
+
filenum = atoi(str ? str : "-9876"); /* ??? */
amfree(str);
fprintf(stderr, "taper: reader-side: got label %s filenum %d\n",
fflush(stderr);
/* we'll need that file descriptor if we're gonna write more */
- if(!nexting){
- aclose(fd);
+ if (!nexting) {
+ aclose(fd);
}
runtime = stopclock();
- if(nexting) startclock();
- if(err) {
- if(strclosing) {
+ if (nexting)
+ startclock();
+ if (err) {
+ if (strclosing) {
errstr = newvstralloc(errstr,
"[input: ", strclosing, ": ",
strerror(err), "]", NULL);
amfree(strclosing);
- }
- else
+ } else
errstr = newvstralloc(errstr,
"[input: ", strerror(err), "]",
NULL);
putresult(TAPE_ERROR, "%s %s\n", handle, q);
amfree(q);
- if(splitsize){
- log_add(L_FAIL, "%s %s %s.%d %d %s", hostname, diskname,
- datestamp, num_splits, level, errstr);
+ if (splitsize != (off_t)0) {
+ log_add(L_FAIL, "%s %s %s.%d %d %s", hostname, qdiskname,
+ datestamp, num_splits, level, errstr);
+ } else {
+ log_add(L_FAIL, "%s %s %s %d %s",
+ hostname, qdiskname, datestamp, level, errstr);
}
- else{
- log_add(L_FAIL, "%s %s %s %d %s",
- hostname, diskname, datestamp, level, errstr);
+ if ((str = syncpipe_getstr()) == NULL) { /* reap stats */
+ put_syncpipe_fault_result(handle);
+ return (-1);
}
- str = syncpipe_getstr(); /* reap stats */
amfree(str);
amfree(errstr);
} else {
char kps_str[NUM_STR_SIZE];
double rt;
- rt = runtime.r.tv_sec+runtime.r.tv_usec/1000000.0;
+ rt = (double)(runtime.r.tv_sec) +
+ ((double)(runtime.r.tv_usec) / 1000000.0);
curdump_rt = timesadd(runtime, curdump_rt);
- snprintf(kb_str, sizeof(kb_str), "%ld", filesize);
- snprintf(kps_str, sizeof(kps_str), "%3.1f",
- rt ? filesize / rt : 0.0);
- str = syncpipe_getstr();
+ snprintf(kb_str, SIZEOF(kb_str), OFF_T_FMT,
+ (OFF_T_FMT_TYPE)filesize);
+ snprintf(kps_str, SIZEOF(kps_str), "%3.1lf",
+ (isnormal(rt) ? (double)filesize / rt : 0.0));
+ if ((str = syncpipe_getstr()) == NULL) {
+ put_syncpipe_fault_result(handle);
+ return (-1);
+ }
errstr = newvstralloc(errstr,
"[sec ", walltime_str(runtime),
" kb ", kb_str,
" ", str,
"]",
NULL);
- q = squote(errstr);
- if (splitsize == 0) { /* Ordinary dump */
- if(first_file.is_partial) {
+ if (splitsize == (off_t)0) { /* Ordinary dump */
+ q = squote(errstr);
+/*@i@*/ if (first_file.is_partial) {
putresult(PARTIAL, "%s %s %d %s\n",
handle, label, filenum, q);
log_add(L_PARTIAL, "%s %s %s %d %s",
- hostname, diskname, datestamp, level, errstr);
- }
- else {
+ hostname, qdiskname, datestamp, level, errstr);
+ } else {
putresult(DONE, "%s %s %d %s\n",
handle, label, filenum, q);
log_add(L_SUCCESS, "%s %s %s %d %s",
- hostname, diskname, datestamp, level, errstr);
+ hostname, qdiskname, datestamp, level, errstr);
}
+ amfree(q);
} else { /* Chunked dump */
num_splits++;
- if(mode == MODE_FILE_WRITE){
+ if (mode == MODE_FILE_WRITE) {
holdfile_path_thischunk = stralloc(holdfile_path);
- holdfile_offset_thischunk = (lseek(fd, (off_t)0, SEEK_CUR))/1024;
+ holdfile_offset_thischunk = (lseek(fd, (off_t)0, SEEK_CUR))/(off_t)1024;
if(!save_holdfile){
- save_holdfile = alloc(sizeof(dumpfile_t));
+ save_holdfile = alloc(SIZEOF(dumpfile_t));
}
- memcpy(save_holdfile, &cur_holdfile,sizeof(dumpfile_t));
+ memcpy(save_holdfile, &cur_holdfile,SIZEOF(dumpfile_t));
}
- log_add(L_CHUNK, "%s %s %s %d %d %s", hostname, diskname,
+ log_add(L_CHUNK, "%s %s %s %d %d %s", hostname, qdiskname,
datestamp, num_splits, level, errstr);
- if(!nexting){ /* split dump complete */
- rt =curdump_rt.r.tv_sec+curdump_rt.r.tv_usec/1000000.0;
- snprintf(kb_str, sizeof(kb_str), "%ld",
- filesize+cur_span_chunkstart);
- snprintf(kps_str, sizeof(kps_str), "%3.1f",
- rt ? (filesize+cur_span_chunkstart) / rt : 0.0);
+ if (!nexting) { /* split dump complete */
+ rt = (double)(curdump_rt.r.tv_sec) +
+ ((double)(curdump_rt.r.tv_usec) / 1000000.0);
+ snprintf(kb_str, SIZEOF(kb_str), OFF_T_FMT,
+ (OFF_T_FMT_TYPE)(filesize + cur_span_chunkstart));
+ snprintf(kps_str, SIZEOF(kps_str), "%3.1lf",
+ isnormal(rt) ?
+ ((double)(filesize+cur_span_chunkstart)) / rt :
+ 0.0);
amfree(errstr);
errstr = newvstralloc(errstr,
"[sec ", walltime_str(curdump_rt),
putresult(DONE, "%s %s %d %s\n", handle, label,
filenum, q);
log_add(L_CHUNKSUCCESS, "%s %s %s %d %s",
- hostname, diskname, datestamp, level, errstr);
+ hostname, qdiskname, datestamp, level, errstr);
amfree(save_holdfile);
amfree(holdfile_path_thischunk);
amfree(q);
- }
+ }
}
amfree(str);
- if(!nexting){
+ if (!nexting) {
num_splits = 0;
expected_splits = 0;
amfree(holdfile_name);
num_holdfiles = 0;
- cur_span_chunkstart = 0;
+ cur_span_chunkstart = (off_t)0;
curdump_rt = times_zero;
}
-
amfree(errstr);
#ifdef HAVE_LIBVTBLC
if ((len = strlen(hostname)) <= 20) {
memset(desc + len, ' ', 1);
offset = len + 1;
- }
- else{
+ } else {
memset(desc + 20, ' ', 1);
offset = 21;
}
- strncpy(desc + offset, diskname, 20);
+ strncpy(desc + offset, qdiskname, 20);
- if ((len = strlen(diskname)) <= 20) {
+ if ((len = strlen(qdiskname)) <= 20) {
memset(desc + offset + len, ' ', 1);
offset = offset + len + 1;
- }
- else{
+ } else {
memset(desc + offset + 20, ' ', 1);
offset = offset + 21;
}
fflush(stderr);
/* pass label string on to tape writer */
- syncpipe_put('L', filenum);
- syncpipe_putstr(vol_label);
+ if (syncpipe_put('L', filenum) == -1) {
+ put_syncpipe_fault_result(handle);
+ return (-1);
+ }
+ if (syncpipe_putstr(vol_label) == -1) {
+ put_syncpipe_fault_result(handle);
+ return (-1);
+ }
/*
* reformat datestamp for later use with set_date from vtblc
vol_date);
/* pass date string on to tape writer */
- syncpipe_put('D', filenum);
- syncpipe_putstr(vol_date);
+ if (syncpipe_put('D', filenum) == -1) {
+ put_syncpipe_fault_result(handle);
+ return (-1);
+ }
+ if (syncpipe_putstr(vol_date) == -1) {
+ put_syncpipe_fault_result(handle);
+ return (-1);
+ }
#endif /* HAVE_LIBVTBLC */
}
/* reset stuff that assumes we're on a new file */
- if(nexting){
- opening = 1;
- nexting = 0;
- closing = 0;
- filesize = 0;
- syncpipe_put('O', 0);
- syncpipe_putstr(datestamp);
- syncpipe_putstr(hostname);
- syncpipe_putstr(diskname);
- syncpipe_putint(level);
- for(bp = buftable; bp < buftable + conf_tapebufs; bp++) {
- bp->status = EMPTY;
- }
- bp = buftable;
- header_written = 0;
- break;
+ if (!nexting)
+ return 0;
+
+#ifdef ASSERTIONS
+ opening = 1;
+#endif
+ nexting = 0;
+ closing = 0;
+ filesize = (off_t)0;
+ if (syncpipe_put('O', 0) == -1) {
+ put_syncpipe_fault_result(handle);
+ return -1;
+ }
+ if (syncpipe_putstr(datestamp) == -1) {
+ put_syncpipe_fault_result(handle);
+ return -1;
+ }
+ if (syncpipe_putstr(hostname) == -1) {
+ put_syncpipe_fault_result(handle);
+ return -1;
+ }
+ if (syncpipe_putstr(qdiskname) == -1) {
+ put_syncpipe_fault_result(handle);
+ return -1;
}
- else return 0;
+ if (syncpipe_putint(level) == -1) {
+ put_syncpipe_fault_result(handle);
+ return -1;
+ }
+ for (bp = buftable; bp < buftable + conf_tapebufs; bp++) {
+ bp->status = EMPTY;
+ }
+ bp = buftable;
+ header_written = 0;
+ break;
+
+ case 'X':
+ /*
+ * Pipe read error: Communications is severed at least
+ * back to us. We send a blind 'Q' (quit) and we don't
+ * wait for a response...
+ */
+ syncpipe_put('Q', 0); /* ACK error */
+ fprintf(stderr, "taper: communications pipe from reader severed\n");
+ return -1;
default:
- assert(0);
+ q = squotef("[Taper syncpipe protocol error]");
+ putresult(TAPE_ERROR, "%s %s\n", handle, q);
+ log_add(L_ERROR, "tape-error %s %s", handle, q);
+ amfree(q);
+ return -1;
}
}
-
return 0;
}
-int taper_fill_buffer(fd, bp, buflen)
-int fd;
-buffer_t *bp;
-int buflen;
+ssize_t
+taper_fill_buffer(
+ int fd,
+ buffer_t *bp,
+ size_t buflen)
{
char *curptr;
- int spaceleft, cnt;
+ ssize_t cnt;
curptr = bp->buffer;
- bp->size = 0;
- spaceleft = buflen;
- cnt = fullread(fd, curptr, spaceleft);
+ cnt = fullread(fd, curptr, buflen);
switch(cnt) {
case 0: /* eof */
- if(interactive) fputs("r0", stderr);
- return bp->size;
+ if (interactive)
+ fputs("r0", stderr);
+ bp->size = 0;
+ return (ssize_t)0;
+ /*NOTREACHED*/
+
case -1: /* error on read, punt */
- if(interactive) fputs("rE", stderr);
+ if (interactive)
+ fputs("rE", stderr);
+ bp->size = 0;
return -1;
+ /*NOTREACHED*/
+
default:
- if(mode == MODE_PORT_WRITE && splitsize > 0){
+ if ((mode == MODE_PORT_WRITE) && (splitsize > (off_t)0)) {
memcpy(splitbuf_wr_ptr, curptr, (size_t)cnt);
splitbuf_wr_ptr += cnt;
}
- spaceleft -= cnt;
- curptr += cnt;
- bp->size += cnt;
+ bp->size = cnt;
+ break;
}
- if(interactive) fputs("R", stderr);
- return bp->size;
+ if (interactive)
+ fputs("R", stderr);
+ return ((ssize_t)bp->size);
}
/* Given a dumpfile in holding, determine its size and figure out how many
* times we'd have to split it.
*/
-int predict_splits(filename)
-char *filename;
+int
+predict_splits(
+ char *filename)
{
int splits = 0;
- long total_kb = 0;
- long adj_splitsize = splitsize - DISK_BLOCK_BYTES/1024;
+ off_t total_kb = (off_t)0;
+ off_t adj_splitsize = splitsize - (off_t)(DISK_BLOCK_BYTES / 1024);
- if(splitsize <= 0) return(0);
+ if (splitsize <= (off_t)0)
+ return(0);
- if(adj_splitsize <= 0){
- error("Split size must be > %ldk", DISK_BLOCK_BYTES/1024);
+ if (adj_splitsize <= (off_t)0) {
+ error("Split size must be > " OFF_T_FMT "k",
+ (OFF_T_FMT_TYPE)(DISK_BLOCK_BYTES/1024));
+ /*NOTREACHED*/
}
/* should only calculuate this once, not on retries etc */
- if(expected_splits != 0) return(expected_splits);
+ if (expected_splits != 0)
+ return(expected_splits);
total_kb = size_holding_files(filename, 1);
- if(total_kb <= 0){
- fprintf(stderr, "taper: r: %ld kb holding file makes no sense, not precalculating splits\n", total_kb);
+ if (total_kb <= (off_t)0) {
+ fprintf(stderr, "taper: r: " OFF_T_FMT
+ " kb holding file makes no sense, not precalculating splits\n",
+ (OFF_T_FMT_TYPE)total_kb);
fflush(stderr);
return(0);
}
- fprintf(stderr, "taper: r: Total dump size should be %ldkb, chunk size is %ldkb\n", total_kb, splitsize);
+ fprintf(stderr, "taper: r: Total dump size should be " OFF_T_FMT
+ "kb, chunk size is " OFF_T_FMT "kb\n",
+ (OFF_T_FMT_TYPE)total_kb,
+ (OFF_T_FMT_TYPE)splitsize);
fflush(stderr);
- splits = total_kb/adj_splitsize;
- if(total_kb % adj_splitsize) splits++;
+ splits = (int)(total_kb / adj_splitsize);
+ if ((splits == 0) || (total_kb % adj_splitsize))
+ splits++;
fprintf(stderr, "taper: r: Expecting to split into %d parts \n", splits);
*
*/
times_t idlewait, rdwait, wrwait, fmwait;
-long total_writes;
-double total_tape_used;
+unsigned long total_writes;
+off_t total_tape_used;
int total_tape_fm;
-void write_file P((void));
-int write_buffer P((buffer_t *bp));
+void write_file(void);
+int write_buffer(buffer_t *bp);
-void tape_writer_side(getp, putp)
-int getp, putp;
+void
+tape_writer_side(
+ int getp,
+ int putp)
{
- char tok;
+ int tok;
int tape_started;
char *str;
char *hostname;
procname = "writer";
syncpipe_init(getp, putp);
-
tape_started = 0;
idlewait = times_zero;
- while(1) {
+ while (1) {
startclock();
- tok = syncpipe_get(&tmpint);
+ if ((tok = syncpipe_get(&tmpint)) == -1) {
+ error("writer: Syncpipe failure before start");
+ /*NOTREACHED*/
+ }
+
idlewait = timesadd(idlewait, stopclock());
- if(tok != 'S' && tok != 'Q' && !tape_started) {
+ if (tok != 'S' && tok != 'Q' && !tape_started) {
error("writer: token '%c' before start", tok);
+ /*NOTREACHED*/
}
switch(tok) {
+ case 'H': /* Reader read pipe side is down */
+ dbprintf(("writer: Communications with reader is down"));
+ error("writer: Communications with reader is down");
+ /*NOTREACHED*/
+
case 'S': /* start-tape */
- if(tape_started) {
+ if (tape_started) {
error("writer: multiple start requests");
+ /*NOTREACHED*/
+ }
+ if ((str = syncpipe_getstr()) == NULL) {
+ error("writer: Syncpipe failure");
+ /*NOTREACHED*/
}
- str = syncpipe_getstr();
- if(!first_tape(str ? str : "bad-datestamp")) {
- if(tape_fd >= 0) {
+ if (!first_tape(str ? str : "bad-datestamp")) {
+ if (tape_fd >= 0) {
tapefd_close(tape_fd);
tape_fd = -1;
}
- syncpipe_put('E', 0);
- syncpipe_putstr(errstr);
+ if (syncpipe_put('E', 0) == -1) {
+ error("writer: Syncpipe failure passing exit code");
+ /*NOTREACHED*/
+ }
+ if (syncpipe_putstr(errstr) == -1) {
+ error("writer: Syncpipe failure passing exit string");
+ /*NOTREACHED*/
+ }
/* wait for reader to acknowledge error */
do {
- tok = syncpipe_get(&tmpint);
- if(tok != 'e') {
+ if ((tok = syncpipe_get(&tmpint)) == -1) {
+ error("writer: Syncpipe failure waiting for error ack");
+ /*NOTREACHED*/
+ }
+ if (tok != 'e') {
error("writer: got '%c' unexpectedly after error", tok);
+ /*NOTREACHED*/
}
- } while(tok != 'e');
+ } while (tok != 'e');
} else {
- syncpipe_put('S', 0);
+ if (syncpipe_put('S', 0) == -1) {
+ error("writer: syncpipe failure while starting tape");
+ /*NOTREACHED*/
+ }
tape_started = 1;
}
amfree(str);
-
break;
case 'O': /* open-output */
- datestamp = syncpipe_getstr();
+ if ((datestamp = syncpipe_getstr()) == NULL) {
+ error("writer: Syncpipe failure during open");
+ /*NOTREACHED*/
+ }
tapefd_setinfo_datestamp(tape_fd, datestamp);
amfree(datestamp);
- hostname = syncpipe_getstr();
+
+ if ((hostname = syncpipe_getstr()) == NULL) {
+ error("writer: Syncpipe failure fetching hostname");
+ /*NOTREACHED*/
+ }
tapefd_setinfo_host(tape_fd, hostname);
amfree(hostname);
- diskname = syncpipe_getstr();
+
+ if ((diskname = syncpipe_getstr()) == NULL) {
+ error("writer: Syncpipe failure fetching diskname");
+ /*NOTREACHED*/
+ }
tapefd_setinfo_disk(tape_fd, diskname);
amfree(diskname);
- level = syncpipe_getint();
+ if ((level = syncpipe_getint()) == -1) {
+ error("writer: Syncpipe failure fetching level");
+ /*NOTREACHED*/
+ }
tapefd_setinfo_level(tape_fd, level);
write_file();
break;
#ifdef HAVE_LIBVTBLC
case 'L': /* read vtbl label */
vtbl_no = tmpint;
- vol_label = syncpipe_getstr();
+ if ((vol_label = syncpipe_getstr()) == NULL) {
+ error("writer: Syncpipe failure fetching vrbl label");
+ /*NOTREACHED*/
+ }
fprintf(stderr, "taper: read label string \"%s\" from pipe\n",
vol_label);
strncpy(vtbl_entry[vtbl_no].label, vol_label, 45);
case 'D': /* read vtbl date */
vtbl_no = tmpint;
- vol_date = syncpipe_getstr();
+ if ((vol_date = syncpipe_getstr()) == NULL) {
+ error("writer: Syncpipe failure fetching vrbl date");
+ /*NOTREACHED*/
+ }
fprintf(stderr, "taper: read date string \"%s\" from pipe\n",
vol_date);
strncpy(vtbl_entry[vtbl_no].date, vol_date, 20);
case 'Q':
end_tape(0); /* XXX check results of end tape ?? */
clear_tapelist();
- amfree(taper_datestamp);
+ free_server_config();
+ amfree(taper_timestamp);
amfree(label);
amfree(errstr);
amfree(changer_resultstr);
malloc_size_2 = malloc_inuse(&malloc_hist_2);
- if(malloc_size_1 != malloc_size_2) {
+ if (malloc_size_1 != malloc_size_2) {
malloc_list(fileno(stderr), malloc_hist_1, malloc_hist_2);
}
-
exit(0);
+ /*NOTREACHED*/
default:
assert(0);
}
}
-void write_file()
+void
+write_file(void)
{
buffer_t *bp;
int full_buffers, i, bufnum;
- char tok;
+ int tok;
char number[NUM_STR_SIZE];
char *rdwait_str, *wrwait_str, *fmwait_str;
int tmpint;
full_buffers = 0;
tok = '?';
- if(bufdebug) {
+ if (bufdebug) {
fprintf(stderr, "taper: w: start file\n");
fflush(stderr);
}
/*
* Tell the reader that the tape is open, and give it all the buffers.
*/
- syncpipe_put('O', 0);
- for(i = 0; i < conf_tapebufs; i++) {
- if(bufdebug) {
+ if (syncpipe_put('O', 0) == -1) {
+ error("writer: Syncpipe failure starting write sequence");
+ /*NOTREACHED*/
+ }
+ for (i = 0; i < conf_tapebufs; i++) {
+ if (bufdebug) {
fprintf(stderr, "taper: w: put R%d\n", i);
fflush(stderr);
}
- syncpipe_put('R', i);
+ if (syncpipe_put('R', i) == -1) {
+ error("writer: Syncpipe failure readying write buffers");
+ /*NOTREACHED*/
+ }
}
/*
*/
startclock();
- if(!write_filemark())
+ if (!write_filemark())
goto tape_error;
fmwait = stopclock();
* of starts/stops, which in turn saves tape and time.
*/
- if(interactive) fputs("[WS]", stderr);
+ if (interactive)
+ fputs("[WS]", stderr);
startclock();
- while(full_buffers < conf_tapebufs - THRESHOLD) {
- tok = syncpipe_get(&bufnum);
- if(tok != 'W') break;
- if(bufdebug) {
+ while (full_buffers < conf_tapebufs - THRESHOLD) {
+ if ((tok = syncpipe_get(&bufnum)) == -1) {
+ error("writer: Syncpipe failure during buffer advance");
+ /*NOTREACHED*/
+ }
+ if (tok != 'W')
+ break;
+ if (bufdebug) {
fprintf(stderr,"taper: w: got W%d\n",bufnum);
fflush(stderr);
}
* in, then we will be STREAMING.
*/
- while(full_buffers) {
- if(tt_file_pad && bp->size < tt_blocksize) {
+ while (full_buffers) {
+ if (tt_file_pad && bp->size < (ssize_t)tt_blocksize) {
memset(bp->buffer+bp->size, 0, tt_blocksize - bp->size);
- bp->size = tt_blocksize;
+ bp->size = (ssize_t)tt_blocksize;
}
- if(!write_buffer(bp)) goto tape_error;
+ if (!write_buffer(bp))
+ goto tape_error;
full_buffers--;
bp = nextbuf(bp);
}
* to wait for buffers to fill, we are then STOPPED again.
*/
- while(tok == 'W' && bp->status == FULL) {
- tok = syncpipe_get(&bufnum);
- if(tok == 'W') {
- if(bufdebug) {
+ while (tok == 'W' && bp->status == FULL) {
+ if ((tok = syncpipe_get(&bufnum)) == -1) {
+ error("writer: Syncpipe failure advancing buffer");
+ /*NOTREACHED*/
+ }
+
+ if (tok == 'W') {
+ if (bufdebug) {
fprintf(stderr,"taper: w: got W%d\n",bufnum);
fflush(stderr);
}
- if(bufnum != bp-buftable) {
+ if(bufnum != (int)(bp - buftable)) {
fprintf(stderr,
"taper: tape-writer: my buf %d reader buf %d\n",
(int)(bp-buftable), bufnum);
fflush(stderr);
- syncpipe_put('E', 0);
- syncpipe_putstr("writer-side buffer mismatch");
+ if (syncpipe_put('E', 0) == -1) {
+ error("writer: Syncpipe failure putting error token");
+ /*NOTREACHED*/
+ }
+ if (syncpipe_putstr("writer-side buffer mismatch") == -1) {
+ error("writer: Syncpipe failure putting error messgae");
+ /*NOTREACHED*/
+ }
goto error_ack;
}
- if(tt_file_pad && bp->size < tt_blocksize) {
+ if (tt_file_pad && bp->size < (ssize_t)tt_blocksize) {
memset(bp->buffer+bp->size, 0, tt_blocksize - bp->size);
- bp->size = tt_blocksize;
+ bp->size = (ssize_t)tt_blocksize;
}
- if(!write_buffer(bp)) goto tape_error;
+ if (!write_buffer(bp))
+ goto tape_error;
bp = nextbuf(bp);
- }
- else if(tok == 'Q')
+ } else if (tok == 'Q') {
return;
- else if(tok == 'X')
+ } else if (tok == 'X') {
goto reader_buffer_snafu;
- else
+ } else {
error("writer-side not expecting token: %c", tok);
+ /*NOTREACHED*/
+ }
}
- } while(tok == 'W');
+ } while (tok == 'W');
/* got close signal from reader, acknowledge it */
- if(tok == 'X')
+ if (tok == 'X')
goto reader_buffer_snafu;
assert(tok == 'C');
- syncpipe_put('C', 0);
+ if (syncpipe_put('C', 0) == -1) {
+ error("writer: Syncpipe failure putting close");
+ /*NOTREACHED*/
+ }
/* tell reader the tape and file number */
- syncpipe_putstr(label);
- snprintf(number, sizeof(number), "%d", filenum);
- syncpipe_putstr(number);
+ if (syncpipe_putstr(label) == -1) {
+ error("writer: Syncpipe failure putting label");
+ /*NOTREACHED*/
+ }
+ snprintf(number, SIZEOF(number), "%d", filenum);
+ if (syncpipe_putstr(number) == -1) {
+ error("writer: Syncpipe failure putting filenum");
+ /*NOTREACHED*/
+ }
- snprintf(number, sizeof(number), "%ld", total_writes);
+ snprintf(number, SIZEOF(number), "%lu", total_writes);
rdwait_str = stralloc(walltime_str(rdwait));
wrwait_str = stralloc(walltime_str(wrwait));
fmwait_str = stralloc(walltime_str(fmwait));
amfree(rdwait_str);
amfree(wrwait_str);
amfree(fmwait_str);
- syncpipe_putstr(errstr);
+ if (syncpipe_putstr(errstr) == -1) {
+ error("writer: Syncpipe failure putting '%s'", errstr);
+ /*NOTREACHED*/
+ }
/* XXX go to next tape if past tape size? */
tape_error:
/* got tape error */
- if(next_tape(1)) syncpipe_put('T', 0); /* next tape in place, try again */
- else syncpipe_put('E', 0); /* no more tapes, fail */
- syncpipe_putstr(errstr);
+ if (next_tape(1)) {
+ if (syncpipe_put('T', 0) == -1) { /* next tape in place, try again */
+ error("writer: Syncpipe failure during tape advance");
+ /*NOTREACHED*/
+ }
+ } else {
+ if (syncpipe_put('E', 0) == -1) { /* no more tapes, fail */
+ error("writer: Syncpipe failure during tape error");
+ /*NOTREACHED*/
+ }
+ }
+ if (syncpipe_putstr(errstr) == -1) {
+ error("writer: Syncpipe failure putting '%s'", errstr);
+ /*NOTREACHED*/
+ }
error_ack:
/* wait for reader to acknowledge error */
do {
- tok = syncpipe_get(&tmpint);
- if(tok != 'W' && tok != 'C' && tok != 'e')
+ if ((tok = syncpipe_get(&tmpint)) == -1) {
+ error("writer: syncpipe failure waiting for error ack");
+ /*NOTREACHED*/
+ }
+
+ if (tok != 'W' && tok != 'C' && tok != 'e') {
error("writer: got '%c' unexpectedly after error", tok);
- } while(tok != 'e');
+ /*NOTREACHED*/
+ }
+ } while (tok != 'e');
return;
reader_buffer_snafu:
- syncpipe_put('x', 0);
+ if (syncpipe_put('x', 0) == -1) {
+ error("writer: syncpipe failure putting buffer snafu");
+ /*NOTREACHED*/
+ }
return;
}
-int write_buffer(bp)
-buffer_t *bp;
+int
+write_buffer(
+ buffer_t *bp)
{
- int rc;
+ ssize_t rc;
assert(bp->status == FULL);
startclock();
- rc = tapefd_write(tape_fd, bp->buffer, bp->size);
- if(rc == bp->size) {
+ rc = tapefd_write(tape_fd, bp->buffer, (size_t)bp->size);
+ if (rc == (ssize_t)bp->size) {
#if defined(NEED_RESETOFS)
static double tape_used_modulus_2gb = 0;
* go silly on us.
*/
tape_used_modulus_2gb += (double)rc;
- if(tape_used_modulus_2gb + (double)rc > (double)0x7fffffff) {
+ if (tape_used_modulus_2gb + (double)rc > (double)0x7fffffff) {
tape_used_modulus_2gb = 0;
tapefd_resetofs(tape_fd);
}
#endif
wrwait = timesadd(wrwait, stopclock());
total_writes += 1;
- total_tape_used += (double)rc;
+ total_tape_used += (off_t)rc;
bp->status = EMPTY;
- if(interactive || bufdebug) dumpstatus(bp);
- if(interactive) fputs("W", stderr);
+ if (interactive || bufdebug)
+ dumpstatus(bp);
+ if (interactive)
+ fputs("W", stderr);
- if(bufdebug) {
+ if (bufdebug) {
fprintf(stderr, "taper: w: put R%d\n", (int)(bp-buftable));
fflush(stderr);
}
- syncpipe_put('R', bp-buftable);
+ if (syncpipe_put('R', (int)(bp-buftable)) == -1) {
+ error("writer: Syncpipe failure during advancing write bufffer");
+ /*NOTREACHED*/
+ }
return 1;
} else {
errstr = newvstralloc(errstr,
(rc != -1) ? "short write" : strerror(errno),
NULL);
wrwait = timesadd(wrwait, stopclock());
- if(interactive) fputs("[WE]", stderr);
+ if (interactive)
+ fputs("[WE]", stderr);
return 0;
}
}
* Cleanup shared memory segments
*/
static void
-signal_handler(int signum)
+signal_handler(
+ int signum)
{
log_add(L_INFO, "Received signal %d", signum);
* segments
*/
static void
-install_signal_handlers(void)
+install_signal_handlers(void)
{
struct sigaction act;
if (sigaction(SIGINT, &act, NULL) != 0) {
error("taper: couldn't install SIGINT handler [%s]", strerror(errno));
+ /*NOTREACHED*/
}
if (sigaction(SIGHUP, &act, NULL) != 0) {
error("taper: couldn't install SIGHUP handler [%s]", strerror(errno));
+ /*NOTREACHED*/
}
if (sigaction(SIGTERM, &act, NULL) != 0) {
error("taper: couldn't install SIGTERM handler [%s]", strerror(errno));
+ /*NOTREACHED*/
}
if (sigaction(SIGUSR1, &act, NULL) != 0) {
error("taper: couldn't install SIGUSR1 handler [%s]", strerror(errno));
+ /*NOTREACHED*/
}
if (sigaction(SIGUSR2, &act, NULL) != 0) {
error("taper: couldn't install SIGUSR2 handler [%s]", strerror(errno));
+ /*NOTREACHED*/
}
if (sigaction(SIGALRM, &act, NULL) != 0) {
error("taper: couldn't install SIGALRM handler [%s]", strerror(errno));
+ /*NOTREACHED*/
}
}
int shmid = -1;
-char *attach_buffers(size)
- unsigned int size;
+char *
+attach_buffers(
+ size_t size)
{
char *result;
shmid = shmget(IPC_PRIVATE, size, IPC_CREAT|0700);
- if(shmid == -1) {
+ if (shmid == -1) {
return NULL;
}
result = (char *)shmat(shmid, (SHM_ARG_TYPE *)NULL, 0);
- if(result == (char *)-1) {
+ if (result == (char *)-1) {
int save_errno = errno;
destroy_buffers();
errno = save_errno;
error("shmat: %s", strerror(errno));
+ /*NOTREACHED*/
}
return result;
}
-void detach_buffers(bufp)
- char *bufp;
+void
+detach_buffers(
+ char *bufp)
{
if ((bufp != NULL) &&
(shmdt((SHM_ARG_TYPE *)bufp) == -1)) {
error("shmdt: %s", strerror(errno));
+ /*NOTREACHED*/
}
}
-void destroy_buffers()
+void
+destroy_buffers(void)
{
- if(shmid == -1) return; /* nothing to destroy */
- if(shmctl(shmid, IPC_RMID, NULL) == -1) {
+ if (shmid == -1)
+ return; /* nothing to destroy */
+ if (shmctl(shmid, IPC_RMID, NULL) == -1) {
error("shmctl: %s", strerror(errno));
+ /*NOTREACHED*/
}
}
#endif
int shmfd = -1;
-unsigned int saved_size;
+size_t saved_size;
-char *attach_buffers(size)
- unsigned int size;
+char *
+attach_buffers(
+ size_t size)
{
char *shmbuf;
#ifdef ZERO_FILE
shmfd = open(ZERO_FILE, O_RDWR);
- if(shmfd == -1) {
+ if (shmfd == -1) {
error("attach_buffers: could not open %s: %s",
ZERO_FILE,
strerror(errno));
+ /*NOTREACHED*/
}
#endif
return shmbuf;
}
-void detach_buffers(bufp)
-char *bufp;
+void
+detach_buffers(
+ char *bufp)
{
if ((bufp != NULL) &&
(munmap((void *)bufp, saved_size) == -1)) {
error("detach_buffers: munmap: %s", strerror(errno));
+ /*NOTREACHED*/
}
if (shmfd != -1)
aclose(shmfd);
}
-void destroy_buffers()
+void
+destroy_buffers(void)
{
}
int getpipe, putpipe;
-void syncpipe_init(rd, wr)
-int rd, wr;
+void
+syncpipe_init(
+ int rd,
+ int wr)
{
getpipe = rd;
putpipe = wr;
}
-char syncpipe_get(intp)
-int *intp;
+void
+syncpipe_read_error(
+ ssize_t rc,
+ ssize_t expected)
{
- int rc;
char buf[sizeof(char) + sizeof(int)];
- rc = fullread(getpipe, buf, sizeof(buf));
- if(rc == 0) /* EOF */
- error("syncpipe_get: %c: unexpected EOF", *procname);
- else if(rc < 0)
- error("syncpipe_get: %c: %s", *procname, strerror(errno));
- else if(rc != sizeof(buf))
- error("syncpipe_get: %s", "short read");
+ if (rc == 0) {
+ dbprintf(("syncpipe_get %s halting: Unexpected read EOF\n", procname));
+ fprintf(stderr, "syncpipe_get %s halting: Unexpected read EOF\n", procname);
+ } else if (rc < 0) {
+ dbprintf(("syncpipe_get %s halting: Read error - %s\n",
+ procname, strerror(errno)));
+ fprintf(stderr, "syncpipe_get %s halting: Read error - %s\n",
+ procname, strerror(errno));
+ } else {
+ dbprintf(("syncpipe_get %s halting: Read "
+ SSIZE_T_FMT " bytes short of " SSIZE_T_FMT "\n",
+ procname, (SSIZE_T_FMT_TYPE)(rc - expected),
+ (SSIZE_T_FMT_TYPE)expected));
+ fprintf(stderr, "syncpipe_get %s halting: Read "
+ SSIZE_T_FMT " bytes short of " SSIZE_T_FMT "\n",
+ procname, (SSIZE_T_FMT_TYPE)(rc - expected),
+ (SSIZE_T_FMT_TYPE)expected);
+ }
+ /* Halt the other side if it's still alive */
+ buf[0] = 'H';
+ memset(&buf[1], 0, SIZEOF(int));
+ if (write(putpipe, buf, SIZEOF(buf)))
+ return;
+}
+
+void
+syncpipe_write_error(
+ ssize_t rc,
+ ssize_t expected)
+{
+ char buf[sizeof(char) + sizeof(int)];
+
+ if (rc == 0) { /* EOF */
+ dbprintf(("syncpipe %s halting: Write EOF\n", procname));
+ fprintf(stderr, "syncpipe %s halting: Write EOF\n", procname);
+ } else if (rc < 0) {
+ dbprintf(("syncpipe %s halting: Write error - %s\n",
+ procname, strerror(errno)));
+ fprintf(stderr, "syncpipe %s halting: Write error - %s\n",
+ procname, strerror(errno));
+ } else {
+ dbprintf(("syncpipe %s halting: Write "
+ SSIZE_T_FMT " bytes short of " SSIZE_T_FMT "\n",
+ procname, (SSIZE_T_FMT_TYPE)(rc - expected),
+ (SSIZE_T_FMT_TYPE)expected));
+ fprintf(stderr, "syncpipe %s halting: Write "
+ SSIZE_T_FMT " bytes short of " SSIZE_T_FMT "\n",
+ procname, (SSIZE_T_FMT_TYPE)(rc - expected),
+ (SSIZE_T_FMT_TYPE)expected);
+ }
+ /* Halt the other side if it's still alive */
+ buf[0] = 'H';
+ memset(&buf[1], 0, SIZEOF(int));
+ if (write(putpipe, buf, SIZEOF(buf)))
+ return;
+}
+
+int
+syncpipe_get(
+ int *intp)
+{
+ ssize_t rc;
+ char buf[SIZEOF(char) + SIZEOF(int)];
- if(bufdebug && *buf != 'R' && *buf != 'W') {
- fprintf(stderr,"taper: %c: getc %c\n",*procname,*buf);
+ memset(buf, 0, sizeof(buf));
+ rc = fullread(getpipe, buf, SIZEOF(buf));
+ if (rc != (ssize_t)sizeof(buf)) {
+ syncpipe_read_error(rc, (ssize_t)sizeof(buf));
+ return (-1);
+ }
+
+ if (bufdebug && *buf != 'R' && *buf != 'W') {
+ fprintf(stderr,"taper: %c: getc %c\n", *procname, *buf);
fflush(stderr);
}
- memcpy(intp, &buf[1], sizeof(int));
- return buf[0];
+ memcpy(intp, &buf[1], SIZEOF(int));
+ return (int)buf[0];
}
-int syncpipe_getint()
+int
+syncpipe_getint(void)
{
- int rc, i;
+ ssize_t rc;
+ int i = 0;
- if ((rc = fullread(getpipe, &i, sizeof(i))) != sizeof(i))
- error("syncpipe_getint: %s", rc < 0 ? strerror(errno) : "short read");
+ rc = fullread(getpipe, &i, SIZEOF(i));
+ if (rc != (ssize_t)sizeof(i)) {
+ syncpipe_read_error(rc, (ssize_t)sizeof(i));
+ return (-1);
+ }
return (i);
}
-char *syncpipe_getstr()
+char *
+syncpipe_getstr(void)
{
- int rc, len;
+ ssize_t rc;
+ int len;
char *str;
- if((len = syncpipe_getint()) <= 0) {
- error("syncpipe_getstr: Protocol error - Invalid length (%d)", len);
- /* NOTREACHED */
+ if ((len = syncpipe_getint()) <= 0) {
+ fprintf(stderr, "syncpipe %s halting: Protocol error - "
+ "Invalid string length (%d)\n", procname, len);
+ syncpipe_put('H', 0); /* Halt the other side */
+ exit(1);
+ /*NOTREACHED*/
}
- str = alloc(len);
+ str = alloc((size_t)len);
- if ((rc = fullread(getpipe, str, len)) != len) {
- error("syncpipe_getstr: %s", rc < 0 ? strerror(errno) : "short read");
- /* NOTREACHED */
+ rc = fullread(getpipe, str, (size_t)len);
+ if (rc != (ssize_t)len) {
+ syncpipe_read_error(rc, (ssize_t)len);
+ return (NULL);
}
-
return (str);
}
-void syncpipe_put(chi, intval)
-int chi;
-int intval;
+int
+syncpipe_put(
+ int chi,
+ int intval)
{
char buf[sizeof(char) + sizeof(int)];
+ ssize_t rc;
buf[0] = (char)chi;
- memcpy(&buf[1], &intval, sizeof(int));
- if(bufdebug && buf[0] != 'R' && buf[0] != 'W') {
+ memcpy(&buf[1], &intval, SIZEOF(int));
+ if (bufdebug && buf[0] != 'R' && buf[0] != 'W') {
fprintf(stderr,"taper: %c: putc %c\n",*procname,buf[0]);
fflush(stderr);
}
- if (fullwrite(putpipe, buf, sizeof(buf)) < 0)
- error("syncpipe_put: %s", strerror(errno));
+ rc = fullwrite(putpipe, buf, SIZEOF(buf));
+ if (rc != (ssize_t)sizeof(buf)) {
+ syncpipe_write_error(rc, (ssize_t)sizeof(buf));
+ return (-1);
+ }
+ return (0);
}
-void syncpipe_putint(i)
-int i;
+int
+syncpipe_putint(
+ int i)
{
+ ssize_t rc;
- if (fullwrite(putpipe, &i, sizeof(i)) < 0)
- error("syncpipe_putint: %s", strerror(errno));
+ rc = fullwrite(putpipe, &i, SIZEOF(i));
+ if (rc != (ssize_t)sizeof(i)) {
+ syncpipe_write_error(rc, (ssize_t)sizeof(i));
+ return (-1);
+ /* NOTREACHED */
+ }
+ return (0);
}
-void syncpipe_putstr(str)
-const char *str;
+int
+syncpipe_putstr(
+ const char *str)
{
- int n;
+ ssize_t n, rc;
- n = strlen(str)+1; /* send '\0' as well */
- syncpipe_putint(n);
- if (fullwrite(putpipe, str, n) < 0)
- error("syncpipe_putstr: %s", strerror(errno));
-}
+ if(!str)
+ str = "UNKNOWN syncpipe_putstr STRING";
+ n = (ssize_t)strlen(str) + 1; /* send '\0' as well */
+ syncpipe_putint((int)n);
+
+ rc = fullwrite(putpipe, str, (size_t)n);
+ if (rc != n) {
+ syncpipe_write_error(rc, n);
+ return (-1);
+ }
+ return (0);
+}
\f
/*
* ========================================================================
* TAPE MANIPULATION SUBSYSTEM
*
*/
+int label_tape(void);
/* local functions */
-int label_tape P((void));
-int label_tape()
+/* return 0 on success */
+/* return 1 on error and set errstr */
+int
+label_tape(void)
{
char *conf_tapelist_old = NULL;
char *result;
static int first_call = 1;
char *timestamp;
- char *error_msg;
+ char *error_msg = NULL;
char *s, *r;
int slot = -1;
- if (taper_scan(NULL, &label, ×tamp, &error_msg, &tapedev) < 0) {
- fprintf(stderr, "%s\n", error_msg);
- errstr = newstralloc(errstr, error_msg);
- amfree(error_msg);
- amfree(timestamp);
+ amfree(label);
+ amfree(tapedev);
+ if (taper_scan(NULL, &label, ×tamp, &tapedev, CHAR_taperscan_output_callback, &error_msg) < 0) {
+ fprintf(stderr, "%s\n", error_msg);
+ errstr = error_msg;
+ error_msg = NULL;
+ amfree(timestamp);
return 0;
}
+ amfree(timestamp);
if(error_msg) {
s = error_msg; r = NULL;
while((s=strstr(s,"slot "))) { s += 5; r=s; };
if(r) {
slot = atoi(r);
}
+ amfree(error_msg);
}
- if((tape_fd = tape_open(tapedev, O_WRONLY)) == -1) {
- if(errno == EACCES) {
+ if ((tape_fd = tape_open(tapedev, O_WRONLY)) == -1) {
+ if (errno == EACCES) {
errstr = newstralloc(errstr,
"writing label: tape is write protected");
} else {
return 0;
}
- tapefd_setinfo_length(tape_fd, tt->length);
+ tapefd_setinfo_length(tape_fd, tapetype_get_length(tt));
- tapefd_setinfo_datestamp(tape_fd, taper_datestamp);
+ tapefd_setinfo_datestamp(tape_fd, taper_timestamp);
tapefd_setinfo_disk(tape_fd, label);
- result = tapefd_wrlabel(tape_fd, taper_datestamp, label, tt_blocksize);
- if(result != NULL) {
+ result = tapefd_wrlabel(tape_fd, taper_timestamp, label, tt_blocksize);
+ if (result != NULL) {
errstr = newstralloc(errstr, result);
return 0;
}
if(slot > -1) {
fprintf(stderr, "taper: slot: %d wrote label `%s' date `%s'\n", slot,
- label, taper_datestamp);
+ label, taper_timestamp);
}
else {
fprintf(stderr, "taper: wrote label `%s' date `%s'\n", label,
- taper_datestamp);
+ taper_timestamp);
}
fflush(stderr);
#endif /* HAVE_LIBVTBLC */
if (strcmp(label, FAKE_LABEL) != 0) {
-
- if(cur_tape == 0) {
+ if (cur_tape == 0) {
conf_tapelist_old = stralloc2(conf_tapelist, ".yesterday");
} else {
char cur_str[NUM_STR_SIZE];
- snprintf(cur_str, sizeof(cur_str), "%d", cur_tape - 1);
+ snprintf(cur_str, SIZEOF(cur_str), "%d", cur_tape - 1);
conf_tapelist_old = vstralloc(conf_tapelist,
".today.", cur_str, NULL);
}
- if(write_tapelist(conf_tapelist_old)) {
+
+ if (write_tapelist(conf_tapelist_old)) {
error("could not write tapelist: %s", strerror(errno));
+ /*NOTREACHED*/
}
amfree(conf_tapelist_old);
remove_tapelabel(label);
- add_tapelabel(atoi(taper_datestamp), label);
- if(write_tapelist(conf_tapelist)) {
+ add_tapelabel(taper_timestamp, label);
+ if (write_tapelist(conf_tapelist)) {
error("could not write tapelist: %s", strerror(errno));
+ /*NOTREACHED*/
}
}
log_add(L_START, "datestamp %s label %s tape %d",
- taper_datestamp, label, cur_tape);
+ taper_timestamp, label, cur_tape);
if (first_call && strcmp(label, FAKE_LABEL) == 0) {
first_call = 0;
log_add(L_WARNING, "tapedev is %s, dumps will be thrown away", tapedev);
}
- total_tape_used=0.0;
+ total_tape_used=(off_t)0;
total_tape_fm = 0;
return 1;
}
-int first_tape(new_datestamp)
-char *new_datestamp;
+/* return 0 on error and set errstr */
+/* return 1 on success */
+int
+first_tape(
+ char *new_datestamp)
{
- if((have_changer = changer_init()) < 0) {
+ if ((have_changer = changer_init()) < 0) {
error("changer initialization failed: %s", strerror(errno));
+ /*NOTREACHED*/
}
changer_debug = 1;
- taper_datestamp = newstralloc(taper_datestamp, new_datestamp);
+ taper_timestamp = newstralloc(taper_timestamp, new_datestamp);
- if(!label_tape())
+ if (!label_tape())
return 0;
filenum = 0;
return 1;
}
-int next_tape(writerror)
-int writerror;
+int
+next_tape(
+ int writerror)
{
end_tape(writerror);
- if(++cur_tape >= runtapes)
+ if (++cur_tape >= runtapes)
return 0;
- if(!label_tape()) {
+ if (!label_tape()) {
return 0;
}
}
-int end_tape(writerror)
-int writerror;
+int
+end_tape(
+ int writerror)
{
char *result;
int rc = 0;
- if(tape_fd >= 0) {
- log_add(L_INFO, "tape %s kb %ld fm %d %s",
+ if (tape_fd >= 0) {
+ log_add(L_INFO, "tape %s kb " OFF_T_FMT " fm %d %s",
label,
- (long) ((total_tape_used+1023.0) / 1024.0),
+ (OFF_T_FMT_TYPE)((total_tape_used+(off_t)1023) / (off_t)1024),
total_tape_fm,
writerror? errstr : "[OK]");
- fprintf(stderr, "taper: writing end marker. [%s %s kb %ld fm %d]\n",
- label,
+ fprintf(stderr, "taper: writing end marker. [%s %s kb "
+ OFF_T_FMT " fm %d]\n", label,
writerror? "ERR" : "OK",
- (long) ((total_tape_used+1023.0) / 1024.0),
+ (OFF_T_FMT_TYPE)((total_tape_used+(off_t)1023) / (off_t)1024),
total_tape_fm);
fflush(stderr);
- if(! writerror) {
- if(! write_filemark()) {
+ if (! writerror) {
+ if (! write_filemark()) {
rc = 1;
goto common_exit;
}
- result = tapefd_wrendmark(tape_fd, taper_datestamp, tt_blocksize);
- if(result != NULL) {
+ result = tapefd_wrendmark(tape_fd, taper_timestamp, tt_blocksize);
+ if (result != NULL) {
errstr = newstralloc(errstr, result);
rc = 1;
goto common_exit;
if (tape_fd >= 0 && is_zftape(tapedev) == 1) {
/* rewind the tape */
- if(tapefd_rewind(tape_fd) == -1 ) {
+ if (tapefd_rewind(tape_fd) == -1 ) {
errstr = newstralloc2(errstr, "rewinding tape: ", strerror(errno));
rc = 1;
goto common_exit;
}
/* close the tape */
- if(tapefd_close(tape_fd) == -1) {
+ if (tapefd_close(tape_fd) == -1) {
errstr = newstralloc2(errstr, "closing tape: ", strerror(errno));
rc = 1;
goto common_exit;
fflush(stderr);
if ((tape_fd = raw_tape_open(rawtapedev, O_RDWR)) == -1) {
- if(errno == EACCES) {
+ if (errno == EACCES) {
errstr = newstralloc(errstr,
"updating volume table: tape is write protected");
} else {
}
/* set volume label and date for first entry */
vtbl_no = 0;
- if(set_label(label, volumes, num_volumes, vtbl_no)){
+ if (set_label(label, volumes, num_volumes, vtbl_no)) {
errstr = newstralloc2(errstr,
"setting label for entry 1: ",
strerror(errno));
goto common_exit;
}
/* date of start writing this tape */
- if (set_date(start_datestr, volumes, num_volumes, vtbl_no)){
+ if (set_date(start_datestr, volumes, num_volumes, vtbl_no)) {
errstr = newstralloc2(errstr,
"setting date for entry 1: ",
strerror(errno));
goto common_exit;
}
/* set volume labels and dates for backup files */
- for (vtbl_no = 1; vtbl_no <= num_volumes - 2; vtbl_no++){
+ for (vtbl_no = 1; vtbl_no <= num_volumes - 2; vtbl_no++) {
fprintf(stderr,"taper: label %i: %s, date %s\n",
vtbl_no,
vtbl_entry[vtbl_no].label,
vtbl_entry[vtbl_no].date);
fflush(stderr);
- if(set_label(vtbl_entry[vtbl_no].label,
- volumes, num_volumes, vtbl_no)){
+ if (set_label(vtbl_entry[vtbl_no].label,
+ volumes, num_volumes, vtbl_no)) {
errstr = newstralloc2(errstr,
"setting label for entry i: ",
strerror(errno));
rc = 1;
goto common_exit;
}
- if(set_date(vtbl_entry[vtbl_no].date,
- volumes, num_volumes, vtbl_no)){
+ if (set_date(vtbl_entry[vtbl_no].date,
+ volumes, num_volumes, vtbl_no)) {
errstr = newstralloc2(errstr,
"setting date for entry i: ",
strerror(errno));
}
/* set volume label and date for last entry */
vtbl_no = num_volumes - 1;
- if(set_label("AMANDA Tape End", volumes, num_volumes, vtbl_no)){
+ if (set_label("AMANDA Tape End", volumes, num_volumes, vtbl_no)) {
errstr = newstralloc2(errstr,
"setting label for last entry: ",
strerror(errno));
goto common_exit;
}
datestr = NULL; /* take current time */
- if (set_date(datestr, volumes, num_volumes, vtbl_no)){
+ if (set_date(datestr, volumes, num_volumes, vtbl_no)) {
errstr = newstralloc2(errstr,
"setting date for last entry 1: ",
strerror(errno));
common_exit:
- if(tape_fd >= 0 && tapefd_close(tape_fd) == -1 && ! writerror) {
+ if (tape_fd >= 0 && tapefd_close(tape_fd) == -1 && ! writerror) {
errstr = newstralloc2(errstr, "closing tape: ", strerror(errno));
rc = 1;
}
}
-int write_filemark()
+int
+write_filemark(void)
{
- if(tapefd_weof(tape_fd, 1) == -1) {
+ if (tapefd_weof(tape_fd, (off_t)1) == -1) {
errstr = newstralloc2(errstr, "writing filemark: ", strerror(errno));
return 0;
}
total_tape_fm++;
return 1;
}
-
-
*/
/*
- * $Id: taperscan.c,v 1.9 2006/03/10 14:29:22 martinea Exp $
+ * $Id: taperscan.c,v 1.17 2006/07/12 12:28:19 martinea Exp $
*
* This contains the implementation of the taper-scan algorithm, as it is
* used by taper, amcheck, and amtape. See the header file taperscan.h for
* interface information. */
-#include <amanda.h>
-#include <tapeio.h>
-#include <conffile.h>
+#include "amanda.h"
+#include "tapeio.h"
+#include "conffile.h"
#include "changer.h"
#include "tapefile.h"
-int scan_read_label P((char *dev, char *wantlabel,
+int scan_read_label (char *dev, char *wantlabel,
char** label, char** timestamp,
- char**error_message));
-int changer_taper_scan P((char *wantlabel, char** gotlabel, char**timestamp,
- char**error_message, char **tapedev));
-char *find_brand_new_tape_label();
+ char**error_message);
+int changer_taper_scan (char *wantlabel, char** gotlabel, char** timestamp,
+ char **tapedev, void (*)(void *data, char *msg),
+ void *data);
+int scan_slot (void *data, int rc, char *slotstr, char *device);
+int taper_scan (char* wantlabel, char** gotlabel, char** timestamp,
+ char** tapedev,
+ void taperscan_output_callback(void *data, char *msg),
+ void *data);
+char *find_brand_new_tape_label (void);
+void FILE_taperscan_output_callback (void *data, char *msg);
+void CHAR_taperscan_output_callback (void *data, char *msg);
/* NO GLOBALS PLEASE! */
* the same interface as taper_scan.
* Return value is the same as taper_scan.
*/
-int scan_read_label(char *dev, char *desired_label,
- char** label, char** timestamp, char** error_message) {
+int scan_read_label(
+ char *dev,
+ char *desired_label,
+ char** label,
+ char** timestamp,
+ char** error_message)
+{
char *result = NULL;
- char *errstr = NULL;
*label = *timestamp = NULL;
result = tape_rdlabel(dev, timestamp, label);
char *labelstr;
labelstr = getconf_str(CNF_LABELSTR);
if(!match(labelstr, *label)) {
- vstrextend(&errstr, "label ", *label,
+ vstrextend(error_message, "label ", *label,
" doesn\'t match labelstr \"",
labelstr, "\"\n", NULL);
return -1;
tp = lookup_tapelabel(*label);
if(tp == NULL) {
- vstrextend(&errstr, "label ", *label,
+ vstrextend(error_message, "label ", *label,
" match labelstr but it not listed in the tapelist file.\n",
NULL);
return -1;
} else if(tp != NULL && !reusable_tape(tp)) {
- vstrextend(&errstr, "cannot overwrite active tape ", *label,
+ vstrextend(error_message, "cannot overwrite active tape ", *label,
"\n", NULL);
return -1;
}
char *first_labelstr_slot;
int backwards;
int tape_status;
+ void (*taperscan_output_callback)(void *data, char *msg);
+ void *data;
} changertrack_t;
-int scan_slot(void *data, int rc, char *slotstr, char *device) {
+int
+scan_slot(
+ void *data,
+ int rc,
+ char *slotstr,
+ char *device)
+{
int label_result;
changertrack_t *ct = ((changertrack_t*)data);
+ int result;
switch (rc) {
default:
- newvstralloc(*(ct->error_message), *(ct->error_message),
- "fatal changer error ", slotstr, ": ",
- changer_resultstr, NULL);
- return 1;
+ vstrextend(ct->error_message,
+ "fatal changer error: slot ", slotstr, ": ",
+ changer_resultstr, "\n", NULL);
+ result = 1;
+ break;
+
case 1:
- newvstralloc(*(ct->error_message), *(ct->error_message),
- "changer error ", slotstr, ": ", changer_resultstr, NULL);
- return 0;
+ vstrextend(ct->error_message,
+ "changer error: slot ", slotstr, ": ", changer_resultstr,
+ "\n", NULL);
+ result = 0;
+ break;
+
case 0:
- vstrextend(ct->error_message, "slot ", slotstr, ": ", NULL);
+ *(ct->error_message) = newvstralloc(*(ct->error_message), "slot ",
+ slotstr, ": ", NULL);
+ amfree(*ct->gotlabel);
+ amfree(*ct->timestamp);
label_result = scan_read_label(device, ct->wantlabel, ct->gotlabel,
ct->timestamp, ct->error_message);
if (label_result == 1 || label_result == 3 ||
(label_result == 2 && !ct->backwards)) {
*(ct->tapedev) = stralloc(device);
ct->tape_status = label_result;
- return 1;
- } else if (label_result == 2) {
- if (ct->first_labelstr_slot == NULL)
- ct->first_labelstr_slot = stralloc(slotstr);
- return 0;
+ result = 1;
} else {
- return 0;
- }
+ if ((label_result == 2) && (ct->first_labelstr_slot == NULL))
+ ct->first_labelstr_slot = stralloc(slotstr);
+ result = 0;
+ }
+ break;
}
- /* NOTREACHED */
- return 1;
+ ct->taperscan_output_callback(ct->data, *(ct->error_message));
+ amfree(*(ct->error_message));
+ return result;
}
static int
-scan_init(void *data, int rc, int nslots, int backwards, int searchable) {
+scan_init(
+ void *data,
+ int rc,
+ int nslots,
+ int backwards,
+ int searchable)
+{
changertrack_t *ct = ((changertrack_t*)data);
+ (void)nslots; /* Quiet unused parameter warning */
+ (void)searchable; /* Quiet unused parameter warning */
+
if (rc) {
- newvstralloc(*(ct->error_message), *(ct->error_message),
- "could not get changer info: ", changer_resultstr, NULL);
+ vstrextend(ct->error_message,
+ "could not get changer info: ", changer_resultstr, "\n",
+ NULL);
+ ct->taperscan_output_callback(ct->data, *(ct->error_message));
+ amfree(*(ct->error_message));
}
ct->backwards = backwards;
return 0;
}
-int changer_taper_scan(char* wantlabel,
- char** gotlabel, char** timestamp,
- char** error_message, char **tapedev) {
- changertrack_t local_data = {wantlabel, gotlabel, timestamp,
- error_message, tapedev, NULL, 0, 0};
+int
+changer_taper_scan(
+ char *wantlabel,
+ char **gotlabel,
+ char **timestamp,
+ char **tapedev,
+ void (*taperscan_output_callback)(void *data, char *msg),
+ void *data)
+{
+ char *error_message = NULL;
+ changertrack_t local_data;
+ char *outslotstr = NULL;
+ int result;
*gotlabel = *timestamp = *tapedev = NULL;
-
+ local_data.wantlabel = wantlabel;
+ local_data.gotlabel = gotlabel;
+ local_data.timestamp = timestamp;
+ local_data.error_message = &error_message;
+ local_data.tapedev = tapedev;
+ local_data.first_labelstr_slot = NULL;
+ local_data.backwards = 0;
+ local_data.tape_status = 0;
+ local_data.taperscan_output_callback = taperscan_output_callback;
+ local_data.data = data;
+
changer_find(&local_data, scan_init, scan_slot, wantlabel);
if (*(local_data.tapedev)) {
return local_data.tape_status;
} else if (local_data.first_labelstr_slot) {
/* Use plan B. */
- if (changer_loadslot(local_data.first_labelstr_slot,
- NULL, tapedev) == 0) {
- return scan_read_label(*tapedev, NULL, gotlabel, timestamp,
- error_message);
+ result = changer_loadslot(local_data.first_labelstr_slot,
+ &outslotstr, tapedev);
+ amfree(outslotstr);
+ if (result == 0) {
+ result = scan_read_label(*tapedev, NULL, gotlabel, timestamp,
+ &error_message);
+ taperscan_output_callback(data, error_message);
+ amfree(error_message);
+ return result;
}
}
/* Didn't find a tape. :-( */
assert(local_data.tape_status <= 0);
+ taperscan_output_callback(data, "changer problem: ");
+ taperscan_output_callback(data, changer_resultstr);
return -1;
}
int taper_scan(char* wantlabel,
- char** gotlabel, char** timestamp, char** error_message,
- char** tapedev) {
+ char** gotlabel, char** timestamp, char** tapedev,
+ void (*taperscan_output_callback)(void *data, char *msg),
+ void *data) {
- *gotlabel = *timestamp = *error_message = NULL;
- *tapedev = getconf_str(CNF_TAPEDEV);
+ char *error_message = NULL;
+ int result;
+ *gotlabel = *timestamp = NULL;
if (wantlabel == NULL) {
tape_t *tmp;
}
if (changer_init()) {
- return changer_taper_scan(wantlabel, gotlabel, timestamp,
- error_message, tapedev);
+ result = changer_taper_scan(wantlabel, gotlabel, timestamp,
+ tapedev,
+ taperscan_output_callback, data);
+ }
+ else {
+ *tapedev = stralloc(getconf_str(CNF_TAPEDEV));
+ result = scan_read_label(*tapedev, wantlabel,
+ gotlabel, timestamp, &error_message);
+ taperscan_output_callback(data, error_message);
+ amfree(error_message);
}
- return scan_read_label(*tapedev, wantlabel,
- gotlabel, timestamp, error_message);
+ return result;
}
#define AUTO_LABEL_MAX_LEN 1024
-char* find_brand_new_tape_label() {
+char *
+find_brand_new_tape_label(void)
+{
char *format;
char newlabel[AUTO_LABEL_MAX_LEN];
- char tmpnum[12];
+ char tmpnum[30]; /* 64-bit integers can be 21 digists... */
char tmpfmt[16];
char *auto_pos = NULL;
- int i, format_len, label_len, auto_len;
+ int i;
+ ssize_t label_len, auto_len;
tape_t *tp;
if (!getconf_seen(CNF_LABEL_NEW_TAPES)) {
return NULL;
}
format = getconf_str(CNF_LABEL_NEW_TAPES);
- format_len = strlen(format);
memset(newlabel, 0, AUTO_LABEL_MAX_LEN);
label_len = 0;
return NULL;
}
- sprintf(tmpfmt, "%%0%dd", auto_len);
+ snprintf(tmpfmt, SIZEOF(tmpfmt), "%%0" SIZE_T_FMT "d",
+ (SIZE_T_FMT_TYPE)auto_len);
for (i = 1; i < INT_MAX; i ++) {
- sprintf(tmpnum, tmpfmt, i);
- if (strlen(tmpnum) != auto_len) {
+ snprintf(tmpnum, SIZEOF(tmpnum), tmpfmt, i);
+ if (strlen(tmpnum) != (size_t)auto_len) {
fprintf(stderr, "All possible auto-labels used.\n");
return NULL;
}
- strncpy(auto_pos, tmpnum, auto_len);
+ strncpy(auto_pos, tmpnum, (size_t)auto_len);
tp = lookup_tapelabel(newlabel);
if (tp == NULL) {
}
}
- /* NOTREACHED. Unless you have over two billion tapes. */
+ /* Should not get here unless you have over two billion tapes. */
fprintf(stderr, "Taper internal error in find_brand_new_tape_label.");
return 0;
}
+
+void
+FILE_taperscan_output_callback(
+ void *data,
+ char *msg)
+{
+ if(!msg) return;
+ if(strlen(msg) == 0) return;
+
+ if(data)
+ fprintf((FILE *)data, "%s", msg);
+ else
+ printf("%s", msg);
+}
+
+void
+CHAR_taperscan_output_callback(
+ /*@keep@*/ void *data,
+ char *msg)
+{
+ char **s = (char **)data;
+
+ if(!msg) return;
+ if(strlen(msg) == 0) return;
+
+ if(*s)
+ strappend(*s, msg);
+ else
+ *s = stralloc(msg);
+}
*/
/*
- * $Id: taperscan.h,v 1.1 2005/12/21 19:07:51 paddy_s Exp $
+ * $Id: taperscan.h,v 1.3 2006/05/25 01:47:20 johnfranks Exp $
*
* This contains the interface to the tape-scan algorithm implementation.
* The interface is rather simple: Calling programs (taper, amcheck,
* amtape) call the function below with a desired tape label, and get back
* all the relevant label information, along with any other error messages.
*/
+#ifndef TAPERSCAN_H
+#define TAPERSCAN_H
+
/* taper_scan(): Scans the changer to find a tape to use. Reads the tape
* label, or invents a new one if label_new_tapes is in use.
*
* All returned strings are newly-allocated. */
-int taper_scan P((char* wantlabel,
- char** gotlabel, char** timestamp, char** error_message,
- char **tapedev));
+int taper_scan (char* wantlabel,
+ char** gotlabel, char** timestamp,
+ char **tapedev,
+ void taperscan_output_callback(void *data, char *msg),
+ void *data);
+void FILE_taperscan_output_callback(void *data, char *msg);
+void CHAR_taperscan_output_callback(void *data, char *msg);
+
+#endif /* !TAPERSCAN_H */
INCLUDES = -I$(top_builddir)/common-src \
-I$(top_srcdir)/common-src
+LINT=@AMLINT@
+LINTFLAGS=@AMLINTFLAGS@
+
lib_LTLIBRARIES = libamtape.la
LIB_EXTENSION = la
tapetype:
@echo "Use amtapetype instead"
+
+lint:
+ @ for p in $(sbin_PROGRAMS); do \
+ if [ $$p = "amtapetype" ]; then \
+ s="$(amtapetype_SOURCES)"; \
+ else \
+ s=$$p.c; \
+ fi; \
+ f="$$s $(libamandad_la_SOURCES)"; \
+ f="$$f "`(cd ../common-src; make listlibsrc 2>&1 > /dev/null)`; \
+ (cd ../common-src; make listlibsrc); \
+ f="$$f "`cat ../common-src/listlibsrc.output`; \
+ echo $(LINT) $$f; \
+ $(LINT) $(LINTFLAGS) $(CPPFLAGS) $(DEFS) -I. -I../config \
+ $(INCLUDES) $$f; \
+ if [ $$? -ne 0 ]; then \
+ exit 1; \
+ fi; \
+ done; \
+ exit 0
+
+listlibsrc:
+ @ for p in $(libamtape_la_SOURCES); do \
+ listlibsrcs="$$listlibsrcs `pwd`/$$p"; \
+ done; \
+ echo $$listlibsrcs > listlibsrc.output
AMANDA_TMPDIR = @AMANDA_TMPDIR@
AMDEP_FALSE = @AMDEP_FALSE@
AMDEP_TRUE = @AMDEP_TRUE@
+AMLINT = @AMLINT@
+AMLINTFLAGS = @AMLINTFLAGS@
AMPLOT_CAT_COMPRESS = @AMPLOT_CAT_COMPRESS@
AMPLOT_CAT_GZIP = @AMPLOT_CAT_GZIP@
AMPLOT_CAT_PACK = @AMPLOT_CAT_PACK@
AMPLOT_COMPRESS = @AMPLOT_COMPRESS@
AMTAR = @AMTAR@
+AM_CFLAGS = @AM_CFLAGS@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AWK = @AWK@
AWK_VAR_ASSIGNMENT_OPT = @AWK_VAR_ASSIGNMENT_OPT@
BINARY_OWNER = @BINARY_OWNER@
+BUILD_MAN_PAGES_FALSE = @BUILD_MAN_PAGES_FALSE@
+BUILD_MAN_PAGES_TRUE = @BUILD_MAN_PAGES_TRUE@
CAT = @CAT@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
INCLUDES = -I$(top_builddir)/common-src \
-I$(top_srcdir)/common-src
+LINT = @AMLINT@
+LINTFLAGS = @AMLINTFLAGS@
lib_LTLIBRARIES = libamtape.la
LIB_EXTENSION = la
libamtape_la_SOURCES = output-file.c \
tapetype:
@echo "Use amtapetype instead"
+
+lint:
+ @ for p in $(sbin_PROGRAMS); do \
+ if [ $$p = "amtapetype" ]; then \
+ s="$(amtapetype_SOURCES)"; \
+ else \
+ s=$$p.c; \
+ fi; \
+ f="$$s $(libamandad_la_SOURCES)"; \
+ f="$$f "`(cd ../common-src; make listlibsrc 2>&1 > /dev/null)`; \
+ (cd ../common-src; make listlibsrc); \
+ f="$$f "`cat ../common-src/listlibsrc.output`; \
+ echo $(LINT) $$f; \
+ $(LINT) $(LINTFLAGS) $(CPPFLAGS) $(DEFS) -I. -I../config \
+ $(INCLUDES) $$f; \
+ if [ $$? -ne 0 ]; then \
+ exit 1; \
+ fi; \
+ done; \
+ exit 0
+
+listlibsrc:
+ @ for p in $(libamtape_la_SOURCES); do \
+ listlibsrcs="$$listlibsrcs `pwd`/$$p"; \
+ done; \
+ echo $$listlibsrcs > listlibsrc.output
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
static int debug_amdd = 0;
static char *pgm = NULL;
+static void usage(void);
+
static void
-usage()
+usage(void)
{
fprintf(stderr, "usage: %s ", pgm);
fprintf(stderr, " [-d]");
exit(1);
}
+static ssize_t (*read_func)(int, void *, size_t);
+static ssize_t (*write_func)(int, const void *, size_t);
+
int
-main(int argc, char **argv) {
+main(
+ int argc,
+ char ** argv)
+{
int infd = 0; /* stdin */
int outfd = 1; /* stdout */
- int blocksize = 512;
- int skip=0;
- int len;
+ size_t blocksize = 512;
+ off_t skip = (off_t)0;
+ ssize_t len;
int pread, fread, pwrite, fwrite;
int res = 0;
char *buf;
- int count = 0;
+ off_t count = (off_t)0;
int have_count = 0;
int save_errno;
int ch;
char *eq;
- int length = 0;
+ off_t length = (off_t)0;
int have_length = 0;
- ssize_t (*read_func)(int, void *, size_t);
- ssize_t (*write_func)(int, const void *, size_t);
if((pgm = strrchr(argv[0], '/')) != NULL) {
pgm++;
debug_amdd = 1;
fprintf(stderr, "debug mode!\n");
break;
+
+#ifndef __lint
case 'l':
have_length = 1;
- length = atoi(optarg);
- len = strlen(optarg);
+ length = OFF_T_ATOI(optarg);
+ len = (ssize_t)strlen(optarg);
if(len > 0) {
switch(optarg[len-1] ) {
case 'k': break;
- case 'b': length /= 2; break;
- case 'M': length *= 1024; break;
- default: length /= 1024; break;
+ case 'b': length /= (off_t)2; break;
+ case 'M': length *= (off_t)1024; break;
+ default: length /= (off_t)1024; break;
}
} else {
- length /= 1024;
+ length /= (off_t)1024;
}
break;
+#endif
case 'h':
default:
usage();
- /* NOTREACHED */
+ /*NOTREACHED*/
}
}
+ /*@ignore@*/
read_func = read;
write_func = write;
+ /*@end@*/
for( ; optind < argc; optind++) {
if(0 == (eq = strchr(argv[optind], '='))) {
usage();
- /* NOTREACHED */
+ /*NOTREACHED*/
}
- len = eq - argv[optind];
- if(0 == strncmp("if", argv[optind], len)) {
- if((infd = tape_open(eq + 1, O_RDONLY)) < 0) {
+ len = (ssize_t)(eq - argv[optind]);
+ if(0 == strncmp("if", argv[optind], (size_t)len)) {
+ if((infd = tape_open(eq + 1, O_RDONLY, 0)) < 0) {
save_errno = errno;
fprintf(stderr, "%s: %s: ", pgm, eq + 1);
errno = save_errno;
fprintf(stderr, "input opened \"%s\", got fd %d\n",
eq + 1, infd);
}
- } else if(0 == strncmp("of", argv[optind], len)) {
+ } else if(0 == strncmp("of", argv[optind], (size_t)len)) {
if((outfd = tape_open(eq + 1, O_RDWR|O_CREAT|O_TRUNC, 0644)) < 0) {
save_errno = errno;
fprintf(stderr, "%s: %s: ", pgm, eq + 1);
}
if(have_length) {
if(debug_amdd) {
- fprintf(stderr, "length set to %d\n", length);
+ fprintf(stderr, "length set to " OFF_T_FMT "\n",
+ (OFF_T_FMT_TYPE)length);
}
tapefd_setinfo_length(outfd, length);
}
- } else if(0 == strncmp("bs", argv[optind], len)) {
- blocksize = atoi(eq + 1);
- len = strlen(argv[optind]);
+ } else if(0 == strncmp("bs", argv[optind], (size_t)len)) {
+ blocksize = SIZE_T_ATOI(eq + 1);
+ len = (ssize_t)strlen(argv[optind]);
if(len > 0) {
switch(argv[optind][len-1] ) {
case 'k': blocksize *= 1024; break;
}
}
if(debug_amdd) {
- fprintf(stderr, "blocksize set to %d\n", blocksize);
+ fprintf(stderr, "blocksize set to " SIZE_T_FMT "\n",
+ (SIZE_T_FMT_TYPE)blocksize);
}
- } else if(0 == strncmp("count", argv[optind], len)) {
- count = atoi(eq + 1);
+ } else if(0 == strncmp("count", argv[optind], (size_t)len)) {
+ count = OFF_T_ATOI(eq + 1);
have_count = 1;
if(debug_amdd) {
- fprintf(stderr, "count set to %d\n", count);
+ fprintf(stderr, "count set to " OFF_T_FMT "\n",
+ (OFF_T_FMT_TYPE)count);
}
- } else if(0 == strncmp("skip", argv[optind], len)) {
- skip = atoi(eq + 1);
+ } else if(0 == strncmp("skip", argv[optind], (size_t)len)) {
+ skip = OFF_T_ATOI(eq + 1);
if(debug_amdd) {
- fprintf(stderr, "skip set to %d\n", skip);
+ fprintf(stderr, "skip set to " OFF_T_FMT "\n",
+ (OFF_T_FMT_TYPE)skip);
}
} else {
fprintf(stderr, "%s: bad argument: \"%s\"\n", pgm, argv[optind]);
eq = "read error";
pread = fread = pwrite = fwrite = 0;
while(0 < (len = (*read_func)(infd, buf, blocksize))) {
- if(skip-- > 0) {
+ if((skip -= (off_t)1) > (off_t)0) {
continue;
}
- if(len == blocksize) {
+ if((size_t)len == blocksize) {
fread++;
} else if(len > 0) {
pread++;
}
- len = (*write_func)(outfd, buf, len);
+ len = (*write_func)(outfd, buf, (size_t)len);
if(len < 0) {
eq = "write error";
break;
- } else if(len == blocksize) {
+ } else if((size_t)len == blocksize) {
fwrite++;
} else if(len > 0) {
pwrite++;
}
if(have_count) {
- if(--count <= 0) {
+ if((count -= (off_t)1) <= (off_t)0) {
len = 0;
break;
}
extern int optind;
-static int do_asf();
-static int do_bsf();
-static int do_status();
+static int do_asf(int fd, off_t count);
+static int do_bsf(int fd, off_t count);
+static int do_status(int fd, off_t count);
+static void usage(void);
struct cmd {
char *name;
- int min_chars;
+ size_t min_chars;
int count;
- int (*func)();
+ int (*func)(int, off_t);
int flags;
} cmd[] = {
- { "eof", 0, 1, tapefd_weof, O_RDWR },
- { "weof", 0, 1, tapefd_weof, O_RDWR },
- { "fsf", 0, 1, tapefd_fsf, O_RDONLY },
- { "asf", 0, 0, do_asf, O_RDONLY },
- { "bsf", 0, 1, do_bsf, O_RDONLY },
- { "rewind", 0, 0, tapefd_rewind, O_RDONLY },
- { "offline", 0, 0, tapefd_unload, O_RDONLY },
- { "rewoffl", 0, 0, tapefd_unload, O_RDONLY },
- { "status", 0, 0, do_status, O_RDONLY },
- { NULL, 0, 0, NULL }
+ { "eof", 0, 1, tapefd_weof, O_RDWR },
+ { "weof", 0, 1, tapefd_weof, O_RDWR },
+ { "fsf", 0, 1, tapefd_fsf, O_RDONLY },
+ { "asf", 0, 0, do_asf, O_RDONLY },
+ { "bsf", 0, 1, do_bsf, O_RDONLY },
+ { "rewind", 0, 0, (int (*)(int, off_t))tapefd_rewind,
+ O_RDONLY },
+ { "offline", 0, 0, (int (*)(int, off_t))tapefd_unload,
+ O_RDONLY },
+ { "rewoffl", 0, 0, (int (*)(int, off_t))tapefd_unload,
+ O_RDONLY },
+ { "status", 0, 0, do_status, O_RDONLY },
+ { NULL, 0, 0, NULL, 0 }
};
static char *pgm;
static char *tapename;
static int
-do_asf(fd, count)
- int fd;
- int count;
+do_asf(
+ int fd,
+ off_t count)
{
int r;
return r;
}
if(debug_ammt) {
- fprintf(stderr, "calling tapefd_fsf(%d)\n", count);
+ fprintf(stderr, "calling tapefd_fsf(" OFF_T_FMT ")\n",
+ (OFF_T_FMT_TYPE)count);
}
return tapefd_fsf(fd, count);
}
static int
-do_bsf(fd, count)
- int fd;
- int count;
+do_bsf(
+ int fd,
+ off_t count)
{
if(debug_ammt) {
- fprintf(stderr, "calling tapefd_fsf(%d)\n", -count);
+ fprintf(stderr, "calling tapefd_fsf(" OFF_T_FMT ")\n",
+ (OFF_T_FMT_TYPE)-count);
}
return tapefd_fsf(fd, -count);
}
static int
-do_status(fd, count)
- int fd;
- int count;
+do_status(
+ int fd,
+ off_t count)
{
int ret;
struct am_mt_status stat;
+ (void)count; /* Quiet unused parameter warning */
+
if(debug_ammt) {
fprintf(stderr, "calling tapefd_status()\n");
}
}
static void
-usage()
+usage(void)
{
fprintf(stderr, "usage: %s [-d] [-f|-t device] command [count]\n", pgm);
exit(1);
}
int
-main(int argc, char **argv) {
+main(
+ int argc,
+ char ** argv)
+{
int ch;
- int count;
- int i;
- int j;
+ off_t count;
+ size_t i;
+ size_t j;
int fd;
int save_errno;
char *s;
break;
default:
usage();
- /* NOTREACHED */
+ /*NOTREACHED*/
}
}
if(optind >= argc) {
usage();
- /* NOTREACHED */
+ /*NOTREACHED*/
}
/*
* Compute the minimum abbreviation for each command.
*/
for(i = 0; cmd[i].name; i++) {
- cmd[i].min_chars = 1;
+ cmd[i].min_chars = (size_t)1;
while (1) {
for(j = 0; cmd[j].name; j++) {
if(i == j) {
continue;
}
- if(0 == strncmp(cmd[i].name, cmd[j].name, cmd[i].min_chars)) {
+ if(0 == strncmp(cmd[i].name, cmd[j].name,
+ cmd[i].min_chars)) {
break;
}
}
if(debug_ammt) {
fprintf(stderr, "syntax: %-20s -> %*.*s\n",
cmd[i].name,
- cmd[i].min_chars,
- cmd[i].min_chars,
+ (int)cmd[i].min_chars,
+ (int)cmd[i].min_chars,
cmd[i].name);
}
}
fprintf(stderr, "tapename is \"%s\"\n", tapename);
}
- count = 1;
+ count = (off_t)1;
if(optind < argc && cmd[i].count) {
- count = atoi(argv[optind]);
+ count = OFF_T_ATOI(argv[optind]);
}
if(debug_ammt) {
fprintf(stderr, "calling tape_open(\"%s\",%d)\n", tapename, cmd[i].flags);
}
- if((fd = tape_open(tapename, cmd[i].flags)) < 0) {
+ if((fd = tape_open(tapename, cmd[i].flags, 0)) < 0) {
goto report_error;
}
if(debug_ammt) {
- fprintf(stderr, "processing %s(%d)\n", cmd[i].name, count);
+ fprintf(stderr, "processing %s(" OFF_T_FMT ")\n",
+ cmd[i].name, (OFF_T_FMT_TYPE)count);
}
if(0 != (*cmd[i].func)(fd, count)) {
goto report_error;
save_errno = errno;
fprintf(stderr, "%s %s", tapename, cmd[i].name);
if(cmd[i].count) {
- fprintf(stderr, " %d", count);
+ fprintf(stderr, " " OFF_T_FMT, (OFF_T_FMT_TYPE)count);
}
errno = save_errno;
perror(" failed");
- exit(1);
+ return (1); /* exit */
}
*/
/*
- * $Id: output-file.c,v 1.10 2006/01/14 04:37:20 paddy_s Exp $
+ * $Id: output-file.c,v 1.14 2006/07/06 15:04:18 martinea Exp $
*
* tapeio.c virtual tape interface for a file device.
*
struct volume_info {
char *basename; /* filename from open */
struct file_info *fi; /* file info array */
- int fi_limit; /* length of file info array */
+ size_t fi_limit; /* length of file info array */
int flags; /* open flags */
- int mask; /* open mask */
- int file_count; /* number of files */
- int file_current; /* current file position */
- int record_current; /* current record position */
+ mode_t mask; /* open mask */
+ off_t file_count; /* number of files */
+ off_t file_current; /* current file position */
+ off_t record_current; /* current record position */
int fd; /* data file descriptor */
int is_online; /* true if "tape" is "online" */
int at_bof; /* true if at begining of file */
int at_eof; /* true if at end of file */
int at_eom; /* true if at end of medium */
int last_operation_write; /* true if last op was a write */
- long amount_written; /* KBytes written since open/rewind */
+ off_t amount_written; /* KBytes written since open/rewind */
} *volume_info = NULL;
struct file_info {
char *name; /* file name (tapefd_getinfo_...) */
struct record_info *ri; /* record info array */
- int ri_count; /* number of record info entries */
- int ri_limit; /* length of record info array */
+ size_t ri_count; /* number of record info entries */
+ size_t ri_limit; /* length of record info array */
int ri_altered; /* true if record info altered */
};
struct record_info {
- int record_size; /* record size */
- int start_record; /* first record in range */
- int end_record; /* last record in range */
+ size_t record_size; /* record size */
+ off_t start_record; /* first record in range */
+ off_t end_record; /* last record in range */
};
-static int open_count = 0;
+static size_t open_count = 0;
+
+static int check_online(int fd);
+static int file_open(int fd);
+static void file_close(int fd);
+static void file_release(int fd);
+static size_t get_record_size(struct file_info *fi, off_t record);
+static void put_record_size(struct file_info *fi, off_t record, size_t size);
/*
* "Open" the tape by scanning the "data" directory. "Tape files"
*/
static int
-check_online(fd)
- int fd;
+check_online(
+ int fd)
{
char *token[MAX_TOKENS];
DIR *tapedir;
struct dirent *entry;
struct file_info *fi;
+ struct file_info **fi_p;
char *line;
int f;
- int pos;
+ off_t pos;
int rc = 0;
+ char *qname = quote_string(volume_info[fd].basename);
/*
* If we are already online, there is nothing else to do.
*/
rc = (errno != ENOENT);
- fprintf(stderr,"ERROR: %s: %s\n", volume_info[fd].basename, strerror(errno));
+ fprintf(stderr,"ERROR: %s (%s)\n", qname, strerror(errno));
goto common_exit;
}
while ((entry = readdir(tapedir)) != NULL) {
/*
* This is a "tape file".
*/
- pos = atoi(entry->d_name);
- amtable_alloc((void **)&volume_info[fd].fi,
+ pos = OFF_T_ATOI(entry->d_name);
+ assert((pos + 1) <= (off_t)SSIZE_MAX);
+ fi_p = &volume_info[fd].fi;
+ amtable_alloc((void **)fi_p,
&volume_info[fd].fi_limit,
- sizeof(*volume_info[fd].fi),
- pos + 1,
+ SIZEOF(*volume_info[fd].fi),
+ (size_t)(pos + 1),
10,
NULL);
fi = &volume_info[fd].fi[pos];
fi->ri_count = 0;
}
fi->name = stralloc(&entry->d_name[6]);
- if (pos + 1 > volume_info[fd].file_count) {
- volume_info[fd].file_count = pos + 1;
+ if ((pos + 1) > volume_info[fd].file_count) {
+ volume_info[fd].file_count = (pos + 1);
}
}
}
* opened.
*/
for (; (line = areads(fd)) != NULL; free(line)) {
- f = split(line, token, sizeof(token) / sizeof(token[0]), " ");
+ f = split(line, token, (int)(sizeof(token) / sizeof(token[0])), " ");
if (f == 2 && strcmp(token[1], "position") == 0) {
- volume_info[fd].file_current = atoi(token[2]);
- volume_info[fd].record_current = 0;
+ volume_info[fd].file_current = OFF_T_ATOI(token[2]);
+ volume_info[fd].record_current = (off_t)0;
}
}
}
if (volume_info[fd].file_current < 0) {
volume_info[fd].file_current = 0;
- volume_info[fd].record_current = 0;
+ volume_info[fd].record_current = (off_t)0;
}
volume_info[fd].is_online = 1;
common_exit:
+ amfree(qname);
return rc;
}
*/
static int
-file_open(fd)
- int fd;
+file_open(
+ int fd)
{
struct file_info *fi;
+ struct file_info **fi_p;
char *datafilename = NULL;
char *recordfilename = NULL;
char *f = NULL;
- int pos;
+ off_t pos;
char *host;
char *disk;
int level;
int flags;
int rfd;
int n;
- char *line = NULL;
+ char *line;
struct record_info *ri;
- int start_record;
- int end_record;
- int record_size;
+ struct record_info **ri_p;
+ off_t start_record;
+ off_t end_record;
+ size_t record_size = 0;
if (volume_info[fd].fd < 0) {
flags = volume_info[fd].flags;
pos = volume_info[fd].file_current;
- amtable_alloc((void **)&volume_info[fd].fi,
+ assert((pos + 1) < (off_t)SSIZE_MAX);
+ fi_p = &volume_info[fd].fi;
+ amtable_alloc((void **)fi_p,
&volume_info[fd].fi_limit,
- sizeof(*volume_info[fd].fi),
- pos + 1,
+ SIZEOF(*volume_info[fd].fi),
+ (size_t)(pos + 1),
10,
NULL);
fi = &volume_info[fd].fi[pos];
host = tapefd_getinfo_host(fd);
disk = tapefd_getinfo_disk(fd);
level = tapefd_getinfo_level(fd);
- snprintf(number, sizeof(number), "%d", level);
+ snprintf(number, SIZEOF(number), "%d", level);
if (host != NULL) {
f = stralloc(host);
}
if (f == NULL) {
f = stralloc(disk);
} else {
- f = newvstralloc(f, f, ".", disk, NULL);
+ vstrextend(&f, ".", disk, NULL);
}
amfree(disk);
}
if (f == NULL) {
f = stralloc(number);
} else {
- f = newvstralloc(f, f, ".", number, NULL);
+ vstrextend(&f, ".", number, NULL);
}
}
if (f == NULL) {
}
}
if (datafilename == NULL) {
- snprintf(number, sizeof(number), "%05d", pos);
+ snprintf(number, SIZEOF(number),
+ "%05" OFF_T_RFMT, (OFF_T_FMT_TYPE)pos);
datafilename = vstralloc(volume_info[fd].basename,
number,
DATA_INDICATOR,
/*
* Load the record information.
*/
- if (volume_info[fd].fd >= 0
- && fi->ri_count == 0
- && (rfd = open(recordfilename, O_RDONLY)) >= 0) {
+ if (volume_info[fd].fd >= 0 && fi->ri_count == 0 &&
+ (rfd = open(recordfilename, O_RDONLY)) >= 0) {
for (; (line = areads(rfd)) != NULL; free(line)) {
n = sscanf(line,
- "%d %d %d",
- &start_record,
- &end_record,
- &record_size);
+ OFF_T_FMT " " OFF_T_FMT " " SIZE_T_FMT,
+ (OFF_T_FMT_TYPE *)&start_record,
+ (OFF_T_FMT_TYPE *)&end_record,
+ (SIZE_T_FMT_TYPE *)&record_size);
if (n == 3) {
- amtable_alloc((void **)&fi->ri,
+ ri_p = &fi->ri;
+ amtable_alloc((void **)ri_p,
&fi->ri_limit,
- sizeof(*fi->ri),
- fi->ri_count + 1,
+ SIZEOF(*fi->ri),
+ (size_t)fi->ri_count + 1,
10,
NULL);
ri = &fi->ri[fi->ri_count];
*/
static void
-file_close(fd)
- int fd;
+file_close(
+ int fd)
{
struct file_info *fi;
- int pos;
+ struct file_info **fi_p;
+ off_t pos;
char number[NUM_STR_SIZE];
char *filename = NULL;
- int r;
+ size_t r;
FILE *f;
aclose(volume_info[fd].fd);
pos = volume_info[fd].file_current;
- amtable_alloc((void **)&volume_info[fd].fi,
+ assert((pos + 1) < (off_t)SSIZE_MAX);
+ fi_p = &volume_info[fd].fi;
+ amtable_alloc((void **)fi_p,
&volume_info[fd].fi_limit,
- sizeof(*volume_info[fd].fi),
- pos + 1,
+ SIZEOF(*volume_info[fd].fi),
+ (size_t)(pos + 1),
10,
NULL);
fi = &volume_info[fd].fi[pos];
if (fi->ri_altered) {
- snprintf(number, sizeof(number), "%05d", pos);
+ snprintf(number, SIZEOF(number),
+ "%05" OFF_T_RFMT, (OFF_T_FMT_TYPE)pos);
filename = vstralloc(volume_info[fd].basename,
number,
RECORD_INDICATOR,
goto common_exit;
}
for (r = 0; r < fi->ri_count; r++) {
- fprintf(f,
- "%d %d %d\n",
- fi->ri[r].start_record,
- fi->ri[r].end_record,
- fi->ri[r].record_size);
+ fprintf(f, OFF_T_FMT " " OFF_T_FMT " " SIZE_T_FMT "\n",
+ (OFF_T_FMT_TYPE)fi->ri[r].start_record,
+ (OFF_T_FMT_TYPE)fi->ri[r].end_record,
+ (SIZE_T_FMT_TYPE)fi->ri[r].record_size);
}
afclose(f);
fi->ri_altered = 0;
*/
static void
-file_release(fd)
- int fd;
+file_release(
+ int fd)
{
- int position;
+ off_t position;
char *filename;
- int pos;
+ off_t pos;
char number[NUM_STR_SIZE];
+ struct file_info **fi_p;
/*
* If the current file is open, release everything beyond it.
position = volume_info[fd].file_current;
}
for (pos = position; pos < volume_info[fd].file_count; pos++) {
- amtable_alloc((void **)&volume_info[fd].fi,
+ assert(pos < (off_t)SSIZE_MAX);
+ fi_p = &volume_info[fd].fi;
+ amtable_alloc((void **)fi_p,
&volume_info[fd].fi_limit,
- sizeof(*volume_info[fd].fi),
- pos + 1,
+ SIZEOF(*volume_info[fd].fi),
+ (size_t)(pos + 1),
10,
NULL);
if (volume_info[fd].fi[pos].name != NULL) {
- snprintf(number, sizeof(number), "%05d", pos);
+ snprintf(number, SIZEOF(number),
+ "%05" OFF_T_RFMT, (OFF_T_FMT_TYPE)pos);
filename = vstralloc(volume_info[fd].basename,
number,
DATA_INDICATOR,
* sorted, does not overlap and does not have gaps.
*/
-static int
-get_record_size(fi, record)
- struct file_info *fi;
- int record;
+static size_t
+get_record_size(
+ struct file_info * fi,
+ off_t record)
{
- int r;
+ size_t r;
struct record_info *ri;
for(r = 0; r < fi->ri_count; r++) {
*/
static void
-put_record_size(fi, record, size)
- struct file_info *fi;
- int record;
- int size;
+put_record_size(
+ struct file_info * fi,
+ off_t record,
+ size_t size)
{
- int r;
+ size_t r;
struct record_info *ri;
+ struct record_info **ri_p;
fi->ri_altered = 1;
- if (record == 0) {
+ if (record == (off_t)0) {
fi->ri_count = 0; /* start over */
}
for(r = 0; r < fi->ri_count; r++) {
ri = &fi->ri[r];
- if (record - 1 <= ri->end_record) {
+ if ((record - (off_t)1) <= ri->end_record) {
/*
* If this record is the same size as the rest of the records
* in this entry, or it would replace the entire entry,
/*
* This record needs a new entry right after the current one.
*/
- ri->end_record = record - 1;
+ ri->end_record = record - (off_t)1;
fi->ri_count = r + 1;
break;
}
/*
* Add a new entry.
*/
- amtable_alloc((void **)&fi->ri,
+ ri_p = &fi->ri;
+ amtable_alloc((void **)ri_p,
&fi->ri_limit,
- sizeof(*fi->ri),
- fi->ri_count + 1,
+ SIZEOF(*fi->ri),
+ (size_t)fi->ri_count + 1,
10,
NULL);
ri = &fi->ri[fi->ri_count];
*/
int
-file_tape_open(filename, flags, mask)
- char *filename;
- int flags;
- int mask;
+file_tape_open(
+ char * filename,
+ int flags,
+ mode_t mask)
{
- int fd = -1;
+ int fd;
int save_errno;
- char *info_file = NULL;
+ char *info_file;
+ struct volume_info **volume_info_p = &volume_info;
/*
* Use only O_RDONLY and O_RDWR.
/*
* Create the internal info structure for this "tape".
*/
- amtable_alloc((void **)&volume_info,
+ amtable_alloc((void **)volume_info_p,
&open_count,
- sizeof(*volume_info),
- fd + 1,
+ SIZEOF(*volume_info),
+ (size_t)fd + 1,
10,
NULL);
volume_info[fd].flags = flags;
volume_info[fd].mask = mask;
volume_info[fd].file_count = 0;
volume_info[fd].file_current = 0;
- volume_info[fd].record_current = 0;
+ volume_info[fd].record_current = (off_t)0;
volume_info[fd].fd = -1;
volume_info[fd].is_online = 0; /* true when .../data found */
volume_info[fd].at_bof = 1; /* by definition */
volume_info[fd].at_eof = 0; /* do not know yet */
volume_info[fd].at_eom = 0; /* may get reset below */
volume_info[fd].last_operation_write = 0;
- volume_info[fd].amount_written = 0;
+ volume_info[fd].amount_written = (off_t)0;
/*
* Save the base directory name and see if we are "online".
}
ssize_t
-file_tapefd_read(fd, buffer, count)
- int fd;
- void *buffer;
- size_t count;
+file_tapefd_read(
+ int fd,
+ void * buffer,
+ size_t count)
{
- int result;
+ ssize_t result;
int file_fd;
- int pos;
- int record_size;
- int read_size;
+ off_t pos;
+ size_t record_size;
+ size_t read_size;
/*
* Make sure we are online.
*/
- if ((result = check_online(fd)) != 0) {
- return result;
+ if (check_online(fd) != 0) {
+ return -1;
}
if (! volume_info[fd].is_online) {
errno = EIO;
* Open the file, if needed.
*/
if ((file_fd = file_open(fd)) < 0) {
- return file_fd;
+ return -1;
}
/*
result = read(file_fd, buffer, read_size);
if (result > 0) {
volume_info[fd].at_bof = 0;
- if (result < record_size) {
- (void)lseek(file_fd, record_size - result, SEEK_CUR);
+ if ((size_t)result < record_size) {
+ if (lseek(file_fd, (off_t)(record_size-result), SEEK_CUR) == (off_t)-1) {
+ dbprintf(("file_tapefd_read: lseek failed: <%s>\n",
+ strerror(errno)));
+ }
}
- volume_info[fd].record_current++;
+ volume_info[fd].record_current += (off_t)1;
} else if (result == 0) {
volume_info[fd].at_eof = 1;
}
}
ssize_t
-file_tapefd_write(fd, buffer, count)
- int fd;
- const void *buffer;
- size_t count;
+file_tapefd_write(
+ int fd,
+ const void *buffer,
+ size_t count)
{
int file_fd;
- int write_count = count;
- long length;
- long kbytes_left;
- int result;
- int pos;
+ ssize_t write_count = (ssize_t)count;
+ off_t length;
+ off_t kbytes_left;
+ ssize_t result;
+ off_t pos;
/*
* Make sure we are online.
*/
- if ((result = check_online(fd)) != 0) {
- return result;
+ if (check_online(fd) != 0) {
+ return -1;
}
if (! volume_info[fd].is_online) {
errno = EIO;
if((file_fd = volume_info[fd].fd) < 0) {
file_release(fd);
if ((file_fd = file_open(fd)) < 0) {
- return file_fd;
+ return -1;
}
}
/*
* Truncate the write if requested and return a simulated ENOSPC.
*/
- if ((length = tapefd_getinfo_length(fd)) > 0) {
+ if ((length = tapefd_getinfo_length(fd)) > (off_t)0) {
kbytes_left = length - volume_info[fd].amount_written;
- if (write_count / 1024 > kbytes_left) {
- write_count = kbytes_left * 1024;
+ if ((off_t)(write_count / 1024) > kbytes_left) {
+ write_count = (ssize_t)kbytes_left * 1024;
}
}
- volume_info[fd].amount_written += (write_count + 1023) / 1024;
+ volume_info[fd].amount_written += (off_t)((write_count + 1023) / 1024);
if (write_count <= 0) {
volume_info[fd].at_bof = 0;
volume_info[fd].at_eom = 1;
* once.
*/
if (! volume_info[fd].last_operation_write) {
- (void)ftruncate(file_fd, lseek(file_fd, 0, SEEK_CUR));
+ off_t curpos;
+
+ if ((curpos = lseek(file_fd, (off_t)0, SEEK_CUR)) < 0) {
+ dbprintf((": Can not determine current file position <%s>",
+ strerror(errno)));
+ return -1;
+ }
+ if (ftruncate(file_fd, curpos) != 0) {
+ dbprintf(("ftruncate failed; Can not trim output file <%s>",
+ strerror(errno)));
+ return -1;
+ }
volume_info[fd].at_bof = 0;
volume_info[fd].at_eom = 1;
}
- result = fullwrite(file_fd, buffer, write_count);
+ result = fullwrite(file_fd, buffer, (size_t)write_count);
if (result >= 0) {
volume_info[fd].last_operation_write = 1;
pos = volume_info[fd].file_current;
put_record_size(&volume_info[fd].fi[pos],
volume_info[fd].record_current,
- result);
- volume_info[fd].record_current++;
+ (size_t)result);
+ volume_info[fd].record_current += (off_t)1;
}
return result;
}
int
-file_tapefd_close(fd)
- int fd;
+file_tapefd_close(
+ int fd)
{
- int pos;
+ off_t pos;
int save_errno;
char *line;
- int len;
+ size_t len;
char number[NUM_STR_SIZE];
- int result;
+ ssize_t result;
+ struct file_info **fi_p;
+ struct record_info **ri_p;
/*
* If our last operation was a write, write a tapemark.
*/
if (volume_info[fd].last_operation_write) {
- if ((result = file_tapefd_weof(fd, 1)) != 0) {
- return result;
+ if ((result = (ssize_t)file_tapefd_weof(fd, (off_t)1)) != 0) {
+ return (int)result;
}
}
* are already at end of tape.
*/
if (! volume_info[fd].at_bof && ! volume_info[fd].at_eom) {
- if ((result = file_tapefd_fsf(fd, 1)) != 0) {
- return result;
+ if ((result = (ssize_t)file_tapefd_fsf(fd, (off_t)1)) != 0) {
+ return (int)result;
}
}
/*
* Release the info structure areas.
*/
- for (pos = 0; pos < volume_info[fd].fi_limit; pos++) {
+ for (pos = 0; pos < (off_t)volume_info[fd].fi_limit; pos++) {
amfree(volume_info[fd].fi[pos].name);
- amtable_free((void **)&volume_info[fd].fi[pos].ri,
+ ri_p = &volume_info[fd].fi[pos].ri;
+ amtable_free((void **)ri_p,
&volume_info[fd].fi[pos].ri_limit);
volume_info[fd].fi[pos].ri_count = 0;
}
- amtable_free((void **)&volume_info[fd].fi, &volume_info[fd].fi_limit);
+ fi_p = &volume_info[fd].fi;
+ amtable_free((void **)fi_p, &volume_info[fd].fi_limit);
volume_info[fd].file_count = 0;
amfree(volume_info[fd].basename);
* Update the status file if we were online.
*/
if (volume_info[fd].is_online) {
- if (lseek(fd, 0, SEEK_SET) != 0) {
+ if (lseek(fd, (off_t)0, SEEK_SET) != (off_t)0) {
save_errno = errno;
aclose(fd);
errno = save_errno;
return -1;
}
- if (ftruncate(fd, 0) != 0) {
+ if (ftruncate(fd, (off_t)0) != 0) {
save_errno = errno;
aclose(fd);
errno = save_errno;
return -1;
}
- snprintf(number, sizeof(number),
- "%d", volume_info[fd].file_current);
+ snprintf(number, SIZEOF(number), "%05" OFF_T_RFMT,
+ (OFF_T_FMT_TYPE)volume_info[fd].file_current);
line = vstralloc("position ", number, "\n", NULL);
len = strlen(line);
result = write(fd, line, len);
amfree(line);
- if (result != len) {
+ if (result != (ssize_t)len) {
if (result >= 0) {
errno = ENOSPC;
}
}
void
-file_tapefd_resetofs(fd)
- int fd;
+file_tapefd_resetofs(
+ int fd)
{
+ (void)fd; /* Quiet unused parameter warning */
}
int
-file_tapefd_status(fd, stat)
- int fd;
- struct am_mt_status *stat;
+file_tapefd_status(
+ int fd,
+ struct am_mt_status *stat)
{
int result;
if ((result = check_online(fd)) != 0) {
return result;
}
- memset((void *)stat, 0, sizeof(*stat));
+ memset((void *)stat, 0, SIZEOF(*stat));
stat->online_valid = 1;
- stat->online = volume_info[fd].is_online;
+ stat->online = (char)volume_info[fd].is_online;
return 0;
}
int
-file_tape_stat(filename, buf)
- char *filename;
- struct stat *buf;
+file_tape_stat(
+ char * filename,
+ struct stat * buf)
{
return stat(filename, buf);
}
int
-file_tape_access(filename, mode)
- char *filename;
- int mode;
+file_tape_access(
+ char * filename,
+ int mode)
{
return access(filename, mode);
}
int
-file_tapefd_rewind(fd)
- int fd;
+file_tapefd_rewind(
+ int fd)
{
- int result = 0;
+ int result;
/*
* Make sure we are online.
* If our last operation was a write, write a tapemark.
*/
if (volume_info[fd].last_operation_write) {
- if ((result = file_tapefd_weof(fd, 1)) != 0) {
+ if ((result = file_tapefd_weof(fd, (off_t)1)) != 0) {
return result;
}
}
* Adjust the position and reset the flags.
*/
volume_info[fd].file_current = 0;
- volume_info[fd].record_current = 0;
+ volume_info[fd].record_current = (off_t)0;
volume_info[fd].at_bof = 1;
volume_info[fd].at_eof = 0;
volume_info[fd].at_eom
= (volume_info[fd].file_current >= volume_info[fd].file_count);
volume_info[fd].last_operation_write = 0;
- volume_info[fd].amount_written = 0;
+ volume_info[fd].amount_written = (off_t)0;
return result;
}
int
-file_tapefd_unload(fd)
- int fd;
+file_tapefd_unload(
+ int fd)
{
int result;
return -1;
}
- file_tapefd_rewind(fd);
+ (void)file_tapefd_rewind(fd);
return 0;
}
int
-file_tapefd_fsf(fd, count)
- int fd, count;
+file_tapefd_fsf(
+ int fd,
+ off_t count)
{
- int result = 0;
+ int result;
/*
* Make sure we are online.
* backward, write a tapemark.
*/
if (volume_info[fd].last_operation_write && count < 0) {
- if ((result = file_tapefd_weof(fd, 1)) != 0) {
+ if ((result = file_tapefd_weof(fd, (off_t)1)) != 0) {
errno = EIO;
return -1;
}
errno = EIO;
result = -1;
}
- volume_info[fd].record_current = 0;
+ volume_info[fd].record_current = (off_t)0;
/*
* Set BOF to true so we can write. Set to EOF to false if the
= (volume_info[fd].file_current >= volume_info[fd].file_count);
volume_info[fd].last_operation_write = 0;
if (volume_info[fd].file_current == 0) {
- volume_info[fd].amount_written = 0;
+ volume_info[fd].amount_written = (off_t)0;
}
return result;
}
int
-file_tapefd_weof(fd, count)
- int fd, count;
+file_tapefd_weof(
+ int fd,
+ off_t count)
{
int file_fd;
- int result = 0;
+ int result;
char *save_host;
char *save_disk;
int save_level;
* Close out the current file if open.
*/
if ((file_fd = volume_info[fd].fd) >= 0) {
- (void)ftruncate(file_fd, lseek(file_fd, 0, SEEK_CUR));
+ off_t curpos;
+
+ if ((curpos = lseek(file_fd, (off_t)0, SEEK_CUR)) < 0) {
+ save_errno = errno;
+ dbprintf((": Can not determine current file position <%s>",
+ strerror(errno)));
+ file_close(fd);
+ errno = save_errno;
+ return -1;
+ }
+ if (ftruncate(file_fd, curpos) != 0) {
+ save_errno = errno;
+ dbprintf(("ftruncate failed; Can not trim output file <%s>",
+ strerror(errno)));
+ file_close(fd);
+ errno = save_errno;
+ return -1;
+ }
+
file_close(fd);
volume_info[fd].file_current++;
- volume_info[fd].record_current = 0;
+ volume_info[fd].record_current = (off_t)0;
volume_info[fd].at_bof = 1;
volume_info[fd].at_eof = 0;
volume_info[fd].at_eom = 1;
file_close(fd);
volume_info[fd].file_current++;
volume_info[fd].file_count = volume_info[fd].file_current;
- volume_info[fd].record_current = 0;
+ volume_info[fd].record_current = (off_t)0;
volume_info[fd].at_bof = 1;
volume_info[fd].at_eof = 0;
volume_info[fd].at_eom = 1;
}
int
-file_tapefd_can_fork(fd)
- int fd;
+file_tapefd_can_fork(
+ int fd)
{
+ (void)fd; /* Quiet unused parameter warning */
return 0;
}
*/
/*
- * $Id: output-file.h,v 1.5 2003/03/06 21:43:57 martinea Exp $
+ * $Id: output-file.h,v 1.6 2006/05/25 01:47:27 johnfranks Exp $
*
* tapeio.c virtual tape interface for a file device.
*/
#include "amanda.h"
-extern int file_tape_access P((char *, int));
-extern int file_tape_open ();
-extern int file_tape_stat P((char *, struct stat *));
-extern int file_tapefd_close P((int));
-extern int file_tapefd_fsf P((int, int));
-extern ssize_t file_tapefd_read P((int, void *, size_t));
-extern int file_tapefd_rewind P((int));
-extern void file_tapefd_resetofs P((int));
-extern int file_tapefd_unload P((int));
-extern int file_tapefd_status P((int, struct am_mt_status *));
-extern int file_tapefd_weof P((int, int));
-extern ssize_t file_tapefd_write P((int, const void *, size_t));
-extern int file_tapefd_can_fork P((int));
+int file_tape_access(char *, int);
+int file_tape_open(char *, int, mode_t);
+int file_tape_stat(char *, struct stat *);
+int file_tapefd_close(int);
+int file_tapefd_fsf(int, off_t);
+ssize_t file_tapefd_read(int, void *, size_t);
+int file_tapefd_rewind(int);
+void file_tapefd_resetofs(int);
+int file_tapefd_unload(int);
+int file_tapefd_status(int, struct am_mt_status *);
+int file_tapefd_weof(int, off_t);
+ssize_t file_tapefd_write(int, const void *, size_t);
+int file_tapefd_can_fork(int);
#endif /* OUTPUT_FILE_H */
*/
/*
- * $Id: output-null.c,v 1.7 2003/03/06 21:43:57 martinea Exp $
+ * $Id: output-null.c,v 1.9 2006/06/02 00:56:06 paddy_s Exp $
*
* tapeio.c virtual tape interface for a null device.
*/
#define W_OK 2
#endif
-static long *amount_written = NULL;
-static int open_count = 0;
+static off_t *amount_written = NULL;
+static size_t open_count = 0;
int
-null_tape_open(filename, flags, mask)
- char *filename;
- int flags;
- int mask;
+null_tape_open(
+ char * filename,
+ int flags,
+ mode_t mask)
{
int fd;
+ off_t **amount_written_p = &amount_written;
+
+ (void)filename; /* Quiet unused parameter warning */
if ((flags & 3) != O_RDONLY) {
flags &= ~3;
}
if ((fd = open("/dev/null", flags, mask)) >= 0) {
tapefd_setinfo_fake_label(fd, 1);
- amtable_alloc((void **)&amount_written,
+ amtable_alloc((void **)amount_written_p,
&open_count,
- sizeof(*amount_written),
- fd + 1,
+ SIZEOF(*amount_written),
+ (size_t)(fd + 1),
10,
NULL);
- amount_written[fd] = 0;
+ amount_written[fd] = (off_t)0;
}
return fd;
}
ssize_t
-null_tapefd_read(fd, buffer, count)
- int fd;
- void *buffer;
- size_t count;
+null_tapefd_read(
+ int fd,
+ void * buffer,
+ size_t count)
{
return read(fd, buffer, count);
}
ssize_t
-null_tapefd_write(fd, buffer, count)
- int fd;
- const void *buffer;
- size_t count;
+null_tapefd_write(
+ int fd,
+ const void *buffer,
+ size_t count)
{
- int write_count = count;
- long length;
- long kbytes_left;
- int r;
+ ssize_t write_count = (ssize_t)count;
+ off_t length;
+ off_t kbytes_left;
+ ssize_t r;
if (write_count <= 0) {
return 0; /* special case */
}
- if ((length = tapefd_getinfo_length(fd)) > 0) {
+ if ((length = tapefd_getinfo_length(fd)) > (off_t)0) {
kbytes_left = length - amount_written[fd];
- if (write_count / 1024 > kbytes_left) {
- write_count = kbytes_left * 1024;
+ if ((off_t)(write_count / 1024) > kbytes_left) {
+ write_count = (ssize_t)kbytes_left * 1024;
}
}
- amount_written[fd] += (write_count + 1023) / 1024;
+ amount_written[fd] += (off_t)((write_count + 1023) / 1024);
if (write_count <= 0) {
errno = ENOSPC;
r = -1;
} else {
- r = write(fd, buffer, write_count);
+ r = write(fd, buffer, (size_t)write_count);
}
return r;
}
int
-null_tapefd_close(fd)
- int fd;
+null_tapefd_close(
+ int fd)
{
return close(fd);
}
void
-null_tapefd_resetofs(fd)
- int fd;
+null_tapefd_resetofs(
+ int fd)
{
+ (void)fd; /* Quiet unused parameter warning */
}
int
-null_tapefd_status(fd, stat)
- int fd;
- struct am_mt_status *stat;
+null_tapefd_status(
+ int fd,
+ struct am_mt_status *stat)
{
- memset((void *)stat, 0, sizeof(*stat));
+ (void)fd; /* Quiet unused parameter warning */
+
+ memset((void *)stat, 0, SIZEOF(*stat));
stat->online_valid = 1;
stat->online = 1;
return 0;
}
int
-null_tape_stat(filename, buf)
- char *filename;
- struct stat *buf;
+null_tape_stat(
+ char * filename,
+ struct stat *buf)
{
+ (void)filename; /* Quiet unused parameter warning */
+
return stat("/dev/null", buf);
}
int
-null_tape_access(filename, mode)
- char *filename;
- int mode;
+null_tape_access(
+ char * filename,
+ int mode)
{
+ (void)filename; /* Quiet unused parameter warning */
+
return access("/dev/null", mode);
}
int
-null_tapefd_rewind(fd)
- int fd;
+null_tapefd_rewind(
+ int fd)
{
- amount_written[fd] = 0;
+ amount_written[fd] = (off_t)0;
return 0;
}
int
-null_tapefd_unload(fd)
- int fd;
+null_tapefd_unload(
+ int fd)
{
- amount_written[fd] = 0;
+ amount_written[fd] = (off_t)0;
return 0;
}
int
-null_tapefd_fsf(fd, count)
- int fd, count;
+null_tapefd_fsf(
+ int fd,
+ off_t count)
{
+ (void)fd; /* Quiet unused parameter warning */
+ (void)count; /* Quiet unused parameter warning */
+
return 0;
}
int
-null_tapefd_weof(fd, count)
- int fd, count;
+null_tapefd_weof(
+ int fd,
+ off_t count)
{
+ (void)fd; /* Quiet unused parameter warning */
+ (void)count; /* Quiet unused parameter warning */
+
return 0;
}
int
-null_tapefd_can_fork(fd)
- int fd;
+null_tapefd_can_fork(
+ int fd)
{
+ (void)fd; /* Quiet unused parameter warning */
+
return 0;
}
*/
/*
- * $Id: output-null.h,v 1.5 2003/03/06 21:43:57 martinea Exp $
+ * $Id: output-null.h,v 1.6 2006/05/25 01:47:27 johnfranks Exp $
*
* tapeio.c virtual tape interface for a null device.
*/
#include "amanda.h"
-extern int null_tape_access P((char *, int));
-extern int null_tape_open ();
-extern int null_tape_stat P((char *, struct stat *));
-extern int null_tapefd_close P((int));
-extern int null_tapefd_fsf P((int, int));
-extern ssize_t null_tapefd_read P((int, void *, size_t));
-extern int null_tapefd_rewind P((int));
-extern void null_tapefd_resetofs P((int));
-extern int null_tapefd_unload P((int));
-extern int null_tapefd_status P((int, struct am_mt_status *));
-extern int null_tapefd_weof P((int, int));
-extern ssize_t null_tapefd_write P((int, const void *, size_t));
-extern int null_tapefd_can_fork P((int));
+int null_tape_access(char *, int);
+int null_tape_open(char *, int, mode_t);
+int null_tape_stat(char *, struct stat *);
+int null_tapefd_close(int);
+int null_tapefd_fsf(int, off_t);
+ssize_t null_tapefd_read(int, void *, size_t);
+int null_tapefd_rewind(int);
+void null_tapefd_resetofs(int);
+int null_tapefd_unload(int);
+int null_tapefd_status(int, struct am_mt_status *);
+int null_tapefd_weof(int, off_t);
+ssize_t null_tapefd_write(int, const void *, size_t);
+int null_tapefd_can_fork(int);
#endif /* OUTPUT_NULL_H */
#ifdef NO_AMANDA
#define amfree(x) do { \
- int save_errno = errno; \
- free(x); \
- (x) = 0; \
- errno = save_errno; \
+ if (x) { \
+ int save_errno = errno; \
+ free(x); \
+ (x) = NULL; \
+ errno = save_errno; \
+ }
} while(0)
#define tape_open open
#define tapefd_read read
rait.c..................................................1
MAX_RAITS.........................................2
rait_table........................................2
- rait_open(char *dev, int flags, int mode).........2
+ rait_open(char *dev, int flags, mode_t mode)......2
rait_close(int fd)................................3
rait_lseek(int fd, long pos, int whence)..........4
- rait_write(int fd, const char *buf, int len) .....5
- rait_read(int fd, char *buf, int len).............6
+ rait_write(int fd, const char *buf, size_t len) ..5
+ rait_read(int fd, char *buf, size_t len)..........6
rait_ioctl(int fd, int op, void *p)...............8
rait_access(devname, R_OK|W_OK)...................8
rait_stat(devname, struct statbuf*)...............8
rait_tapefd_status(rait_tapefd, stat)........10
rait_tapefd_weof(rait_tapefd, count).........10
-
-
rait.h.................................................1
typedef RAIT......................................1
ifdef RAIT_REDIRECT...............................1
#endif
static RAIT *rait_table = 0; /* table to keep track of RAITS */
-static int rait_table_count;
+static size_t rait_table_count;
#ifdef NO_AMANDA
/*
*/
static int
-amtable_alloc(void **table,
- int *current,
- size_t elsize,
- int count,
- int bump,
- void *dummy) {
+amtable_alloc(
+ void ** table,
+ int * current,
+ size_t elsize,
+ int count,
+ int bump,
+ void * dummy)
+{
void *table_new;
int table_count_new;
if (count >= *current) {
table_count_new = ((count + bump) / bump) * bump;
- table_new = malloc(table_count_new * elsize);
- if (0 == table_new) {
- errno = ENOMEM;
- return -1;
- }
+ table_new = alloc(table_count_new * elsize);
if (0 != *table) {
memcpy(table_new, *table, *current * elsize);
amfree(*table);
*/
void
-amtable_free(table, current)
- void **table;
- int *current;
+amtable_free(
+ void ** table,
+ int * current)
{
amfree(*table);
*current = 0;
}
#endif
-#define rait_table_alloc(fd) amtable_alloc((void **)&rait_table, \
- &rait_table_count, \
- sizeof(*rait_table), \
- (fd), \
- 10, \
+#define rait_table_alloc(fd) amtable_alloc((void **)rait_table_p, \
+ &rait_table_count, \
+ SIZEOF(*rait_table), \
+ (size_t)(fd), \
+ 10, \
NULL)
int
-rait_open(char *dev, int flags, int mask) {
+rait_open(
+ char * dev,
+ int flags,
+ mode_t mask)
+{
int fd; /* the file descriptor number to return */
RAIT *res; /* resulting RAIT structure */
char *dev_left; /* string before { */
int rait_flag; /* true if RAIT syntax in dev */
int save_errno;
int r;
+ RAIT **rait_table_p = &rait_table;
+ int **fds_p;
rait_debug((stderr,"rait_open( %s, %d, %d )\n", dev, flags, mask));
res = &rait_table[fd];
- memset(res, 0, sizeof(*res));
+ memset(res, 0, SIZEOF(*res));
res->nopen = 1;
res->fd_count = 0;
}
while (0 != (dev_real = tapeio_next_devname(dev_left, dev_right, &dev_next))) {
- r = amtable_alloc((void **)&res->fds,
+ fds_p = &(res->fds);
+ r = amtable_alloc((void **)fds_p,
&res->fd_count,
- sizeof(*res->fds),
- res->nfds + 1,
+ SIZEOF(*res->fds),
+ (size_t)res->nfds + 1,
10,
NULL);
if (0 != r) {
*/
res->nfds = 0;
- r = amtable_alloc((void **)&res->fds,
+ fds_p = &(res->fds);
+ r = amtable_alloc((void **)fds_p,
&res->fd_count,
- sizeof(*res->fds),
- res->nfds + 1,
+ SIZEOF(*res->fds),
+ (size_t)res->nfds + 1,
1,
NULL);
if (0 != r) {
(void)tapefd_close(fd);
- memset(res, 0, sizeof(*res));
+ memset(res, 0, SIZEOF(*res));
errno = ENOMEM;
fd = -1;
} else {
}
if (fd >= 0 && res->nfds > 0) {
- res->readres = (int *) malloc(res->nfds * sizeof(*res->readres));
- if (0 == res->readres) {
- (void)rait_close(fd);
- errno = ENOMEM;
- fd = -1;
- } else {
- memset(res->readres, 0, res->nfds * sizeof(*res->readres));
- }
+ res->readres = alloc(res->nfds * SIZEOF(*res->readres));
+ memset(res->readres, 0, res->nfds * SIZEOF(*res->readres));
}
rait_debug((stderr, "rait_open:returning %d%s%s\n",
#ifdef NO_AMANDA
int
-tapeio_init_devname(char * dev,
- char **dev_left,
- char **dev_right,
- char **dev_next) {
+tapeio_init_devname(
+ char * dev,
+ char ** dev_left,
+ char ** dev_right,
+ char ** dev_next)
+{
/*
** find the first { and then the first } that follows it
*/
}
char *
-tapeio_next_devname(char * dev_left,
- char * dev_right,
- char **dev_next) {
+tapeio_next_devname(
+ char * dev_left,
+ char * dev_right,
+ char ** dev_next)
+{
char *dev_real = 0;
char *next;
int len;
next = *dev_next;
if (0 != (*dev_next = strchr(next, ','))
|| 0 != (*dev_next = strchr(next, '}'))){
-
+
**dev_next = 0; /* zap the terminator */
(*dev_next)++;
- /*
+ /*
** we have one string picked out, build it into the buffer
*/
len = strlen(dev_left) + strlen(next) + strlen(dev_right) + 1;
- if ( 0 != (dev_real = malloc(len)) ) {
- strcpy(dev_real, dev_left); /* safe */
- strcat(dev_real, next); /* safe */
- strcat(dev_real, dev_right); /* safe */
- }
+ dev_real = alloc(len);
+ strcpy(dev_real, dev_left); /* safe */
+ strcat(dev_real, next); /* safe */
+ strcat(dev_real, dev_right); /* safe */
}
return dev_real;
}
/*
** close everything we opened and free our memory.
*/
-int
-rait_close(int fd) {
+int
+rait_close(
+ int fd)
+{
int i; /* index into RAIT drives */
int j; /* individual tapefd_close result */
int res; /* result from close */
RAIT *pr; /* RAIT entry from table */
int save_errno = errno;
- int kid;
+ pid_t kid;
+ int **fds_p;
rait_debug((stderr,"rait_close( %d )\n", fd));
- if (fd < 0 || fd >= rait_table_count) {
+ if ((fd < 0) || ((size_t)fd >= rait_table_count)) {
errno = EBADF;
rait_debug((stderr, "rait_close:returning %d: %s\n",
-1,
}
if (0 == pr->readres && 0 < pr->nfds) {
- pr->readres = (int *) malloc(pr->nfds * sizeof(*pr->readres));
- if (0 == pr->readres) {
- errno = ENOMEM;
- rait_debug((stderr, "rait_close:returning %d: %s\n",
- -1,
- strerror(errno)));
- return -1;
- }
- memset(pr->readres, 0, pr->nfds * sizeof(*pr->readres));
+ pr->readres = alloc(pr->nfds * SIZEOF(*pr->readres));
+ memset(pr->readres, 0, pr->nfds * SIZEOF(*pr->readres));
}
res = 0;
- /*
+ /*
** this looks strange, but we start kids who are going to close the
** drives in parallel just after the parent has closed their copy of
** the descriptor. ('cause closing tape devices usually causes slow
exit(j);
} else {
/* remember who the child is or that an error happened */
- pr->readres[i] = kid;
+ pr->readres[i] = (ssize_t)kid;
}
}
else {
for( i = 0; i < pr->nfds; i++ ) {
int stat;
if(pr->readres[i] != -1) {
- waitpid( pr->readres[i], &stat, 0);
+ waitpid((pid_t)pr->readres[i], &stat, 0);
if( WEXITSTATUS(stat) != 0 ) {
res = WEXITSTATUS(stat);
- if( res == 255 )
+ if( res == 255 )
res = -1;
}
}
(void)close(fd); /* close the dummy /dev/null descriptor */
}
if (0 != pr->fds) {
- amtable_free((void **)&pr->fds, &pr->fd_count);
+ fds_p = &pr->fds;
+ amtable_free((void **)fds_p, &pr->fd_count);
}
if (0 != pr->readres) {
amfree(pr->readres);
** seek out to the nth byte on the RAIT set.
** this is assumed to be evenly divided across all the stripes
*/
-int
-rait_lseek(int fd, long pos, int whence) {
+off_t
+rait_lseek(
+ int fd,
+ off_t pos,
+ int whence)
+{
int i; /* drive number in RAIT */
- long res, /* result of lseeks */
+ off_t res, /* result of lseeks */
total; /* total of results */
RAIT *pr; /* RAIT slot in table */
- rait_debug((stderr, "rait_lseek(%d,%ld,%d)\n",fd,pos,whence));
+ rait_debug((stderr, "rait_lseek(%d," OFF_T_FMT ",%d)\n",
+ fd, (OFF_T_FMT_TYPE)pos, whence));
- if (fd < 0 || fd >= rait_table_count) {
+ if ((fd < 0) || ((size_t)fd >= rait_table_count)) {
errno = EBADF;
rait_debug((stderr, "rait_lseek:returning %d: %s\n",
-1,
strerror(errno)));
- return -1;
+ return (off_t)-1;
}
pr = &rait_table[fd];
rait_debug((stderr, "rait_lseek:returning %d: %s\n",
-1,
strerror(errno)));
- return -1;
+ return (off_t)-1;
}
- if (pr->nfds > 1 && (pos % (pr->nfds-1)) != 0) {
+ if ((pr->nfds > 1) && ((pos % (off_t)(pr->nfds-1)) != (off_t)0)) {
errno = EDOM;
- total = -1;
+ total = (off_t)-1;
} else {
- total = 0;
- pos = pos / pr->nfds;
+ total = (off_t)0;
+ pos = pos / (off_t)pr->nfds;
for( i = 0; i < pr->nfds; i++ ) {
- if (0 >= (res = lseek(pr->fds[i], pos, whence))) {
+ if ((off_t)0 >= (res = lseek(pr->fds[i], pos, whence))) {
total = res;
break;
}
/*\f*/
/*
-** if we only have one stream, just do a write,
+** if we only have one stream, just do a write,
** otherwise compute an xor sum, and do several
** writes...
*/
-ssize_t
-rait_write(int fd, const void *bufptr, size_t len) {
+ssize_t
+rait_write(
+ int fd,
+ const void *bufptr,
+ size_t len)
+{
const char *buf = bufptr;
- int i = 0, j; /* drive number, byte offset */
- RAIT *pr; /* RAIT structure for this RAIT */
- int res, total = 0;
+ int i; /* drive number */
+ size_t j; /* byte offset */
+ RAIT *pr; /* RAIT structure for this RAIT */
+ ssize_t res;
+ ssize_t total = 0;
int data_fds; /* number of data stream file descriptors */
rait_debug((stderr, "rait_write(%d,%lx,%d)\n",fd,(unsigned long)buf,len));
- if (fd < 0 || fd >= rait_table_count) {
+ if ((fd < 0) || ((size_t)fd >= rait_table_count)) {
errno = EBADF;
rait_debug((stderr, "rait_write:returning %d: %s\n",
-1,
len = len / data_fds;
/* make sure we have enough buffer space */
- if (len > pr->xorbuflen) {
+ if (len > (size_t)pr->xorbuflen) {
if (0 != pr->xorbuf) {
amfree(pr->xorbuf);
}
- pr->xorbuf = malloc(len);
- if (0 == pr->xorbuf) {
- errno = ENOMEM;
- rait_debug((stderr, "rait_write:returning %d: %s\n",
- -1,
- strerror(errno)));
- return -1;
- }
+ pr->xorbuf = alloc(len);
pr->xorbuflen = len;
}
}
/* write the chunks in the main buffer */
- if (total >= 0) {
- for( i = 0; i < data_fds; i++ ) {
- res = tapefd_write(pr->fds[i], buf + len*i , len);
- rait_debug((stderr, "rait_write: write(%d,%lx,%d) returns %d%s%s\n",
+ for( i = 0; i < data_fds; i++ ) {
+ res = tapefd_write(pr->fds[i], buf + len*i , len);
+ rait_debug((stderr, "rait_write: write(%d,%lx,%d) returns %d%s%s\n",
pr->fds[i],
(unsigned long)(buf + len*i),
len,
res,
(res < 0) ? ": " : "",
(res < 0) ? strerror(errno) : ""));
- if (res < 0) {
- total = res;
- break;
- }
- total += res;
+ if (res < 0) {
+ total = res;
+ break;
}
+ total += res;
}
if (total >= 0 && pr->nfds > 1) {
/* write the sum, don't include it in the total bytes written */
** the missing block from the other three, then return the data.
** there's some silliness here for reading tape with bigger buffers
** than we wrote with, (thus the extra bcopys down below). On disk if
-** you read with a bigger buffer size than you wrote with, you just
+** you read with a bigger buffer size than you wrote with, you just
** garble the data...
*/
-ssize_t
-rait_read(int fd, void *bufptr, size_t len) {
+ssize_t
+rait_read(
+ int fd,
+ void * bufptr,
+ size_t len)
+{
char *buf = bufptr;
- int nerrors,
- neofs,
- total,
- errorblock;
- int i,j;
+ int nerrors, neofs, errorblock;
+ ssize_t total;
+ int i;
+ size_t j;
RAIT *pr;
int data_fds;
int save_errno = errno;
- int maxreadres = 0;
+ ssize_t maxreadres = 0;
int sum_mismatch = 0;
rait_debug((stderr, "rait_read(%d,%lx,%d)\n",fd,(unsigned long)buf,len));
- if (fd < 0 || fd >= rait_table_count) {
+ if ((fd < 0) || ((size_t)fd >= rait_table_count)) {
errno = EBADF;
rait_debug((stderr, "rait_read:returning %d: %s\n",
-1,
nerrors = 0;
neofs = 0;
- total = 0;
errorblock = -1;
/* once again , we slice it evenly... */
if (pr->nfds > 1) {
}
if (pr->nfds > 1) {
/* make sure we have enough buffer space */
- if (len > pr->xorbuflen) {
+ if (len > (size_t)pr->xorbuflen) {
if (0 != pr->xorbuf) {
amfree(pr->xorbuf);
}
- pr->xorbuf = malloc(len);
- if (0 == pr->xorbuf) {
- errno = ENOMEM;
- rait_debug((stderr, "rait_write:returning %d: %s\n",
- -1,
- strerror(errno)));
- return -1;
- }
+ pr->xorbuf = alloc(len);
pr->xorbuflen = len;
}
pr->readres[i] = tapefd_read(pr->fds[i], pr->xorbuf , len);
/*
* Make sure all the reads were the same length
*/
- for (j = 0; j < pr->nfds; j++) {
+ for (j = 0; j < (size_t)pr->nfds; j++) {
if (pr->readres[j] != maxreadres) {
nerrors++;
- errorblock = j;
+ errorblock = (int)j;
}
}
* If no errors, check that the xor sum matches
*/
if ( nerrors == 0 && pr->nfds > 1 ) {
- for(i = 0; i < maxreadres; i++ ) {
+ for(i = 0; i < (int)maxreadres; i++ ) {
int sum = 0;
- for(j = 0; j < pr->nfds - 1; j++) {
+ for(j = 0; (j + 1) < (size_t)pr->nfds; j++) {
sum ^= (buf + len * j)[i];
}
if (sum != pr->xorbuf[i]) {
}
}
- /*
+ /*
** now decide what "really" happened --
** all n getting eof is a "real" eof
** just one getting an error/eof is recoverable if we are doing RAIT
/* pack together partial reads... */
total = pr->readres[0];
for( i = 1; i < data_fds; i++ ) {
- if (total != len * i) {
- memmove(buf + total, buf + len*i, pr->readres[i]);
+ if (total != (ssize_t)(len * i)) {
+ memmove(buf + total, buf + len*i, (size_t)pr->readres[i]);
}
total += pr->readres[i];
}
/*\f*/
-int rait_ioctl(int fd, int op, void *p) {
+int
+rait_ioctl(
+ int fd,
+ int op,
+ void * p)
+{
int i, res = 0;
RAIT *pr;
int errors = 0;
rait_debug((stderr, "rait_ioctl(%d,%d)\n",fd,op));
- if (fd < 0 || fd >= rait_table_count) {
+ if ((fd < 0) || ((size_t)fd >= rait_table_count)) {
errno = EBADF;
rait_debug((stderr, "rait_ioctl:returning %d: %s\n",
-1,
}
for( i = 0; i < pr->nfds ; i++ ) {
+ /*@ignore@*/
res = ioctl(pr->fds[i], op, p);
- if ( res != 0 ) {
+ /*@end@*/
+ if ( res != 0 ) {
errors++;
if (errors > 1) {
break;
/*
** access() all the devices, returning if any fail
*/
-int rait_access(char *devname, int flags) {
+int
+rait_access(
+ char * devname,
+ int flags)
+{
int res = 0;
char *dev_left; /* string before { */
char *dev_right; /* string after } */
rait_debug((stderr,"rait_access:access( %s, %d ) yields %d\n",
dev_real, flags, res ));
amfree(dev_real);
- if (res < 0) {
+ if (res < 0) {
break;
}
}
/*
** stat all the devices, returning the last one unless one fails
*/
-int rait_stat(char *devname, struct stat *buf) {
+int
+rait_stat(
+ char * devname,
+ struct stat *buf)
+{
int res = 0;
char *dev_left; /* string before { */
char *dev_right; /* string after } */
rait_debug((stderr,"rait_stat:stat( %s ) yields %d (%s)\n",
dev_real, res, (res != 0) ? strerror(errno) : "no error" ));
amfree(dev_real);
- if (res != 0) {
+ if (res != 0) {
break;
}
}
/*\f*/
-int rait_copy(char *f1, char *f2, int buflen) {
+int
+rait_copy(
+ char * f1,
+ char * f2,
+ size_t buflen)
+{
int t1, t2;
- int len, wres;
+ ssize_t len;
+ ssize_t wres;
char *buf;
int save_errno;
errno = save_errno;
return -1;
}
- buf = malloc(buflen);
- if (0 == buf) {
- (void)rait_close(t1);
- (void)rait_close(t2);
- errno = ENOMEM;
- return -1;
- }
+ buf = alloc(buflen);
do {
len = rait_read(t1,buf,buflen);
if (len > 0 ) {
- wres = rait_write(t2, buf, len);
+ wres = rait_write(t2, buf, (size_t)len);
if (wres < 0) {
len = -1;
break;
** Amanda Tape API routines:
*/
-static int rait_tapefd_ioctl(int (*func0)(int),
- int (*func1)(int, int),
- int fd,
- int count) {
+static int
+rait_tapefd_ioctl(
+ int (*func0)(int),
+ int (*func1)(int, off_t),
+ int fd,
+ off_t count)
+{
int i, j, res = 0;
RAIT *pr;
int errors = 0;
- int kid;
- int stat;
+ pid_t kid;
+ int status = 0;
rait_debug((stderr, "rait_tapefd_ioctl(%d,%d)\n",fd,count));
- if (fd < 0 || fd >= rait_table_count) {
+ if ((fd < 0) || ((size_t)fd >= rait_table_count)) {
errno = EBADF;
rait_debug((stderr, "rait_tapefd_ioctl:returning %d: %s\n",
-1,
}
if (0 == pr->readres && 0 < pr->nfds) {
- pr->readres = (int *) malloc(pr->nfds * sizeof(*pr->readres));
- if (0 == pr->readres) {
- errno = ENOMEM;
- rait_debug((stderr, "rait_tapefd_ioctl:returning %d: %s\n",
- -1,
- strerror(errno)));
- return -1;
- }
- memset(pr->readres, 0, pr->nfds * sizeof(*pr->readres));
+ pr->readres = alloc(pr->nfds * SIZEOF(*pr->readres));
+ memset(pr->readres, 0, pr->nfds * SIZEOF(*pr->readres));
}
for( i = 0; i < pr->nfds ; i++ ) {
if ((kid = fork()) < 1) {
rait_debug((stderr, "in kid, fork returned %d\n", kid));
/* if we are the kid, or fork failed do the action */
- if (0 != func0) {
+ if (func0 != NULL) {
res = (*func0)(pr->fds[i]);
} else {
res = (*func1)(pr->fds[i], count);
}
- rait_debug((stderr, "in kid, func ( %d ) returned %d errno %d\n", pr->fds[i], res, errno));
+ rait_debug((stderr, "in kid, func (%d) returned %d errno %s\n",
+ pr->fds[i], res, strerror(errno)));
if (kid == 0)
exit(res);
} else {
rait_debug((stderr, "in parent, fork returned %d\n", kid));
- pr->readres[i] = kid;
+ pr->readres[i] = (ssize_t)kid;
}
}
else {
- if(0 != func0) {
+ if(func0 != NULL) {
j = (*func0)(pr->fds[i]);
} else {
j = (*func1)(pr->fds[i], count);
for( i = 0; i < pr->nfds ; i++ ) {
if(tapefd_can_fork(pr->fds[i])) {
rait_debug((stderr, "in parent, waiting for %d\n", pr->readres[i]));
- waitpid( pr->readres[i], &stat, 0);
- if( WEXITSTATUS(stat) != 0 ) {
- res = WEXITSTATUS(stat);
- if( res == 255 )
+ waitpid((pid_t)pr->readres[i], &status, 0);
+ if( WEXITSTATUS(status) != 0 ) {
+ res = WEXITSTATUS(status);
+ if( res == 255 )
res = -1;
}
rait_debug((stderr, "in parent, return code was %d\n", res));
- if ( res != 0 ) {
+ if ( res != 0 ) {
errors++;
res = 0;
}
return res;
}
-int rait_tapefd_fsf(int fd, int count) {
- return rait_tapefd_ioctl(0, tapefd_fsf, fd, count);
+int
+rait_tapefd_fsf(
+ int fd,
+ off_t count)
+{
+ return rait_tapefd_ioctl(NULL, tapefd_fsf, fd, count);
}
-int rait_tapefd_rewind(int fd) {
- return rait_tapefd_ioctl(tapefd_rewind, 0, fd, -1);
+int
+rait_tapefd_rewind(
+ int fd)
+{
+ return rait_tapefd_ioctl(tapefd_rewind, NULL, fd, (off_t)-1);
}
-int rait_tapefd_unload(int fd) {
- return rait_tapefd_ioctl(tapefd_unload, 0, fd, -1);
+int
+rait_tapefd_unload(
+ int fd)
+{
+ return rait_tapefd_ioctl(tapefd_unload, NULL, fd, (off_t)-1);
}
-int rait_tapefd_weof(int fd, int count) {
- return rait_tapefd_ioctl(0, tapefd_weof, fd, count);
+int
+rait_tapefd_weof(
+ int fd,
+ off_t count)
+{
+ return rait_tapefd_ioctl(NULL, tapefd_weof, fd, count);
}
-int rait_tape_open(char *name, int flags, int mask) {
+int
+rait_tape_open(
+ char * name,
+ int flags,
+ mode_t mask)
+{
return rait_open(name, flags, mask);
}
-int rait_tapefd_status(int fd, struct am_mt_status *stat) {
+int
+rait_tapefd_status(
+ int fd,
+ struct am_mt_status *stat)
+{
int i;
RAIT *pr;
int res = 0;
rait_debug((stderr, "rait_tapefd_status(%d)\n",fd));
- if (fd < 0 || fd >= rait_table_count) {
+ if ((fd < 0) || ((size_t)fd >= rait_table_count)) {
errno = EBADF;
rait_debug((stderr, "rait_tapefd_status:returning %d: %s\n",
-1,
return res;
}
-void rait_tapefd_resetofs(int fd) {
- rait_lseek(fd, 0L, SEEK_SET);
+void
+rait_tapefd_resetofs(
+ int fd)
+{
+ (void)rait_lseek(fd, (off_t)0, SEEK_SET);
}
-int
-rait_tapefd_can_fork(fd)
- int fd;
+int
+rait_tapefd_can_fork(
+ int fd)
{
+ (void)fd; /* Quiet unused parameter warning */
+
return 0;
}
typedef struct {
int nopen;
int nfds;
- int fd_count;
+ size_t fd_count;
int *fds;
- int *readres;
- int xorbuflen;
+ ssize_t *readres;
+ size_t xorbuflen;
char *xorbuf;
} RAIT;
#ifdef NO_AMANDA
#define stralloc strdup
-#define P(x) x /* for function prototypes */
/*
* Tape drive status structure. This abstracts the things we are
char eot; /* true if tape is at end of medium */
char protected; /* true if tape is write protected */
long flags; /* device flags, whatever that is */
- long fileno; /* tape file number */
- long blkno; /* block within file */
+ off_t fileno; /* tape file number */
+ off_t blkno; /* block within file */
int device_status_size; /* size of orig device status field */
unsigned long device_status; /* "device status", whatever that is */
int error_status_size; /* size of orig error status field */
};
#endif
-extern int rait_open ();
-extern int rait_access P((char *, int));
-extern int rait_stat P((char *, struct stat *));
-extern int rait_close P((int ));
-extern int rait_lseek P((int , long, int));
-extern ssize_t rait_write P((int , const void *, size_t));
-extern ssize_t rait_read P((int , void *, size_t));
-extern int rait_ioctl P((int , int, void *));
-extern int rait_copy P((char *f1, char *f2, int buflen));
-
-extern char *rait_init_namelist P((char * dev,
- char **dev_left,
- char **dev_right,
- char **dev_next));
-extern int rait_next_name P((char * dev_left,
- char * dev_right,
- char **dev_next,
- char * dev_real));
-
-extern int rait_tape_open ();
-extern int rait_tapefd_fsf P((int rait_tapefd, int count));
-extern int rait_tapefd_rewind P((int rait_tapefd));
-extern void rait_tapefd_resetofs P((int rait_tapefd));
-extern int rait_tapefd_unload P((int rait_tapefd));
-extern int rait_tapefd_status P((int rait_tapefd, struct am_mt_status *stat));
-extern int rait_tapefd_weof P((int rait_tapefd, int count));
-extern int rait_tapefd_can_fork P((int));
+int rait_open(char *dev, int flags, mode_t mask);
+int rait_access(char *, int);
+int rait_stat(char *, struct stat *);
+int rait_close(int);
+off_t rait_lseek(int, off_t, int);
+ssize_t rait_write(int, const void *, size_t);
+ssize_t rait_read(int, void *, size_t);
+int rait_ioctl(int, int, void *);
+int rait_copy(char *f1, char *f2, size_t buflen);
+char *rait_init_namelist(char * dev, char **dev_left, char **dev_right, char **dev_next);
+int rait_next_name(char * dev_left, char * dev_right, char **dev_next, char * dev_real);
+int rait_tape_open(char *, int, mode_t);
+int rait_tapefd_fsf(int rait_tapefd, off_t count);
+int rait_tapefd_rewind(int rait_tapefd);
+void rait_tapefd_resetofs(int rait_tapefd);
+int rait_tapefd_unload(int rait_tapefd);
+int rait_tapefd_status(int rait_tapefd, struct am_mt_status *stat);
+int rait_tapefd_weof(int rait_tapefd, off_t count);
+int rait_tapefd_can_fork(int);
#ifdef RAIT_REDIRECT
*/
/*
- * $Id: output-tape.c,v 1.14 2006/03/09 20:06:12 johnfranks Exp $
+ * $Id: output-tape.c,v 1.18 2006/08/22 14:19:39 martinea Exp $
*
* tapeio.c virtual tape interface for normal tape drives.
*/
*/
int
-tape_tapefd_fsf(fd, count)
- int fd;
- int count;
+tape_tapefd_fsf(
+ int fd,
+ off_t count)
{
size_t buflen;
char *buffer = NULL;
* Rewind a tape to the beginning.
*/
int
-tape_tapefd_rewind(fd)
- int fd;
+tape_tapefd_rewind(
+ int fd)
{
int st;
* Rewind and unload a tape.
*/
int
-tape_tapefd_unload(fd)
- int fd;
+tape_tapefd_unload(
+ int fd)
{
int st;
/*
* Forward space the tape device count files.
*/
-int tape_tapefd_fsf(fd, count)
- int fd, count;
+int
+tape_tapefd_fsf(
+ int fd,
+ off_t count)
{
int st;
int status;
* Write some number of end of file marks (a.k.a. tape marks).
*/
int
-tape_tapefd_weof(fd, count)
- int fd, count;
+tape_tapefd_weof(
+ int fd,
+ off_t count)
{
int st;
int status;
- while (--count >= 0) {
+ while (--count >= (off_t)0) {
if ((status = ioctl(fd, T_WRFILEM, &st)) != 0) {
break;
}
* Rewind a tape to the beginning.
*/
int
-tape_tapefd_rewind(fd)
- int fd;
+tape_tapefd_rewind(
+ int fd)
{
struct stop st;
* Rewind and unload a tape.
*/
int
-tape_tapefd_unload(fd)
- int fd;
+tape_tapefd_unload(
+ int fd)
{
struct stop st;
* Forward space the tape device count files.
*/
int
-tape_tapefd_fsf(fd, count)
- int fd, count;
+tape_tapefd_fsf(
+ int fd,
+ off_t count)
{
struct stop st;
+ if ((count > (off_t)INT_MAX) || (count < (off_t)INT_MIN)) {
+#ifdef EOVERFLOW
+ errno = EOVERFLOW;
+#else
+ errno = EINVAL;
+#endif
+ return -1;
+ }
+
st.st_op = STFSF;
- st.st_count = count;
+ st.st_count = (int)count;
return ioctl(fd, STIOCTOP, &st);
}
* Write some number of end of file marks (a.k.a. tape marks).
*/
int
-tape_tapefd_weof(fd, count)
- int fd, count;
+tape_tapefd_weof(
+ int fd,
+ off_t count)
{
struct stop st;
+ if ((count > (off_t)INT_MAX) || (count < (off_t)INT_MIN)) {
+#ifdef EOVERFLOW
+ errno = EOVERFLOW;
+#else
+ errno = EINVAL;
+#endif
+ return -1;
+ }
+
st.st_op = STWEOF;
- st.st_count = count;
+ st.st_count = (int)count;
return ioctl(fd, STIOCTOP, &st);
}
* Rewind a tape to the beginning.
*/
int
-tape_tapefd_rewind(fd)
- int fd;
+tape_tapefd_rewind(
+ int fd)
{
int st;
* Rewind and unload a tape.
*/
int
-tape_tapefd_unload(fd)
- int fd;
+tape_tapefd_unload(
+ int fd)
{
int st;
int f;
* Forward space the tape device count files.
*/
int
-tape_tapefd_fsf(fd, count)
- int fd, count;
+tape_tapefd_fsf(
+ int fd,
+ off_t count)
{
int st;
int status;
* Write some number of end of file marks (a.k.a. tape marks).
*/
int
-tape_tapefd_weof(fd, count)
- int fd, count;
+tape_tapefd_weof(
+ int fd,
+ off_t count)
{
int st;
int c;
* Rewind a tape to the beginning.
*/
int
-tape_tapefd_rewind(fd)
- int fd;
+tape_tapefd_rewind(
+ int fd)
{
struct mtop mt;
int rc=-1, cnt;
* Rewind and unload a tape.
*/
int
-tape_tapefd_unload(fd)
- int fd;
+tape_tapefd_unload(
+ int fd)
{
struct mtop mt;
int rc=-1, cnt;
* Forward space the tape device count files.
*/
int
-tape_tapefd_fsf(fd, count)
- int fd, count;
+tape_tapefd_fsf(
+ int fd,
+ off_t count)
{
struct mtop mt;
+ if ((count > (off_t)INT_MAX) || (count < (off_t)INT_MIN)) {
+#ifdef EOVERFLOW
+ errno = EOVERFLOW;
+#else
+ errno = EINVAL;
+#endif
+ return -1;
+ }
+
mt.mt_op = MTFSF;
- mt.mt_count = count;
+ mt.mt_count = (int)count;
return ioctl(fd, MTIOCTOP, &mt);
}
/*
* Write some number of end of file marks (a.k.a. tape marks).
- */
-int tape_tapefd_weof(fd, count)
-int fd, count;
-/*
+ *
* write <count> filemarks on the tape.
*/
+int
+tape_tapefd_weof(
+ int fd,
+ off_t count)
{
struct mtop mt;
+ if ((count > (off_t)INT_MAX) || (count < (off_t)INT_MIN)) {
+#ifdef EOVERFLOW
+ errno = EOVERFLOW;
+#else
+ errno = EINVAL;
+#endif
+ return -1;
+ }
+
mt.mt_op = MTWEOF;
- mt.mt_count = count;
+ mt.mt_count = (int)count;
return ioctl(fd, MTIOCTOP, &mt);
}
* is_zftape(filename) checks if filename is a valid ftape device name.
*/
int
-is_zftape(filename)
- const char *filename;
+is_zftape(
+ const char *filename)
{
if (strncmp(filename, "/dev/nftape", 11) == 0) return(1);
if (strncmp(filename, "/dev/nqft", 9) == 0) return(1);
}
#endif /* HAVE_LINUX_ZFTAPE_H */
-int tape_tape_open(filename, flags, mask)
- char *filename;
- int flags;
- int mask;
+int
+tape_tape_open(
+ char *filename,
+ int flags,
+ mode_t mask)
{
- int ret = 0, delay = 2, timeout = 200;
+ int ret;
+ time_t timeout = 200;
+ unsigned delay = 2;
if ((flags & 3) != O_RDONLY) {
flags &= ~3;
flags |= O_RDWR;
}
- while (1) {
- ret = open(filename, flags, mask);
- /* if tape open fails with errno==EAGAIN, EBUSY or EINTR, it
- * is worth retrying a few seconds later. */
- if (ret >= 0 ||
- (1
-#ifdef EAGAIN
- && errno != EAGAIN
-#endif
-#ifdef EBUSY
- && errno != EBUSY
-#endif
-#ifdef EINTR
- && errno != EINTR
-#endif
- )) {
- break;
+ ret = open(filename, flags, mask);
+ while (ret < 0) {
+ if ((errno != EAGAIN) && (errno != EBUSY) && (errno != EINTR)) {
+ /*
+ * Open failed completely: just return
+ */
+ fprintf(stderr, "Opening tapedev %s: got error %s.\n",
+ filename, strerror(errno));
+ return -1;
}
+
+ /*
+ * if tape open fails with errno==EAGAIN, EBUSY or EINTR, it
+ * may be worth retrying a few seconds later.
+ */
timeout -= delay;
if (timeout <= 0) {
- break;
+ /* Open failed: just return */
+ fprintf(stderr, "Opening tapedev %s: not ready.\n", filename);
+ return -1;
}
- if (delay < 16) {
+
+ if (delay < 16)
delay *= 2;
- }
+
sleep(delay);
+ ret = open(filename, flags, mask);
}
+
+#ifdef MTIOCGET
+ /* Now check that we opened a tape device. */
+ {
+ struct mtget mt;
+
+ memset(&mt, 0, SIZEOF(mt));
+ if (ioctl(ret, MTIOCGET, &mt) < 0) {
+ close(ret);
+ fprintf(stderr, "tapedev %s is not a tape device!\n", filename);
+ return -1;
+ }
+
+#ifdef GMT_ONLINE
+ if (!GMT_ONLINE(mt.mt_gstat)) {
+ close(ret);
+ fprintf(stderr, "tapedev %s is offline or has no loaded tape.\n",
+ filename);
+ return -1;
+ }
+#endif /* GMT_ONLINE */
+ }
+#endif /* MTIOCGET */
+
+
#ifdef HAVE_LINUX_ZFTAPE_H
/*
* switch the block size for the zftape driver (3.04d)
* (its default is 10kb and not 32kb)
* A. Gebhardt <albrecht.gebhardt@uni-klu.ac.at>
*/
- if (ret >= 0 && is_zftape(filename) == 1) {
+ if (is_zftape(filename) == 1) {
struct mtop mt;
mt.mt_op = MTSETBLK;
return ret;
}
-ssize_t tape_tapefd_read(fd, buffer, count)
- int fd;
- void *buffer;
- size_t count;
+ssize_t
+tape_tapefd_read(
+ int fd,
+ void *buffer,
+ size_t count)
{
return read(fd, buffer, count);
}
-ssize_t tape_tapefd_write(fd, buffer, count)
- int fd;
- const void *buffer;
- size_t count;
+ssize_t
+tape_tapefd_write(
+ int fd,
+ const void *buffer,
+ size_t count)
{
return write(fd, buffer, count);
}
-int tape_tapefd_close(fd)
- int fd;
+int
+tape_tapefd_close(
+ int fd)
{
return close(fd);
-}
+}
-void tape_tapefd_resetofs(fd)
- int fd;
+void
+tape_tapefd_resetofs(
+ int fd)
{
/*
* this *should* be a no-op on the tape, but resets the kernel's view
* of the file offset, preventing it from barfing should we pass the
* filesize limit (eg OSes with 2 GB filesize limits) on a long tape.
*/
- lseek(fd, (off_t) 0L, SEEK_SET);
+ if (lseek(fd, (off_t)0, SEEK_SET) < 0) {
+ dbprintf(("tape_tapefd_resetofs: lseek failed: <%s>\n",
+ strerror(errno)));
+ }
}
int
-tape_tapefd_status(fd, stat)
- int fd;
- struct am_mt_status *stat;
+tape_tapefd_status(
+ int fd,
+ struct am_mt_status *stat)
{
- int res = 0;
+ int res;
int anything_valid = 0;
#if defined(MTIOCGET)
struct mtget buf;
#endif
- memset((void *)stat, 0, sizeof(*stat));
+ memset((void *)stat, 0, SIZEOF(*stat));
#if defined(MTIOCGET) /* { */
res = ioctl(fd,MTIOCGET,&buf);
-
if (res >= 0) {
+ /*@ignore@*/
#ifdef MT_ONL /* { */
/* IRIX-ish system */
anything_valid = 1;
stat->online = 1; /* ioctl fails otherwise */
#ifdef HAVE_MT_DSREG
stat->device_status_valid = 1;
- stat->device_status_size = sizeof(buf.mt_dsreg);
+ stat->device_status_size = SIZEOF(buf.mt_dsreg);
stat->device_status = (unsigned long)buf.mt_dsreg;
#endif
#ifdef HAVE_MT_ERREG
stat->error_status_valid = 1;
- stat->error_status_size = sizeof(buf.mt_erreg);
+ stat->error_status_size = SIZEOF(buf.mt_erreg);
stat->error_status = (unsigned long)buf.mt_erreg;
#endif
#if defined(HAVE_MT_FLAGS) && defined(MTF_SCSI) /* { */
#endif /* } */
#endif /* } */
#endif /* } */
+ /*@end@*/
}
#endif /* } */
res = fstat(fd, &sbuf);
stat->online_valid = 1;
- stat->online = (res == 0);
+ stat->online = (char)(res == 0);
}
return res;
}
-int tape_tape_stat(filename, buf)
- char *filename;
- struct stat *buf;
+int
+tape_tape_stat(
+ char *filename,
+ struct stat *buf)
{
return stat(filename, buf);
}
-int tape_tape_access(filename, mode)
- char *filename;
- int mode;
+int
+tape_tape_access(
+ char *filename,
+ int mode)
{
return access(filename, mode);
}
int
-tape_tapefd_can_fork(fd)
- int fd;
+tape_tapefd_can_fork(
+ int fd)
{
+ (void)fd; /* Quiet unused parameter warning */
+
return 1;
}
*/
/*
- * $Id: output-tape.h,v 1.5 2003/03/06 21:43:58 martinea Exp $
+ * $Id: output-tape.h,v 1.6 2006/05/25 01:47:27 johnfranks Exp $
*
* tapeio.c virtual tape interface for normal tape drives.
*/
#include "amanda.h"
#endif
-extern int tape_tape_access P((char *, int));
-extern int tape_tape_open ();
-extern int tape_tape_stat P((char *, struct stat *));
-extern int tape_tapefd_close P((int));
-extern int tape_tapefd_fsf P((int, int));
-extern ssize_t tape_tapefd_read P((int, void *, size_t));
-extern int tape_tapefd_rewind P((int));
-extern void tape_tapefd_resetofs P((int));
-extern int tape_tapefd_unload P((int));
-extern int tape_tapefd_status P((int, struct am_mt_status *));
-extern int tape_tapefd_weof P((int, int));
-extern ssize_t tape_tapefd_write P((int, const void *, size_t));
-extern int tape_tapefd_can_fork P((int));
+int tape_tape_access(char *, int);
+int tape_tape_open(char *, int, mode_t);
+int tape_tape_stat(char *, struct stat *);
+int tape_tapefd_close(int);
+int tape_tapefd_fsf(int, off_t);
+ssize_t tape_tapefd_read(int, void *, size_t);
+int tape_tapefd_rewind(int);
+void tape_tapefd_resetofs(int);
+int tape_tapefd_unload(int);
+int tape_tapefd_status(int, struct am_mt_status *);
+int tape_tapefd_weof(int, off_t);
+ssize_t tape_tapefd_write(int, const void *, size_t);
+int tape_tapefd_can_fork(int);
#endif /* OUTPUT_TAPE_H */
*/
/*
- * $Id: tapeio.c,v 1.53 2006/01/14 04:37:20 paddy_s Exp $
+ * $Id: tapeio.c,v 1.57 2006/07/06 15:04:18 martinea Exp $
*
* implements generic tape I/O functions
*/
#include "amanda.h"
-#include <stdarg.h>
-#include <errno.h>
-
#include "tapeio.h"
#include "fileheader.h"
+
#ifndef R_OK
#define R_OK 4
#define W_OK 2
static struct virtualtape {
char *prefix;
- int (*xxx_tape_access) P((char *, int));
- int (*xxx_tape_open) (char *, int, int);
- int (*xxx_tape_stat) P((char *, struct stat *));
- int (*xxx_tapefd_close) P((int));
- int (*xxx_tapefd_fsf) P((int, int));
- ssize_t (*xxx_tapefd_read) P((int, void *, size_t));
- int (*xxx_tapefd_rewind) P((int));
- void (*xxx_tapefd_resetofs) P((int));
- int (*xxx_tapefd_unload) P((int));
- int (*xxx_tapefd_status) P((int, struct am_mt_status *));
- int (*xxx_tapefd_weof) P((int, int));
- ssize_t (*xxx_tapefd_write) P((int, const void *, size_t));
- int (*xxx_tapefd_can_fork) P((int));
+ int (*xxx_tape_access)(char *, int);
+ int (*xxx_tape_open)(char *, int, mode_t);
+ int (*xxx_tape_stat)(char *, struct stat *);
+ int (*xxx_tapefd_close)(int);
+ int (*xxx_tapefd_fsf)(int, off_t);
+ ssize_t (*xxx_tapefd_read)(int, void *, size_t);
+ int (*xxx_tapefd_rewind)(int);
+ void (*xxx_tapefd_resetofs)(int);
+ int (*xxx_tapefd_unload)(int);
+ int (*xxx_tapefd_status)(int, struct am_mt_status *);
+ int (*xxx_tapefd_weof)(int, off_t);
+ ssize_t (*xxx_tapefd_write)(int, const void *, size_t);
+ int (*xxx_tapefd_can_fork)(int);
} vtable[] = {
/* note: "tape" has to be the first entry because it is the
** default if no prefix match is found.
file_tapefd_read, file_tapefd_rewind, file_tapefd_resetofs,
file_tapefd_unload, file_tapefd_status, file_tapefd_weof,
file_tapefd_write, file_tapefd_can_fork },
- {NULL,},
+ {NULL, NULL, NULL, NULL,
+ NULL, NULL,
+ NULL, NULL, NULL,
+ NULL, NULL, NULL,
+ NULL, NULL}
};
static struct tape_info {
char *disk;
int level;
char *datestamp;
- long length;
+ off_t length;
char *tapetype;
int fake_label;
int ioctl_fork;
int master_fd;
} *tape_info = NULL;
-static int tape_info_count = 0;
+static struct tape_info **tape_info_p = &tape_info;
+
+static size_t tape_info_count = 0;
static char *errstr = NULL;
+static void tape_info_init(void *ptr);
+static int name2slot(char *name, char **ntrans);
+
/*
* Additional initialization function for tape_info table.
*/
static void
-tape_info_init(ptr)
- void *ptr;
+tape_info_init(
+ void *ptr)
{
struct tape_info *t = ptr;
*/
static int
-name2slot(name, ntrans)
- char *name;
- char **ntrans;
+name2slot(
+ char *name,
+ char **ntrans)
{
char *pc;
- int len, i;
+ size_t len;
+ int i;
if(0 != (pc = strchr(name, ':'))) {
- len = pc - name;
+ len = (size_t)(pc - name);
for( i = 0 ; vtable[i].prefix && vtable[i].prefix[0]; i++ ) {
if(0 == strncmp(vtable[i].prefix, name , len)
&& '\0' == vtable[i].prefix[len]) {
*/
int
-tapeio_init_devname(char * dev,
- char **dev_left,
- char **dev_right,
- char **dev_next) {
+tapeio_init_devname(
+ char * dev,
+ char **dev_left,
+ char **dev_right,
+ char **dev_next)
+{
int ch;
char *p;
int depth;
depth = 1;
p++;
while(depth > 0) {
- while((ch = *p++) != '\0' && ch != '{' && ch != '}') {}
+ ch = *p++;
+ while((ch != '\0') && (ch != '{') && (ch != '}'))
+ ch = *p++;
if(ch == '\0') {
/*
* Did not find a matching '}'.
*/
char *
-tapeio_next_devname(char * dev_left,
- char * dev_right,
- char **dev_next) {
+tapeio_next_devname(
+ char * dev_left,
+ char * dev_right,
+ char **dev_next)
+{
int ch;
char *next;
char *p;
p = next = *dev_next; /* remember the start point */
depth = 0;
do {
- while((ch = *p++) != '\0' && ch != '{' && ch != '}' && ch != ',') {}
+ ch = *p++;
+ while((ch != '\0') && (ch != '{') && (ch != '}') && (ch != ','))
+ ch = *p++;
if(ch == '\0') {
/*
* Found the end of a name.
*/
char *
-tapefd_getinfo_host(fd)
- int fd;
+tapefd_getinfo_host(
+ int fd)
{
- amtable_alloc((void **)&tape_info,
+ amtable_alloc((void **)tape_info_p,
&tape_info_count,
- sizeof(*tape_info),
- fd + 1,
+ SIZEOF(*tape_info),
+ (size_t)fd + 1,
10,
tape_info_init);
if(tape_info[fd].master_fd != -1)
}
void
-tapefd_setinfo_host(fd, v)
- int fd;
- char *v;
+tapefd_setinfo_host(
+ int fd,
+ char *v)
{
- amtable_alloc((void **)&tape_info,
+ amtable_alloc((void **)tape_info_p,
&tape_info_count,
- sizeof(*tape_info),
- fd + 1,
+ SIZEOF(*tape_info),
+ (size_t)fd + 1,
10,
tape_info_init);
amfree(tape_info[fd].host);
}
char *
-tapefd_getinfo_disk(fd)
- int fd;
+tapefd_getinfo_disk(
+ int fd)
{
- amtable_alloc((void **)&tape_info,
+ amtable_alloc((void **)tape_info_p,
&tape_info_count,
- sizeof(*tape_info),
- fd + 1,
+ SIZEOF(*tape_info),
+ (size_t)fd + 1,
10,
tape_info_init);
if(tape_info[fd].master_fd != -1)
}
void
-tapefd_setinfo_disk(fd, v)
- int fd;
- char *v;
+tapefd_setinfo_disk(
+ int fd,
+ char *v)
{
- amtable_alloc((void **)&tape_info,
+ amtable_alloc((void **)tape_info_p,
&tape_info_count,
- sizeof(*tape_info),
- fd + 1,
+ SIZEOF(*tape_info),
+ (size_t)fd + 1,
10,
tape_info_init);
amfree(tape_info[fd].disk);
}
int
-tapefd_getinfo_level(fd)
- int fd;
+tapefd_getinfo_level(
+ int fd)
{
- amtable_alloc((void **)&tape_info,
+ amtable_alloc((void **)tape_info_p,
&tape_info_count,
- sizeof(*tape_info),
- fd + 1,
+ SIZEOF(*tape_info),
+ (size_t)fd + 1,
10,
tape_info_init);
if(tape_info[fd].master_fd != -1)
}
void
-tapefd_setinfo_level(fd, v)
- int fd;
- int v;
+tapefd_setinfo_level(
+ int fd,
+ int v)
{
- amtable_alloc((void **)&tape_info,
+ amtable_alloc((void **)tape_info_p,
&tape_info_count,
- sizeof(*tape_info),
- fd + 1,
+ SIZEOF(*tape_info),
+ (size_t)fd + 1,
10,
tape_info_init);
tape_info[fd].level = v;
}
char *
-tapefd_getinfo_datestamp(fd)
- int fd;
+tapefd_getinfo_datestamp(
+ int fd)
{
- amtable_alloc((void **)&tape_info,
+ amtable_alloc((void **)tape_info_p,
&tape_info_count,
- sizeof(*tape_info),
- fd + 1,
+ SIZEOF(*tape_info),
+ (size_t)fd + 1,
10,
tape_info_init);
return tape_info[fd].datestamp;
}
void
-tapefd_setinfo_datestamp(fd, v)
- int fd;
- char *v;
+tapefd_setinfo_datestamp(
+ int fd,
+ char *v)
{
- amtable_alloc((void **)&tape_info,
+ amtable_alloc((void **)tape_info_p,
&tape_info_count,
- sizeof(*tape_info),
- fd + 1,
+ SIZEOF(*tape_info),
+ (size_t)fd + 1,
10,
tape_info_init);
tape_info[fd].datestamp = newstralloc(tape_info[fd].datestamp, v);
}
-long
-tapefd_getinfo_length(fd)
- int fd;
+off_t
+tapefd_getinfo_length(
+ int fd)
{
- amtable_alloc((void **)&tape_info,
+ amtable_alloc((void **)tape_info_p,
&tape_info_count,
- sizeof(*tape_info),
- fd + 1,
+ SIZEOF(*tape_info),
+ (size_t)fd + 1,
10,
tape_info_init);
return tape_info[fd].length;
}
void
-tapefd_setinfo_length(fd, v)
- int fd;
- long v;
+tapefd_setinfo_length(
+ int fd,
+ off_t v)
{
- amtable_alloc((void **)&tape_info,
+ amtable_alloc((void **)tape_info_p,
&tape_info_count,
- sizeof(*tape_info),
- fd + 1,
+ SIZEOF(*tape_info),
+ (size_t)fd + 1,
10,
tape_info_init);
tape_info[fd].length = v;
}
char *
-tapefd_getinfo_tapetype(fd)
- int fd;
+tapefd_getinfo_tapetype(
+ int fd)
{
- amtable_alloc((void **)&tape_info,
+ amtable_alloc((void **)tape_info_p,
&tape_info_count,
- sizeof(*tape_info),
- fd + 1,
+ SIZEOF(*tape_info),
+ (size_t)fd + 1,
10,
tape_info_init);
return tape_info[fd].tapetype;
}
void
-tapefd_setinfo_tapetype(fd, v)
- int fd;
- char *v;
+tapefd_setinfo_tapetype(
+ int fd,
+ char *v)
{
- amtable_alloc((void **)&tape_info,
+ amtable_alloc((void **)tape_info_p,
&tape_info_count,
- sizeof(*tape_info),
- fd + 1,
+ SIZEOF(*tape_info),
+ (size_t)fd + 1,
10,
tape_info_init);
tape_info[fd].tapetype = newstralloc(tape_info[fd].tapetype, v);
}
int
-tapefd_getinfo_fake_label(fd)
- int fd;
+tapefd_getinfo_fake_label(
+ int fd)
{
- amtable_alloc((void **)&tape_info,
+ amtable_alloc((void **)tape_info_p,
&tape_info_count,
- sizeof(*tape_info),
- fd + 1,
+ SIZEOF(*tape_info),
+ (size_t)fd + 1,
10,
tape_info_init);
return tape_info[fd].fake_label;
}
void
-tapefd_setinfo_fake_label(fd, v)
- int fd;
- int v;
+tapefd_setinfo_fake_label(
+ int fd,
+ int v)
{
- amtable_alloc((void **)&tape_info,
+ amtable_alloc((void **)tape_info_p,
&tape_info_count,
- sizeof(*tape_info),
- fd + 1,
+ SIZEOF(*tape_info),
+ (size_t)fd + 1,
10,
tape_info_init);
tape_info[fd].fake_label = v;
}
int
-tapefd_getinfo_ioctl_fork(fd)
- int fd;
+tapefd_getinfo_ioctl_fork(
+ int fd)
{
- amtable_alloc((void **)&tape_info,
+ amtable_alloc((void **)tape_info_p,
&tape_info_count,
- sizeof(*tape_info),
- fd + 1,
+ SIZEOF(*tape_info),
+ (size_t)fd + 1,
10,
tape_info_init);
return tape_info[fd].ioctl_fork;
}
void
-tapefd_setinfo_ioctl_fork(fd, v)
- int fd;
- int v;
+tapefd_setinfo_ioctl_fork(
+ int fd,
+ int v)
{
- amtable_alloc((void **)&tape_info,
+ amtable_alloc((void **)tape_info_p,
&tape_info_count,
- sizeof(*tape_info),
- fd + 1,
+ SIZEOF(*tape_info),
+ (size_t)fd + 1,
10,
tape_info_init);
tape_info[fd].ioctl_fork = v;
}
void
-tapefd_set_master_fd(fd, master_fd)
- int fd;
- int master_fd;
+tapefd_set_master_fd(
+ int fd,
+ int master_fd)
{
- amtable_alloc((void **)&tape_info,
+ amtable_alloc((void **)tape_info_p,
&tape_info_count,
- sizeof(*tape_info),
- fd + 1,
+ SIZEOF(*tape_info),
+ (size_t)fd + 1,
10,
tape_info_init);
tape_info[fd].master_fd = master_fd;
*/
int
-tape_access(filename, mode)
- char *filename;
- int mode;
+tape_access(
+ char *filename,
+ int mode)
{
char *tname;
int vslot;
}
int
-tape_stat(filename, buf)
- char *filename;
- struct stat *buf;
+tape_stat(
+ char *filename,
+ struct stat *buf)
{
char *tname;
int vslot;
}
int
-tape_open(char *filename, int mode, ...)
+tape_open(
+ char *filename,
+ int mode, ...)
{
char *tname;
int vslot;
int fd;
- int mask;
+ mode_t mask;
va_list ap;
va_start(ap, mode);
- mask = va_arg(ap, int);
+ mask = (mode_t)va_arg(ap, int);
va_end(ap);
vslot = name2slot(filename, &tname);
if((fd = vtable[vslot].xxx_tape_open(tname, mode, mask)) >= 0) {
- amtable_alloc((void **)&tape_info,
+ amtable_alloc((void **)tape_info_p,
&tape_info_count,
- sizeof(*tape_info),
- fd + 1,
+ SIZEOF(*tape_info),
+ (size_t)(fd + 1),
10,
tape_info_init);
/*
}
int
-tapefd_close(fd)
- int fd;
+tapefd_close(
+ int fd)
{
- int vslot, res = -1;
+ int res;
+ int vslot;
- if(fd < 0
- || fd >= tape_info_count
- || (vslot = tape_info[fd].vtape_index) < 0) {
+ if ((fd < 0) || ((size_t)fd >= tape_info_count)
+ || ((vslot = tape_info[fd].vtape_index) < 0)) {
errno = EBADF;
return -1;
}
+
+ vslot = tape_info[fd].vtape_index;
if((res = vtable[vslot].xxx_tapefd_close(fd)) == 0) {
amfree(tape_info[fd].host);
amfree(tape_info[fd].disk);
amfree(tape_info[fd].datestamp);
amfree(tape_info[fd].tapetype);
- memset(tape_info + fd, 0, sizeof(*tape_info));
+ memset(tape_info + fd, 0, SIZEOF(*tape_info));
tape_info_init((void *)(tape_info + fd));
}
return res;
}
int
-tapefd_can_fork(fd)
- int fd;
+tapefd_can_fork(
+ int fd)
{
- int vslot, res = -1;
+ int vslot;
- if(fd < 0
- || fd >= tape_info_count
- || (vslot = tape_info[fd].vtape_index) < 0) {
+ if ((fd < 0) || ((size_t)fd >= tape_info_count)
+ || (tape_info[fd].vtape_index < 0)) {
errno = EBADF;
return -1;
}
- res = vtable[vslot].xxx_tapefd_can_fork(fd);
- return res;
+ vslot = tape_info[fd].vtape_index;
+ return vtable[vslot].xxx_tapefd_can_fork(fd);
}
int
-tapefd_fsf(fd, count)
- int fd;
- int count;
+tapefd_fsf(
+ int fd,
+ off_t count)
{
int vslot;
- if(fd < 0
- || fd >= tape_info_count
- || (vslot = tape_info[fd].vtape_index) < 0) {
+ if ((fd < 0) || ((size_t)fd >= tape_info_count)
+ || (tape_info[fd].vtape_index < 0)) {
errno = EBADF;
return -1;
}
+
+ vslot = tape_info[fd].vtape_index;
return vtable[vslot].xxx_tapefd_fsf(fd, count);
}
int
-tapefd_rewind(fd)
- int fd;
+tapefd_rewind(
+ int fd)
{
int vslot;
- if(fd < 0
- || fd >= tape_info_count
- || (vslot = tape_info[fd].vtape_index) < 0) {
+ if ((fd < 0) || ((size_t)fd >= tape_info_count)
+ || (tape_info[fd].vtape_index < 0)) {
errno = EBADF;
return -1;
}
+
+ vslot = tape_info[fd].vtape_index;
return vtable[vslot].xxx_tapefd_rewind(fd);
}
void
-tapefd_resetofs(fd)
- int fd;
+tapefd_resetofs(
+ int fd)
{
int vslot;
- if(fd < 0
- || fd >= tape_info_count
- || (vslot = tape_info[fd].vtape_index) < 0) {
+ if ((fd < 0) || ((size_t)fd >= tape_info_count)
+ || (tape_info[fd].vtape_index < 0)) {
errno = EBADF; /* not that it matters */
return;
}
+
+ vslot = tape_info[fd].vtape_index;
vtable[vslot].xxx_tapefd_resetofs(fd);
}
int
-tapefd_unload(fd)
- int fd;
+tapefd_unload(
+ int fd)
{
int vslot;
- if(fd < 0
- || fd >= tape_info_count
- || (vslot = tape_info[fd].vtape_index) < 0) {
+ if ((fd < 0) || ((size_t)fd >= tape_info_count)
+ || (tape_info[fd].vtape_index < 0)) {
errno = EBADF;
return -1;
}
+
+ vslot = tape_info[fd].vtape_index;
return vtable[vslot].xxx_tapefd_unload(fd);
}
int
-tapefd_status(fd, stat)
- int fd;
- struct am_mt_status *stat;
+tapefd_status(
+ int fd,
+ struct am_mt_status *stat)
{
int vslot;
- if(fd < 0
- || fd >= tape_info_count
- || (vslot = tape_info[fd].vtape_index) < 0) {
+ if ((fd < 0) || ((size_t)fd >= tape_info_count)
+ || (tape_info[fd].vtape_index < 0)) {
errno = EBADF;
return -1;
}
+
+ vslot = tape_info[fd].vtape_index;
return vtable[vslot].xxx_tapefd_status(fd, stat);
}
int
-tapefd_weof(fd, count)
- int fd;
- int count;
+tapefd_weof(
+ int fd,
+ off_t count)
{
int vslot;
- if(fd < 0
- || fd >= tape_info_count
- || (vslot = tape_info[fd].vtape_index) < 0) {
+ if ((fd < 0) || ((size_t)fd >= tape_info_count)
+ || (tape_info[fd].vtape_index < 0)) {
errno = EBADF;
return -1;
}
+
+ vslot = tape_info[fd].vtape_index;
return vtable[vslot].xxx_tapefd_weof(fd, count);
-}
+}
+
ssize_t
-tapefd_read(fd, buffer, count)
- int fd;
- void *buffer;
- size_t count;
+tapefd_read(
+ int fd,
+ void *buffer,
+ size_t count)
{
int vslot;
- if(fd < 0
- || fd >= tape_info_count
- || (vslot = tape_info[fd].vtape_index) < 0) {
+ if ((fd < 0) || ((size_t)fd >= tape_info_count)
+ || (tape_info[fd].vtape_index < 0)) {
errno = EBADF;
return -1;
}
+
+ vslot = tape_info[fd].vtape_index;
return vtable[vslot].xxx_tapefd_read(fd, buffer, count);
}
ssize_t
-tapefd_write(fd, buffer, count)
- int fd;
- const void *buffer;
- size_t count;
+tapefd_write(
+ int fd,
+ const void *buffer,
+ size_t count)
{
int vslot;
- if(fd < 0
- || fd >= tape_info_count
- || (vslot = tape_info[fd].vtape_index) < 0) {
+ if ((fd < 0) || ((size_t)fd >= tape_info_count)
+ || (tape_info[fd].vtape_index < 0)) {
errno = EBADF;
return -1;
}
+
+ vslot = tape_info[fd].vtape_index;
return vtable[vslot].xxx_tapefd_write(fd, buffer, count);
}
char *
-tape_rewind(devname)
- char *devname;
+tape_rewind(
+ char *devname)
{
int fd;
char *r = NULL;
}
char *
-tape_unload(devname)
- char *devname;
+tape_unload(
+ char *devname)
{
int fd;
char *r = NULL;
}
char *
-tape_fsf(devname, count)
- char *devname;
- int count;
+tape_fsf(
+ char *devname,
+ off_t count)
{
int fd;
char count_str[NUM_STR_SIZE];
strerror(errno),
NULL);
} else if(tapefd_fsf(fd, count) == -1) {
- snprintf(count_str, sizeof(count_str), "%d", count);
+ snprintf(count_str, SIZEOF(count_str), OFF_T_FMT,
+ (OFF_T_FMT_TYPE)count);
r = errstr = newvstralloc(errstr,
"tape_fsf: fsf ",
count_str,
string will start with NOT_AMANDA_TAPE_MSG. */
char *
-tapefd_rdlabel(fd, datestamp, label)
- int fd;
- char **datestamp;
- char **label;
+tapefd_rdlabel(
+ int fd,
+ char **datestamp,
+ char **label)
{
- int rc;
+ ssize_t rc;
size_t buflen;
char *buffer = NULL;
dumpfile_t file;
/* make sure buffer is null-terminated */
buffer[rc] = '\0';
- parse_file_header(buffer, &file, rc);
+ parse_file_header(buffer, &file, (size_t)rc);
if(file.type != F_TAPESTART) {
r = stralloc(NOT_AMANDA_TAPE_MSG);
} else {
}
}
amfree(buffer);
- errstr = newvstralloc(errstr, r, NULL);
+ if (r)
+ errstr = newvstralloc(errstr, r, NULL);
return r;
}
char *
-tape_rdlabel(devname, datestamp, label)
- char *devname;
- char **datestamp;
- char **label;
+tape_rdlabel(
+ char *devname,
+ char **datestamp,
+ char **label)
{
int fd;
char *r = NULL;
if(fd >= 0) {
tapefd_close(fd);
}
- errstr = newvstralloc(errstr, r, NULL);
+ if (r)
+ errstr = newvstralloc(errstr, r, NULL);
return r;
}
char *
-tapefd_wrlabel(fd, datestamp, label, size)
- int fd;
- char *datestamp;
- char *label;
- unsigned int size;
+tapefd_wrlabel(
+ int fd,
+ char *datestamp,
+ char *label,
+ size_t size)
{
- int rc;
+ ssize_t rc;
char *buffer = NULL;
dumpfile_t file;
char *r = NULL;
} else {
fh_init(&file);
file.type = F_TAPESTART;
- strncpy(file.datestamp, datestamp, sizeof(file.datestamp) - 1);
- file.datestamp[sizeof(file.datestamp) - 1] = '\0';
- strncpy(file.name, label, sizeof(file.name) - 1);
- file.name[sizeof(file.name) - 1] = '\0';
+ strncpy(file.datestamp, datestamp, SIZEOF(file.datestamp) - 1);
+ file.datestamp[SIZEOF(file.datestamp) - 1] = '\0';
+ strncpy(file.name, label, SIZEOF(file.name) - 1);
+ file.name[SIZEOF(file.name) - 1] = '\0';
buffer = alloc(size);
file.blocksize = size;
build_header(buffer, &file, size);
tapefd_setinfo_host(fd, NULL);
tapefd_setinfo_disk(fd, label);
tapefd_setinfo_level(fd, -1);
- if((rc = tapefd_write(fd, buffer, size)) != size) {
+ if((rc = tapefd_write(fd, buffer, size)) != (ssize_t)size) {
r = errstr = newstralloc2(errstr,
"writing label: ",
(rc != -1) ? "short write"
}
char *
-tape_wrlabel(devname, datestamp, label, size)
- char *devname;
- char *datestamp;
- char *label;
- unsigned int size;
+tape_wrlabel(
+ char *devname,
+ char *datestamp,
+ char *label,
+ size_t size)
{
int fd;
char *r = NULL;
}
char *
-tapefd_wrendmark(fd, datestamp, size)
- int fd;
- char *datestamp;
- unsigned int size;
+tapefd_wrendmark(
+ int fd,
+ char *datestamp,
+ size_t size)
{
- int rc;
+ ssize_t rc;
char *buffer = NULL;
dumpfile_t file;
char *r = NULL;
fh_init(&file);
file.type = F_TAPEEND;
- strncpy(file.datestamp, datestamp, sizeof(file.datestamp) - 1);
- file.datestamp[sizeof(file.datestamp) - 1] = '\0';
+ strncpy(file.datestamp, datestamp, SIZEOF(file.datestamp) - 1);
+ file.datestamp[SIZEOF(file.datestamp) - 1] = '\0';
buffer = alloc(size);
file.blocksize = size;
build_header(buffer, &file, size);
tapefd_setinfo_disk(fd, "TAPEEND");
tapefd_setinfo_level(fd, -1);
- if((rc = tapefd_write(fd, buffer, size)) != size) {
+ if((rc = tapefd_write(fd, buffer, size)) != (ssize_t)size) {
r = errstr = newstralloc2(errstr, "writing endmark: ",
(rc != -1) ? "short write" : strerror(errno));
}
}
char *
-tape_wrendmark(devname, datestamp, size)
- char *devname;
- char *datestamp;
- unsigned int size;
+tape_wrendmark(
+ char *devname,
+ char *datestamp,
+ size_t size)
{
int fd;
char *r = NULL;
}
char *
-tape_writable(devname)
- char *devname;
+tape_writable(
+ char *devname)
{
int fd = -1;
char *r = NULL;
static char *pgm;
static void
-do_help()
+do_help(void)
{
fprintf(stderr, " ?|help\n");
fprintf(stderr, " open [\"file\"|$TAPE [\"mode\":O_RDONLY]]\n");
}
static void
-usage()
+usage(void)
{
fprintf(stderr, "usage: %s [-c cmd [args] [%% cmd [args] ...]]\n", pgm);
do_help();
static int token_count;
static int fd = -1;
-static int current_file = 0;
-static int current_record = 0;
+static off_t current_file = (off_t)0;
+static off_t current_record = (off_t)0;
static int have_length = 0;
-static int length = 0;
+static int length = (off_t)0;
static int show_timestamp = 0;
char write_buf[TEST_BLOCKSIZE];
static void
-do_open()
+do_open(void)
{
- int mode;
+ mode_t mode;
char *file;
if(token_count < 2
}
static void
-do_close()
+do_close(void)
{
- int result;
+ int result;
fprintf(stderr, "tapefd_close(): ");
if((result = tapefd_close(fd)) < 0) {
}
static void
-do_read()
+do_read(void)
{
- int result;
- int count = 0;
+ ssize_t result;
+ off_t count = (off_t)0;
int have_count = 0;
- char buf[sizeof(write_buf)];
+ char buf[SIZEOF(write_buf)];
int *p;
- int i;
+ off_t i;
char *s;
time_t then;
struct tm *tm;
if(token_count > 1 && strcmp(token[1], "all") != 0) {
- count = atoi(token[1]);
+ count = OFF_T_ATOI(token[1]);
have_count = 1;
}
p = (int *)buf;
for(i = 0; (! have_count) || (i < count); i++) {
- fprintf(stderr, "tapefd_read(%d): ", i);
- if((result = tapefd_read(fd, buf, sizeof(buf))) < 0) {
+ fprintf(stderr, "tapefd_read(" OFF_T_FMT "): ", (OFF_T_FMT_TYPE)i);
+ if((result = tapefd_read(fd, buf, SIZEOF(buf))) < 0) {
perror("");
break;
} else if(result == 0) {
- fprintf(stderr, "%d (EOF)\n", result);
+ fprintf(stderr, SSIZE_T_FMT" (EOF)\n", result);
/*
* If we were not given a count, EOF breaks the loop, otherwise
* we keep trying (to test read after EOF handling).
break;
}
} else {
- if(result == sizeof(buf)) {
+ if(result == (ssize_t)sizeof(buf)) {
s = "OK";
} else {
s = "short read";
* the effort to deal with.
*/
fprintf(stderr,
- "%d (%s): file %d: record %d",
+ SSIZE_T_FMT " (%s): file %d: record %d",
result,
s,
p[0],
}
static void
-do_write()
+do_write(void)
{
- int result;
- int count;
- int *p;
- int i;
+ int result;
+ off_t count;
+ off_t *p;
+ off_t i;
char *s;
time_t now;
struct tm *tm;
if(token_count > 1) {
- count = atoi(token[1]);
+ count = OFF_T_ATOI(token[1]);
} else {
- count = 1;
+ count = (off_t)1;
}
if(token_count > 2 && strcmp(token[2], "+") != 0) {
- current_file = atoi(token[2]);
+ current_file = OFF_T_ATOI(token[2]);
}
if(token_count > 3 && strcmp(token[3], "+") != 0) {
- current_record = atoi(token[3]);
+ current_record = OFF_T_ATOI(token[3]);
}
if(token_count > 4 && token[4][0] != '\0') {
tapefd_setinfo_level(fd, atoi(token[6]));
}
- p = (int *)write_buf;
+ p = (off_t *)write_buf;
time(&now);
p[2] = now;
tm = localtime(&now);
- for(i = 0; i < count; i++, current_record++) {
+ for(i = 0; i < count; i++, (current_record += (off_t)1)) {
p[0] = current_file;
p[1] = current_record;
- fprintf(stderr, "tapefd_write(%d): ", i);
- if((result = tapefd_write(fd, write_buf, sizeof(write_buf))) < 0) {
+ fprintf(stderr, "tapefd_write(" OFF_T_FMT "): ", i);
+ if((result = tapefd_write(fd, write_buf, SIZEOF(write_buf))) < 0) {
perror("");
break;
} else {
- if(result == sizeof(write_buf)) {
+ if(result == (ssize_t)sizeof(write_buf)) {
s = "OK";
} else {
s = "short write";
}
fprintf(stderr,
- "%d (%s): file %d: record %d",
+ "%d (%s): file " OFF_T_FMT ": record " OFF_T_FMT,
result,
s,
p[0],
}
static void
-do_fsf()
+do_fsf(void)
{
- int result;
- int count;
+ int result;
+ off_t count;
if(token_count > 1) {
- count = atoi(token[1]);
+ count = OFF_T_ATOI(token[1]);
} else {
- count = 1;
+ count = (off_t)1;
}
- fprintf(stderr, "tapefd_fsf(%d): ", count);
+ fprintf(stderr, "tapefd_fsf(" OFF_T_FMT "): ", (OFF_T_FMT_TYPE)count);
if((result = tapefd_fsf(fd, count)) < 0) {
perror("");
} else {
fprintf(stderr, "%d (OK)\n", result);
current_file += count;
- current_record = 0;
+ current_record = (off_t)0;
}
}
static void
-do_weof()
+do_weof(void)
{
- int result;
- int count;
+ int result;
+ off_t count;
if(token_count > 1) {
- count = atoi(token[1]);
+ count = OFF_T_ATOI(token[1]);
} else {
- count = 1;
+ count = (off_t)1;
}
- fprintf(stderr, "tapefd_weof(%d): ", count);
+ fprintf(stderr, "tapefd_weof(" OFF_T_FMT "): ", count);
if((result = tapefd_weof(fd, count)) < 0) {
perror("");
} else {
fprintf(stderr, "%d (OK)\n", result);
current_file += count;
- current_record = 0;
+ current_record = (off_t)0;
}
}
static void
-do_rewind()
+do_rewind(void)
{
- int result;
+ int result;
fprintf(stderr, "tapefd_rewind(): ");
if((result = tapefd_rewind(fd)) < 0) {
perror("");
} else {
fprintf(stderr, "%d (OK)\n", result);
- current_file = 0;
- current_record = 0;
+ current_file = (off_t)0;
+ current_record = (off_t)0;
}
}
static void
-do_unload()
+do_unload(void)
{
- int result;
+ int result;
fprintf(stderr, "tapefd_unload(): ");
if((result = tapefd_unload(fd)) < 0) {
perror("");
} else {
fprintf(stderr, "%d (OK)\n", result);
- current_file = -1;
- current_record = -1;
+ current_file = (off_t)-1;
+ current_record = (off_t)-1;
}
}
struct cmd {
char *name;
int min_chars;
- void (*func)();
+ void (*func)(void);
} cmd[] = {
{ "?", 0, do_help },
{ "help", 0, do_help },
};
int
-main(argc, argv)
- int argc;
- char **argv;
+main(
+ int argc,
+ char **argv)
{
int ch;
int cmdline = 0;
break;
case 'l':
have_length = 1;
- length = atoi(optarg);
+ length = OFF_T_ATOI(optarg);
j = strlen(optarg);
if(j > 0) {
switch(optarg[j-1] ) {
case 'k': break;
- case 'b': length /= 2; break;
- case 'M': length *= 1024; break;
- default: length /= 1024; break;
+ case 'b': length /= (off_t)2; break;
+ case 'M': length *= (off_t)1024; break;
+ default: length /= (off_t)1024; break;
}
} else {
- length /= 1024;
+ length /= (off_t)1024;
}
break;
case 't':
*/
time(&now);
srandom(now);
- for(j = 0; j < sizeof(write_buf); j++) {
+ for(j = 0; j < (int)SIZEOF(write_buf); j++) {
write_buf[j] = (char)random();
}
while(1) {
if(cmdline) {
for(token_count = 1;
- token_count < (sizeof(token_area) / sizeof(token_area[0]))
+ token_count < (int)(SIZEOF(token_area) / SIZEOF(token_area[0]))
&& optind < argc;
token_count++, optind++) {
if(strcmp(argv[optind], "%") == 0) {
}
token_count = split(line,
token_area,
- sizeof(token_area) / sizeof(token_area[0]),
+ SIZEOF(token_area) / SIZEOF(token_area[0]),
" ");
}
amfree(line);
* University of Maryland at College Park
*/
/*
- * $Id: tapeio.h,v 1.20 2005/12/21 19:07:51 paddy_s Exp $
+ * $Id: tapeio.h,v 1.21 2006/05/25 01:47:27 johnfranks Exp $
*
* interface for tapeio.c
*/
#define FAKE_LABEL "[fake-label]"
#define NO_LABEL "[no-label-yet]"
-int tape_open (char *, int, ...);
+int tape_open(char *, int, ...);
-int tapefd_rewind P((int tapefd));
-int tapefd_unload P((int tapefd));
-int tapefd_fsf P((int tapefd, int count));
-int tapefd_weof P((int tapefd, int count));
+int tapefd_rewind(int tapefd);
+int tapefd_unload(int tapefd);
+int tapefd_fsf(int tapefd, off_t count);
+int tapefd_weof(int tapefd, off_t count);
-int tapefd_status P((int tapefd, struct am_mt_status *));
+int tapefd_status(int tapefd, struct am_mt_status *);
-void tapefd_resetofs P((int tapefd));
+void tapefd_resetofs(int tapefd);
-ssize_t tapefd_read P((int tapefd, void *buffer, size_t count));
-ssize_t tapefd_write P((int tapefd, const void *buffer, size_t count));
+ssize_t tapefd_read(int, void *, size_t);
+ssize_t tapefd_write(int tapefd, const void *buffer, size_t count);
-char *tapefd_rdlabel P((int tapefd, char **datestamp, char **label));
-char *tapefd_wrlabel P((int tapefd,
+char *tapefd_rdlabel(int tapefd, char **datestamp, char **label);
+char *tapefd_wrlabel(int tapefd,
char *datestamp,
char *label,
- unsigned int s));
+ size_t s);
-char *auto_tapefd_label P((int tapefd, char **datestamp, char **label));
-char *auto_tape_label P((char *dev, char **datestamp, char **label));
+char *auto_tapefd_label(int tapefd, char **datestamp, char **label);
+char *auto_tape_label(char *dev, char **datestamp, char **label);
-char *tapefd_wrendmark P((int tapefd, char *datestamp, unsigned int s));
+char *tapefd_wrendmark(int tapefd, char *datestamp, size_t s);
-int tapefd_eof P((int tapefd)); /* just used in tapeio-test */
-int tapefd_close P((int tapefd));
-int tapefd_can_fork P((int tapefd));
+int tapefd_eof(int tapefd); /* just used in tapeio-test */
+int tapefd_close(int tapefd);
+int tapefd_can_fork(int tapefd);
-char *tape_unload P((char *dev));
-char *tape_rewind P((char *dev));
-char *tape_fsf P((char *dev, int count));
-char *tape_rdlabel P((char *dev, char **datestamp, char **label));
-char *tape_wrlabel P((char *dev,
+char *tape_unload(char *dev);
+char *tape_rewind(char *dev);
+char *tape_fsf(char *dev, off_t count);
+char *tape_rdlabel(char *dev, char **datestamp, char **label);
+char *tape_wrlabel(char *dev,
char *datestamp,
char *label,
- unsigned int size));
-char *tape_wrendmark P((char *dev,
+ size_t size);
+char *tape_wrendmark(char *dev,
char *datestamp,
- unsigned int size));
-char *tape_writable P((char *dev));
-
-int tape_access P((char *dev, int mode));
-int tape_stat P((char *filename, struct stat *buf));
-
-char *tapefd_getinfo_label P((int fd));
-void tapefd_setinfo_label P((int fd, char *v));
-char *tapefd_getinfo_host P((int fd));
-void tapefd_setinfo_host P((int fd, char *v));
-char *tapefd_getinfo_disk P((int fd));
-void tapefd_setinfo_disk P((int fd, char *v));
-int tapefd_getinfo_level P((int fd));
-void tapefd_setinfo_level P((int fd, int v));
-char *tapefd_getinfo_datestamp P((int fd));
-void tapefd_setinfo_datestamp P((int fd, char *v));
-long tapefd_getinfo_length P((int fd));
-void tapefd_setinfo_length P((int fd, long v));
-char *tapefd_getinfo_tapetype P((int fd));
-void tapefd_setinfo_tapetype P((int fd, char *v));
-int tapefd_getinfo_fake_label P((int fd));
-void tapefd_setinfo_fake_label P((int fd, int v));
-int tapefd_getinfo_ioctl_fork P((int fd));
-void tapefd_setinfo_ioctl_fork P((int fd, int v));
-void tapefd_set_master_fd P((int tapefd, int master_fd));
+ size_t size);
+char *tape_writable(char *dev);
+
+int tape_access(char *dev, int mode);
+int tape_stat(char *filename, struct stat *buf);
+
+char *tapefd_getinfo_label(int fd);
+void tapefd_setinfo_label(int fd, char *v);
+char *tapefd_getinfo_host(int fd);
+void tapefd_setinfo_host(int fd, char *v);
+char *tapefd_getinfo_disk(int fd);
+void tapefd_setinfo_disk(int fd, char *v);
+int tapefd_getinfo_level(int fd);
+void tapefd_setinfo_level(int fd, int v);
+char *tapefd_getinfo_datestamp(int fd);
+void tapefd_setinfo_datestamp(int fd, char *v);
+off_t tapefd_getinfo_length(int fd);
+void tapefd_setinfo_length(int fd, off_t v);
+char *tapefd_getinfo_tapetype(int fd);
+void tapefd_setinfo_tapetype(int fd, char *v);
+int tapefd_getinfo_fake_label(int fd);
+void tapefd_setinfo_fake_label(int fd, int v);
+int tapefd_getinfo_ioctl_fork(int fd);
+void tapefd_setinfo_ioctl_fork(int fd, int v);
+void tapefd_set_master_fd(int tapefd, int master_fd);
#ifdef HAVE_LINUX_ZFTAPE_H
-int is_zftape P((const char *filename));
+int is_zftape(const char *filename);
#endif
-int tapeio_init_devname P((char * dev,
+int tapeio_init_devname(char * dev,
char **dev_left,
char **dev_right,
- char **dev_next));
-char *tapeio_next_devname P((char * dev_left,
+ char **dev_next);
+char *tapeio_next_devname(char * dev_left,
char * dev_right,
- char **dev_next));
+ char **dev_next);
#define NOT_AMANDA_TAPE_MSG "not an amanda tape"
#define CHECK_NOT_AMANDA_TAPE_MSG(x) (!BSTRNCMP(x, NOT_AMANDA_TAPE_MSG))
* University of Maryland at College Park
*/
/*
- * $Id: tapetype.c,v 1.24 2006/03/10 11:56:06 martinea Exp $
+ * $Id: tapetype.c,v 1.27 2006/08/24 01:57:16 paddy_s Exp $
*
* tests a tape in a given tape unit and prints a tapetype entry for
* it. */
static char *tapedev;
static int fd;
-static int blockkb = 32;
-static int blocksize;
+static size_t blockkb = 32;
+static size_t blocksize;
static char *randombytes = (char *) NULL;
-static char *prandombytes = (char *) NULL;
#if USE_RAND
/* If the C library does not define random(), try to use rand() by
#define srandom(seed) srand(seed)
#endif
-static void allocrandombytes() {
- int i, j, page_size;
- char *p;
+static char *getrandombytes(void);
+static int writeblock(int fd);
+static off_t writeblocks(int fd, off_t nblks);
+static void allocrandombytes(void);
+static void do_pass0(off_t size, time_t *seconds, int dorewind);
+static void do_pass(off_t size, off_t *blocks, off_t *files, time_t *seconds);
+static void help(void);
+static void initnotrandombytes(void);
+static void initrandombytes(void);
+static void show_progress(off_t *blocks, off_t *files);
+static void usage(void);
+
+int main(int argc, char **argv);
+
+static void
+allocrandombytes(void)
+{
+ size_t i;
+ size_t j;
+ size_t page_size;
+ char *p;
if (randombytes == (char *)NULL) {
#if defined(HAVE_GETPAGESIZE)
- page_size = getpagesize();
+ page_size = (size_t)getpagesize();
#else
- page_size = 1024;
+ page_size = (size_t)1024;
#endif
j = (NBLOCKS * blocksize) + page_size; /* buffer space plus one page */
j = am_round(j, page_size); /* even number of pages */
- p = alloc(j);
- i = (p - (char *)0) & (page_size - 1); /* page boundary offset */
+ p = (char *)alloc(j);
+ i = (size_t)(p - (char *)0) & (page_size - 1);/* page boundary offset */
if(i != 0) {
- randombytes = p + page_size - i; /* round up to page boundary */
+ randombytes = p + (page_size - i); /* round up to page boundary */
} else {
randombytes = p; /* alloc already on boundary */
}
- prandombytes = p;
}
}
-static void initnotrandombytes() {
- int i, j;
+static void
+initnotrandombytes(void)
+{
+ unsigned long i;
+ unsigned long j;
char *p;
allocrandombytes();
- j =NBLOCKS * blocksize;
+ j = NBLOCKS * blocksize;
p = randombytes;
for(i=0; i < j; ++i) {
*p++ = (char) (i % 256);
}
}
-static void initrandombytes() {
- int i, j;
+static void
+initrandombytes(void)
+{
+ unsigned long i, j;
char *p;
allocrandombytes();
}
}
-static char *getrandombytes() {
- static int counter = 0;
+static char *
+getrandombytes(void)
+{
+ static unsigned long counter = 0;
return randombytes + ((counter++ % NBLOCKS) * blocksize);
}
static int short_write;
-int writeblock(fd)
- int fd;
+static int
+writeblock(
+ int fd)
{
- size_t w;
+ ssize_t w;
- if ((w = tapefd_write(fd, getrandombytes(), blocksize)) == blocksize) {
+ if ((w = tapefd_write(fd, getrandombytes(), blocksize)) == (ssize_t)blocksize) {
return 1;
}
if (w >= 0) {
/* returns number of blocks actually written */
-size_t writeblocks(int fd, size_t nblks)
+static off_t
+writeblocks(
+ int fd,
+ off_t nblks)
{
- size_t blks = 0;
+ off_t blks = (off_t)0;
while (blks < nblks) {
if (! writeblock(fd)) {
- return 0;
+ return (off_t)0;
}
- blks++;
+ blks += (off_t)1;
}
return blks;
}
-void usage()
+static void
+usage(void)
{
fputs("usage: ", stderr);
fputs(sProgName, stderr);
fputs(" [-c]", stderr);
fputs(" [-o]", stderr);
fputs(" [-b blocksize]", stderr);
- fputs(" [-e estsize]", stderr);
+ fputs(" -e estsize", stderr);
fputs(" [-f tapedev]", stderr);
fputs(" [-t typename]", stderr);
fputc('\n', stderr);
}
-void help()
+static void
+help(void)
{
usage();
- fputs("\
- -h display this message\n\
- -c run hardware compression detection test only\n\
- -o overwrite amanda tape\n\
- -b blocksize record block size (default: 32k)\n\
- -e estsize estimated tape size (default: 1g == 1024m)\n\
- -f tapedev tape device name (default: $TAPE)\n\
- -t typename tapetype name (default: unknown-tapetype)\n\
-\n\
-Note: disable hardware compression when running this program.\n\
-", stderr);
+ fputs("-h display this message\n"
+ "-c run hardware compression detection test only\n"
+ "-o overwrite amanda tape\n"
+ "-b blocksize record block size (default: 32k)\n"
+ "-e estsize estimated tape size (No default!)\n"
+ "-f tapedev tape device name (default: $TAPE)\n"
+ "-t typename tapetype name (default: unknown-tapetype)\n"
+ "\n"
+ "Note: disable hardware compression when running this program.\n",
+ stderr);
}
int do_tty;
-void show_progress(blocks, files)
- size_t *blocks, *files;
+static void
+show_progress(
+ off_t * blocks,
+ off_t * files)
{
- fprintf(stderr, "wrote %ld %dKb block%s in %ld file%s",
- (long)*blocks, blockkb, (*blocks == 1) ? "" : "s",
- (long)*files, (*files == 1) ? "" : "s");
+ fprintf(stderr, "wrote " OFF_T_FMT " " SIZE_T_FMT "Kb block%s in " OFF_T_FMT " file%s",
+ (OFF_T_FMT_TYPE)*blocks,
+ (SIZE_T_FMT_TYPE)blockkb, (*blocks == (off_t)1) ? "" : "s",
+ (OFF_T_FMT_TYPE)*files, (*files == (off_t)1) ? "" : "s");
}
-void do_pass(size, blocks, files, seconds)
- size_t size, *blocks, *files;
- time_t *seconds;
+static void
+do_pass(
+ off_t size,
+ off_t * blocks,
+ off_t * files,
+ time_t * seconds)
{
- size_t blks;
+ off_t blks;
time_t start, end;
int save_errno;
while(1) {
- if ((blks = writeblocks(fd, size)) <= 0 || tapefd_weof(fd, 1) != 0)
+ if ((blks = writeblocks(fd, size)) <= (off_t)0 || tapefd_weof(fd, (off_t)1) != 0)
break;
*blocks += blks;
- (*files)++;
+ *files += (off_t)1;
if(do_tty) {
putc('\r', stderr);
show_progress(blocks, files);
time(&end);
- if (*blocks == 0) {
+ if (*blocks == (off_t)0) {
fprintf(stderr, "%s: could not write any data in this pass: %s\n",
sProgName, short_write ? "short write" : strerror(save_errno));
exit(1);
putc('\r', stderr);
}
show_progress(blocks, files);
- fprintf(stderr, " in %ld second%s (%s)\n",
- (long)*seconds, ((long)*seconds == 1) ? "" : "s",
+ fprintf(stderr, " in " TIME_T_FMT " second%s (%s)\n",
+ (TIME_T_FMT_TYPE)*seconds, (*seconds == 1) ? "" : "s",
short_write ? "short write" : strerror(save_errno));
}
-void do_pass0(size, seconds, dorewind)
- size_t size;
- time_t *seconds;
- int dorewind;
+static void
+do_pass0(
+ off_t size,
+ time_t * seconds,
+ int dorewind)
{
- size_t blks;
+ off_t blks;
time_t start, end;
int save_errno;
time(&start);
blks = writeblocks(fd, size);
- tapefd_weof(fd, 1);
+ tapefd_weof(fd, (off_t)1);
save_errno = errno;
time(&end);
- if (blks <= 0) {
+ if (blks <= (off_t)0) {
fprintf(stderr, "%s: could not write any data in this pass: %s\n",
sProgName, short_write ? "short write" : strerror(save_errno));
exit(1);
}
-int main(argc, argv)
- int argc;
- char *argv[];
+int
+main(
+ int argc,
+ char ** argv)
{
- size_t pass1blocks = 0;
- size_t pass2blocks = 0;
+ off_t pass1blocks = (off_t)0;
+ off_t pass2blocks = (off_t)0;
time_t pass1time;
time_t pass2time;
time_t timediff;
- size_t pass1files = 0;
- size_t pass2files = 0;
- size_t estsize;
- size_t pass0size;
- size_t pass1size;
- size_t pass2size;
- size_t blockdiff;
- size_t filediff;
- long filemark;
- long speed;
- size_t size;
+ off_t pass1files = (off_t)0;
+ off_t pass2files = (off_t)0;
+ off_t estsize;
+ off_t pass0size;
+ off_t pass1size;
+ off_t pass2size;
+ off_t blockdiff;
+ off_t filediff;
+ size_t filemark;
+ unsigned long speed;
+ off_t size;
char *sizeunits;
int ch;
- char *suffix;
+ char *suffix = NULL;
char *typename;
time_t now;
int hwcompr = 0;
/* Don't die when child closes pipe */
signal(SIGPIPE, SIG_IGN);
- estsize = 1024 * 1024; /* assume 1 GByte for now */
+ estsize = (off_t)0;
tapedev = getenv("TAPE");
typename = "unknown-tapetype";
while ((ch = getopt(argc, argv, "b:e:f:t:hco")) != EOF) {
switch (ch) {
case 'b':
- blockkb = strtol(optarg, &suffix, 0);
- if (*suffix == '\0' || *suffix == 'k' || *suffix == 'K') {
- } else if (*suffix == 'm' || *suffix == 'M') {
- blockkb *= 1024;
- } else if (*suffix == 'g' || *suffix == 'G') {
- blockkb *= 1024 * 1024;
- } else {
- fprintf(stderr, "%s: unknown size suffix \'%c\'\n", sProgName, *suffix);
- return 1;
+ blockkb = (size_t)strtol(optarg, &suffix, 0);
+ if (!(*suffix == '\0' || *suffix == 'k' || *suffix == 'K')) {
+ if (*suffix == 'm' || *suffix == 'M') {
+ blockkb *= 1024;
+ } else if (*suffix == 'g' || *suffix == 'G') {
+ blockkb *= (1024 * 1024);
+ } else {
+ fprintf(stderr, "%s: unknown size suffix \'%c\'\n",
+ sProgName, *suffix);
+ return 1;
+ }
}
break;
case 'e':
- estsize = strtol(optarg, &suffix, 0);
- if (*suffix == '\0' || *suffix == 'k' || *suffix == 'K') {
- } else if (*suffix == 'm' || *suffix == 'M') {
- estsize *= 1024;
- } else if (*suffix == 'g' || *suffix == 'G') {
- estsize *= 1024 * 1024;
- } else {
- fprintf(stderr, "%s: unknown size suffix \'%c\'\n", sProgName, *suffix);
- return 1;
+ estsize = OFF_T_STRTOL(optarg, &suffix, 0);
+ if (!(*suffix == '\0' || *suffix == 'k' || *suffix == 'K')) {
+ if (*suffix == 'm' || *suffix == 'M') {
+ estsize *= (off_t)1024;
+ } else if (*suffix == 'g' || *suffix == 'G') {
+ estsize *= (off_t)(1024 * 1024);
+ } else {
+ fprintf(stderr, "%s: unknown size suffix \'%c\'\n",
+ sProgName, *suffix);
+ return 1;
+ }
}
break;
+
case 'f':
tapedev = stralloc(optarg);
break;
+
case 't':
typename = stralloc(optarg);
break;
+
case 'c':
comprtstonly = 1;
break;
+
case 'h':
help();
return 1;
- break;
+
case 'o':
overwrite_label=1;
break;
+
default:
fprintf(stderr, "%s: unknown option \'%c\'\n", sProgName, ch);
- /* fall through to ... */
+ /*FALLTHROUGH*/
+
case '?':
usage();
return 1;
- break;
}
}
blocksize = blockkb * 1024;
- if (tapedev == NULL || optind < argc) {
+ if (tapedev == NULL) {
+ fprintf(stderr, "%s: No tapedev specified\n", sProgName);
+ usage();
+ return 1;
+ }
+ if (optind < argc) {
usage();
return 1;
}
+ if (estsize == 0) {
+ if (comprtstonly) {
+ estsize = (off_t)(1024 * 1024); /* assume 1 GByte for now */
+ } else {
+ fprintf(stderr, "%s: please specify estimated tape capacity (e.g. '-e 4g')\n", sProgName);
+ usage();
+ return 1;
+ }
+ }
+
+
/* verifier tape */
- fd = tape_open(tapedev, O_RDONLY);
+ fd = tape_open(tapedev, O_RDONLY, 0);
if (fd == -1) {
fprintf(stderr, "%s: could not open %s: %s\n",
sProgName, tapedev, strerror(errno));
return 1;
}
- fd = tape_open(tapedev, O_RDWR);
+ fd = tape_open(tapedev, O_RDWR, 0);
if (fd == -1) {
fprintf(stderr, "%s: could not open %s: %s\n",
sProgName, tapedev, strerror(errno));
initnotrandombytes();
fprintf(stderr, "Estimate phase 1...");
- pass0size = 8 * 1024 / blockkb;
+ pass0size = (off_t)(8 * 1024 / blockkb);
pass1time = 0;
pass2time = 0;
/*
*/
while (pass1time < 25 || ((100*(pass2time-pass1time)/pass2time) >= 10) ) {
if (pass1time != 0) {
- int i = pass1time;
+ time_t t = pass1time;
do {
- pass0size *= 2;
- i *= 2;
- } while (i < 25);
+ pass0size *= (off_t)2;
+ t *= 2;
+ } while (t < 25);
}
/*
* first a dummy pass to rewind, stop, start and
*/
do_pass0(pass0size, &pass2time, 1);
do_pass0(pass0size, &pass1time, 0);
- if (pass0size >= 10 * 1024 * 1024) {
+ if (pass0size >= (off_t)(10 * 1024 * 1024)) {
fprintf(stderr,
"\rTape device is too fast to detect hardware compression...\n");
break; /* avoid loops if tape is superfast or broken */
}
}
- fprintf(stderr, "\rWriting %d Mbyte compresseable data: %d sec\n",
- (int)(blockkb * pass0size / 1024), (int)pass1time);
+ fprintf(stderr,
+ "\rWriting " OFF_T_FMT " Mbyte compresseable data: "
+ TIME_T_FMT " sec\n",
+ (OFF_T_FMT_TYPE)((off_t)blockkb * pass0size / (off_t)1024),
+ (TIME_T_FMT_TYPE)pass1time);
/*
* now generate uncompressable data and try again
*/
time(&now);
- srandom(now);
+ srandom((unsigned)now);
initrandombytes();
fprintf(stderr, "Estimate phase 2...");
do_pass0(pass0size, &pass2time, 1); /* rewind and get drive streaming */
do_pass0(pass0size, &pass2time, 0);
- fprintf(stderr, "\rWriting %d Mbyte uncompresseable data: %d sec\n",
- (int)(blockkb * pass0size / 1024), (int)pass2time);
+ fprintf(stderr, "\rWriting " OFF_T_FMT
+ " Mbyte uncompresseable data: " TIME_T_FMT " sec\n",
+ (OFF_T_FMT_TYPE)((off_t)blockkb * pass0size / (off_t)1024),
+ (TIME_T_FMT_TYPE)pass2time);
/*
* Compute the time difference between writing the compressable and
/*
* Inform about estimated time needed to run the remaining of this program
*/
- fprintf(stderr, "Estimated time to write 2 * %lu Mbyte: ", (unsigned long) (estsize / 1024));
- pass1time = (time_t)(2.0 * pass2time * estsize / (1.0 * pass0size * blockkb));
+ fprintf(stderr, "Estimated time to write 2 * %lu Mbyte: ", (unsigned long) (estsize / (off_t)1024));
+ pass1time = (time_t)(2.0 * (double)pass2time * (double)estsize /
+ (1.0 * (double)pass0size * (double)blockkb));
/* avoid overflow and underflow by doing math in floating point */
- fprintf(stderr, "%ld sec = ", pass1time);
- fprintf(stderr, "%ld h %ld min\n", (pass1time/3600), ((pass1time%3600) / 60));
+ fprintf(stderr, TIME_T_FMT " sec = ",
+ (TIME_T_FMT_TYPE)pass1time);
+ fprintf(stderr, TIME_T_FMT " h " TIME_T_FMT " min\n",
+ (TIME_T_FMT_TYPE)(pass1time/(time_t)3600),
+ (TIME_T_FMT_TYPE)((pass1time%(time_t)3600) / (time_t)60));
if (comprtstonly) {
exit(hwcompr);
/*
* Do pass 1 -- write files that are 1% of the estimated size until error.
*/
- pass1size = (estsize * 0.01) / blockkb; /* 1% of estimate */
- if(pass1size <= 0) {
- pass1size = 2; /* strange end case */
+ pass1size = (off_t)(((double)estsize * 0.01) / (double)blockkb); /* 1% of estimate */
+ if(pass1size <= (off_t)0) {
+ pass1size = (off_t)2; /* strange end case */
}
do_pass(pass1size, &pass1blocks, &pass1files, &pass1time);
/*
* Do pass 2 -- write smaller files until error.
*/
- pass2size = pass1size / 2;
+ pass2size = pass1size / (off_t)2;
do_pass(pass2size, &pass2blocks, &pass2files, &pass2time);
/*
* 2 than in pass 1 since we wrote twice as many tape marks. But
* odd things happen, so make sure the result does not go negative.
*/
- blockdiff = 0;
+ blockdiff = (off_t)0;
} else {
blockdiff = pass1blocks - pass2blocks;
}
/*
* This should not happen, but just in case ...
*/
- filediff = 1;
+ filediff = (off_t)1;
} else {
filediff = pass2files - pass1files;
}
- filemark = blockdiff * blockkb / filediff;
+ filemark = (size_t)((blockdiff * (off_t)blockkb) / filediff);
/*
* Compute the length as the average of the two pass sizes including
* tape marks.
*/
- size = ((pass1blocks * blockkb + filemark * pass1files)
- + (pass2blocks * blockkb + filemark * pass2files)) / 2;
- if (size >= 1024 * 1024 * 1000) {
- size /= 1024 * 1024;
+ size = ((pass1blocks * (off_t)blockkb + (off_t)filemark * pass1files)
+ + (pass2blocks * (off_t)blockkb + (off_t)filemark * pass2files))
+ / (off_t)2;
+ if (size >= (off_t)(1024 * 1024 * 1000)) {
+ size /= (off_t)(1024 * 1024);
sizeunits = "gbytes";
- } else if (size >= 1024 * 1000) {
- size /= 1024;
+ } else if (size >= (off_t)(1024 * 1000)) {
+ size /= (off_t)1024;
sizeunits = "mbytes";
} else {
sizeunits = "kbytes";
/*
* Compute the speed as the average of the two passes.
*/
- speed = (((double)pass1blocks * blockkb / pass1time)
- + ((double)pass2blocks * blockkb / pass2time)) / 2;
+ speed = (unsigned long)((((double)pass1blocks
+ * (double)blockkb / (double)pass1time)
+ + ((double)pass2blocks * (double)blockkb / (double)pass2time)) / 2.0);
/*
* Dump the tapetype.
printf("define tapetype %s {\n", typename);
printf(" comment \"just produced by tapetype prog (hardware compression %s)\"\n",
hwcompr ? "on" : "off");
- printf(" length %ld %s\n", (long)size, sizeunits);
- printf(" filemark %ld kbytes\n", filemark);
- printf(" speed %ld kps\n", speed);
+ printf(" length " OFF_T_FMT " %s\n", (OFF_T_FMT_TYPE)size, sizeunits);
+ printf(" filemark " SIZE_T_FMT " kbytes\n", (SIZE_T_FMT_TYPE)filemark);
+ printf(" speed %lu kps\n", speed);
printf("}\n");
if (tapefd_rewind(fd) == -1) {
fprintf(stderr, "%s: could not rewind %s: %s\n",
sProgName, tapedev, strerror(errno));
- free(randombytes);
return 1;
}
if (tapefd_close(fd) == -1) {
fprintf(stderr, "%s: could not close %s: %s\n",
sProgName, tapedev, strerror(errno));
- free(randombytes);
return 1;
}
- free(randombytes);
return 0;
}