2 * attr.c Unpack an Attribute record returned from the tape
4 * Kern Sibbald, June MMIII (code pulled from filed/restore.c and updated)
9 Copyright (C) 2003-2005 Kern Sibbald
11 This program is free software; you can redistribute it and/or
12 modify it under the terms of the GNU General Public License
13 version 2 as ammended with additional clauses defined in the
14 file LICENSE in the main source directory.
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 the file LICENSE for additional details.
26 extern const int win32_client;
30 ATTR *attr = (ATTR *)malloc(sizeof(ATTR));
31 memset(attr, 0, sizeof(ATTR));
32 attr->ofname = get_pool_memory(PM_FNAME);
33 attr->olname = get_pool_memory(PM_FNAME);
34 attr->attrEx = get_pool_memory(PM_FNAME);
38 void free_attr(ATTR *attr)
40 free_pool_memory(attr->olname);
41 free_pool_memory(attr->ofname);
42 free_pool_memory(attr->attrEx);
46 int unpack_attributes_record(JCR *jcr, int32_t stream, char *rec, ATTR *attr)
50 * An Attributes record consists of:
55 * Link name (if file linked i.e. FT_LNK)
56 * Extended attributes (Win32)
57 * plus optional values determined by AR_ flags in upper bits of Type
61 attr->stream = stream;
62 Dmsg1(100, "Attr: %s\n", rec);
63 if (sscanf(rec, "%d %d", &attr->file_index, &attr->type) != 2) {
64 Jmsg(jcr, M_FATAL, 0, _("Error scanning attributes: %s\n"), rec);
65 Dmsg1(100, "\nError scanning attributes. %s\n", rec);
68 Dmsg2(100, "Got Attr: FilInx=%d type=%d\n", attr->file_index, attr->type);
69 if (attr->type & AR_DATA_STREAM) {
70 attr->data_stream = 1;
72 attr->data_stream = 0;
74 attr->type &= FT_MASK; /* keep only type bits */
76 while (*p++ != ' ') /* skip record file index */
78 while (*p++ != ' ') /* skip type */
81 attr->fname = p; /* set filname position */
82 while (*p++ != 0) /* skip filename */
84 attr->attr = p; /* set attributes position */
85 while (*p++ != 0) /* skip attributes */
87 attr->lname = p; /* set link position */
88 while (*p++ != 0) /* skip link */
90 pm_strcpy(attr->attrEx, p); /* copy extended attributes, if any */
92 if (attr->data_stream) {
94 while (*p++ != 0) /* skip extended attributes */
97 attr->data_stream = (int32_t)val;
99 Dmsg7(200, "unpack_attr FI=%d Type=%d fname=%s attr=%s lname=%s attrEx=%s ds=%d\n",
100 attr->file_index, attr->type, attr->fname, attr->attr, attr->lname,
101 attr->attrEx, attr->data_stream);
107 static void strip_double_slashes(char *fname)
112 if (p && p[1] == '/') {
122 * Build attr->ofname from attr->fname and
123 * attr->olname from attr->olname
125 void build_attr_output_fnames(JCR *jcr, ATTR *attr)
128 * Prepend the where directory so that the
129 * files are put where the user wants.
131 * We do a little jig here to handle Win32 files with
132 * a drive letter -- we simply change the drive
133 * from, for example, c: to c/ for
134 * every filename if a prefix is supplied.
137 if (jcr->where[0] == 0) {
138 pm_strcpy(attr->ofname, attr->fname);
139 pm_strcpy(attr->olname, attr->lname);
142 int wherelen = strlen(jcr->where);
143 pm_strcpy(attr->ofname, jcr->where); /* copy prefix */
144 if (win32_client && attr->fname[1] == ':') {
145 attr->fname[1] = '/'; /* convert : to / */
147 fn = attr->fname; /* take whole name */
148 /* Ensure where is terminated with a slash */
149 if (jcr->where[wherelen-1] != '/' && fn[0] != '/') {
150 pm_strcat(attr->ofname, "/");
152 pm_strcat(attr->ofname, fn); /* copy rest of name */
154 * Fixup link name -- if it is an absolute path
156 if (attr->type == FT_LNKSAVED || attr->type == FT_LNK) {
158 /* Always add prefix to hard links (FT_LNKSAVED) and
159 * on user request to soft links
161 if (attr->lname[0] == '/' &&
162 (attr->type == FT_LNKSAVED || jcr->prefix_links)) {
163 pm_strcpy(attr->olname, jcr->where);
169 if (win32_client && attr->lname[1] == ':') {
170 attr->lname[1] = '/'; /* turn : into / */
172 fn = attr->lname; /* take whole name */
173 /* Ensure where is terminated with a slash */
174 if (add_link && jcr->where[wherelen-1] != '/' && fn[0] != '/') {
175 pm_strcat(attr->olname, "/");
177 pm_strcat(attr->olname, fn); /* copy rest of link */
181 strip_double_slashes(attr->ofname);
182 strip_double_slashes(attr->olname);
186 extern char *getuser(uid_t uid, char *name, int len);
187 extern char *getgroup(gid_t gid, char *name, int len);
190 * Print an ls style message, also send M_RESTORED
192 void print_ls_output(JCR *jcr, ATTR *attr)
196 char en1[30], en2[30];
199 p = encode_mode(attr->statp.st_mode, buf);
200 p += sprintf(p, " %2d ", (uint32_t)attr->statp.st_nlink);
201 p += sprintf(p, "%-8.8s %-8.8s", getuser(attr->statp.st_uid, en1, sizeof(en1)),
202 getgroup(attr->statp.st_gid, en2, sizeof(en2)));
203 p += sprintf(p, "%8.8s ", edit_uint64(attr->statp.st_size, ec1));
204 p = encode_time(attr->statp.st_ctime, p);
207 for (f=attr->ofname; *f && (p-buf) < (int)sizeof(buf)-10; ) {
210 if (attr->type == FT_LNK) {
216 for (f=attr->olname; *f && (p-buf) < (int)sizeof(buf)-10; ) {
222 Dmsg1(20, "%s", buf);
223 Jmsg(jcr, M_RESTORED, 1, "%s", buf);