X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=bacula%2Fsrc%2Flib%2Fattr.c;h=c05a66c467b9a0bd8cfacffc49d05b25e0285093;hb=897707854a8240d026e933215009f931bb9c5762;hp=4147da5670a6690313eca4e97d662e628170b60d;hpb=2623d16dc34cd3c3fab846c498a4d55e7a3e6110;p=bacula%2Fbacula diff --git a/bacula/src/lib/attr.c b/bacula/src/lib/attr.c index 4147da5670..c05a66c467 100644 --- a/bacula/src/lib/attr.c +++ b/bacula/src/lib/attr.c @@ -1,42 +1,53 @@ /* - * attr.c Unpack an Attribute record returned from the tape - * - * Kern Sibbald, June MMIII (code pulled from filed/restore.c and updated) - * - * Version $Id$ - */ + Bacula® - The Network Backup Solution -/* - Copyright (C) 2000, 2001, 2002 Kern Sibbald and John Walker + Copyright (C) 2003-2010 Free Software Foundation Europe e.V. - 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. + 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 + 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., 59 Temple Place - Suite 330, Boston, - MA 02111-1307, USA. + 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) + * */ + #include "bacula.h" #include "jcr.h" +#include "lib/breg.h" -extern int win32_client; +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; } @@ -44,73 +55,111 @@ void free_attr(ATTR *attr) { free_pool_memory(attr->olname); free_pool_memory(attr->ofname); + free_pool_memory(attr->attrEx); 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 - * Type (FT_types) - * Filename - * Attributes - * Link name (if file linked i.e. FT_LNK) - * Extended attributes (Win32) + * File_index + * Type (FT_types) + * Filename + * Attributes + * Link name (if file linked i.e. FT_LNK) + * Extended attributes (Win32) * plus optional values determined by AR_ flags in upper bits of Type - * Data_stream + * Data_stream * */ attr->stream = stream; - Dmsg1(100, "Attr: %s\n", rec); + 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(100, "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 { attr->data_stream = 0; } - attr->type &= FT_MASK; /* keep only type bits */ + attr->type &= FT_MASK; /* keep only type bits */ p = rec; while (*p++ != ' ') /* skip record file index */ { } while (*p++ != ' ') /* skip type */ { } - - attr->fname = p; /* set filname position */ - while (*p++ != 0) /* skip filename */ + + attr->fname = p; /* set filname position */ + while (*p++ != 0) /* skip filename */ { } - attr->attr = p; /* set attributes position */ - while (*p++ != 0) /* skip attributes */ + attr->attr = p; /* set attributes position */ + while (*p++ != 0) /* skip attributes */ { } - attr->lname = p; /* set link position */ - while (*p++ != 0) /* skip link */ + attr->lname = p; /* set link position */ + while (*p++ != 0) /* skip link */ { } - attr->attrEx = p; /* set extended attributes position */ - - 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(200, "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); - *mp_chr(attr->ofname) = 0; - *mp_chr(attr->olname) = 0; + attr->attrEx, attr->data_stream, attr->delta_seq); + *attr->ofname = 0; + *attr->olname = 0; return 1; } +#if defined(HAVE_WIN32) +static void strip_double_slashes(char *fname) +{ + char *p = fname; + while (p && *p) { + p = strpbrk(p, "/\\"); + if (p != NULL) { + if (IsPathSeparator(p[1])) { + strcpy(p, p+1); + } + p++; + } + } +} +#endif + /* * Build attr->ofname from attr->fname and - * attr->olname from attr->olname + * attr->olname from attr->olname */ void build_attr_output_fnames(JCR *jcr, ATTR *attr) { @@ -119,81 +168,124 @@ void build_attr_output_fnames(JCR *jcr, ATTR *attr) * files are put where the user wants. * * We do a little jig here to handle Win32 files with - * a drive letter -- we simply strip the drive: from - * every filename if a prefix is supplied. - * + * a drive letter -- we simply change the drive + * from, for example, c: to c/ for + * every filename if a prefix is supplied. + * */ - if (jcr->where[0] == 0) { - pm_strcpy(&attr->ofname, attr->fname); - pm_strcpy(&attr->olname, attr->lname); + + 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 { - char *fn; + const char *fn; int wherelen = strlen(jcr->where); - pm_strcpy(&attr->ofname, jcr->where); /* copy prefix */ - if (win32_client && attr->fname[1] == ':') { - fn = attr->fname+2; /* skip over drive: */ - } else { - fn = attr->fname; /* take whole name */ + pm_strcpy(attr->ofname, jcr->where); /* copy prefix */ +#if defined(HAVE_WIN32) + if (attr->fname[1] == ':') { + attr->fname[1] = '/'; /* convert : to / */ } +#endif + fn = attr->fname; /* take whole name */ /* Ensure where is terminated with a slash */ - if (jcr->where[wherelen-1] != '/' && fn[0] != '/') { - pm_strcat(&attr->ofname, "/"); - } - pm_strcat(&attr->ofname, fn); /* copy rest of name */ + if (!IsPathSeparator(jcr->where[wherelen-1]) && !IsPathSeparator(fn[0])) { + pm_strcat(attr->ofname, "/"); + } + pm_strcat(attr->ofname, fn); /* copy rest of name */ /* * Fixup link name -- if it is an absolute path */ if (attr->type == FT_LNKSAVED || attr->type == FT_LNK) { - bool add_link; - /* Always add prefix to hard links (FT_LNKSAVED) and - * on user request to soft links - */ - if (attr->lname[0] == '/' && - (attr->type == FT_LNKSAVED || jcr->prefix_links)) { - pm_strcpy(&attr->olname, jcr->where); - add_link = true; - } else { - mp_chr(attr->olname)[0] = 0; - add_link = false; - } - if (win32_client && attr->lname[1] == ':') { - fn = attr->lname+2; /* skip over drive: */ - } else { - fn = attr->lname; /* take whole name */ - } - /* Ensure where is terminated with a slash */ - if (add_link && jcr->where[wherelen-1] != '/' && fn[0] != '/') { - pm_strcat(&attr->olname, "/"); - } - pm_strcat(&attr->olname, fn); /* copy rest of link */ + bool add_link; + /* Always add prefix to hard links (FT_LNKSAVED) and + * on user request to soft links + */ + if (IsPathSeparator(attr->lname[0]) && + (attr->type == FT_LNKSAVED || jcr->prefix_links)) { + pm_strcpy(attr->olname, jcr->where); + add_link = true; + } else { + attr->olname[0] = 0; + add_link = false; + } + +#if defined(HAVE_WIN32) + if (attr->lname[1] == ':') { + attr->lname[1] = '/'; /* turn : into / */ + } +#endif + fn = attr->lname; /* take whole name */ + /* Ensure where is terminated with a slash */ + 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); +#endif } -extern char *getuser(uid_t uid); -extern char *getgroup(gid_t gid); +extern char *getuser(uid_t uid, char *name, int len); +extern char *getgroup(gid_t gid, char *name, int len); /* * Print an ls style message, also send M_RESTORED */ void print_ls_output(JCR *jcr, ATTR *attr) { - char buf[5000]; + char buf[5000]; char ec1[30]; + char en1[30], en2[30]; char *p, *f; - int n; + 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); - n = sprintf(p, " %2d ", (uint32_t)attr->statp.st_nlink); - p += n; - n = sprintf(p, "%-8.8s %-8.8s", getuser(attr->statp.st_uid), getgroup(attr->statp.st_gid)); - p += n; - n = sprintf(p, "%8.8s ", edit_uint64(attr->statp.st_size, ec1)); - p += n; + p += sprintf(p, " %2d ", (uint32_t)attr->statp.st_nlink); + 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++ = ' '; - for (f=mp_chr(attr->ofname); *f && (p-buf) < (int)sizeof(buf)-10; ) { + for (f=attr->ofname; *f && (p-buf) < (int)sizeof(buf)-10; ) { *p++ = *f++; } if (attr->type == FT_LNK) { @@ -202,12 +294,12 @@ void print_ls_output(JCR *jcr, ATTR *attr) *p++ = '>'; *p++ = ' '; /* Copy link name */ - for (f=mp_chr(attr->olname); *f && (p-buf) < (int)sizeof(buf)-10; ) { - *p++ = *f++; + for (f=attr->olname; *f && (p-buf) < (int)sizeof(buf)-10; ) { + *p++ = *f++; } } *p++ = '\n'; *p = 0; - Dmsg1(20, "%s", buf); - Jmsg(jcr, M_RESTORED, 0, "%s", buf); + Dmsg1(dbglvl, "%s", buf); + Jmsg(jcr, M_RESTORED, 1, "%s", buf); }