/* file.c - Additional file attributes

   Copyright (C) 1993 Werner Almesberger <werner.almesberger@lrc.di.epfl.ch>
   Copyright (C) 1998 Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de>

   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program. If not, see <http://www.gnu.org/licenses/>.

   On Debian systems, the complete text of the GNU General Public License
   can be found in /usr/share/common-licenses/GPL-3 file.
*/

/* FAT32, VFAT, Atari format support, and various fixes additions May 1998
 * by Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de> */


#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <unistd.h>

#define _LINUX_STAT_H		/* hack to avoid inclusion of <linux/stat.h> */
#define _LINUX_STRING_H_	/* hack to avoid inclusion of <linux/string.h>*/
#define _LINUX_FS_H             /* hack to avoid inclusion of <linux/fs.h> */

# include <asm/types.h>

#include <linux/msdos_fs.h>

#include "common.h"
#include "file.h"


FDSC *fp_root = NULL;


static void put_char(char **p,unsigned char c)
{
    if ((c >= ' ' && c < 0x7f) || c >= 0xa0) *(*p)++ = c;
    else {
	*(*p)++ = '\\';
	*(*p)++ = '0'+(c >> 6);
	*(*p)++ = '0'+((c >> 3) & 7);
	*(*p)++ = '0'+(c & 7);
    }
}


char *file_name(unsigned char *fixed)
{
    static char path[MSDOS_NAME*4+2];
    char *p;
    int i,j;

    p = path;
    for (i = j =  0; i < 8; i++)
	if (fixed[i] != ' ') {
	    while (j++ < i) *p++ = ' ';
	    put_char(&p,fixed[i]);
	}
    if (strncmp(fixed+8,"   ",3)) {
	*p++ = '.';
	for (i = j =  0; i < 3; i++)
	    if (fixed[i+8] != ' ') {
		while (j++ < i) *p++ = ' ';
		put_char(&p,fixed[i+8]);
	    }
    }
    *p = 0;
    return path;
}


int file_cvt(unsigned char *name,unsigned char *fixed)
{
    unsigned char c;
    int size,ext,cnt;

    size = 8;
    ext = 0;
    while (*name) {
	c = *name;
	if (c < ' ' || c > 0x7e || strchr("*?<>|\"/",c)) {
	    printf("Invalid character in name. Use \\ooo for special "
	      "characters.\n");
	    return 0;
	}
	if (c == '.') {
	    if (ext) {
		printf("Duplicate dots in name.\n");
		return 0;
	    }
	    while (size--) *fixed++ = ' ';
	    size = 3;
	    ext = 1;
	    name++;
	    continue;
	}
	if (c == '\\') {
	    c = 0;
	    for (cnt = 3; cnt; cnt--) {
		if (*name < '0' || *name > '7') {
		    printf("Invalid octal character.\n");
		    return 0;
		}
		c = c*8+*name++-'0';
	    }
	    if (cnt < 4) {
		printf("Expected three octal digits.\n");
		return 0;
	    }
	    name += 3;
	}
	if (islower(c)) c = toupper(c);
	if (size) {
	    *fixed++ = c;
	    size--;
	}
	name++;
    }
    if (*name || size == 8) return 0;
    if (!ext) {
	while (size--) *fixed++ = ' ';
	size = 3;
    }
    while (size--) *fixed++ = ' ';
    return 1;
}


void file_add(char *path,FD_TYPE type)
{
    FDSC **current,*walk;
    char name[MSDOS_NAME];
    char *here;

    current = &fp_root;
    if (*path != '/') die("%s: Absolute path required.",path);
    path++;
    while (1) {
	if ((here = strchr(path,'/'))) *here = 0;
	if (!file_cvt(path,name)) exit(2);
	for (walk = *current; walk; walk = walk->next)
	    if (!here && (!strncmp(name,walk->name,MSDOS_NAME) || (type ==
	      fdt_undelete && !strncmp(name+1,walk->name+1,MSDOS_NAME-1))))
		die("Ambiguous name: \"%s\"",path);
	    else if (here && !strncmp(name,walk->name,MSDOS_NAME)) break;
	if (!walk) {
	    walk = alloc(sizeof(FDSC));
	    strncpy(walk->name,name,MSDOS_NAME);
	    walk->type = here ? fdt_none : type;
	    walk->first = NULL;
	    walk->next = *current;
	    *current = walk;
	}
	current = &walk->first;
	if (!here) break;
	*here = '/';
	path = here+1;
    }
}


FDSC **file_cd(FDSC **curr,char *fixed)
{
    FDSC **walk;

    if (!curr || !*curr) return NULL;
    for (walk = curr; *walk; walk = &(*walk)->next)
	if (!strncmp((*walk)->name,fixed,MSDOS_NAME) && (*walk)->first)
	    return &(*walk)->first;
    return NULL;
}


static FDSC **file_find(FDSC **dir,char *fixed)
{
    if (!dir || !*dir) return NULL;
    if (*(unsigned char *) fixed == DELETED_FLAG) {
	while (*dir) {
	    if (!strncmp((*dir)->name+1,fixed+1,MSDOS_NAME-1) && !(*dir)->first)
		return dir;
	    dir = &(*dir)->next;
	}
	return NULL;
    }
    while (*dir) {
	if (!strncmp((*dir)->name,fixed,MSDOS_NAME) && !(*dir)->first)
	    return dir;
	dir = &(*dir)->next;
    }
    return NULL;
}


FD_TYPE file_type(FDSC **curr,char *fixed)
{
    FDSC **this;

    if ((this = file_find(curr,fixed))) return (*this)->type;
    return fdt_none;
}


void file_modify(FDSC **curr,char *fixed)
{
    FDSC **this,*next;

    if (!(this = file_find(curr,fixed)))
	die("Internal error: file_find failed");
    switch ((*this)->type) {
	case fdt_drop:
	    printf("Dropping %s\n",file_name(fixed));
	    *(unsigned char *) fixed = DELETED_FLAG;
	    break;
	case fdt_undelete:
	    *fixed = *(*this)->name;
	    printf("Undeleting %s\n",file_name(fixed));
	    break;
	default:
	    die("Internal error: file_modify");
    }
    next = (*this)->next;
    free(*this);
    *this = next;
}


static void report_unused(FDSC *this)
{
    FDSC *next;

    while (this) {
	next = this->next;
	if (this->first) report_unused(this->first);
	else if (this->type != fdt_none)
		printf("Warning: did not %s file %s\n",this->type == fdt_drop ?
		  "drop" : "undelete",file_name(this->name));
	free(this);
	this = next;
    }
}


void file_unused(void)
{
    report_unused(fp_root);
}

/* Local Variables: */
/* tab-width: 8     */
/* End:             */
