From cbada87866289948aa30bf5436b3c187f3a7fb65 Mon Sep 17 00:00:00 2001 From: Kern Sibbald Date: Thu, 26 Feb 2004 21:37:47 +0000 Subject: [PATCH] mtimeonly and keepatime in Include + first cut disk seeking + test win32 installer git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@1090 91ce42f0-d328-0410-95d8-f526ca767f89 --- bacula/kernstodo | 4 +- bacula/src/dird/inc_conf.c | 8 ++ bacula/src/filed/backup.c | 2 +- bacula/src/filed/estimate.c | 2 +- bacula/src/filed/job.c | 2 - bacula/src/filed/verify.c | 2 +- bacula/src/findlib/find.c | 4 +- bacula/src/findlib/find.h | 12 +- bacula/src/findlib/find_one.c | 246 +++++++++++++++++----------------- bacula/src/findlib/match.c | 6 + bacula/src/findlib/protos.h | 24 ++-- bacula/src/jcr.h | 1 - bacula/src/lib/edit.c | 31 ++--- bacula/src/stored/block.c | 70 +++++----- bacula/src/stored/dev.c | 4 + bacula/src/stored/dev.h | 1 + bacula/src/version.h | 4 +- bacula/src/win32/README.win32 | 29 ++++ bacula/src/win32/params.nsh | 104 ++++++++++++++ bacula/src/win32/util.nsh | 94 ++++++------- 20 files changed, 398 insertions(+), 252 deletions(-) create mode 100644 bacula/src/win32/README.win32 create mode 100644 bacula/src/win32/params.nsh diff --git a/bacula/kernstodo b/bacula/kernstodo index b864cc3317..9480d9e151 100644 --- a/bacula/kernstodo +++ b/bacula/kernstodo @@ -71,6 +71,9 @@ For 1.33 Testing/Documentation: http://howtos.linux.com/guides/nag2/x-087-2-nfs.mountd.shtml For 1.33 +- Add a regression test for dbcheck. +- Add disk seeking on restore. +- Add atime preservation. - Allow for optional cancelling of SD and FD in case DIR gets a fatal error. Requested by Jesse Guardiani - Remove h_errno from bnet.c by including proper header. @@ -1389,4 +1392,3 @@ Block Position: 0 - Look at ASSERT() at 384 src/lib/bnet.c - Dates are wrong in restore list from Win32 FD. - Dates are wrong in catalog from Win32 FD. - diff --git a/bacula/src/dird/inc_conf.c b/bacula/src/dird/inc_conf.c index 2f22866902..9d09e1a535 100644 --- a/bacula/src/dird/inc_conf.c +++ b/bacula/src/dird/inc_conf.c @@ -85,6 +85,8 @@ static struct res_items newinc_items[] = { #define INC_KW_REPLACE 8 /* restore options */ #define INC_KW_READFIFO 9 /* Causes fifo data to be read */ #define INC_KW_PORTABLE 10 +#define INC_KW_MTIMEONLY 11 +#define INC_KW_KEEPATIME 12 /* Include keywords -- these are keywords that can appear * in the options lists of an old include ( Include = compression= ...) @@ -100,6 +102,8 @@ static struct s_kw FS_option_kw[] = { {"replace", INC_KW_REPLACE}, {"readfifo", INC_KW_READFIFO}, {"portable", INC_KW_PORTABLE}, + {"mtimeonly", INC_KW_MTIMEONLY}, + {"keepatime", INC_KW_KEEPATIME}, {NULL, 0} }; @@ -145,6 +149,10 @@ static struct s_fs_opt FS_options[] = { {"no", INC_KW_READFIFO, "0"}, {"yes", INC_KW_PORTABLE, "p"}, {"no", INC_KW_PORTABLE, "0"}, + {"yes", INC_KW_MTIMEONLY, "m"}, + {"no", INC_KW_MTIMEONLY, "0"}, + {"yes", INC_KW_KEEPATIME, "k"}, + {"no", INC_KW_KEEPATIME, "0"}, {NULL, 0, 0} }; diff --git a/bacula/src/filed/backup.c b/bacula/src/filed/backup.c index e42d2dab79..37d598ea54 100644 --- a/bacula/src/filed/backup.c +++ b/bacula/src/filed/backup.c @@ -80,7 +80,7 @@ int blast_data_to_storage_daemon(JCR *jcr, char *addr) jcr->compress_buf = get_memory(jcr->compress_buf_size); Dmsg1(100, "set_find_options ff=%p\n", jcr->ff); - set_find_options((FF_PKT *)jcr->ff, jcr->incremental, jcr->mtime, jcr->mtime_only); + set_find_options((FF_PKT *)jcr->ff, jcr->incremental, jcr->mtime); Dmsg0(110, "start find files\n"); start_heartbeat_monitor(jcr); diff --git a/bacula/src/filed/estimate.c b/bacula/src/filed/estimate.c index 679f9fe4eb..39650087fe 100644 --- a/bacula/src/filed/estimate.c +++ b/bacula/src/filed/estimate.c @@ -41,7 +41,7 @@ int make_estimate(JCR *jcr) jcr->JobStatus = JS_Running; - set_find_options((FF_PKT *)jcr->ff, jcr->incremental, jcr->mtime, jcr->mtime_only); + set_find_options((FF_PKT *)jcr->ff, jcr->incremental, jcr->mtime); stat = find_files(jcr, (FF_PKT *)jcr->ff, tally_file, (void *)jcr); return stat; diff --git a/bacula/src/filed/job.c b/bacula/src/filed/job.c index b3890910bd..cdd886d65b 100644 --- a/bacula/src/filed/job.c +++ b/bacula/src/filed/job.c @@ -627,7 +627,6 @@ static int level_cmd(JCR *jcr) Dmsg2(100, "Got since time: %s mtime_only=%d\n", ctime(&mtime), mtime_only); jcr->incremental = 1; /* set incremental or decremental backup */ jcr->mtime = mtime; /* set since time */ - jcr->mtime_only = mtime_only; /* and what to compare */ /* * We get his UTC since time, then sync the clocks and correct it * to agree with our clock. @@ -677,7 +676,6 @@ static int level_cmd(JCR *jcr) Dmsg2(100, "adj = %d since_time=%d\n", (int)adj, (int)since_time); jcr->incremental = 1; /* set incremental or decremental backup */ jcr->mtime = since_time; /* set since time */ - jcr->mtime_only = mtime_only; /* and what to compare */ } else { Jmsg1(jcr, M_FATAL, 0, "Unknown backup level: %s\n", level); free_memory(level); diff --git a/bacula/src/filed/verify.c b/bacula/src/filed/verify.c index d094d0bb91..bf65d87597 100644 --- a/bacula/src/filed/verify.c +++ b/bacula/src/filed/verify.c @@ -44,7 +44,7 @@ void do_verify(JCR *jcr) Jmsg1(jcr, M_ABORT, 0, _("Cannot malloc %d network read buffer\n"), DEFAULT_NETWORK_BUFFER_SIZE); } - set_find_options((FF_PKT *)jcr->ff, jcr->incremental, jcr->mtime, jcr->mtime_only); + set_find_options((FF_PKT *)jcr->ff, jcr->incremental, jcr->mtime); Dmsg0(10, "Start find files\n"); /* Subroutine verify_file() is called for each file */ find_files(jcr, (FF_PKT *)jcr->ff, verify_file, (void *)jcr); diff --git a/bacula/src/findlib/find.c b/bacula/src/findlib/find.c index 9a52dbd4c4..9db0ed8c18 100644 --- a/bacula/src/findlib/find.c +++ b/bacula/src/findlib/find.c @@ -51,7 +51,6 @@ FF_PKT *init_find_files() ff->sys_fname = get_pool_memory(PM_FNAME); init_include_exclude_files(ff); /* init lists */ - ff->mtime_only = 0; /* use both st_mtime and st_ctime */ /* Get system path and filename maximum lengths */ path_max = pathconf(".", _PC_PATH_MAX); @@ -76,12 +75,11 @@ FF_PKT *init_find_files() * of save_time. For additional options, see above */ void -set_find_options(FF_PKT *ff, int incremental, time_t save_time, int mtime_only) +set_find_options(FF_PKT *ff, int incremental, time_t save_time) { Dmsg0(100, "Enter set_find_options()\n"); ff->incremental = incremental; ff->save_time = save_time; - ff->mtime_only = mtime_only; Dmsg0(100, "Leave set_find_options()\n"); } diff --git a/bacula/src/findlib/find.h b/bacula/src/findlib/find.h index 7251b7f03e..3f3b1b900d 100755 --- a/bacula/src/findlib/find.h +++ b/bacula/src/findlib/find.h @@ -83,6 +83,8 @@ enum { #define FO_READFIFO (1<<8) /* read data from fifo */ #define FO_SHA1 (1<<9) /* Do SHA1 checksum */ #define FO_PORTABLE (1<<10) /* Use portable data format -- no BackupWrite */ +#define FO_MTIMEONLY (1<<11) /* Use mtime rather than mtime & ctime */ +#define FO_KEEPATIME (1<<12) /* Reset access time */ struct s_included_file { struct s_included_file *next; @@ -114,16 +116,14 @@ struct FF_PKT { int32_t LinkFI; /* FileIndex of main hard linked file */ struct f_link *linked; /* Set if this file is hard linked */ int type; /* FT_ type from above */ - uint32_t flags; /* control flags */ + uint32_t flags; /* backup options */ int ff_errno; /* errno */ - int incremental; /* do incremental save */ BFILE bfd; /* Bacula file descriptor */ time_t save_time; /* start of incremental time */ - int mtime_only; /* incremental on mtime_only */ - int dereference; /* follow links */ + bool dereference; /* follow links (not implemented) */ + bool null_output_device; /* using null output device */ + bool incremental; /* incremental save */ int GZIP_level; /* compression level */ - int atime_preserve; /* preserve access times */ - int null_output_device; /* using null output device */ char VerifyOpts[20]; struct s_included_file *included_files_list; struct s_excluded_file *excluded_files_list; diff --git a/bacula/src/findlib/find_one.c b/bacula/src/findlib/find_one.c index ef5f4bc860..cc3f5be47c 100755 --- a/bacula/src/findlib/find_one.c +++ b/bacula/src/findlib/find_one.c @@ -28,8 +28,8 @@ #include "bacula.h" #include "find.h" -extern int32_t name_max; /* filename max length */ -extern int32_t path_max; /* path name max length */ +extern int32_t name_max; /* filename max length */ +extern int32_t path_max; /* path name max length */ /* * Structure for keeping track of hard linked files, we @@ -40,11 +40,11 @@ extern int32_t path_max; /* path name max length */ */ struct f_link { struct f_link *next; - dev_t dev; /* device */ - ino_t ino; /* inode with device is unique */ + dev_t dev; /* device */ + ino_t ino; /* inode with device is unique */ short linkcount; - uint32_t FileIndex; /* Bacula FileIndex of this file */ - char name[1]; /* The name */ + uint32_t FileIndex; /* Bacula FileIndex of this file */ + char name[1]; /* The name */ }; static void free_dir_ff_pkt(FF_PKT *dir_ff_pkt) @@ -56,7 +56,7 @@ static void free_dir_ff_pkt(FF_PKT *dir_ff_pkt) } /* - * Find a single file. + * Find a single file. * handle_file is the callback for handling the file. * p is the filename * parent_device is the device we are currently on @@ -65,7 +65,7 @@ static void free_dir_ff_pkt(FF_PKT *dir_ff_pkt) */ int find_one_file(JCR *jcr, FF_PKT *ff_pkt, int handle_file(FF_PKT *ff, void *hpkt), - void *pkt, char *fname, dev_t parent_device, int top_level) + void *pkt, char *fname, dev_t parent_device, int top_level) { struct utimbuf restore_times; int rtn_stat; @@ -97,11 +97,11 @@ find_one_file(JCR *jcr, FF_PKT *ff_pkt, int handle_file(FF_PKT *ff, void *hpkt), Dmsg1(300, "Non-directory incremental: %s\n", ff_pkt->fname); /* Not a directory */ if (ff_pkt->statp.st_mtime < ff_pkt->save_time - && (ff_pkt->mtime_only || - ff_pkt->statp.st_ctime < ff_pkt->save_time)) { - /* Incremental option, file not changed */ - ff_pkt->type = FT_NOCHG; - return handle_file(ff_pkt, pkt); + && ((ff_pkt->flags & FO_MTIMEONLY) || + ff_pkt->statp.st_ctime < ff_pkt->save_time)) { + /* Incremental option, file not changed */ + ff_pkt->type = FT_NOCHG; + return handle_file(ff_pkt, pkt); } } @@ -123,21 +123,21 @@ find_one_file(JCR *jcr, FF_PKT *ff_pkt, int handle_file(FF_PKT *ff, void *hpkt), */ if (ff_pkt->statp.st_nlink > 1 && (S_ISREG(ff_pkt->statp.st_mode) - || S_ISCHR(ff_pkt->statp.st_mode) - || S_ISBLK(ff_pkt->statp.st_mode) - || S_ISFIFO(ff_pkt->statp.st_mode) - || S_ISSOCK(ff_pkt->statp.st_mode))) { + || S_ISCHR(ff_pkt->statp.st_mode) + || S_ISBLK(ff_pkt->statp.st_mode) + || S_ISFIFO(ff_pkt->statp.st_mode) + || S_ISSOCK(ff_pkt->statp.st_mode))) { struct f_link *lp; /* Search link list of hard linked files */ for (lp = ff_pkt->linklist; lp; lp = lp->next) - if (lp->ino == ff_pkt->statp.st_ino && lp->dev == ff_pkt->statp.st_dev) { - ff_pkt->link = lp->name; - ff_pkt->type = FT_LNKSAVED; /* Handle link, file already saved */ - ff_pkt->LinkFI = lp->FileIndex; - return handle_file(ff_pkt, pkt); - } + if (lp->ino == ff_pkt->statp.st_ino && lp->dev == ff_pkt->statp.st_dev) { + ff_pkt->link = lp->name; + ff_pkt->type = FT_LNKSAVED; /* Handle link, file already saved */ + ff_pkt->LinkFI = lp->FileIndex; + return handle_file(ff_pkt, pkt); + } /* File not previously dumped. Chain it into our list. */ lp = (struct f_link *)bmalloc(sizeof(struct f_link) + strlen(fname) +1); @@ -146,7 +146,7 @@ find_one_file(JCR *jcr, FF_PKT *ff_pkt, int handle_file(FF_PKT *ff, void *hpkt), strcpy(lp->name, fname); lp->next = ff_pkt->linklist; ff_pkt->linklist = lp; - ff_pkt->linked = lp; /* mark saved link */ + ff_pkt->linked = lp; /* mark saved link */ } else { ff_pkt->linked = NULL; } @@ -158,16 +158,16 @@ find_one_file(JCR *jcr, FF_PKT *ff_pkt, int handle_file(FF_PKT *ff, void *hpkt), sizeleft = ff_pkt->statp.st_size; /* Don't bother opening empty, world readable files. Also do not open - files when archive is meant for /dev/null. */ + files when archive is meant for /dev/null. */ if (ff_pkt->null_output_device || (sizeleft == 0 - && MODE_RALL == (MODE_RALL & ff_pkt->statp.st_mode))) { - ff_pkt->type = FT_REGE; + && MODE_RALL == (MODE_RALL & ff_pkt->statp.st_mode))) { + ff_pkt->type = FT_REGE; } else { - ff_pkt->type = FT_REG; + ff_pkt->type = FT_REG; } rtn_stat = handle_file(ff_pkt, pkt); if (ff_pkt->linked) { - ff_pkt->linked->FileIndex = ff_pkt->FileIndex; + ff_pkt->linked->FileIndex = ff_pkt->FileIndex; } return rtn_stat; @@ -178,21 +178,21 @@ find_one_file(JCR *jcr, FF_PKT *ff_pkt, int handle_file(FF_PKT *ff, void *hpkt), size = readlink(fname, buffer, path_max + name_max + 101); if (size < 0) { - /* Could not follow link */ - ff_pkt->type = FT_NOFOLLOW; - ff_pkt->ff_errno = errno; - rtn_stat = handle_file(ff_pkt, pkt); - if (ff_pkt->linked) { - ff_pkt->linked->FileIndex = ff_pkt->FileIndex; - } - return rtn_stat; + /* Could not follow link */ + ff_pkt->type = FT_NOFOLLOW; + ff_pkt->ff_errno = errno; + rtn_stat = handle_file(ff_pkt, pkt); + if (ff_pkt->linked) { + ff_pkt->linked->FileIndex = ff_pkt->FileIndex; + } + return rtn_stat; } buffer[size] = 0; - ff_pkt->link = buffer; /* point to link */ - ff_pkt->type = FT_LNK; /* got a real link */ + ff_pkt->link = buffer; /* point to link */ + ff_pkt->type = FT_LNK; /* got a real link */ rtn_stat = handle_file(ff_pkt, pkt); if (ff_pkt->linked) { - ff_pkt->linked->FileIndex = ff_pkt->FileIndex; + ff_pkt->linked->FileIndex = ff_pkt->FileIndex; } return rtn_stat; @@ -201,7 +201,7 @@ find_one_file(JCR *jcr, FF_PKT *ff_pkt, int handle_file(FF_PKT *ff, void *hpkt), struct dirent *entry, *result; char *link; int link_len; - int len; + int len; int status; dev_t our_device = ff_pkt->statp.st_dev; @@ -211,16 +211,16 @@ find_one_file(JCR *jcr, FF_PKT *ff_pkt, int handle_file(FF_PKT *ff, void *hpkt), * in principle, we should be able to access everything. */ if (!have_win32_api() || (ff_pkt->flags & FO_PORTABLE)) { - if (access(fname, R_OK) == -1 && geteuid() != 0) { - /* Could not access() directory */ - ff_pkt->type = FT_NOACCESS; - ff_pkt->ff_errno = errno; - rtn_stat = handle_file(ff_pkt, pkt); - if (ff_pkt->linked) { - ff_pkt->linked->FileIndex = ff_pkt->FileIndex; - } - return rtn_stat; - } + if (access(fname, R_OK) == -1 && geteuid() != 0) { + /* Could not access() directory */ + ff_pkt->type = FT_NOACCESS; + ff_pkt->ff_errno = errno; + rtn_stat = handle_file(ff_pkt, pkt); + if (ff_pkt->linked) { + ff_pkt->linked->FileIndex = ff_pkt->FileIndex; + } + return rtn_stat; + } } /* Build a canonical directory name with a trailing slash in link var */ @@ -230,18 +230,18 @@ find_one_file(JCR *jcr, FF_PKT *ff_pkt, int handle_file(FF_PKT *ff, void *hpkt), bstrncpy(link, fname, link_len); /* Strip all trailing slashes */ while (len >= 1 && link[len - 1] == '/') - len--; + len--; link[len++] = '/'; /* add back one */ link[len] = 0; ff_pkt->link = link; if (ff_pkt->incremental && - (ff_pkt->statp.st_mtime < ff_pkt->save_time && - ff_pkt->statp.st_ctime < ff_pkt->save_time)) { - /* Incremental option, directory entry not changed */ - ff_pkt->type = FT_DIRNOCHG; + (ff_pkt->statp.st_mtime < ff_pkt->save_time && + ff_pkt->statp.st_ctime < ff_pkt->save_time)) { + /* Incremental option, directory entry not changed */ + ff_pkt->type = FT_DIRNOCHG; } else { - ff_pkt->type = FT_DIR; + ff_pkt->type = FT_DIR; } /* @@ -262,7 +262,7 @@ find_one_file(JCR *jcr, FF_PKT *ff_pkt, int handle_file(FF_PKT *ff, void *hpkt), dir_ff_pkt->excluded_files_list = NULL; dir_ff_pkt->excluded_paths_list = NULL; dir_ff_pkt->linklist = NULL; - + ff_pkt->link = ff_pkt->fname; /* reset "link" */ /* @@ -270,15 +270,15 @@ find_one_file(JCR *jcr, FF_PKT *ff_pkt, int handle_file(FF_PKT *ff, void *hpkt), * user has turned it off for this directory. */ if (ff_pkt->flags & FO_NO_RECURSION) { - /* No recursion into this directory */ - ff_pkt->type = FT_NORECURSE; - rtn_stat = handle_file(ff_pkt, pkt); - if (ff_pkt->linked) { - ff_pkt->linked->FileIndex = ff_pkt->FileIndex; - } - free(link); - free_dir_ff_pkt(dir_ff_pkt); - return rtn_stat; + /* No recursion into this directory */ + ff_pkt->type = FT_NORECURSE; + rtn_stat = handle_file(ff_pkt, pkt); + if (ff_pkt->linked) { + ff_pkt->linked->FileIndex = ff_pkt->FileIndex; + } + free(link); + free_dir_ff_pkt(dir_ff_pkt); + return rtn_stat; } /* @@ -286,16 +286,16 @@ find_one_file(JCR *jcr, FF_PKT *ff_pkt, int handle_file(FF_PKT *ff, void *hpkt), * avoid doing so if the user only wants to dump one file system. */ if (!top_level && !(ff_pkt->flags & FO_MULTIFS) && - parent_device != ff_pkt->statp.st_dev) { - /* returning here means we do not handle this directory */ - ff_pkt->type = FT_NOFSCHG; - rtn_stat = handle_file(ff_pkt, pkt); - if (ff_pkt->linked) { - ff_pkt->linked->FileIndex = ff_pkt->FileIndex; - } - free(link); - free_dir_ff_pkt(dir_ff_pkt); - return rtn_stat; + parent_device != ff_pkt->statp.st_dev) { + /* returning here means we do not handle this directory */ + ff_pkt->type = FT_NOFSCHG; + rtn_stat = handle_file(ff_pkt, pkt); + if (ff_pkt->linked) { + ff_pkt->linked->FileIndex = ff_pkt->FileIndex; + } + free(link); + free_dir_ff_pkt(dir_ff_pkt); + return rtn_stat; } /* * Decend into or "recurse" into the directory to read @@ -303,15 +303,15 @@ find_one_file(JCR *jcr, FF_PKT *ff_pkt, int handle_file(FF_PKT *ff, void *hpkt), */ errno = 0; if ((directory = opendir(fname)) == NULL) { - ff_pkt->type = FT_NOOPEN; - ff_pkt->ff_errno = errno; - rtn_stat = handle_file(ff_pkt, pkt); - if (ff_pkt->linked) { - ff_pkt->linked->FileIndex = ff_pkt->FileIndex; - } - free(link); - free_dir_ff_pkt(dir_ff_pkt); - return rtn_stat; + ff_pkt->type = FT_NOOPEN; + ff_pkt->ff_errno = errno; + rtn_stat = handle_file(ff_pkt, pkt); + if (ff_pkt->linked) { + ff_pkt->linked->FileIndex = ff_pkt->FileIndex; + } + free(link); + free_dir_ff_pkt(dir_ff_pkt); + return rtn_stat; } /* @@ -322,38 +322,38 @@ find_one_file(JCR *jcr, FF_PKT *ff_pkt, int handle_file(FF_PKT *ff, void *hpkt), rtn_stat = 1; entry = (struct dirent *)malloc(sizeof(struct dirent) + name_max + 100); for ( ; !job_canceled(jcr); ) { - char *p, *q; - int i; + char *p, *q; + int i; - status = readdir_r(directory, entry, &result); - if (status != 0 || result == NULL) { + status = readdir_r(directory, entry, &result); + if (status != 0 || result == NULL) { // Dmsg2(99, "readdir returned stat=%d result=0x%x\n", -// status, (long)result); - break; - } - ASSERT(name_max+1 > (int)sizeof(struct dirent) + (int)NAMELEN(entry)); - p = entry->d_name; +// status, (long)result); + break; + } + ASSERT(name_max+1 > (int)sizeof(struct dirent) + (int)NAMELEN(entry)); + p = entry->d_name; /* Skip `.', `..', and excluded file names. */ if (p[0] == '\0' || (p[0] == '.' && (p[1] == '\0' || (p[1] == '.' && p[2] == '\0')))) { - continue; - } - - if ((int)NAMELEN(entry) + len >= link_len) { - link_len = len + NAMELEN(entry) + 1; - link = (char *)brealloc(link, link_len + 1); - } - q = link + len; - for (i=0; i < (int)NAMELEN(entry); i++) { - *q++ = *p++; - } - *q = 0; - if (!file_is_excluded(ff_pkt, link)) { - rtn_stat = find_one_file(jcr, ff_pkt, handle_file, pkt, link, our_device, 0); - if (ff_pkt->linked) { - ff_pkt->linked->FileIndex = ff_pkt->FileIndex; - } - } + continue; + } + + if ((int)NAMELEN(entry) + len >= link_len) { + link_len = len + NAMELEN(entry) + 1; + link = (char *)brealloc(link, link_len + 1); + } + q = link + len; + for (i=0; i < (int)NAMELEN(entry); i++) { + *q++ = *p++; + } + *q = 0; + if (!file_is_excluded(ff_pkt, link)) { + rtn_stat = find_one_file(jcr, ff_pkt, handle_file, pkt, link, our_device, 0); + if (ff_pkt->linked) { + ff_pkt->linked->FileIndex = ff_pkt->FileIndex; + } + } } closedir(directory); free(link); @@ -366,14 +366,14 @@ find_one_file(JCR *jcr, FF_PKT *ff_pkt, int handle_file(FF_PKT *ff, void *hpkt), * the directory modes and dates. Temp directory values * were used without this record. */ - handle_file(dir_ff_pkt, pkt); /* handle directory entry */ + handle_file(dir_ff_pkt, pkt); /* handle directory entry */ if (ff_pkt->linked) { - ff_pkt->linked->FileIndex = dir_ff_pkt->FileIndex; + ff_pkt->linked->FileIndex = dir_ff_pkt->FileIndex; } free_dir_ff_pkt(dir_ff_pkt); - if (ff_pkt->atime_preserve) { - utime(fname, &restore_times); + if (ff_pkt->flags & FO_KEEPATIME) { + utime(fname, &restore_times); } return rtn_stat; } /* end check for directory */ @@ -386,8 +386,8 @@ find_one_file(JCR *jcr, FF_PKT *ff_pkt, int handle_file(FF_PKT *ff, void *hpkt), #ifdef HAVE_FREEBSD_OS /* * On FreeBSD, all block devices are character devices, so - * to be able to read a raw disk, we need the check for - * a character device. + * to be able to read a raw disk, we need the check for + * a character device.     * crw-r-----  1 root  operator  - 116, 0x00040002 Jun  9 19:32 /dev/ad0s3     * crw-r-----  1 root  operator  - 116, 0x00040002 Jun  9 19:32 /dev/rad0s3 */ @@ -395,9 +395,9 @@ find_one_file(JCR *jcr, FF_PKT *ff_pkt, int handle_file(FF_PKT *ff, void *hpkt), #else if (top_level && S_ISBLK(ff_pkt->statp.st_mode)) { #endif - ff_pkt->type = FT_RAW; /* raw partition */ + ff_pkt->type = FT_RAW; /* raw partition */ } else if (top_level && S_ISFIFO(ff_pkt->statp.st_mode) && - ff_pkt->flags & FO_READFIFO) { + ff_pkt->flags & FO_READFIFO) { ff_pkt->type = FT_FIFO; } else { /* The only remaining types are special (character, ...) files */ @@ -420,8 +420,8 @@ int term_find_one(FF_PKT *ff) lc = lp; lp = lp->next; if (lc) { - free(lc); - count++; + free(lc); + count++; } } return count; diff --git a/bacula/src/findlib/match.c b/bacula/src/findlib/match.c index 4e6f69d157..95a574572f 100644 --- a/bacula/src/findlib/match.c +++ b/bacula/src/findlib/match.c @@ -125,6 +125,12 @@ void add_fname_to_include_list(FF_PKT *ff, int prefixed, char *fname) case 's': inc->options |= FO_SPARSE; break; + case 'm': + inc->options |= FO_MTIMEONLY; + break; + case 'k': + inc->options |= FO_KEEPATIME; + break; case 'V': /* verify options */ /* Copy Verify Options */ for (j=0; *p && *p != ':'; p++) { diff --git a/bacula/src/findlib/protos.h b/bacula/src/findlib/protos.h index a77b7644f1..98d1abafc9 100644 --- a/bacula/src/findlib/protos.h +++ b/bacula/src/findlib/protos.h @@ -23,19 +23,19 @@ */ /* from attribs.c */ -void encode_stat (char *buf, FF_PKT *ff_pkt, int data_stream); -int decode_stat (char *buf, struct stat *statp, int32_t *LinkFI); -int32_t decode_LinkFI (char *buf, struct stat *statp); -int encode_attribsEx (JCR *jcr, char *attribsEx, FF_PKT *ff_pkt); -int set_attributes (JCR *jcr, ATTR *attr, BFILE *ofd); -int select_data_stream(FF_PKT *ff_pkt); +void encode_stat (char *buf, FF_PKT *ff_pkt, int data_stream); +int decode_stat (char *buf, struct stat *statp, int32_t *LinkFI); +int32_t decode_LinkFI (char *buf, struct stat *statp); +int encode_attribsEx (JCR *jcr, char *attribsEx, FF_PKT *ff_pkt); +int set_attributes (JCR *jcr, ATTR *attr, BFILE *ofd); +int select_data_stream(FF_PKT *ff_pkt); /* from create_file.c */ -int create_file (JCR *jcr, ATTR *attr, BFILE *ofd, int replace); +int create_file (JCR *jcr, ATTR *attr, BFILE *ofd, int replace); /* From find.c */ FF_PKT *init_find_files(); -void set_find_options(FF_PKT *ff, int incremental, time_t mtime, int mtime_only); +void set_find_options(FF_PKT *ff, int incremental, time_t mtime); int find_files(JCR *jcr, FF_PKT *ff, int sub(FF_PKT *ff_pkt, void *hpkt), void *pkt); int term_find_files(FF_PKT *ff); @@ -47,11 +47,11 @@ void add_fname_to_exclude_list(FF_PKT *ff, char *fname); int file_is_excluded(FF_PKT *ff, char *file); int file_is_included(FF_PKT *ff, char *file); struct s_included_file *get_next_included_file(FF_PKT *ff, - struct s_included_file *inc); + struct s_included_file *inc); /* From find_one.c */ int find_one_file(JCR *jcr, FF_PKT *ff, int handle_file(FF_PKT *ff_pkt, void *hpkt), - void *pkt, char *p, dev_t parent_device, int top_level); + void *pkt, char *p, dev_t parent_device, int top_level); int term_find_one(FF_PKT *ff); @@ -61,7 +61,7 @@ int enable_backup_privileges(JCR *jcr, int ignore_errors); /* from makepath.c */ int make_path(JCR *jcr, const char *argpath, int mode, - int parent_mode, uid_t owner, gid_t group, - int preserve_existing, char *verbose_fmt_string); + int parent_mode, uid_t owner, gid_t group, + int preserve_existing, char *verbose_fmt_string); /* from bfile.c -- see bfile.h */ diff --git a/bacula/src/jcr.h b/bacula/src/jcr.h index 8cfeceb364..0b3e41e8d0 100644 --- a/bacula/src/jcr.h +++ b/bacula/src/jcr.h @@ -184,7 +184,6 @@ struct JCR { /*********FIXME********* add missing files and files to be retried */ int incremental; /* set if incremental for SINCE */ time_t mtime; /* begin time for SINCE */ - int mtime_only; /* compare only mtime and not ctime as well */ int listing; /* job listing in estimate */ long Ticket; /* Ticket */ char *big_buf; /* I/O buffer */ diff --git a/bacula/src/lib/edit.c b/bacula/src/lib/edit.c index b9e24a7bc3..99184336cd 100644 --- a/bacula/src/lib/edit.c +++ b/bacula/src/lib/edit.c @@ -107,33 +107,26 @@ static bool get_modifier(char *str, char *mod, int mod_len) */ strip_trailing_junk(str); len = strlen(str); - /* Strip trailing spaces */ - for (i=len; i>0; i--) { - if (!B_ISSPACE(str[i-1])) { - break; - } - str[i-1] = 0; - } + /* Find beginning of the modifier */ - for ( ; i>0; i--) { + for (i=len; i > 0; i--) { if (!B_ISALPHA(str[i-1])) { break; } } - /* If not found, error */ - if (i == 0 || i == len) { + + /* If nothing found, error */ + if (i == 0) { Dmsg2(200, "error i=%d len=%d\n", i, len); return false; } - /* Move modifier to mod */ + + /* Move modifier to its location */ bstrncpy(mod, &str[i], mod_len); - if (strlen(mod) == 0) { /* Make sure we have a modifier */ - Dmsg0(200, "No modifier found\n"); - return false; - } Dmsg2(200, "in=%s mod=%s:\n", str, mod); + /* Backup over any spaces in front of modifier */ - for ( ; i>0; i--) { + for ( ; i > 0; i--) { if (B_ISSPACE(str[i-1])) { continue; } @@ -179,8 +172,7 @@ int duration_to_utime(char *str, utime_t *value) } } if (mod[i] == NULL) { - Dmsg0(200, "Modifier not found\n"); - return 0; /* modifer not found */ + i = 1; /* no modifier, assume 1 */ } Dmsg2(200, "str=%s: mult=%d\n", str, mult[i]); errno = 0; @@ -251,8 +243,7 @@ int size_to_uint64(char *str, int str_len, uint64_t *value) } } if (mod[i] == NULL) { - Dmsg0(200, "Modifier not found\n"); - return 0; /* modifer not found */ + i = 0; /* no modifier found, assume 1 */ } Dmsg2(200, "str=%s: mult=%d\n", str, mult[i]); errno = 0; diff --git a/bacula/src/stored/block.c b/bacula/src/stored/block.c index aa97abc959..bc9c09b62b 100644 --- a/bacula/src/stored/block.c +++ b/bacula/src/stored/block.c @@ -438,43 +438,42 @@ int write_block_to_dev(JCR *jcr, DEVICE *dev, DEV_BLOCK *block) } /* Limit maximum File size on volume to user specified value */ - if (dev_state(dev, ST_TAPE)) { - if ((dev->max_file_size > 0) && - (dev->file_addr+block->binbuf) >= dev->max_file_size) { + if ((dev->max_file_size > 0) && + (dev->file_size+block->binbuf) >= dev->max_file_size) { + if (dev_state(dev, ST_TAPE) && weof_dev(dev, 1) != 0) { /* write eof */ /* Write EOF */ - if (weof_dev(dev, 1) != 0) { /* write eof */ - Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg); - block->write_failed = true; - dev->VolCatInfo.VolCatErrors++; - dev->state |= (ST_EOF | ST_EOT | ST_WEOT); - Dmsg0(100, "dir_update_volume_info\n"); - dev->VolCatInfo.VolCatFiles = dev->file; - dir_update_volume_info(jcr, dev, 0); - return 0; - } - - /* Do bookkeeping to handle EOF just written */ + Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg); + block->write_failed = true; + dev->VolCatInfo.VolCatErrors++; + dev->state |= (ST_EOF | ST_EOT | ST_WEOT); Dmsg0(100, "dir_update_volume_info\n"); dev->VolCatInfo.VolCatFiles = dev->file; dir_update_volume_info(jcr, dev, 0); - if (!dir_create_jobmedia_record(jcr)) { - Jmsg(jcr, M_ERROR, 0, _("Could not create JobMedia record for Volume=\"%s\" Job=%s\n"), - jcr->VolCatInfo.VolCatName, jcr->Job); - return 0; - } - /* - * Walk through all attached jcrs indicating the file has changed - */ - Dmsg1(100, "Walk attached jcrs. Volume=%s\n", dev->VolCatInfo.VolCatName); - for (JCR *mjcr=NULL; (mjcr=next_attached_jcr(dev, mjcr)); ) { - if (mjcr->JobId == 0) { - continue; /* ignore console */ - } - mjcr->NewFile = true; /* set reminder to do set_new_file_params */ + return 0; + } + + /* Create a JobMedia record so restore can seek */ + Dmsg0(100, "dir_update_volume_info\n"); + dev->VolCatInfo.VolCatFiles = dev->file; + dir_update_volume_info(jcr, dev, 0); + if (!dir_create_jobmedia_record(jcr)) { + Jmsg(jcr, M_ERROR, 0, _("Could not create JobMedia record for Volume=\"%s\" Job=%s\n"), + jcr->VolCatInfo.VolCatName, jcr->Job); + return 0; + } + dev->file_size = 0; /* reset file size */ + /* + * Walk through all attached jcrs indicating the file has changed + */ + Dmsg1(100, "Walk attached jcrs. Volume=%s\n", dev->VolCatInfo.VolCatName); + for (JCR *mjcr=NULL; (mjcr=next_attached_jcr(dev, mjcr)); ) { + if (mjcr->JobId == 0) { + continue; /* ignore console */ } - set_new_file_parameters(jcr, dev); + mjcr->NewFile = true; /* set reminder to do set_new_file_params */ } + set_new_file_parameters(jcr, dev); } dev->VolCatInfo.VolCatWrites++; @@ -585,7 +584,6 @@ int write_block_to_dev(JCR *jcr, DEVICE *dev, DEV_BLOCK *block) dev->VolCatInfo.VolCatBytes += block->binbuf; dev->VolCatInfo.VolCatBlocks++; - dev->file_addr += wlen; dev->EndBlock = dev->block_num; dev->EndFile = dev->file; dev->block_num++; @@ -596,6 +594,7 @@ int write_block_to_dev(JCR *jcr, DEVICE *dev, DEV_BLOCK *block) jcr->EndBlock = dev->EndBlock; jcr->EndFile = dev->EndFile; } else { + /* Save address of start of block just written */ jcr->EndBlock = (uint32_t)dev->file_addr; jcr->EndFile = (uint32_t)(dev->file_addr >> 32); } @@ -606,6 +605,8 @@ int write_block_to_dev(JCR *jcr, DEVICE *dev, DEV_BLOCK *block) jcr->VolLastIndex = block->LastIndex; } jcr->WroteVol = true; + dev->file_addr += wlen; /* update file address */ + dev->file_size += wlen; Dmsg2(190, "write_block: wrote block %d bytes=%d\n", dev->block_num, wlen); @@ -728,6 +729,7 @@ reread: off_t pos = lseek(dev->fd, (off_t)0, SEEK_CUR); /* get curr pos */ pos -= block->read_len; lseek(dev->fd, pos, SEEK_SET); + dev->file_addr = pos; } Mmsg1(&dev->errmsg, _("Setting block buffer size to %u bytes.\n"), block->block_len); Jmsg(jcr, M_INFO, 0, "%s", dev->errmsg); @@ -757,7 +759,6 @@ reread: dev->VolCatInfo.VolCatBytes += block->block_len; dev->VolCatInfo.VolCatBlocks++; - dev->file_addr += block->block_len; dev->EndBlock = dev->block_num; dev->EndFile = dev->file; dev->block_num++; @@ -769,7 +770,11 @@ reread: } else { jcr->EndBlock = (uint32_t)dev->file_addr; jcr->EndFile = (uint32_t)(dev->file_addr >> 32); + dev->block_num = jcr->EndBlock; + dev->file = jcr->EndFile; } + dev->file_addr += block->block_len; + dev->file_size += block->block_len; /* * If we read a short block on disk, @@ -791,6 +796,7 @@ reread: lseek(dev->fd, pos, SEEK_SET); Dmsg2(100, "Did lseek blk_size=%d rdlen=%d\n", block->block_len, block->read_len); + dev->file_addr = pos; } Dmsg2(200, "Exit read_block read_len=%d block_len=%d\n", block->read_len, block->block_len); diff --git a/bacula/src/stored/dev.c b/bacula/src/stored/dev.c index 0bea32dcf7..c0d85f23b2 100644 --- a/bacula/src/stored/dev.c +++ b/bacula/src/stored/dev.c @@ -1057,12 +1057,16 @@ reposition_dev(DEVICE *dev, uint32_t file, uint32_t block) if (!(dev_state(dev, ST_TAPE))) { off_t pos = (((off_t)file)<<32) + block; + Dmsg1(100, "===== lseek to %d\n", (int)pos); if (lseek(dev->fd, pos, SEEK_SET) == (off_t)-1) { dev->dev_errno = errno; Mmsg2(&dev->errmsg, _("lseek error on %s. ERR=%s.\n"), dev->dev_name, strerror(dev->dev_errno)); return 0; } + dev->file = file; + dev->block_num = block; + dev->file_addr = pos; return 1; } Dmsg4(100, "reposition_dev from %u:%u to %u:%u\n", diff --git a/bacula/src/stored/dev.h b/bacula/src/stored/dev.h index 69ad8e9482..50e0325733 100644 --- a/bacula/src/stored/dev.h +++ b/bacula/src/stored/dev.h @@ -173,6 +173,7 @@ public: uint32_t block_num; /* current block number base 0 */ uint32_t file; /* current file number base 0 */ uint64_t file_addr; /* Current file read/write address */ + uint64_t file_size; /* Current file size */ uint32_t EndBlock; /* last block written */ uint32_t EndFile; /* last file written */ uint32_t min_block_size; /* min block size */ diff --git a/bacula/src/version.h b/bacula/src/version.h index a8659b5a71..7f1599386e 100644 --- a/bacula/src/version.h +++ b/bacula/src/version.h @@ -2,8 +2,8 @@ #undef VERSION #define VERSION "1.33.4" #define VSTRING "1" -#define BDATE "24 Feb 2004" -#define LSMDATE "24Feb04" +#define BDATE "26 Feb 2004" +#define LSMDATE "26Feb04" /* Debug flags */ #undef DEBUG diff --git a/bacula/src/win32/README.win32 b/bacula/src/win32/README.win32 new file mode 100644 index 0000000000..2967b4b364 --- /dev/null +++ b/bacula/src/win32/README.win32 @@ -0,0 +1,29 @@ + +This code written by: + + Christopher S. Hull, February 2004 + +This directory /src/win32 contains the build +environment for building the native Win32 Bacula File daemon. +The directory structure is: + + src/win32 Makefiles and scripts + baculafd Visual Studio Files + Release Release objects, and bacula-fd.exe + Debug Debug object, and bacula-fd.exe produced + by VC++ + console Build of console program (not yet complete) + filed Links to core filed code + findlib Links to core findlib code + lib Links to core lib code + pthreads The POSIX pthreads library (third party) + zlib The zlib library (third party) + +To build it, make sure that VC++ 6.0 include files are in +the INCLUDE environment variable, the libraries are in +the LIB environment variable and the compiler and tools +are on the PATH. Then enter: + + make + +See License.txt for the License. diff --git a/bacula/src/win32/params.nsh b/bacula/src/win32/params.nsh new file mode 100644 index 0000000000..f2f1a8f411 --- /dev/null +++ b/bacula/src/win32/params.nsh @@ -0,0 +1,104 @@ +; +; -- written by Alexis de Valence -- +; GetONEParameter + +; Usage: +; Push 3 ; to get the 3rd parameter of the command line +; Call GetONEParameter +; Pop $R0 ; saves the result in $R0 +; returns an empty string if not found + +Function GetONEParameter + Exch $R0 + Push $R1 + Push $R2 + Push $R3 + Push $R4 + Push $R5 + Push $R6 + +; init variables + IntOp $R5 $R0 + 1 + StrCpy $R2 0 + StrCpy $R4 1 + StrCpy $R6 0 + + loop3: ; looking for a char that's not a space + IntOp $R2 $R2 + 1 + StrCpy $R0 $CMDLINE 1 $R2 + StrCmp $R0 " " loop3 + StrCpy $R3 $R2 ; found the begining of the current parameter + + + loop: ; scanning for the end of the current parameter + + StrCpy $R0 $CMDLINE 1 $R2 + StrCmp $R0 " " loop2 + StrCmp $R0 "" last + IntOp $R2 $R2 + 1 + Goto loop + + last: ; there will be no other parameter to extract + StrCpy $R6 1 + + loop2: ; found the end of the current parameter + + IntCmp $R4 $R5 0 NextParam end + StrCpy $R6 1 ; to quit after this process + + IntOp $R1 $R2 - $R3 ;number of letter of current parameter + StrCpy $R0 $CMDLINE $R1 $R3 ; stores the result in R0 + + NextParam: + IntCmp $R6 1 end ; leave if found or if not enough parameters + + ; process the next parameter + IntOp $R4 $R4 + 1 + + Goto loop3 + + end: + + Pop $R6 ; restore R0 - R6 to their initial value + Pop $R5 + Pop $R4 + Pop $R3 + Pop $R2 + Pop $R1 + + Exch $R0 ;Puts the result on the stack + + FunctionEnd + +; -- written by Michel Meyers -- +; ParameterGiven - checks first 9 parameters on the command line +; Usage: +; Push "/parameter" ; to check command line for /parameter +; Call ParameterGiven +; Pop $R0 ; saves the result in $R0 (result = true or false) + + Function ParameterGiven + Exch $R0 + Push $R1 + Push $R2 + Push $R3 + + StrCpy $R1 0 + StrCpy $R3 0 + loopme: + StrCmp $R1 9 AllChecked + IntOp $R1 $R1 + 1 + Push $R1 + Call GetONEParameter + Pop $R2 ; saves the result in $R2 + StrCmp $R0 $R2 Found + Goto loopme + + Found: + StrCpy $R3 1 + Goto loopme + + AllChecked: + Exch $R3 + +FunctionEnd diff --git a/bacula/src/win32/util.nsh b/bacula/src/win32/util.nsh index 7477d03d7e..1004c1595e 100644 --- a/bacula/src/win32/util.nsh +++ b/bacula/src/win32/util.nsh @@ -30,66 +30,66 @@ Exch $R0 FunctionEnd - Function GetWindowsVersion - Push $R0 - Push $R1 - ReadRegStr $R0 HKLM "SOFTWARE\Microsoft\Windows NT\CurrentVersion" CurrentVersion - StrCmp $R0 "" 0 lbl_winnt - ; we are not NT. - ReadRegStr $R0 HKLM SOFTWARE\Microsoft\Windows\CurrentVersion VersionNumber +; Function GetWindowsVersion +; Push $R0 +; Push $R1 +; ReadRegStr $R0 HKLM "SOFTWARE\Microsoft\Windows NT\CurrentVersion" CurrentVersion +; StrCmp $R0 "" 0 lbl_winnt +; ; we are not NT. +; ReadRegStr $R0 HKLM SOFTWARE\Microsoft\Windows\CurrentVersion VersionNumber - StrCpy $R1 $R0 1 - StrCmp $R1 '4' 0 lbl_error +; StrCpy $R1 $R0 1 +; StrCmp $R1 '4' 0 lbl_error - StrCpy $R1 $R0 3 +; StrCpy $R1 $R0 3 - StrCmp $R1 '4.0' lbl_win32_95 - StrCmp $R1 '4.9' lbl_win32_ME lbl_win32_98 +; StrCmp $R1 '4.0' lbl_win32_95 +; StrCmp $R1 '4.9' lbl_win32_ME lbl_win32_98 - lbl_win32_95: - StrCpy $R0 '95' - Goto lbl_done +; lbl_win32_95: +; StrCpy $R0 '95' +; Goto lbl_done - lbl_win32_98: - StrCpy $R0 '98' - Goto lbl_done +; lbl_win32_98: +; StrCpy $R0 '98' +; Goto lbl_done - lbl_win32_ME: - StrCpy $R0 'ME' - Goto lbl_done +; lbl_win32_ME: +; StrCpy $R0 'ME' +; Goto lbl_done - lbl_winnt: +; lbl_winnt: - StrCpy $R1 $R0 1 +; StrCpy $R1 $R0 1 - StrCmp $R1 '3' lbl_winnt_x - StrCmp $R1 '4' lbl_winnt_x +; StrCmp $R1 '3' lbl_winnt_x +; StrCmp $R1 '4' lbl_winnt_x - StrCpy $R1 $R0 3 +; StrCpy $R1 $R0 3 - StrCmp $R1 '5.0' lbl_winnt_2000 - StrCmp $R1 '5.1' lbl_winnt_XP - StrCmp $R1 '5.2' lbl_winnt_dotNET lbl_error +; StrCmp $R1 '5.0' lbl_winnt_2000 +; StrCmp $R1 '5.1' lbl_winnt_XP +; StrCmp $R1 '5.2' lbl_winnt_dotNET lbl_error - lbl_winnt_x: - StrCpy $R0 "NT $R0" 6 - Goto lbl_done +; lbl_winnt_x: +; StrCpy $R0 "NT $R0" 6 +; Goto lbl_done - lbl_winnt_2000: - Strcpy $R0 '2000' - Goto lbl_done +; lbl_winnt_2000: +; Strcpy $R0 '2000' +; Goto lbl_done - lbl_winnt_XP: - Strcpy $R0 'XP' - Goto lbl_done +; lbl_winnt_XP: +; Strcpy $R0 'XP' +; Goto lbl_done - lbl_winnt_dotNET: - Strcpy $R0 '.NET Server' - Goto lbl_done +; lbl_winnt_dotNET: +; Strcpy $R0 '.NET Server' +; Goto lbl_done - lbl_error: - Strcpy $R0 '' - lbl_done: - Pop $R1 - Exch $R0 - FunctionEnd +; lbl_error: +; Strcpy $R0 '' +; lbl_done: +; Pop $R1 +; Exch $R0 +; FunctionEnd -- 2.39.5