]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/lib/attr.c
Reorganize regex code
[bacula/bacula] / bacula / src / lib / attr.c
1 /*
2    Bacula® - The Network Backup Solution
3
4    Copyright (C) 2003-2010 Free Software Foundation Europe e.V.
5
6    The main author of Bacula is Kern Sibbald, with contributions from
7    many others, a complete list can be found in the file AUTHORS.
8    This program is Free Software; you can redistribute it and/or
9    modify it under the terms of version two of the GNU General Public
10    License as published by the Free Software Foundation and included
11    in the file LICENSE.
12
13    This program is distributed in the hope that it will be useful, but
14    WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16    General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21    02110-1301, USA.
22
23    Bacula® is a registered trademark of Kern Sibbald.
24    The licensor of Bacula is the Free Software Foundation Europe
25    (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
26    Switzerland, email:ftf@fsfeurope.org.
27 */
28 /*
29  *   attr.c  Unpack an Attribute record returned from the tape
30  *
31  *    Kern Sibbald, June MMIII  (code pulled from filed/restore.c and updated)
32  *
33  */
34
35
36 #include "bacula.h"
37 #include "jcr.h"
38 #include "lib/breg.h"
39
40 ATTR *new_attr(JCR *jcr)
41 {
42    ATTR *attr = (ATTR *)malloc(sizeof(ATTR));
43    memset(attr, 0, sizeof(ATTR));
44    attr->ofname = get_pool_memory(PM_FNAME);
45    attr->olname = get_pool_memory(PM_FNAME);
46    attr->attrEx = get_pool_memory(PM_FNAME);
47    attr->jcr = jcr;
48    attr->uid = getuid();
49    return attr;
50 }
51
52 void free_attr(ATTR *attr)
53 {
54    free_pool_memory(attr->olname);
55    free_pool_memory(attr->ofname);
56    free_pool_memory(attr->attrEx);
57    free(attr);
58 }
59
60 int unpack_attributes_record(JCR *jcr, int32_t stream, char *rec, int32_t reclen, ATTR *attr)
61 {
62    char *p;
63    int object_len;
64    /*
65     * An Attributes record consists of:
66     *    File_index
67     *    Type   (FT_types)
68     *    Filename
69     *    Attributes
70     *    Link name (if file linked i.e. FT_LNK)
71     *    Extended attributes (Win32)
72     *  plus optional values determined by AR_ flags in upper bits of Type
73     *    Data_stream
74     *
75     */
76    attr->stream = stream;
77    Dmsg1(400, "Attr: %s\n", rec);
78    if (sscanf(rec, "%d %d", &attr->file_index, &attr->type) != 2) {
79       Jmsg(jcr, M_FATAL, 0, _("Error scanning attributes: %s\n"), rec);
80       Dmsg1(100, "\nError scanning attributes. %s\n", rec);
81       return 0;
82    }
83    Dmsg2(400, "Got Attr: FilInx=%d type=%d\n", attr->file_index, attr->type);
84    if (attr->type & AR_DATA_STREAM) {
85       attr->data_stream = 1;
86    } else {
87       attr->data_stream = 0;
88    }
89    attr->type &= FT_MASK;             /* keep only type bits */
90    p = rec;
91    while (*p++ != ' ')               /* skip record file index */
92       { }
93    while (*p++ != ' ')               /* skip type */
94       { }
95
96    attr->fname = p;                   /* set filname position */
97    while (*p++ != 0)                  /* skip filename */
98       { }
99    attr->attr = p;                    /* set attributes position */
100    while (*p++ != 0)                  /* skip attributes */
101       { }
102    attr->lname = p;                   /* set link position */
103    while (*p++ != 0)                  /* skip link */
104       { }
105    if (attr->type == FT_RESTORE_FIRST) {
106       /* We have an object, so do a binary copy */
107       object_len = reclen + rec - p;
108       attr->attrEx = check_pool_memory_size(attr->attrEx, object_len + 1);
109       memcpy(attr->attrEx, p, object_len);  
110       /* Add a EOS for those who attempt to print the object */
111       p = attr->attrEx + object_len;
112       *p = 0;
113    } else {
114       pm_strcpy(attr->attrEx, p);     /* copy extended attributes, if any */
115       if (attr->data_stream) {
116          int64_t val;
117          while (*p++ != 0)               /* skip extended attributes */
118             { }
119          from_base64(&val, p);
120          attr->data_stream = (int32_t)val;
121       }
122    }
123    Dmsg7(400, "unpack_attr FI=%d Type=%d fname=%s attr=%s lname=%s attrEx=%s ds=%d\n",
124       attr->file_index, attr->type, attr->fname, attr->attr, attr->lname,
125       attr->attrEx, attr->data_stream);
126    *attr->ofname = 0;
127    *attr->olname = 0;
128    return 1;
129 }
130
131 #if defined(HAVE_WIN32)
132 static void strip_double_slashes(char *fname)
133 {
134    char *p = fname;
135    while (p && *p) {
136       p = strpbrk(p, "/\\");
137       if (p != NULL) {
138          if (IsPathSeparator(p[1])) {
139             strcpy(p, p+1);
140          }
141          p++;
142       }
143    }
144 }
145 #endif
146
147 /*
148  * Build attr->ofname from attr->fname and
149  *       attr->olname from attr->olname
150  */
151 void build_attr_output_fnames(JCR *jcr, ATTR *attr)
152 {
153    /*
154     * Prepend the where directory so that the
155     * files are put where the user wants.
156     *
157     * We do a little jig here to handle Win32 files with
158     *   a drive letter -- we simply change the drive
159     *   from, for example, c: to c/ for
160     *   every filename if a prefix is supplied.
161     *
162     */
163
164    if (jcr->where_bregexp) { 
165       char *ret;
166       apply_bregexps(attr->fname, jcr->where_bregexp, &ret);
167       pm_strcpy(attr->ofname, ret);
168
169       if (attr->type == FT_LNKSAVED || attr->type == FT_LNK) {
170          /* Always add prefix to hard links (FT_LNKSAVED) and
171           *  on user request to soft links
172           */
173
174          if ((attr->type == FT_LNKSAVED || jcr->prefix_links)) {
175             apply_bregexps(attr->lname, jcr->where_bregexp, &ret);
176             pm_strcpy(attr->olname, ret);
177
178          } else {
179             pm_strcpy(attr->olname, attr->lname);
180          }
181       }
182       
183    } else if (jcr->where[0] == 0) {
184       pm_strcpy(attr->ofname, attr->fname);
185       pm_strcpy(attr->olname, attr->lname);
186
187    } else {
188       const char *fn;
189       int wherelen = strlen(jcr->where);
190       pm_strcpy(attr->ofname, jcr->where);  /* copy prefix */
191 #if defined(HAVE_WIN32)
192       if (attr->fname[1] == ':') {
193          attr->fname[1] = '/';     /* convert : to / */
194       }
195 #endif
196       fn = attr->fname;            /* take whole name */
197       /* Ensure where is terminated with a slash */
198       if (!IsPathSeparator(jcr->where[wherelen-1]) && !IsPathSeparator(fn[0])) {
199          pm_strcat(attr->ofname, "/");
200       }
201       pm_strcat(attr->ofname, fn); /* copy rest of name */
202       /*
203        * Fixup link name -- if it is an absolute path
204        */
205       if (attr->type == FT_LNKSAVED || attr->type == FT_LNK) {
206          bool add_link;
207          /* Always add prefix to hard links (FT_LNKSAVED) and
208           *  on user request to soft links
209           */
210          if (IsPathSeparator(attr->lname[0]) &&
211              (attr->type == FT_LNKSAVED || jcr->prefix_links)) {
212             pm_strcpy(attr->olname, jcr->where);
213             add_link = true;
214          } else {
215             attr->olname[0] = 0;
216             add_link = false;
217          }
218
219 #if defined(HAVE_WIN32)
220          if (attr->lname[1] == ':') {
221             attr->lname[1] = '/';    /* turn : into / */
222          }
223 #endif
224          fn = attr->lname;       /* take whole name */
225          /* Ensure where is terminated with a slash */
226          if (add_link && 
227             !IsPathSeparator(jcr->where[wherelen-1]) && 
228             !IsPathSeparator(fn[0])) {
229             pm_strcat(attr->olname, "/");
230          }
231          pm_strcat(attr->olname, fn);     /* copy rest of link */
232       }
233    }
234 #if defined(HAVE_WIN32)
235    strip_double_slashes(attr->ofname);
236    strip_double_slashes(attr->olname);
237 #endif
238 }
239
240 extern char *getuser(uid_t uid, char *name, int len);
241 extern char *getgroup(gid_t gid, char *name, int len);
242
243 /*
244  * Print an ls style message, also send M_RESTORED
245  */
246 void print_ls_output(JCR *jcr, ATTR *attr)
247 {
248    char buf[5000];
249    char ec1[30];
250    char en1[30], en2[30];
251    char *p, *f;
252    guid_list *guid;
253
254    if (attr->type == FT_DELETED) { /* TODO: change this to get last seen values */
255       bsnprintf(buf, sizeof(buf),
256                 "----------   - -        -                - ---------- --------  %s\n", attr->ofname);
257       Dmsg1(20, "%s", buf);
258       Jmsg(jcr, M_RESTORED, 1, "%s", buf);
259       return;
260    }
261
262    if (!jcr->id_list) {
263       jcr->id_list = new_guid_list();
264    }
265    guid = jcr->id_list;
266    p = encode_mode(attr->statp.st_mode, buf);
267    p += sprintf(p, "  %2d ", (uint32_t)attr->statp.st_nlink);
268    p += sprintf(p, "%-8.8s %-8.8s", 
269                 guid->uid_to_name(attr->statp.st_uid, en1, sizeof(en1)),
270                 guid->gid_to_name(attr->statp.st_gid, en2, sizeof(en2)));
271    p += sprintf(p, "%12.12s ", edit_int64(attr->statp.st_size, ec1));
272    p = encode_time(attr->statp.st_ctime, p);
273    *p++ = ' ';
274    *p++ = ' ';
275    for (f=attr->ofname; *f && (p-buf) < (int)sizeof(buf)-10; ) {
276       *p++ = *f++;
277    }
278    if (attr->type == FT_LNK) {
279       *p++ = ' ';
280       *p++ = '-';
281       *p++ = '>';
282       *p++ = ' ';
283       /* Copy link name */
284       for (f=attr->olname; *f && (p-buf) < (int)sizeof(buf)-10; ) {
285          *p++ = *f++;
286       }
287    }
288    *p++ = '\n';
289    *p = 0;
290    Dmsg1(20, "%s", buf);
291    Jmsg(jcr, M_RESTORED, 1, "%s", buf);
292 }