/* 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>
   Copyright (C) 2008-2014 Daniel Baumann <mail@daniel-baumann.ch>

   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/>.

   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>

#include "common.h"
#include "file.h"
#include "msdos_fs.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);
    }
}

/**
 * Construct the "pretty-printed" representation of the name in a short directory entry.
 *
 * @param[in]    fixed  Pointer to name[0] of a DIR_ENT
 *
 * @return  Pointer to static string containing pretty "8.3" equivalent of the
 *          name in the directory entry.
 */
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((const char *)(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((unsigned char *)path, (unsigned char *)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;
}

/* Returns the attribute of the file FIXED in directory CURR or FDT_NONE if no
   such file exists or if CURR is 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((unsigned char *)fixed));
	*(unsigned char *)fixed = DELETED_FLAG;
	break;
    case fdt_undelete:
	*fixed = *(*this)->name;
	printf("Undeleting %s\n", file_name((unsigned char *)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((unsigned char *)this->name));
	free(this);
	this = next;
    }
}

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