Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenfile.c
Go to the documentation of this file.
00001 /* file.c - Additional file attributes */ 00002 00003 /* Written 1993 by Werner Almesberger */ 00004 00005 /* FAT32, VFAT, Atari format support, and various fixes additions May 1998 00006 * by Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de> */ 00007 00008 #include "vfatlib.h" 00009 00010 #define NDEBUG 00011 #include <debug.h> 00012 00013 FDSC *fp_root = NULL; 00014 00015 00016 static void put_char(char **p,unsigned char c) 00017 { 00018 if ((c >= ' ' && c < 0x7f) || c >= 0xa0) *(*p)++ = c; 00019 else { 00020 *(*p)++ = '\\'; 00021 *(*p)++ = '0'+(c >> 6); 00022 *(*p)++ = '0'+((c >> 3) & 7); 00023 *(*p)++ = '0'+(c & 7); 00024 } 00025 } 00026 00027 00028 char *file_name(unsigned char *fixed) 00029 { 00030 static char path[MSDOS_NAME*4+2]; 00031 char *p; 00032 int i,j; 00033 00034 p = path; 00035 for (i = j = 0; i < 8; i++) 00036 if (fixed[i] != ' ') { 00037 while (j++ < i) *p++ = ' '; 00038 put_char(&p,fixed[i]); 00039 } 00040 if (strncmp((char*)fixed+8," ",3)) { 00041 *p++ = '.'; 00042 for (i = j = 0; i < 3; i++) 00043 if (fixed[i+8] != ' ') { 00044 while (j++ < i) *p++ = ' '; 00045 put_char(&p,fixed[i+8]); 00046 } 00047 } 00048 *p = 0; 00049 return path; 00050 } 00051 00052 int file_cvt(unsigned char *name,unsigned char *fixed) 00053 { 00054 unsigned char c; 00055 int size,ext,cnt; 00056 00057 size = 8; 00058 ext = 0; 00059 while (*name) { 00060 c = *name; 00061 if (c < ' ' || c > 0x7e || strchr("*?<>|\"/",c)) { 00062 VfatPrint("Invalid character in name. Use \\ooo for special " 00063 "characters.\n"); 00064 return 0; 00065 } 00066 if (c == '.') { 00067 if (ext) { 00068 VfatPrint("Duplicate dots in name.\n"); 00069 return 0; 00070 } 00071 while (size--) *fixed++ = ' '; 00072 size = 3; 00073 ext = 1; 00074 name++; 00075 continue; 00076 } 00077 if (c == '\\') { 00078 c = 0; 00079 for (cnt = 3; cnt; cnt--) { 00080 if (*name < '0' || *name > '7') { 00081 VfatPrint("Invalid octal character.\n"); 00082 return 0; 00083 } 00084 c = c*8+*name++-'0'; 00085 } 00086 if (cnt < 4) { 00087 VfatPrint("Expected three octal digits.\n"); 00088 return 0; 00089 } 00090 name += 3; 00091 } 00092 if (islower(c)) c = toupper(c); 00093 if (size) { 00094 *fixed++ = c; 00095 size--; 00096 } 00097 name++; 00098 } 00099 if (*name || size == 8) return 0; 00100 if (!ext) { 00101 while (size--) *fixed++ = ' '; 00102 size = 3; 00103 } 00104 while (size--) *fixed++ = ' '; 00105 return 1; 00106 } 00107 00108 00109 void file_add(char *path,FD_TYPE type) 00110 { 00111 FDSC **current,*walk; 00112 char name[MSDOS_NAME]; 00113 char *here; 00114 00115 current = &fp_root; 00116 if (*path != '/') die("%s: Absolute path required.",path); 00117 path++; 00118 while (1) { 00119 if ((here = strchr(path,'/'))) *here = 0; 00120 if (!file_cvt((unsigned char*)path,(unsigned char *)name)) {return; /*exit(2);*/} 00121 for (walk = *current; walk; walk = walk->next) 00122 if (!here && (!strncmp(name,walk->name,MSDOS_NAME) || (type == 00123 fdt_undelete && !strncmp(name+1,walk->name+1,MSDOS_NAME-1)))) 00124 die("Ambiguous name: \"%s\"",path); 00125 else if (here && !strncmp(name,walk->name,MSDOS_NAME)) break; 00126 if (!walk) { 00127 walk = vfalloc(sizeof(FDSC)); 00128 strncpy(walk->name,name,MSDOS_NAME); 00129 walk->type = here ? fdt_none : type; 00130 walk->first = NULL; 00131 walk->next = *current; 00132 *current = walk; 00133 } 00134 current = &walk->first; 00135 if (!here) break; 00136 *here = '/'; 00137 path = here+1; 00138 } 00139 } 00140 00141 00142 FDSC **file_cd(FDSC **curr,char *fixed) 00143 { 00144 FDSC **walk; 00145 00146 if (!curr || !*curr) return NULL; 00147 for (walk = curr; *walk; walk = &(*walk)->next) 00148 if (!strncmp((*walk)->name,fixed,MSDOS_NAME) && (*walk)->first) 00149 return &(*walk)->first; 00150 return NULL; 00151 } 00152 00153 00154 static FDSC **file_find(FDSC **dir,char *fixed) 00155 { 00156 if (!dir || !*dir) return NULL; 00157 if (*(unsigned char *) fixed == DELETED_FLAG) { 00158 while (*dir) { 00159 if (!strncmp((*dir)->name+1,fixed+1,MSDOS_NAME-1) && !(*dir)->first) 00160 return dir; 00161 dir = &(*dir)->next; 00162 } 00163 return NULL; 00164 } 00165 while (*dir) { 00166 if (!strncmp((*dir)->name,fixed,MSDOS_NAME) && !(*dir)->first) 00167 return dir; 00168 dir = &(*dir)->next; 00169 } 00170 return NULL; 00171 } 00172 00173 00174 FD_TYPE file_type(FDSC **curr,char *fixed) 00175 { 00176 FDSC **this; 00177 00178 if ((this = file_find(curr,fixed))) return (*this)->type; 00179 return fdt_none; 00180 } 00181 00182 00183 void file_modify(FDSC **curr,unsigned char *fixed) 00184 { 00185 FDSC **this,*next; 00186 00187 if (!(this = file_find(curr,(char *)fixed))) 00188 die("Internal error: file_find failed"); 00189 switch ((*this)->type) { 00190 case fdt_drop: 00191 VfatPrint("Dropping %s\n",file_name(fixed)); 00192 *fixed = DELETED_FLAG; 00193 break; 00194 case fdt_undelete: 00195 *fixed = *(*this)->name; 00196 VfatPrint("Undeleting %s\n",file_name(fixed)); 00197 break; 00198 default: 00199 die("Internal error: file_modify"); 00200 } 00201 next = (*this)->next; 00202 vffree(*this); 00203 *this = next; 00204 } 00205 00206 00207 static void report_unused(FDSC *this) 00208 { 00209 FDSC *next; 00210 00211 while (this) { 00212 next = this->next; 00213 if (this->first) report_unused(this->first); 00214 else if (this->type != fdt_none) 00215 VfatPrint("Warning: did not %s file %s\n",this->type == fdt_drop ? 00216 "drop" : "undelete",file_name((unsigned char*)this->name)); 00217 vffree(this); 00218 this = next; 00219 } 00220 } 00221 00222 00223 void file_unused(void) 00224 { 00225 report_unused(fp_root); 00226 } 00227 00228 /* Local Variables: */ 00229 /* tab-width: 8 */ 00230 /* End: */ Generated on Fri May 25 2012 04:16:00 for ReactOS by
1.7.6.1
|