2 * attr.c Unpack an Attribute record returned from the tape
4 * Kern Sibbald, June MMIII (code pulled from filed/restore.c and updated)
10 Copyright (C) 2000, 2001, 2002 Kern Sibbald and John Walker
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.
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.
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,
32 extern int win32_client;
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 attr->attrEx = get_pool_memory(PM_FNAME);
44 void free_attr(ATTR *attr)
46 free_pool_memory(attr->olname);
47 free_pool_memory(attr->ofname);
48 free_pool_memory(attr->attrEx);
52 int unpack_attributes_record(JCR *jcr, int32_t stream, char *rec, ATTR *attr)
56 * An Attributes record consists of:
61 * Link name (if file linked i.e. FT_LNK)
62 * Extended attributes (Win32)
63 * plus optional values determined by AR_ flags in upper bits of Type
67 attr->stream = stream;
68 Dmsg1(100, "Attr: %s\n", rec);
69 if (sscanf(rec, "%d %d", &attr->file_index, &attr->type) != 2) {
70 Jmsg(jcr, M_FATAL, 0, _("Error scanning attributes: %s\n"), rec);
71 Dmsg1(100, "\nError scanning attributes. %s\n", rec);
74 Dmsg2(100, "Got Attr: FilInx=%d type=%d\n", attr->file_index, attr->type);
75 if (attr->type & AR_DATA_STREAM) {
76 attr->data_stream = 1;
78 attr->data_stream = 0;
80 attr->type &= FT_MASK; /* keep only type bits */
82 while (*p++ != ' ') /* skip record file index */
84 while (*p++ != ' ') /* skip type */
87 attr->fname = p; /* set filname position */
88 while (*p++ != 0) /* skip filename */
90 attr->attr = p; /* set attributes position */
91 while (*p++ != 0) /* skip attributes */
93 attr->lname = p; /* set link position */
94 while (*p++ != 0) /* skip link */
96 pm_strcpy(&attr->attrEx, p); /* copy extended attributes, if any */
98 if (attr->data_stream) {
100 while (*p++ != 0) /* skip extended attributes */
102 from_base64(&val, p);
103 attr->data_stream = (int32_t)val;
105 Dmsg7(200, "unpack_attr FI=%d Type=%d fname=%s attr=%s lname=%s attrEx=%s ds=%d\n",
106 attr->file_index, attr->type, attr->fname, attr->attr, attr->lname,
107 attr->attrEx, attr->data_stream);
108 *mp_chr(attr->ofname) = 0;
109 *mp_chr(attr->olname) = 0;
114 * Build attr->ofname from attr->fname and
115 * attr->olname from attr->olname
117 void build_attr_output_fnames(JCR *jcr, ATTR *attr)
120 * Prepend the where directory so that the
121 * files are put where the user wants.
123 * We do a little jig here to handle Win32 files with
124 * a drive letter -- we simply strip the drive: from
125 * every filename if a prefix is supplied.
128 if (jcr->where[0] == 0) {
129 pm_strcpy(&attr->ofname, attr->fname);
130 pm_strcpy(&attr->olname, attr->lname);
133 int wherelen = strlen(jcr->where);
134 pm_strcpy(&attr->ofname, jcr->where); /* copy prefix */
135 if (win32_client && attr->fname[1] == ':') {
136 fn = attr->fname+2; /* skip over drive: */
138 fn = attr->fname; /* take whole name */
140 /* Ensure where is terminated with a slash */
141 if (jcr->where[wherelen-1] != '/' && fn[0] != '/') {
142 pm_strcat(&attr->ofname, "/");
144 pm_strcat(&attr->ofname, fn); /* copy rest of name */
146 * Fixup link name -- if it is an absolute path
148 if (attr->type == FT_LNKSAVED || attr->type == FT_LNK) {
150 /* Always add prefix to hard links (FT_LNKSAVED) and
151 * on user request to soft links
153 if (attr->lname[0] == '/' &&
154 (attr->type == FT_LNKSAVED || jcr->prefix_links)) {
155 pm_strcpy(&attr->olname, jcr->where);
158 mp_chr(attr->olname)[0] = 0;
161 if (win32_client && attr->lname[1] == ':') {
162 fn = attr->lname+2; /* skip over drive: */
164 fn = attr->lname; /* take whole name */
166 /* Ensure where is terminated with a slash */
167 if (add_link && jcr->where[wherelen-1] != '/' && fn[0] != '/') {
168 pm_strcat(&attr->olname, "/");
170 pm_strcat(&attr->olname, fn); /* copy rest of link */
175 extern char *getuser(uid_t uid);
176 extern char *getgroup(gid_t gid);
179 * Print an ls style message, also send M_RESTORED
181 void print_ls_output(JCR *jcr, ATTR *attr)
187 p = encode_mode(attr->statp.st_mode, buf);
188 p += sprintf(p, " %2d ", (uint32_t)attr->statp.st_nlink);
189 p += sprintf(p, "%-8.8s %-8.8s", getuser(attr->statp.st_uid), getgroup(attr->statp.st_gid));
190 p += sprintf(p, "%8.8s ", edit_uint64(attr->statp.st_size, ec1));
191 p = encode_time(attr->statp.st_ctime, p);
194 for (f=mp_chr(attr->ofname); *f && (p-buf) < (int)sizeof(buf)-10; ) {
197 if (attr->type == FT_LNK) {
203 for (f=mp_chr(attr->olname); *f && (p-buf) < (int)sizeof(buf)-10; ) {
209 Dmsg1(20, "%s", buf);
210 Jmsg(jcr, M_RESTORED, 0, "%s", buf);