/*
Bacula® - The Network Backup Solution
- Copyright (C) 2000-2008 Free Software Foundation Europe e.V.
+ Copyright (C) 2000-2009 Free Software Foundation Europe e.V.
The main author of Bacula is Kern Sibbald, with contributions from
many others, a complete list can be found in the file AUTHORS.
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
- Bacula® is a registered trademark of John Walker.
+ Bacula® is a registered trademark of Kern Sibbald.
The licensor of Bacula is the Free Software Foundation Europe
(FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
Switzerland, email:ftf@fsfeurope.org.
#include "bacula.h"
#include "filed.h"
-#include "lib/htable.h"
/* Forward referenced functions */
int save_file(JCR *jcr, FF_PKT *ff_pkt, bool top_level);
-static void strip_path(FF_PKT *ff_pkt);
-static void unstrip_path(FF_PKT *ff_pkt);
static int send_data(JCR *jcr, int stream, FF_PKT *ff_pkt, DIGEST *digest, DIGEST *signature_digest);
-static bool encode_and_send_attributes(JCR *jcr, FF_PKT *ff_pkt, int &data_stream);
-static bool read_and_send_acl(JCR *jcr, int acltype, int stream);
+bool encode_and_send_attributes(JCR *jcr, FF_PKT *ff_pkt, int &data_stream);
static bool crypto_session_start(JCR *jcr);
static void crypto_session_end(JCR *jcr);
static bool crypto_session_send(JCR *jcr, BSOCK *sd);
-typedef struct CurFile {
- hlink link;
- char *fname;
- char *lstat;
- bool seen;
-} CurFile;
-
-#define accurate_mark_file_as_seen(elt) ((elt)->seen = 1)
-#define accurate_file_has_been_seen(elt) ((elt)->seen)
-
-/*
- * This function is called for each file seen in fileset.
- * We check in file_list hash if fname have been backuped
- * the last time. After we can compare Lstat field.
- *
- */
-/* TODO: tweak verify code to use the same function ?? */
-bool accurate_check_file(JCR *jcr, FF_PKT *ff_pkt)
-{
- char *p;
- int stat=false;
- struct stat statc; /* catalog stat */
- char *Opts_Digest;
- char *fname;
- CurFile *elt;
-
- int32_t LinkFIc;
-
- if (*ff_pkt->VerifyOpts) { /* use mtime + ctime checks by default */
- Opts_Digest = ff_pkt->VerifyOpts;
- } else {
- Opts_Digest = "cm";
- }
-
- if (jcr->accurate == false || jcr->JobLevel == L_FULL) {
- return true;
- }
-
- strip_path(ff_pkt);
-
- if (S_ISDIR(ff_pkt->statp.st_mode)) {
- fname = ff_pkt->link;
- } else {
- fname = ff_pkt->fname;
- }
-
- elt = (CurFile *) jcr->file_list->lookup(fname);
-
- if (!elt) {
- Dmsg1(500, "accurate %s = yes (not found)\n", fname);
- stat=true;
- goto bail_out;
- }
-
- if (accurate_file_has_been_seen(elt)) {
- Dmsg1(500, "accurate %s = no (already seen)\n", fname);
- stat=false;
- goto bail_out;
- }
-
- decode_stat(elt->lstat, &statc, &LinkFIc); /* decode catalog stat */
-// *do_Digest = CRYPTO_DIGEST_NONE;
-
- for (p=Opts_Digest; *p; p++) {
- char ed1[30], ed2[30];
- switch (*p) {
- case 'i': /* compare INODEs */
- if (statc.st_ino != ff_pkt->statp.st_ino) {
- Jmsg(jcr, M_SAVED, 0, _("%s st_ino differ. Cat: %s File: %s\n"), fname,
- edit_uint64((uint64_t)statc.st_ino, ed1),
- edit_uint64((uint64_t)ff_pkt->statp.st_ino, ed2));
- stat = true;
- }
- break;
- case 'p': /* permissions bits */
- if (statc.st_mode != ff_pkt->statp.st_mode) {
- Jmsg(jcr, M_SAVED, 0, _("%s st_mode differ. Cat: %x File: %x\n"), fname,
- (uint32_t)statc.st_mode, (uint32_t)ff_pkt->statp.st_mode);
- stat = true;
- }
- break;
-// case 'n': /* number of links */
-// if (statc.st_nlink != ff_pkt->statp.st_nlink) {
-// Jmsg(jcr, M_SAVED, 0, _("%s st_nlink differ. Cat: %d File: %d\n"), fname,
-// (uint32_t)statc.st_nlink, (uint32_t)ff_pkt->statp.st_nlink);
-// stat = true;
-// }
-// break;
- case 'u': /* user id */
- if (statc.st_uid != ff_pkt->statp.st_uid) {
- Jmsg(jcr, M_SAVED, 0, _("%s st_uid differ. Cat: %u File: %u\n"), fname,
- (uint32_t)statc.st_uid, (uint32_t)ff_pkt->statp.st_uid);
- stat = true;
- }
- break;
- case 'g': /* group id */
- if (statc.st_gid != ff_pkt->statp.st_gid) {
- Jmsg(jcr, M_SAVED, 0, _("%s st_gid differ. Cat: %u File: %u\n"), fname,
- (uint32_t)statc.st_gid, (uint32_t)ff_pkt->statp.st_gid);
- stat = true;
- }
- break;
- case 's': /* size */
- if (statc.st_size != ff_pkt->statp.st_size) {
- Jmsg(jcr, M_SAVED, 0, _("%s st_size differ. Cat: %s File: %s\n"), fname,
- edit_uint64((uint64_t)statc.st_size, ed1),
- edit_uint64((uint64_t)ff_pkt->statp.st_size, ed2));
- stat = true;
- }
- break;
-// case 'a': /* access time */
-// if (statc.st_atime != ff_pkt->statp.st_atime) {
-// Jmsg(jcr, M_SAVED, 0, _("%s st_atime differs\n"), fname);
-// stat = true;
-// }
-// break;
- case 'm':
- if (statc.st_mtime != ff_pkt->statp.st_mtime) {
- Jmsg(jcr, M_SAVED, 0, _("%s st_mtime differs\n"), fname);
- stat = true;
- }
- break;
- case 'c': /* ctime */
- if (statc.st_ctime != ff_pkt->statp.st_ctime) {
- Jmsg(jcr, M_SAVED, 0, _("%s st_ctime differs\n"), fname);
- stat = true;
- }
- break;
- case 'd': /* file size decrease */
- if (statc.st_size > ff_pkt->statp.st_size) {
- Jmsg(jcr, M_SAVED, 0, _("%s st_size decrease. Cat: %s File: %s\n"), fname,
- edit_uint64((uint64_t)statc.st_size, ed1),
- edit_uint64((uint64_t)ff_pkt->statp.st_size, ed2));
- stat = true;
- }
- break;
- case '5': /* compare MD5 */
- Dmsg1(500, "set Do_MD5 for %s\n", ff_pkt->fname);
-// *do_Digest = CRYPTO_DIGEST_MD5;
- break;
- case '1': /* compare SHA1 */
-// *do_Digest = CRYPTO_DIGEST_SHA1;
- break;
- case ':':
- case 'V':
- default:
- break;
- }
- }
- accurate_mark_file_as_seen(elt);
- Dmsg2(500, "accurate %s = %i\n", fname, stat);
-
-bail_out:
- unstrip_path(ff_pkt);
- return stat;
-}
-
-/*
- * This function doesn't work very well with smartalloc
- * TODO: use bigbuffer from htable
- */
-int accurate_cmd(JCR *jcr)
-{
- BSOCK *dir = jcr->dir_bsock;
- int len;
- uint64_t nb;
- CurFile *elt=NULL;
-
- if (jcr->accurate==false || job_canceled(jcr) || jcr->JobLevel==L_FULL) {
- return true;
- }
-
- if (sscanf(dir->msg, "accurate files=%ld", &nb) != 1) {
- dir->fsend(_("2991 Bad accurate command\n"));
- return false;
- }
-
- jcr->file_list = (htable *)malloc(sizeof(htable));
- jcr->file_list->init(elt, &elt->link, nb);
-
- /*
- * buffer = sizeof(CurFile) + dirmsg
- * dirmsg = fname + lstat
- */
- /* get current files */
- while (dir->recv() >= 0) {
- len = strlen(dir->msg);
- if ((len+1) < dir->msglen) {
-// elt = (CurFile *)malloc(sizeof(CurFile));
-// elt->fname = (char *) malloc(dir->msglen+1);
-
- /* we store CurFile, fname and lstat in the same chunk */
- elt = (CurFile *)malloc(sizeof(CurFile)+dir->msglen+1);
- elt->fname = (char *) elt+sizeof(CurFile);
- memcpy(elt->fname, dir->msg, dir->msglen);
- elt->fname[dir->msglen]='\0';
- elt->lstat = elt->fname + len + 1;
- elt->seen=0;
- jcr->file_list->insert(elt->fname, elt);
- Dmsg2(500, "add fname=%s lstat=%s\n", elt->fname, elt->lstat);
- }
- }
-
-// jcr->file_list->stats();
- /* TODO: send a EOM ?
- * dir->fsend("2000 OK accurate\n");
- */
- return true;
-}
-
-bool accurate_send_deleted_list(JCR *jcr)
-{
- CurFile *elt;
- FF_PKT *ff_pkt;
-
- int stream = STREAM_UNIX_ATTRIBUTES;
-
- if (jcr->accurate == false || jcr->JobLevel == L_FULL) {
- goto bail_out;
- }
-
- if (jcr->file_list == NULL) {
- goto bail_out;
- }
-
- ff_pkt = init_find_files();
- ff_pkt->type = FT_DELETED;
-
- foreach_htable (elt, jcr->file_list) {
- if (!accurate_file_has_been_seen(elt)) { /* already seen */
- Dmsg3(500, "deleted fname=%s lstat=%s seen=%i\n", elt->fname, elt->lstat, elt->seen);
- ff_pkt->fname = elt->fname;
- decode_stat(elt->lstat, &ff_pkt->statp, &ff_pkt->LinkFI); /* decode catalog stat */
- encode_and_send_attributes(jcr, ff_pkt, stream);
- }
-// Free(elt->fname);
- }
- term_find_files(ff_pkt);
-bail_out:
- /* TODO: clean htable when this function is not reached ? */
- if (jcr->file_list) {
- jcr->file_list->destroy();
- free(jcr->file_list);
- jcr->file_list = NULL;
- }
- return true;
-}
-
/*
* Find all the requested files and send them
* to the Storage daemon.
} else {
buf_size = 0; /* use default */
}
- if (!bnet_set_buffer_size(sd, buf_size, BNET_SETBUF_WRITE)) {
+ if (!sd->set_buffer_size(buf_size, BNET_SETBUF_WRITE)) {
set_jcr_job_status(jcr, JS_ErrorTerminated);
Jmsg(jcr, M_FATAL, 0, _("Cannot set buffer size FD->SD.\n"));
return false;
jcr->buf_size = sd->msglen;
/* Adjust for compression so that output buffer is
- * 12 bytes + 0.1% larger than input buffer plus 18 bytes.
- * This gives a bit extra plus room for the sparse addr if any.
- * Note, we adjust the read size to be smaller so that the
- * same output buffer can be used without growing it.
+ * 12 bytes + 0.1% larger than input buffer plus 18 bytes.
+ * This gives a bit extra plus room for the sparse addr if any.
+ * Note, we adjust the read size to be smaller so that the
+ * same output buffer can be used without growing it.
*
- * The zlib compression workset is initialized here to minimise
- * the "per file" load. The jcr member is only set, if the init was successful.
+ * The zlib compression workset is initialized here to minimize
+ * the "per file" load. The jcr member is only set, if the init
+ * was successful.
*/
jcr->compress_buf_size = jcr->buf_size + ((jcr->buf_size+999) / 1000) + 30;
jcr->compress_buf = get_memory(jcr->compress_buf_size);
start_heartbeat_monitor(jcr);
- jcr->acl_text = get_pool_memory(PM_MESSAGE);
+ jcr->acl_data = get_pool_memory(PM_MESSAGE);
+ jcr->xattr_data = get_pool_memory(PM_MESSAGE);
/* Subroutine save_file() is called for each file */
if (!find_files(jcr, (FF_PKT *)jcr->ff, save_file, plugin_save)) {
accurate_send_deleted_list(jcr); /* send deleted list to SD */
- free_pool_memory(jcr->acl_text);
-
stop_heartbeat_monitor(jcr);
sd->signal(BNET_EOD); /* end of sending data */
+ if (jcr->acl_data) {
+ free_pool_memory(jcr->acl_data);
+ jcr->acl_data = NULL;
+ }
+ if (jcr->xattr_data) {
+ free_pool_memory(jcr->xattr_data);
+ jcr->xattr_data = NULL;
+ }
if (jcr->big_buf) {
free(jcr->big_buf);
jcr->big_buf = NULL;
break;
case FT_NOFSCHG:
/* Suppress message for /dev filesystems */
-// if (strncmp(ff_pkt->fname, "/dev/", 5) != 0) {
if (!is_in_fileset(ff_pkt)) {
Jmsg(jcr, M_INFO, 1, _(" %s is a different filesystem. Will not descend from %s into %s\n"),
ff_pkt->fname, ff_pkt->top_fname, ff_pkt->fname);
break;
case FT_NOACCESS: {
berrno be;
- Jmsg(jcr, M_NOTSAVED, 0, _(" Could not access %s: ERR=%s\n"), ff_pkt->fname,
+ Jmsg(jcr, M_NOTSAVED, 0, _(" Could not access \"%s\": ERR=%s\n"), ff_pkt->fname,
be.bstrerror(ff_pkt->ff_errno));
- jcr->Errors++;
+ jcr->JobErrors++;
return 1;
}
case FT_NOFOLLOW: {
berrno be;
- Jmsg(jcr, M_NOTSAVED, 0, _(" Could not follow link %s: ERR=%s\n"),
+ Jmsg(jcr, M_NOTSAVED, 0, _(" Could not follow link \"%s\": ERR=%s\n"),
ff_pkt->fname, be.bstrerror(ff_pkt->ff_errno));
- jcr->Errors++;
+ jcr->JobErrors++;
return 1;
}
case FT_NOSTAT: {
berrno be;
- Jmsg(jcr, M_NOTSAVED, 0, _(" Could not stat %s: ERR=%s\n"), ff_pkt->fname,
+ Jmsg(jcr, M_NOTSAVED, 0, _(" Could not stat \"%s\": ERR=%s\n"), ff_pkt->fname,
be.bstrerror(ff_pkt->ff_errno));
- jcr->Errors++;
+ jcr->JobErrors++;
return 1;
}
case FT_DIRNOCHG:
return 1;
case FT_NOOPEN: {
berrno be;
- Jmsg(jcr, M_NOTSAVED, 0, _(" Could not open directory %s: ERR=%s\n"),
+ Jmsg(jcr, M_NOTSAVED, 0, _(" Could not open directory \"%s\": ERR=%s\n"),
ff_pkt->fname, be.bstrerror(ff_pkt->ff_errno));
- jcr->Errors++;
+ jcr->JobErrors++;
return 1;
}
default:
Jmsg(jcr, M_NOTSAVED, 0, _(" Unknown file type %d; not saved: %s\n"),
ff_pkt->type, ff_pkt->fname);
- jcr->Errors++;
+ jcr->JobErrors++;
return 1;
}
if (signing_digest == NULL) {
Jmsg(jcr, M_NOTSAVED, 0, _("%s signature digest initialization failed\n"),
stream_to_ascii(signing_algorithm));
- jcr->Errors++;
+ jcr->JobErrors++;
goto good_rtn;
}
}
do_read = true;
}
- Dmsg1(100, "do_read=%d\n", do_read);
+ Dmsg1(400, "do_read=%d\n", do_read);
if (do_read) {
btimer_t *tid;
if (bopen(&ff_pkt->bfd, ff_pkt->fname, O_RDONLY | O_BINARY | noatime, 0) < 0) {
ff_pkt->ff_errno = errno;
berrno be;
- Jmsg(jcr, M_NOTSAVED, 0, _(" Cannot open %s: ERR=%s.\n"), ff_pkt->fname,
+ Jmsg(jcr, M_NOTSAVED, 0, _(" Cannot open \"%s\": ERR=%s.\n"), ff_pkt->fname,
be.bstrerror());
- jcr->Errors++;
+ jcr->JobErrors++;
if (tid) {
stop_thread_timer(tid);
tid = NULL;
if (!bopen_rsrc(&ff_pkt->bfd, ff_pkt->fname, O_RDONLY | O_BINARY, 0) < 0) {
ff_pkt->ff_errno = errno;
berrno be;
- Jmsg(jcr, M_NOTSAVED, -1, _(" Cannot open resource fork for %s: ERR=%s.\n"),
+ Jmsg(jcr, M_NOTSAVED, -1, _(" Cannot open resource fork for \"%s\": ERR=%s.\n"),
ff_pkt->fname, be.bstrerror());
- jcr->Errors++;
+ jcr->JobErrors++;
if (is_bopen(&ff_pkt->bfd)) {
bclose(&ff_pkt->bfd);
}
Dmsg1(300, "Saving Finder Info for \"%s\"\n", ff_pkt->fname);
sd->fsend("%ld %d 0", jcr->JobFiles, STREAM_HFSPLUS_ATTRIBUTES);
Dmsg1(300, "bfiled>stored:header %s\n", sd->msg);
- memcpy(sd->msg, ff_pkt->hfsinfo.fndrinfo, 32);
+ pm_memcpy(sd->msg, ff_pkt->hfsinfo.fndrinfo, 32);
sd->msglen = 32;
if (digest) {
crypto_digest_update(digest, (uint8_t *)sd->msg, sd->msglen);
}
#endif
- if (ff_pkt->flags & FO_ACL) {
- /* Read access ACLs for files, dirs and links */
- if (!read_and_send_acl(jcr, BACL_TYPE_ACCESS, STREAM_UNIX_ACCESS_ACL)) {
- goto bail_out;
+ /*
+ * Save ACLs for anything not being a symlink and not being a plugin.
+ */
+ if (!ff_pkt->cmd_plugin) {
+ if (ff_pkt->flags & FO_ACL && ff_pkt->type != FT_LNK) {
+ if (!build_acl_streams(jcr, ff_pkt))
+ goto bail_out;
}
- /* Directories can have default ACLs too */
- if (ff_pkt->type == FT_DIREND && (BACL_CAP & BACL_CAP_DEFAULTS_DIR)) {
- if (!read_and_send_acl(jcr, BACL_TYPE_DEFAULT, STREAM_UNIX_DEFAULT_ACL)) {
+ }
+
+ /*
+ * Save Extended Attributes for all files not being a plugin.
+ */
+ if (!ff_pkt->cmd_plugin) {
+ if (ff_pkt->flags & FO_XATTR) {
+ if (!build_xattr_streams(jcr, ff_pkt))
goto bail_out;
- }
}
}
}
/* Send our header */
- sd->fsend("%ld %d 0", jcr->JobFiles, STREAM_SIGNED_DIGEST);
+ sd->fsend("%ld %ld 0", jcr->JobFiles, STREAM_SIGNED_DIGEST);
Dmsg1(300, "bfiled>stored:header %s\n", sd->msg);
/* Encode signature data */
* Currently this is not a problem as the only other stream, resource forks,
* are not handled as sparse files.
*/
-int send_data(JCR *jcr, int stream, FF_PKT *ff_pkt, DIGEST *digest,
- DIGEST *signing_digest)
+static int send_data(JCR *jcr, int stream, FF_PKT *ff_pkt, DIGEST *digest,
+ DIGEST *signing_digest)
{
BSOCK *sd = jcr->store_bsock;
uint64_t fileAddr = 0; /* file address */
/* Check for sparse blocks */
if (ff_pkt->flags & FO_SPARSE) {
ser_declare;
- bool haveBlock = true;
- if (sd->msglen == rsize &&
- fileAddr+sd->msglen < (uint64_t)ff_pkt->statp.st_size ||
+ bool allZeros = false;
+ if ((sd->msglen == rsize &&
+ fileAddr+sd->msglen < (uint64_t)ff_pkt->statp.st_size) ||
((ff_pkt->type == FT_RAW || ff_pkt->type == FT_FIFO) &&
(uint64_t)ff_pkt->statp.st_size == 0)) {
- haveBlock = !is_buf_zero(rbuf, rsize);
+ allZeros = is_buf_zero(rbuf, rsize);
}
- if (haveBlock) {
+ if (!allZeros) {
+ /* Put file address as first data in buffer */
ser_begin(wbuf, SPARSE_FADDR_SIZE);
ser_uint64(fileAddr); /* store fileAddr in begin of buffer */
}
fileAddr += sd->msglen; /* update file address */
- if (!haveBlock) {
+ /* Skip block of all zeros */
+ if (allZeros) {
continue; /* skip block of zeros */
}
}
berrno be;
Jmsg(jcr, M_ERROR, 0, _("Read error on file %s. ERR=%s\n"),
ff_pkt->fname, be.bstrerror(ff_pkt->bfd.berrno));
- if (jcr->Errors++ > 1000) { /* insanity check */
+ if (jcr->JobErrors++ > 1000) { /* insanity check */
Jmsg(jcr, M_FATAL, 0, _("Too many errors.\n"));
}
} else if (ff_pkt->flags & FO_ENCRYPT) {
return 0;
}
-/*
- * Read and send an ACL for the last encountered file.
- */
-static bool read_and_send_acl(JCR *jcr, int acltype, int stream)
-{
-#ifdef HAVE_ACL
- BSOCK *sd = jcr->store_bsock;
- POOLMEM *msgsave;
- int len;
-#ifdef FD_NO_SEND_TEST
- return true;
-#endif
-
- len = bacl_get(jcr, acltype);
- if (len < 0) {
- Jmsg1(jcr, M_WARNING, 0, _("Error reading ACL of %s\n"), jcr->last_fname);
- return true;
- }
- if (len == 0) {
- return true; /* no ACL */
- }
-
- /* Send header */
- if (!sd->fsend("%ld %d 0", jcr->JobFiles, stream)) {
- Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
- sd->bstrerror());
- return false;
- }
-
- /* Send the buffer to the storage deamon */
- Dmsg2(400, "Backing up ACL type 0x%2x <%s>\n", acltype, jcr->acl_text);
- msgsave = sd->msg;
- sd->msg = jcr->acl_text;
- sd->msglen = len + 1;
- if (!sd->send()) {
- sd->msg = msgsave;
- sd->msglen = 0;
- Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
- sd->bstrerror());
- return false;
- }
-
- jcr->JobBytes += sd->msglen;
- sd->msg = msgsave;
- if (!sd->signal(BNET_EOD)) {
- Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
- sd->bstrerror());
- return false;
- }
-
- Dmsg1(200, "ACL of file: %s successfully backed up!\n", jcr->last_fname);
-#endif
- return true;
-}
-
-static bool encode_and_send_attributes(JCR *jcr, FF_PKT *ff_pkt, int &data_stream)
+bool encode_and_send_attributes(JCR *jcr, FF_PKT *ff_pkt, int &data_stream)
{
BSOCK *sd = jcr->store_bsock;
char attribs[MAXSTRING];
Jmsg0(jcr, M_FATAL, 0, _("Invalid file flags, no supported data stream type.\n"));
return false;
}
- encode_stat(attribs, ff_pkt, data_stream);
+ encode_stat(attribs, &ff_pkt->statp, ff_pkt->LinkFI, data_stream);
/* Now possibly extend the attributes */
attr_stream = encode_attribsEx(jcr, attribsEx, ff_pkt);
/* Copy to first path separator -- Win32 might have c: ... */
while (*in && !IsPathSeparator(*in)) {
- *out++ = *in++;
+ out++; in++;
}
- *out++ = *in++;
+ out++; in++;
numsep++; /* one separator seen */
for (stripped=0; stripped<count && *in; stripped++) {
while (*in && !IsPathSeparator(*in)) {
}
/*
- * If requested strip leading components of the path
+ * If requested strip leading components of the path so that we can
+ * save file as if it came from a subdirectory. This is most useful
+ * for dealing with snapshots, by removing the snapshot directory, or
+ * in handling vendor migrations where files have been restored with
+ * a vendor product into a subdirectory.
*/
-static void strip_path(FF_PKT *ff_pkt)
+void strip_path(FF_PKT *ff_pkt)
{
if (!(ff_pkt->flags & FO_STRIPPATH) || ff_pkt->strip_path <= 0) {
Dmsg1(200, "No strip for %s\n", ff_pkt->fname);
ff_pkt->link_save = get_pool_memory(PM_FNAME);
}
pm_strcpy(ff_pkt->fname_save, ff_pkt->fname);
+ if (ff_pkt->type != FT_LNK && ff_pkt->fname != ff_pkt->link) {
+ pm_strcpy(ff_pkt->link_save, ff_pkt->link);
+ Dmsg2(500, "strcpy link_save=%d link=%d\n", strlen(ff_pkt->link_save),
+ strlen(ff_pkt->link));
+ sm_check(__FILE__, __LINE__, true);
+ }
/*
* Strip path. If it doesn't succeed put it back. If
* Do not strip symlinks.
* I.e. if either stripping fails don't strip anything.
*/
- if (do_strip(ff_pkt->strip_path, ff_pkt->fname)) {
- /* Strip links but not symlinks */
- if (ff_pkt->type != FT_LNK && ff_pkt->fname != ff_pkt->link) {
- pm_strcpy(ff_pkt->link_save, ff_pkt->link);
- if (!do_strip(ff_pkt->strip_path, ff_pkt->link)) {
- strcpy(ff_pkt->link, ff_pkt->link_save);
- strcpy(ff_pkt->fname, ff_pkt->fname_save);
- }
- }
- } else {
- strcpy(ff_pkt->fname, ff_pkt->fname_save);
+ if (!do_strip(ff_pkt->strip_path, ff_pkt->fname)) {
+ unstrip_path(ff_pkt);
+ goto rtn;
}
- Dmsg2(200, "fname=%s stripped=%s\n", ff_pkt->fname_save, ff_pkt->fname);
+ /* Strip links but not symlinks */
+ if (ff_pkt->type != FT_LNK && ff_pkt->fname != ff_pkt->link) {
+ if (!do_strip(ff_pkt->strip_path, ff_pkt->link)) {
+ unstrip_path(ff_pkt);
+ }
+ }
+
+rtn:
+ Dmsg3(100, "fname=%s stripped=%s link=%s\n", ff_pkt->fname_save, ff_pkt->fname,
+ ff_pkt->link);
}
-static void unstrip_path(FF_PKT *ff_pkt)
+void unstrip_path(FF_PKT *ff_pkt)
{
if (!(ff_pkt->flags & FO_STRIPPATH) || ff_pkt->strip_path <= 0) {
return;
}
strcpy(ff_pkt->fname, ff_pkt->fname_save);
if (ff_pkt->type != FT_LNK && ff_pkt->fname != ff_pkt->link) {
+ Dmsg2(500, "strcpy link=%s link_save=%s\n", ff_pkt->link,
+ ff_pkt->link_save);
strcpy(ff_pkt->link, ff_pkt->link_save);
+ Dmsg2(500, "strcpy link=%d link_save=%d\n", strlen(ff_pkt->link),
+ strlen(ff_pkt->link_save));
+ sm_check(__FILE__, __LINE__, true);
}
}