"Fossies" - the Fresh Open Source Software Archive 
Member "dosfstools-4.2/src/file.c" (31 Jan 2021, 6770 Bytes) of package /linux/misc/dosfstools-4.2.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "file.c" see the
Fossies "Dox" file reference documentation and the latest
Fossies "Diffs" side-by-side code changes report:
4.1_vs_4.2.
1 /* file.c - Additional file attributes
2
3 Copyright (C) 1993 Werner Almesberger <werner.almesberger@lrc.di.epfl.ch>
4 Copyright (C) 1998 Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de>
5 Copyright (C) 2008-2014 Daniel Baumann <mail@daniel-baumann.ch>
6 Copyright (C) 2020 Pali Rohár <pali.rohar@gmail.com>
7
8 This program is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU 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, see <http://www.gnu.org/licenses/>.
20
21 The complete text of the GNU General Public License
22 can be found in /usr/share/common-licenses/GPL-3 file.
23 */
24
25 /* FAT32, VFAT, Atari format support, and various fixes additions May 1998
26 * by Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de> */
27
28 #include <stdlib.h>
29 #include <stdio.h>
30 #include <string.h>
31 #include <ctype.h>
32 #include <unistd.h>
33
34 #include "common.h"
35 #include "file.h"
36 #include "msdos_fs.h"
37 #include "charconv.h"
38
39 FDSC *fp_root = NULL;
40
41 static void put_char(char **p, unsigned char c, unsigned int out_size)
42 {
43 if (dos_char_to_printable(p, c, out_size))
44 return;
45 if (out_size >= 1 && c >= ' ' && c < 0x7f)
46 *(*p)++ = c;
47 else if (out_size >= 4) {
48 *(*p)++ = '\\';
49 *(*p)++ = '0' + (c >> 6);
50 *(*p)++ = '0' + ((c >> 3) & 7);
51 *(*p)++ = '0' + (c & 7);
52 }
53 }
54
55 /**
56 * Construct the "pretty-printed" representation of the name in a short directory entry.
57 *
58 * @param[in] fixed Pointer to name[0] of a DIR_ENT
59 *
60 * @return Pointer to static string containing pretty "8.3" equivalent of the
61 * name in the directory entry.
62 */
63 char *file_name(unsigned char *fixed)
64 {
65 static char path[256];
66 char *p;
67 int i, j;
68
69 p = path;
70 i = j = 0;
71 if (fixed[0] == 0x05) {
72 put_char(&p, 0xe5, path + sizeof(path) - 1 - p);
73 ++i;
74 ++j;
75 }
76 for (; i < 8; i++)
77 if (fixed[i] != ' ') {
78 while (j++ < i)
79 *p++ = ' ';
80 put_char(&p, fixed[i], path + sizeof(path) - 1 - p);
81 }
82 if (strncmp((const char *)(fixed + 8), " ", 3)) {
83 *p++ = '.';
84 for (i = j = 0; i < 3; i++)
85 if (fixed[i + 8] != ' ') {
86 while (j++ < i)
87 *p++ = ' ';
88 put_char(&p, fixed[i + 8], path + sizeof(path) - 1 - p);
89 }
90 }
91 *p = 0;
92 return path;
93 }
94
95 int file_cvt(unsigned char *name, unsigned char *fixed)
96 {
97 unsigned char c;
98 int size, ext, cnt;
99
100 size = 8;
101 ext = 0;
102 while (*name) {
103 c = *name;
104 if (c < ' ' || c > 0x7e || strchr("*?<>|\"/", c)) {
105 printf("Invalid character in name. Use \\ooo for special "
106 "characters.\n");
107 return 0;
108 }
109 if (c == '.') {
110 if (ext) {
111 printf("Duplicate dots in name.\n");
112 return 0;
113 }
114 while (size--)
115 *fixed++ = ' ';
116 size = 3;
117 ext = 1;
118 name++;
119 continue;
120 }
121 if (c == '\\') {
122 c = 0;
123 name++;
124 for (cnt = 3; cnt; cnt--) {
125 if (*name < '0' || *name > '7') {
126 printf("Expected three octal digits.\n");
127 return 0;
128 }
129 c = c * 8 + *name++ - '0';
130 }
131 name--;
132 }
133 if (islower(c))
134 c = toupper(c);
135 if (size) {
136 if (size == 8 && c == 0xE5)
137 *fixed++ = 0x05;
138 else
139 *fixed++ = c;
140 size--;
141 }
142 name++;
143 }
144 if (*name || size == 8)
145 return 0;
146 if (!ext) {
147 while (size--)
148 *fixed++ = ' ';
149 size = 3;
150 }
151 while (size--)
152 *fixed++ = ' ';
153 return 1;
154 }
155
156 void file_add(char *path, FD_TYPE type)
157 {
158 FDSC **current, *walk;
159 char name[MSDOS_NAME];
160 char *here;
161
162 current = &fp_root;
163 if (*path != '/')
164 die("%s: Absolute path required.", path);
165 path++;
166 while (1) {
167 if ((here = strchr(path, '/')))
168 *here = 0;
169 if (!file_cvt((unsigned char *)path, (unsigned char *)name))
170 exit(2);
171 for (walk = *current; walk; walk = walk->next)
172 if (!here && (!strncmp(name, walk->name, MSDOS_NAME) || (type ==
173 fdt_undelete
174 &&
175 !strncmp
176 (name + 1,
177 walk->name
178 + 1,
179 MSDOS_NAME
180 - 1))))
181 die("Ambiguous name: \"%s\"", path);
182 else if (here && !strncmp(name, walk->name, MSDOS_NAME))
183 break;
184 if (!walk) {
185 walk = alloc(sizeof(FDSC));
186 strncpy(walk->name, name, MSDOS_NAME);
187 walk->type = here ? fdt_none : type;
188 walk->first = NULL;
189 walk->next = *current;
190 *current = walk;
191 }
192 current = &walk->first;
193 if (!here)
194 break;
195 *here = '/';
196 path = here + 1;
197 }
198 }
199
200 FDSC **file_cd(FDSC ** curr, char *fixed)
201 {
202 FDSC **walk;
203
204 if (!curr || !*curr)
205 return NULL;
206 for (walk = curr; *walk; walk = &(*walk)->next)
207 if (!strncmp((*walk)->name, fixed, MSDOS_NAME) && (*walk)->first)
208 return &(*walk)->first;
209 return NULL;
210 }
211
212 static FDSC **file_find(FDSC ** dir, char *fixed)
213 {
214 if (!dir || !*dir)
215 return NULL;
216 if (*(unsigned char *)fixed == DELETED_FLAG) {
217 while (*dir) {
218 if (!strncmp((*dir)->name + 1, fixed + 1, MSDOS_NAME - 1)
219 && !(*dir)->first)
220 return dir;
221 dir = &(*dir)->next;
222 }
223 return NULL;
224 }
225 while (*dir) {
226 if (!strncmp((*dir)->name, fixed, MSDOS_NAME) && !(*dir)->first)
227 return dir;
228 dir = &(*dir)->next;
229 }
230 return NULL;
231 }
232
233 /* Returns the attribute of the file FIXED in directory CURR or FDT_NONE if no
234 such file exists or if CURR is NULL. */
235 FD_TYPE file_type(FDSC ** curr, char *fixed)
236 {
237 FDSC **this;
238
239 if ((this = file_find(curr, fixed)))
240 return (*this)->type;
241 return fdt_none;
242 }
243
244 void file_modify(FDSC ** curr, char *fixed)
245 {
246 FDSC **this, *next;
247
248 if (!(this = file_find(curr, fixed)))
249 die("Internal error: file_find failed");
250 switch ((*this)->type) {
251 case fdt_drop:
252 printf("Dropping %s\n", file_name((unsigned char *)fixed));
253 *(unsigned char *)fixed = DELETED_FLAG;
254 break;
255 case fdt_undelete:
256 *fixed = *(*this)->name;
257 printf("Undeleting %s\n", file_name((unsigned char *)fixed));
258 break;
259 default:
260 die("Internal error: file_modify");
261 }
262 next = (*this)->next;
263 free(*this);
264 *this = next;
265 }
266
267 static void report_unused(FDSC * this)
268 {
269 FDSC *next;
270
271 while (this) {
272 next = this->next;
273 if (this->first)
274 report_unused(this->first);
275 else if (this->type != fdt_none)
276 printf("Warning: did not %s file %s\n", this->type == fdt_drop ?
277 "drop" : "undelete", file_name((unsigned char *)this->name));
278 free(this);
279 this = next;
280 }
281 }
282
283 void file_unused(void)
284 {
285 report_unused(fp_root);
286 }