]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/lib/attr.c
Doc updates + fixed win32 crash in idcache cleanups + dlist class
[bacula/bacula] / bacula / src / lib / attr.c
1 /*
2  *   attr.c  Unpack an Attribute record returned from the tape
3  * 
4  *    Kern Sibbald, June MMIII  (code pulled from filed/restore.c and updated)
5  *
6  *   Version $Id$
7  */
8
9 /*
10    Copyright (C) 2000, 2001, 2002 Kern Sibbald and John Walker
11
12    This program is free software; you can redistribute it and/or
13    modify it under the terms of the GNU General Public License as
14    published by the Free Software Foundation; either version 2 of
15    the License, or (at your option) any later version.
16
17    This program is distributed in the hope that it will be useful,
18    but WITHOUT ANY WARRANTY; without even the implied warranty of
19    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20    General Public License for more details.
21
22    You should have received a copy of the GNU General Public
23    License along with this program; if not, write to the Free
24    Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
25    MA 02111-1307, USA.
26
27  */
28
29 #include "bacula.h"
30 #include "jcr.h"
31
32 extern int win32_client;
33
34 ATTR *new_attr()
35 {
36    ATTR *attr = (ATTR *)malloc(sizeof(ATTR));
37    memset(attr, 0, sizeof(ATTR));
38    attr->ofname = get_pool_memory(PM_FNAME);
39    attr->olname = get_pool_memory(PM_FNAME);
40    return attr;
41 }
42
43 void free_attr(ATTR *attr)
44 {
45    free_pool_memory(attr->olname);
46    free_pool_memory(attr->ofname);
47    free(attr);
48 }
49
50 int unpack_attributes_record(JCR *jcr, int32_t stream, char *rec, ATTR *attr)
51 {
52    char *p;
53    /*              
54     * An Attributes record consists of:
55     *    File_index
56     *    Type   (FT_types)
57     *    Filename
58     *    Attributes
59     *    Link name (if file linked i.e. FT_LNK)
60     *    Extended attributes (Win32)
61     *  plus optional values determined by AR_ flags in upper bits of Type
62     *    Data_stream
63     *
64     */
65    attr->stream = stream;
66    Dmsg1(100, "Attr: %s\n", rec);
67    if (sscanf(rec, "%d %d", &attr->file_index, &attr->type) != 2) {
68       Jmsg(jcr, M_FATAL, 0, _("Error scanning attributes: %s\n"), rec);
69       Dmsg1(100, "\nError scanning attributes. %s\n", rec);
70       return 0;
71    }
72    Dmsg2(100, "Got Attr: FilInx=%d type=%d\n", attr->file_index, attr->type);
73    if (attr->type & AR_DATA_STREAM) {
74       attr->data_stream = 1;
75    } else {
76       attr->data_stream = 0;
77    }
78    attr->type &= FT_MASK;             /* keep only type bits */
79    p = rec;
80    while (*p++ != ' ')               /* skip record file index */
81       { }
82    while (*p++ != ' ')               /* skip type */
83       { }
84    
85    attr->fname = p;                   /* set filname position */
86    while (*p++ != 0)                  /* skip filename */
87       { }
88    attr->attr = p;                    /* set attributes position */
89    while (*p++ != 0)                  /* skip attributes */
90       { }
91    attr->lname = p;                   /* set link position */
92    while (*p++ != 0)                  /* skip link */
93       { }
94    attr->attrEx = p;                  /* set extended attributes position */
95
96    if (attr->data_stream) {
97       int64_t val;
98       while (*p++ != 0)               /* skip extended attributes */
99          { }
100       from_base64(&val, p);
101       attr->data_stream = (int32_t)val;
102    }
103    Dmsg7(200, "unpack_attr FI=%d Type=%d fname=%s attr=%s lname=%s attrEx=%s ds=%d\n",
104       attr->file_index, attr->type, attr->fname, attr->attr, attr->lname,
105       attr->attrEx, attr->data_stream);
106    *mp_chr(attr->ofname) = 0;
107    *mp_chr(attr->olname) = 0;
108    return 1;
109 }
110
111 /*
112  * Build attr->ofname from attr->fname and
113  *       attr->olname from attr->olname 
114  */
115 void build_attr_output_fnames(JCR *jcr, ATTR *attr)
116 {
117    /*
118     * Prepend the where directory so that the
119     * files are put where the user wants.
120     *
121     * We do a little jig here to handle Win32 files with
122     *   a drive letter -- we simply strip the drive: from
123     *   every filename if a prefix is supplied.
124     *     
125     */
126    if (jcr->where[0] == 0) {
127       pm_strcpy(&attr->ofname, attr->fname);
128       pm_strcpy(&attr->olname, attr->lname);
129    } else {
130       char *fn;
131       int wherelen = strlen(jcr->where);
132       pm_strcpy(&attr->ofname, jcr->where);  /* copy prefix */
133       if (win32_client && attr->fname[1] == ':') {
134          fn = attr->fname+2;          /* skip over drive: */
135       } else {
136          fn = attr->fname;            /* take whole name */
137       }
138       /* Ensure where is terminated with a slash */
139       if (jcr->where[wherelen-1] != '/' && fn[0] != '/') {
140          pm_strcat(&attr->ofname, "/");
141       }   
142       pm_strcat(&attr->ofname, fn); /* copy rest of name */
143       /*
144        * Fixup link name -- if it is an absolute path
145        */
146       if (attr->type == FT_LNKSAVED || attr->type == FT_LNK) {
147          bool add_link;
148          /* Always add prefix to hard links (FT_LNKSAVED) and
149           *  on user request to soft links
150           */
151          if (attr->lname[0] == '/' &&
152              (attr->type == FT_LNKSAVED || jcr->prefix_links)) {
153             pm_strcpy(&attr->olname, jcr->where);
154             add_link = true;
155          } else {
156             mp_chr(attr->olname)[0] = 0;
157             add_link = false;
158          }
159          if (win32_client && attr->lname[1] == ':') {
160             fn = attr->lname+2;     /* skip over drive: */
161          } else {
162             fn = attr->lname;       /* take whole name */
163          }
164          /* Ensure where is terminated with a slash */
165          if (add_link && jcr->where[wherelen-1] != '/' && fn[0] != '/') {
166             pm_strcat(&attr->olname, "/");
167          }   
168          pm_strcat(&attr->olname, fn);     /* copy rest of link */
169       }
170    }
171 }
172
173 extern char *getuser(uid_t uid);
174 extern char *getgroup(gid_t gid);
175
176 /*
177  * Print an ls style message, also send M_RESTORED
178  */
179 void print_ls_output(JCR *jcr, ATTR *attr)
180 {
181    char buf[5000]; 
182    char ec1[30];
183    char *p, *f;
184
185    p = encode_mode(attr->statp.st_mode, buf);
186    p += sprintf(p, "  %2d ", (uint32_t)attr->statp.st_nlink);
187    p += sprintf(p, "%-8.8s %-8.8s", getuser(attr->statp.st_uid), getgroup(attr->statp.st_gid));
188    p += sprintf(p, "%8.8s ", edit_uint64(attr->statp.st_size, ec1));
189    p = encode_time(attr->statp.st_ctime, p);
190    *p++ = ' ';
191    *p++ = ' ';
192    for (f=mp_chr(attr->ofname); *f && (p-buf) < (int)sizeof(buf)-10; ) {
193       *p++ = *f++;
194    }
195    if (attr->type == FT_LNK) {
196       *p++ = ' ';
197       *p++ = '-';
198       *p++ = '>';
199       *p++ = ' ';
200       /* Copy link name */
201       for (f=mp_chr(attr->olname); *f && (p-buf) < (int)sizeof(buf)-10; ) {
202          *p++ = *f++;
203       }
204    }
205    *p++ = '\n';
206    *p = 0;
207    Dmsg1(20, "%s", buf);
208    Jmsg(jcr, M_RESTORED, 0, "%s", buf);
209 }