1 /* file.c - Additional file attributes */
3 /* Written 1993 by Werner Almesberger */
5 /* FAT32, VFAT, Atari format support, and various fixes additions May 1998
6 * by Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de> */
16 static void put_char(char **p
,unsigned char c
)
18 if ((c
>= ' ' && c
< 0x7f) || c
>= 0xa0) *(*p
)++ = c
;
21 *(*p
)++ = '0'+(c
>> 6);
22 *(*p
)++ = '0'+((c
>> 3) & 7);
23 *(*p
)++ = '0'+(c
& 7);
28 char *file_name(unsigned char *fixed
)
30 static char path
[MSDOS_NAME
*4+2];
35 for (i
= j
= 0; i
< 8; i
++)
36 if (fixed
[i
] != ' ') {
37 while (j
++ < i
) *p
++ = ' ';
38 put_char(&p
,fixed
[i
]);
40 if (strncmp((char*)fixed
+8," ",3)) {
42 for (i
= j
= 0; i
< 3; i
++)
43 if (fixed
[i
+8] != ' ') {
44 while (j
++ < i
) *p
++ = ' ';
45 put_char(&p
,fixed
[i
+8]);
52 int file_cvt(unsigned char *name
,unsigned char *fixed
)
61 if (c
< ' ' || c
> 0x7e || strchr("*?<>|\"/",c
)) {
62 VfatPrint("Invalid character in name. Use \\ooo for special "
68 VfatPrint("Duplicate dots in name.\n");
71 while (size
--) *fixed
++ = ' ';
79 for (cnt
= 3; cnt
; cnt
--) {
80 if (*name
< '0' || *name
> '7') {
81 VfatPrint("Invalid octal character.\n");
87 VfatPrint("Expected three octal digits.\n");
92 if (islower(c
)) c
= toupper(c
);
99 if (*name
|| size
== 8) return 0;
101 while (size
--) *fixed
++ = ' ';
104 while (size
--) *fixed
++ = ' ';
109 void file_add(char *path
,FD_TYPE type
)
111 FDSC
**current
,*walk
;
112 char name
[MSDOS_NAME
];
116 if (*path
!= '/') die("%s: Absolute path required.",path
);
119 if ((here
= strchr(path
,'/'))) *here
= 0;
120 if (!file_cvt((unsigned char*)path
,(unsigned char *)name
)) {return; /*exit(2);*/}
121 for (walk
= *current
; walk
; walk
= walk
->next
)
122 if (!here
&& (!strncmp(name
,walk
->name
,MSDOS_NAME
) || (type
==
123 fdt_undelete
&& !strncmp(name
+1,walk
->name
+1,MSDOS_NAME
-1))))
124 die("Ambiguous name: \"%s\"",path
);
125 else if (here
&& !strncmp(name
,walk
->name
,MSDOS_NAME
)) break;
127 walk
= vfalloc(sizeof(FDSC
));
128 strncpy(walk
->name
,name
,MSDOS_NAME
);
129 walk
->type
= here
? fdt_none
: type
;
131 walk
->next
= *current
;
134 current
= &walk
->first
;
142 FDSC
**file_cd(FDSC
**curr
,char *fixed
)
146 if (!curr
|| !*curr
) return NULL
;
147 for (walk
= curr
; *walk
; walk
= &(*walk
)->next
)
148 if (!strncmp((*walk
)->name
,fixed
,MSDOS_NAME
) && (*walk
)->first
)
149 return &(*walk
)->first
;
154 static FDSC
**file_find(FDSC
**dir
,char *fixed
)
156 if (!dir
|| !*dir
) return NULL
;
157 if (*(unsigned char *) fixed
== DELETED_FLAG
) {
159 if (!strncmp((*dir
)->name
+1,fixed
+1,MSDOS_NAME
-1) && !(*dir
)->first
)
166 if (!strncmp((*dir
)->name
,fixed
,MSDOS_NAME
) && !(*dir
)->first
)
174 FD_TYPE
file_type(FDSC
**curr
,char *fixed
)
178 if ((this = file_find(curr
,fixed
))) return (*this)->type
;
183 void file_modify(FDSC
**curr
,unsigned char *fixed
)
187 if (!(this = file_find(curr
,(char *)fixed
)))
188 die("Internal error: file_find failed");
189 switch ((*this)->type
) {
191 VfatPrint("Dropping %s\n",file_name(fixed
));
192 *fixed
= DELETED_FLAG
;
195 *fixed
= *(*this)->name
;
196 VfatPrint("Undeleting %s\n",file_name(fixed
));
199 die("Internal error: file_modify");
201 next
= (*this)->next
;
207 static void report_unused(FDSC
*this)
213 if (this->first
) report_unused(this->first
);
214 else if (this->type
!= fdt_none
)
215 VfatPrint("Warning: did not %s file %s\n",this->type
== fdt_drop
?
216 "drop" : "undelete",file_name((unsigned char*)this->name
));
223 void file_unused(void)
225 report_unused(fp_root
);
228 /* Local Variables: */