"SfR Fresh" - the SfR Freeware/Shareware Archive

Member "dosfstools-2.11/dosfsck/file.c" of archive dosfstools-2.11.src.tar.gz:


As a special service "SfR Fresh" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file. That can be also achieved for any archive member file by clicking within an archive contents listing on the first character of the file(path) respectively on the according byte size field.
    1 /* file.c  -  Additional file attributes */
    2 
    3 /* Written 1993 by Werner Almesberger */
    4 
    5 /* FAT32, VFAT, Atari format support, and various fixes additions May 1998
    6  * by Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de> */
    7 
    8 
    9 #include <stdlib.h>
   10 #include <stdio.h>
   11 #include <string.h>
   12 #include <ctype.h>
   13 #include <unistd.h>
   14 
   15 #define _LINUX_STAT_H		/* hack to avoid inclusion of <linux/stat.h> */
   16 #define _LINUX_STRING_H_	/* hack to avoid inclusion of <linux/string.h>*/
   17 #define _LINUX_FS_H             /* hack to avoid inclusion of <linux/fs.h> */
   18 
   19 #include <linux/version.h>
   20 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
   21 # define __KERNEL__
   22 # include <asm/types.h>
   23 # undef __KERNEL__
   24 #endif
   25 
   26 #include <linux/msdos_fs.h>
   27 
   28 #include "common.h"
   29 #include "file.h"
   30 
   31 
   32 FDSC *fp_root = NULL;
   33 
   34 
   35 static void put_char(char **p,unsigned char c)
   36 {
   37     if ((c >= ' ' && c < 0x7f) || c >= 0xa0) *(*p)++ = c;
   38     else {
   39 	*(*p)++ = '\\';
   40 	*(*p)++ = '0'+(c >> 6);
   41 	*(*p)++ = '0'+((c >> 3) & 7);
   42 	*(*p)++ = '0'+(c & 7);
   43     }
   44 }
   45 
   46 
   47 char *file_name(unsigned char *fixed)
   48 {
   49     static char path[MSDOS_NAME*4+2];
   50     char *p;
   51     int i,j;
   52 
   53     p = path;
   54     for (i = j =  0; i < 8; i++)
   55 	if (fixed[i] != ' ') {
   56 	    while (j++ < i) *p++ = ' ';
   57 	    put_char(&p,fixed[i]);
   58 	}
   59     if (strncmp(fixed+8,"   ",3)) {
   60 	*p++ = '.';
   61 	for (i = j =  0; i < 3; i++)
   62 	    if (fixed[i+8] != ' ') {
   63 		while (j++ < i) *p++ = ' ';
   64 		put_char(&p,fixed[i+8]);
   65 	    }
   66     }
   67     *p = 0;
   68     return path;
   69 }
   70 
   71 
   72 int file_cvt(unsigned char *name,unsigned char *fixed)
   73 {
   74     unsigned char c;
   75     int size,ext,cnt;
   76 
   77     size = 8;
   78     ext = 0;
   79     while (*name) {
   80 	c = *name;
   81 	if (c < ' ' || c > 0x7e || strchr("*?<>|\"/",c)) {
   82 	    printf("Invalid character in name. Use \\ooo for special "
   83 	      "characters.\n");
   84 	    return 0;
   85 	}
   86 	if (c == '.') {
   87 	    if (ext) {
   88 		printf("Duplicate dots in name.\n");
   89 		return 0;
   90 	    }
   91 	    while (size--) *fixed++ = ' ';
   92 	    size = 3;
   93 	    ext = 1;
   94 	    name++;
   95 	    continue;
   96 	}
   97 	if (c == '\\') {
   98 	    c = 0;
   99 	    for (cnt = 3; cnt; cnt--) {
  100 		if (*name < '0' || *name > '7') {
  101 		    printf("Invalid octal character.\n");
  102 		    return 0;
  103 		}
  104 		c = c*8+*name++-'0';
  105 	    }
  106 	    if (cnt < 4) {
  107 		printf("Expected three octal digits.\n");
  108 		return 0;
  109 	    }
  110 	    name += 3;
  111 	}
  112 	if (islower(c)) c = toupper(c);
  113 	if (size) {
  114 	    *fixed++ = c;
  115 	    size--;
  116 	}
  117 	name++;
  118     }
  119     if (*name || size == 8) return 0;
  120     if (!ext) {
  121 	while (size--) *fixed++ = ' ';
  122 	size = 3;
  123     }
  124     while (size--) *fixed++ = ' ';
  125     return 1;
  126 }
  127 
  128 
  129 void file_add(char *path,FD_TYPE type)
  130 {
  131     FDSC **current,*walk;
  132     char name[MSDOS_NAME];
  133     char *here;
  134 
  135     current = &fp_root;
  136     if (*path != '/') die("%s: Absolute path required.",path);
  137     path++;
  138     while (1) {
  139 	if ((here = strchr(path,'/'))) *here = 0;
  140 	if (!file_cvt(path,name)) exit(2);
  141 	for (walk = *current; walk; walk = walk->next)
  142 	    if (!here && (!strncmp(name,walk->name,MSDOS_NAME) || (type ==
  143 	      fdt_undelete && !strncmp(name+1,walk->name+1,MSDOS_NAME-1))))
  144 		die("Ambiguous name: \"%s\"",path);
  145 	    else if (here && !strncmp(name,walk->name,MSDOS_NAME)) break;
  146 	if (!walk) {
  147 	    walk = alloc(sizeof(FDSC));
  148 	    strncpy(walk->name,name,MSDOS_NAME);
  149 	    walk->type = here ? fdt_none : type;
  150 	    walk->first = NULL;
  151 	    walk->next = *current;
  152 	    *current = walk;
  153 	}
  154 	current = &walk->first;
  155 	if (!here) break;
  156 	*here = '/';
  157 	path = here+1;
  158     }
  159 }
  160 
  161 
  162 FDSC **file_cd(FDSC **curr,char *fixed)
  163 {
  164     FDSC **walk;
  165 
  166     if (!curr || !*curr) return NULL;
  167     for (walk = curr; *walk; walk = &(*walk)->next)
  168 	if (!strncmp((*walk)->name,fixed,MSDOS_NAME) && (*walk)->first)
  169 	    return &(*walk)->first;
  170     return NULL;
  171 }
  172 
  173 
  174 static FDSC **file_find(FDSC **dir,char *fixed)
  175 {
  176     if (!dir || !*dir) return NULL;
  177     if (*(unsigned char *) fixed == DELETED_FLAG) {
  178 	while (*dir) {
  179 	    if (!strncmp((*dir)->name+1,fixed+1,MSDOS_NAME-1) && !(*dir)->first)
  180 		return dir;
  181 	    dir = &(*dir)->next;
  182 	}
  183 	return NULL;
  184     }
  185     while (*dir) {
  186 	if (!strncmp((*dir)->name,fixed,MSDOS_NAME) && !(*dir)->first)
  187 	    return dir;
  188 	dir = &(*dir)->next;
  189     }
  190     return NULL;
  191 }
  192 
  193 
  194 FD_TYPE file_type(FDSC **curr,char *fixed)
  195 {
  196     FDSC **this;
  197 
  198     if ((this = file_find(curr,fixed))) return (*this)->type;
  199     return fdt_none;
  200 }
  201 
  202 
  203 void file_modify(FDSC **curr,char *fixed)
  204 {
  205     FDSC **this,*next;
  206 
  207     if (!(this = file_find(curr,fixed)))
  208 	die("Internal error: file_find failed");
  209     switch ((*this)->type) {
  210 	case fdt_drop:
  211 	    printf("Dropping %s\n",file_name(fixed));
  212 	    *(unsigned char *) fixed = DELETED_FLAG;
  213 	    break;
  214 	case fdt_undelete:
  215 	    *fixed = *(*this)->name;
  216 	    printf("Undeleting %s\n",file_name(fixed));
  217 	    break;
  218 	default:
  219 	    die("Internal error: file_modify");
  220     }
  221     next = (*this)->next;
  222     free(*this);
  223     *this = next;
  224 }
  225 
  226 
  227 static void report_unused(FDSC *this)
  228 {
  229     FDSC *next;
  230 
  231     while (this) {
  232 	next = this->next;
  233 	if (this->first) report_unused(this->first);
  234 	else if (this->type != fdt_none)
  235 		printf("Warning: did not %s file %s\n",this->type == fdt_drop ?
  236 		  "drop" : "undelete",file_name(this->name));
  237 	free(this);
  238 	this = next;
  239     }
  240 }
  241 
  242 
  243 void file_unused(void)
  244 {
  245     report_unused(fp_root);
  246 }
  247 
  248 /* Local Variables: */
  249 /* tab-width: 8     */
  250 /* End:             */