X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=bacula%2Fsrc%2Flib%2Fattr.c;h=c05a66c467b9a0bd8cfacffc49d05b25e0285093;hb=897707854a8240d026e933215009f931bb9c5762;hp=ac509288cd641fd6c447cb882b27e45f3fbb3470;hpb=66716ecf7c18274dc510bf316678f2c802551ead;p=bacula%2Fbacula diff --git a/bacula/src/lib/attr.c b/bacula/src/lib/attr.c index ac509288cd..c05a66c467 100644 --- a/bacula/src/lib/attr.c +++ b/bacula/src/lib/attr.c @@ -1,36 +1,53 @@ +/* + Bacula® - The Network Backup Solution + + Copyright (C) 2003-2010 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. + This program is Free Software; you can redistribute it and/or + modify it under the terms of version three of the GNU Affero General Public + License as published by the Free Software Foundation and included + in the file LICENSE. + + 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 Affero 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. + + 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. +*/ /* * attr.c Unpack an Attribute record returned from the tape * * Kern Sibbald, June MMIII (code pulled from filed/restore.c and updated) * - * Version $Id$ */ -/* - Copyright (C) 2003-2006 Kern Sibbald - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - version 2 as amended with additional clauses defined in the - file LICENSE in the main source directory. - 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 - the file LICENSE for additional details. - - */ #include "bacula.h" #include "jcr.h" +#include "lib/breg.h" +static const int dbglvl = 150; -ATTR *new_attr() +ATTR *new_attr(JCR *jcr) { ATTR *attr = (ATTR *)malloc(sizeof(ATTR)); memset(attr, 0, sizeof(ATTR)); attr->ofname = get_pool_memory(PM_FNAME); attr->olname = get_pool_memory(PM_FNAME); attr->attrEx = get_pool_memory(PM_FNAME); + attr->jcr = jcr; + attr->uid = getuid(); return attr; } @@ -42,9 +59,10 @@ void free_attr(ATTR *attr) free(attr); } -int unpack_attributes_record(JCR *jcr, int32_t stream, char *rec, ATTR *attr) +int unpack_attributes_record(JCR *jcr, int32_t stream, char *rec, int32_t reclen, ATTR *attr) { char *p; + int object_len; /* * An Attributes record consists of: * File_index @@ -58,13 +76,17 @@ int unpack_attributes_record(JCR *jcr, int32_t stream, char *rec, ATTR *attr) * */ attr->stream = stream; - Dmsg1(400, "Attr: %s\n", rec); - if (sscanf(rec, "%ld %ld", &attr->file_index, &attr->type) != 2) { + Dmsg1(dbglvl, "Attr: %s\n", rec); + if (sscanf(rec, "%d %d", &attr->file_index, &attr->type) != 2) { Jmsg(jcr, M_FATAL, 0, _("Error scanning attributes: %s\n"), rec); - Dmsg1(100, "\nError scanning attributes. %s\n", rec); + Dmsg1(dbglvl, "\nError scanning attributes. %s\n", rec); return 0; } - Dmsg2(400, "Got Attr: FilInx=%d type=%d\n", attr->file_index, attr->type); + Dmsg2(dbglvl, "Got Attr: FilInx=%d type=%d\n", attr->file_index, attr->type); + /* + * Note AR_DATA_STREAM should never be set since it is encoded + * at the end of the attributes. + */ if (attr->type & AR_DATA_STREAM) { attr->data_stream = 1; } else { @@ -86,18 +108,34 @@ int unpack_attributes_record(JCR *jcr, int32_t stream, char *rec, ATTR *attr) attr->lname = p; /* set link position */ while (*p++ != 0) /* skip link */ { } - pm_strcpy(attr->attrEx, p); /* copy extended attributes, if any */ - - if (attr->data_stream) { - int64_t val; - while (*p++ != 0) /* skip extended attributes */ - { } - from_base64(&val, p); - attr->data_stream = (int32_t)val; + attr->delta_seq = 0; + if (attr->type == FT_RESTORE_FIRST) { + /* We have an object, so do a binary copy */ + object_len = reclen + rec - p; + attr->attrEx = check_pool_memory_size(attr->attrEx, object_len + 1); + memcpy(attr->attrEx, p, object_len); + /* Add a EOS for those who attempt to print the object */ + p = attr->attrEx + object_len; + *p = 0; + } else { + pm_strcpy(attr->attrEx, p); /* copy extended attributes, if any */ + if (attr->data_stream) { + int64_t val; + while (*p++ != 0) /* skip extended attributes */ + { } + from_base64(&val, p); + attr->data_stream = (int32_t)val; + } else { + while (*p++ != 0) /* skip extended attributes */ + { } + if (p - rec < reclen) { + attr->delta_seq = str_to_int32(p); /* delta_seq */ + } + } } - Dmsg7(400, "unpack_attr FI=%d Type=%d fname=%s attr=%s lname=%s attrEx=%s ds=%d\n", + Dmsg8(dbglvl, "unpack_attr FI=%d Type=%d fname=%s attr=%s lname=%s attrEx=%s datastr=%d delta_seq=%d\n", attr->file_index, attr->type, attr->fname, attr->attr, attr->lname, - attr->attrEx, attr->data_stream); + attr->attrEx, attr->data_stream, attr->delta_seq); *attr->ofname = 0; *attr->olname = 0; return 1; @@ -108,11 +146,11 @@ static void strip_double_slashes(char *fname) { char *p = fname; while (p && *p) { - p = strchr(p, '/'); - if (p && p[1] == '/') { - strcpy(p, p+1); - } - if (p) { + p = strpbrk(p, "/\\"); + if (p != NULL) { + if (IsPathSeparator(p[1])) { + strcpy(p, p+1); + } p++; } } @@ -135,9 +173,30 @@ void build_attr_output_fnames(JCR *jcr, ATTR *attr) * every filename if a prefix is supplied. * */ - if (jcr->where[0] == 0) { + + if (jcr->where_bregexp) { + char *ret; + apply_bregexps(attr->fname, jcr->where_bregexp, &ret); + pm_strcpy(attr->ofname, ret); + + if (attr->type == FT_LNKSAVED || attr->type == FT_LNK) { + /* Always add prefix to hard links (FT_LNKSAVED) and + * on user request to soft links + */ + + if ((attr->type == FT_LNKSAVED || jcr->prefix_links)) { + apply_bregexps(attr->lname, jcr->where_bregexp, &ret); + pm_strcpy(attr->olname, ret); + + } else { + pm_strcpy(attr->olname, attr->lname); + } + } + + } else if (jcr->where[0] == 0) { pm_strcpy(attr->ofname, attr->fname); pm_strcpy(attr->olname, attr->lname); + } else { const char *fn; int wherelen = strlen(jcr->where); @@ -149,7 +208,7 @@ void build_attr_output_fnames(JCR *jcr, ATTR *attr) #endif fn = attr->fname; /* take whole name */ /* Ensure where is terminated with a slash */ - if (jcr->where[wherelen-1] != '/' && fn[0] != '/') { + if (!IsPathSeparator(jcr->where[wherelen-1]) && !IsPathSeparator(fn[0])) { pm_strcat(attr->ofname, "/"); } pm_strcat(attr->ofname, fn); /* copy rest of name */ @@ -161,7 +220,7 @@ void build_attr_output_fnames(JCR *jcr, ATTR *attr) /* Always add prefix to hard links (FT_LNKSAVED) and * on user request to soft links */ - if (attr->lname[0] == '/' && + if (IsPathSeparator(attr->lname[0]) && (attr->type == FT_LNKSAVED || jcr->prefix_links)) { pm_strcpy(attr->olname, jcr->where); add_link = true; @@ -177,15 +236,17 @@ void build_attr_output_fnames(JCR *jcr, ATTR *attr) #endif fn = attr->lname; /* take whole name */ /* Ensure where is terminated with a slash */ - if (add_link && jcr->where[wherelen-1] != '/' && fn[0] != '/') { + if (add_link && + !IsPathSeparator(jcr->where[wherelen-1]) && + !IsPathSeparator(fn[0])) { pm_strcat(attr->olname, "/"); } pm_strcat(attr->olname, fn); /* copy rest of link */ } } #if defined(HAVE_WIN32) - strip_double_slashes(attr->ofname); - strip_double_slashes(attr->olname); + strip_double_slashes(attr->ofname); + strip_double_slashes(attr->olname); #endif } @@ -201,12 +262,26 @@ void print_ls_output(JCR *jcr, ATTR *attr) char ec1[30]; char en1[30], en2[30]; char *p, *f; + guid_list *guid; + if (attr->type == FT_DELETED) { /* TODO: change this to get last seen values */ + bsnprintf(buf, sizeof(buf), + "---------- - - - - ---------- -------- %s\n", attr->ofname); + Dmsg1(dbglvl, "%s", buf); + Jmsg(jcr, M_RESTORED, 1, "%s", buf); + return; + } + + if (!jcr->id_list) { + jcr->id_list = new_guid_list(); + } + guid = jcr->id_list; p = encode_mode(attr->statp.st_mode, buf); p += sprintf(p, " %2d ", (uint32_t)attr->statp.st_nlink); - p += sprintf(p, "%-8.8s %-8.8s", getuser(attr->statp.st_uid, en1, sizeof(en1)), - getgroup(attr->statp.st_gid, en2, sizeof(en2))); - p += sprintf(p, "%10.10s ", edit_uint64(attr->statp.st_size, ec1)); + p += sprintf(p, "%-8.8s %-8.8s", + guid->uid_to_name(attr->statp.st_uid, en1, sizeof(en1)), + guid->gid_to_name(attr->statp.st_gid, en2, sizeof(en2))); + p += sprintf(p, "%12.12s ", edit_int64(attr->statp.st_size, ec1)); p = encode_time(attr->statp.st_ctime, p); *p++ = ' '; *p++ = ' '; @@ -225,6 +300,6 @@ void print_ls_output(JCR *jcr, ATTR *attr) } *p++ = '\n'; *p = 0; - Dmsg1(20, "%s", buf); + Dmsg1(dbglvl, "%s", buf); Jmsg(jcr, M_RESTORED, 1, "%s", buf); }