/*  Copyright 1996-2005,2007-2009,2011 Alain Knaff.
 *  This file is part of mtools.
 *
 *  Mtools 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.
 *
 *  Mtools 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 Mtools.  If not, see <http://www.gnu.org/licenses/>.
 *
 */
#include "sysincludes.h"
#include "mtools.h"
#include "codepage.h"
#include "mtoolsPaths.h"

/* global variables */
/* they are not really harmful here, because there is only one configuration
 * file per invocations */

#define MAX_LINE_LEN 256

/* scanner */
static char buffer[MAX_LINE_LEN+1]; /* buffer for the whole line */
static char *pos; /* position in line */
static char *token; /* last scanned token */
static size_t token_length; /* length of the token */
static FILE *fp; /* file pointer for configuration file */
static int linenumber; /* current line number. Only used for printing
						* error messages */
static int lastTokenLinenumber; /* line numnber for last token */
static const char *filename=NULL; /* current file name. Used for printing
				   * error messages, and for storing in
				   * the device definition (mtoolstest) */
static int file_nr=0;


static unsigned int flag_mask; /* mask of currently set flags */

/* devices */
static unsigned int cur_devs; /* current number of defined devices */
static int cur_dev; /* device being filled in. If negative, none */
static int trusted=0; /* is the currently parsed device entry trusted? */
static unsigned int nr_dev; /* number of devices that the current table can 
			       hold */
struct device *devices; /* the device table */
static int token_nr; /* number of tokens in line */

static char default_drive='\0'; /* default drive */

/* "environment" variables */
unsigned int mtools_skip_check=0;
unsigned int mtools_fat_compatibility=0;
unsigned int mtools_ignore_short_case=0;
uint8_t mtools_rate_0=0;
uint8_t mtools_rate_any=0;
unsigned int mtools_no_vfat=0;
unsigned int mtools_numeric_tail=1;
unsigned int mtools_dotted_dir=0;
unsigned int mtools_twenty_four_hour_clock=1;
unsigned int mtools_lock_timeout=30;
unsigned int mtools_default_codepage=850;
const char *mtools_date_string="yyyy-mm-dd";
char *country_string=0;

typedef struct switches_l {
    const char *name;
    caddr_t address;
    enum {
	T_INT,
	T_STRING,
	T_UINT,
	T_UINT8,
	T_UINT16
    } type;
} switches_t;

static switches_t global_switches[] = {
    { "MTOOLS_LOWER_CASE", (caddr_t) & mtools_ignore_short_case, T_UINT },
    { "MTOOLS_FAT_COMPATIBILITY", (caddr_t) & mtools_fat_compatibility, T_UINT },
    { "MTOOLS_SKIP_CHECK", (caddr_t) & mtools_skip_check, T_UINT },
    { "MTOOLS_NO_VFAT", (caddr_t) & mtools_no_vfat, T_UINT },
    { "MTOOLS_RATE_0", (caddr_t) &mtools_rate_0, T_UINT8 },
    { "MTOOLS_RATE_ANY", (caddr_t) &mtools_rate_any, T_UINT8 },
    { "MTOOLS_NAME_NUMERIC_TAIL", (caddr_t) &mtools_numeric_tail, T_UINT },
    { "MTOOLS_DOTTED_DIR", (caddr_t) &mtools_dotted_dir, T_UINT },
    { "MTOOLS_TWENTY_FOUR_HOUR_CLOCK",
      (caddr_t) &mtools_twenty_four_hour_clock, T_UINT },
    { "MTOOLS_DATE_STRING",
      (caddr_t) &mtools_date_string, T_STRING },
    { "MTOOLS_LOCK_TIMEOUT", (caddr_t) &mtools_lock_timeout, T_UINT },
    { "DEFAULT_CODEPAGE", (caddr_t) &mtools_default_codepage, T_UINT }
};

typedef struct {
    const char *name;
    unsigned int flag;
} flags_t;

static flags_t openflags[] = {
#ifdef O_SYNC
    { "sync",		O_SYNC },
#endif
#ifdef O_NDELAY
    { "nodelay",	O_NDELAY },
#endif
#ifdef O_EXCL
    { "exclusive",	O_EXCL },
#endif
    { "none", 0 }  /* hack for those compilers that choke on commas
		    * after the last element of an array */
};

static flags_t misc_flags[] = {
#ifdef USE_XDF
    { "use_xdf",		USE_XDF_FLAG },
#endif
    { "scsi",			SCSI_FLAG },
    { "nolock",			NOLOCK_FLAG },
    { "mformat_only",	MFORMAT_ONLY_FLAG },
    { "filter",			FILTER_FLAG },
    { "privileged",		PRIV_FLAG },
    { "vold",			VOLD_FLAG },
    { "remote",			FLOPPYD_FLAG },
    { "swap",			SWAP_FLAG },
};

static struct {
    const char *name;
    signed char fat_bits;
    unsigned int tracks;
    unsigned short heads;
    unsigned short sectors;
} default_formats[] = {
    { "hd514",			12, 80, 2, 15 },
    { "high-density-5-1/4",	12, 80, 2, 15 },
    { "1.2m",			12, 80, 2, 15 },

    { "hd312",			12, 80, 2, 18 },
    { "high-density-3-1/2",	12, 80, 2, 18 },
    { "1.44m",	 		12, 80, 2, 18 },

    { "dd312",			12, 80, 2, 9 },
    { "double-density-3-1/2",	12, 80, 2, 9 },
    { "720k",			12, 80, 2, 9 },

    { "dd514",			12, 40, 2, 9 },
    { "double-density-5-1/4",	12, 40, 2, 9 },
    { "360k",			12, 40, 2, 9 },

    { "320k",			12, 40, 2, 8 },
    { "180k",			12, 40, 1, 9 },
    { "160k",			12, 40, 1, 8 }
};

#define OFFS(x) ((caddr_t)&((struct device *)0)->x)

static switches_t dswitches[]= {
    { "FILE", OFFS(name), T_STRING },
    { "OFFSET", OFFS(offset), T_UINT },
    { "PARTITION", OFFS(partition), T_UINT },
    { "FAT", OFFS(fat_bits), T_INT },
    { "FAT_BITS", OFFS(fat_bits), T_UINT },
    { "MODE", OFFS(mode), T_UINT },
    { "TRACKS",  OFFS(tracks), T_UINT },
    { "CYLINDERS",  OFFS(tracks), T_UINT },
    { "HEADS", OFFS(heads), T_UINT16 },
    { "SECTORS", OFFS(sectors), T_UINT16 },
    { "HIDDEN", OFFS(hidden), T_UINT },
    { "PRECMD", OFFS(precmd), T_STRING },
    { "BLOCKSIZE", OFFS(blocksize), T_UINT },
    { "CODEPAGE", OFFS(codepage), T_UINT }
};

#if (defined  HAVE_TOUPPER_L || defined HAVE_STRNCASECMP_L)
static locale_t C=NULL;

static void init_canon(void) {
    if(C == NULL)
	C = newlocale(LC_CTYPE_MASK, "C", NULL);
}
#endif

#ifdef HAVE_TOUPPER_L
static int canon_drv(int drive) {
    int ret;
    init_canon();
    ret = toupper_l(drive, C);
    return ret;
}
#else
static int canon_drv(int drive) {
    return toupper(drive);
}
#endif

#ifdef HAVE_STRNCASECMP_L
static int cmp_tok(const char *a, const char *b, int len) {
    init_canon();
    return strncasecmp_l(a, b, len, C);
}
#else
static int cmp_tok(const char *a, const char *b, int len) {
    return strncasecmp(a, b, len);
}
#endif


static char ch_canon_drv(char drive) {
    return (char) canon_drv( (unsigned char) drive);
}

static void maintain_default_drive(char drive)
{
    if(default_drive == ':')
	return; /* we have an image */
    if(default_drive == '\0' ||
       default_drive > drive)
	default_drive = drive;
}

char get_default_drive(void)
{
    if(default_drive != '\0')
	return default_drive;
    else
	return 'A';
}

static void syntax(const char *msg, int thisLine) NORETURN;
static void syntax(const char *msg, int thisLine)
{
    char drive='\0';
    if(thisLine)
	lastTokenLinenumber = linenumber;
    if(cur_dev >= 0)
	drive = devices[cur_dev].drive;
    fprintf(stderr,"Syntax error at line %d ", lastTokenLinenumber);
    if(drive) fprintf(stderr, "for drive %c: ", drive);
    if(token) fprintf(stderr, "column %ld ", (long)(token - buffer));
    fprintf(stderr, "in file %s: %s", filename, msg);
    if(errno != 0)
	fprintf(stderr, " (%s)", strerror(errno));
    fprintf(stderr, "\n");
    exit(1);
}

static void get_env_conf(void)
{
    char *s;
    unsigned int i;

    for(i=0; i< sizeof(global_switches) / sizeof(*global_switches); i++) {
	s = getenv(global_switches[i].name);
	if(s) {
	    errno = 0;
	    switch(global_switches[i].type) {
	    case T_INT:
		* ((int *)global_switches[i].address) = strtoi(s,0,0);
		break;
	    case T_UINT:
		* ((unsigned int *)global_switches[i].address) = strtoui(s,0,0);
		break;
	    case T_UINT8:
		* ((uint8_t *)global_switches[i].address) = strtou8(s,0,0);
		break;
	    case T_UINT16:
		* ((uint16_t *)global_switches[i].address) = strtou16(s,0,0);
		break;
	    case T_STRING:
		* ((char **)global_switches[i].address) = s;
		break;
	    }
	    if(errno != 0) {
		fprintf(stderr, "Bad number %s for %s (%s)\n", s,
			global_switches[i].name,
			strerror(errno));
		exit(1);
	    }
	}
    }
}

static int mtools_getline(void)
{
    if(!fp || !fgets(buffer, MAX_LINE_LEN+1, fp))
	return -1;
    linenumber++;
    pos = buffer;
    token_nr = 0;
    buffer[MAX_LINE_LEN] = '\0';
    if(strlen(buffer) == MAX_LINE_LEN)
	syntax("line too long", 1);
    return 0;
}
		
static void skip_junk(int expect)
{
    lastTokenLinenumber = linenumber;
    while(!pos || !*pos || strchr(" #\n\t", *pos)) {
	if(!pos || !*pos || *pos == '#') {
	    if(mtools_getline()) {
		pos = 0;
		if(expect)
		    syntax("end of file unexpected", 1);
		return;
	    }
	} else
	    pos++;
    }
    token_nr++;
}

/* get the next token */
static char *get_next_token(void)
{
    skip_junk(0);
    if(!pos) {
	token_length = 0;
	token = 0;
	return 0;
    }
    token = pos;
    token_length = strcspn(token, " \t\n#:=");
    pos += token_length;
    return token;
}

static int match_token(const char *template)
{
    return (strlen(template) == token_length &&
	    !cmp_tok(template, token, token_length));
}

static void expect_char(char c)
{
    char buf[11];

    skip_junk(1);
    if(*pos != c) {
	sprintf(buf, "expected %c", c);
	syntax(buf, 1);
    }
    pos++;
}

static char *get_string(void)
{
    char *end, *str;

    skip_junk(1);
    if(*pos != '"')
	syntax(" \" expected", 0);
    str = pos+1;
    end = strchr(str, '\"');
    if(!end)
	syntax("unterminated string constant", 1);
    *end = '\0';
    pos = end+1;
    return str;
}

static unsigned long get_unumber(unsigned long max)
{
    char *last;
    unsigned long n;

    skip_junk(1);
    last = pos;
    n=strtoul(pos, &pos, 0);
    if(errno)
	syntax("bad number", 0);
    if(last == pos)
	syntax("numeral expected", 0);
    if(n > max)
	syntax("number too big", 0);
    pos++;
    token_nr++;
    return n;
}

static int get_number(void)
{
    char *last;
    int n;

    skip_junk(1);
    last = pos;
    n=(int) strtol(pos, &pos, 0);
    if(errno)
	syntax("bad number", 0);
    if(last == pos)
	syntax("numeral expected", 0);
    pos++;
    token_nr++;
    return n;
}

/* purge all entries pertaining to a given drive from the table */
static void purge(char drive, int fn)
{
    unsigned int i, j;

    drive = ch_canon_drv(drive);
    for(j=0, i=0; i < cur_devs; i++) {
	if(devices[i].drive != drive ||
	   devices[i].file_nr == fn)
	    devices[j++] = devices[i];
    }
    cur_devs = j;
}

static void grow(void)
{
    if(cur_devs >= nr_dev - 2) {
	nr_dev = (cur_devs + 2) << 1;
	if(!(devices=Grow(devices, nr_dev, struct device))){
	    printOom();
	    exit(1);
	}
    }
}
	

static void init_drive(void)
{
    memset((char *)&devices[cur_dev], 0, sizeof(struct device));
    devices[cur_dev].ssize = 2;
}

/* prepends a device to the table */
static void prepend(void)
{
    unsigned int i;

    grow();
    for(i=cur_devs; i>0; i--)
	devices[i] = devices[i-1];
    cur_dev = 0;
    cur_devs++;
    init_drive();
}


/* appends a device to the table */
static void append(void)
{
    grow();
    cur_dev = cur_devs;
    cur_devs++;
    init_drive();
}


static void finish_drive_clause(void)
{
    if(cur_dev == -1) {
	trusted = 0;
	return;
    }
    if(!devices[cur_dev].name)
	syntax("missing filename", 0);
    if(devices[cur_dev].tracks ||
       devices[cur_dev].heads ||
       devices[cur_dev].sectors) {
	if(!devices[cur_dev].tracks ||
	   !devices[cur_dev].heads ||
	   !devices[cur_dev].sectors)
	    syntax("incomplete geometry: either indicate all of track/heads/sectors or none of them", 0);
	if(!(devices[cur_dev].misc_flags &
	     (MFORMAT_ONLY_FLAG | FILTER_FLAG)))
	    syntax("if you supply a geometry, you also must supply one of the `mformat_only' or `filter' flags", 0);
    }
    devices[cur_dev].file_nr = file_nr;
    devices[cur_dev].cfg_filename = filename;
    if(! (flag_mask & PRIV_FLAG) && IS_SCSI(&devices[cur_dev]))
	devices[cur_dev].misc_flags |= PRIV_FLAG;
    if(!trusted && (devices[cur_dev].misc_flags & PRIV_FLAG)) {
	fprintf(stderr,
		"Warning: privileged flag ignored for drive %c: defined in file %s\n",
		canon_drv(devices[cur_dev].drive), filename);
	devices[cur_dev].misc_flags &= ~PRIV_FLAG;
    }
    trusted = 0;
    cur_dev = -1;
}

static int set_var(struct switches_l *switches, int nr,
		   caddr_t base_address)
{
    int i;
    for(i=0; i < nr; i++) {
	if(match_token(switches[i].name)) {
	    expect_char('=');
	    if(switches[i].type == T_UINT)
		* ((unsigned int *)((long)switches[i].address+base_address)) =
		    (unsigned int) get_unumber(UINT_MAX);
	    else if(switches[i].type == T_UINT8)
		* ((uint8_t *)((long)switches[i].address+base_address)) =
		    (uint8_t) get_unumber(UINT8_MAX);
	    else if(switches[i].type == T_UINT16)
		* ((uint16_t *)((long)switches[i].address+base_address)) =
		    (uint16_t) get_unumber(UINT16_MAX);
	    else if(switches[i].type == T_INT)
		* ((int *)((long)switches[i].address+base_address)) =
		    get_number();
	    else if (switches[i].type == T_STRING)
		* ((char**)((long)switches[i].address+base_address))=
		    strdup(get_string());
	    return 0;
	}
    }
    return 1;
}

static int set_openflags(struct device *dev)
{
    unsigned int i;

    for(i=0; i < sizeof(openflags) / sizeof(*openflags); i++) {
	if(match_token(openflags[i].name)) {
	    dev->mode |= openflags[i].flag;
	    return 0;
	}
    }
    return 1;
}

static int set_misc_flags(struct device *dev)
{
    unsigned int i;
    for(i=0; i < sizeof(misc_flags) / sizeof(*misc_flags); i++) {
	if(match_token(misc_flags[i].name)) {
	    flag_mask |= misc_flags[i].flag;
	    skip_junk(0);
	    if(pos && *pos == '=') {
		pos++;
		switch(get_number()) {
		    case 0:
			return 0;
		    case 1:
			break;
		    default:
			syntax("expected 0 or 1", 0);
		}
	    }
	    dev->misc_flags |= misc_flags[i].flag;
	    return 0;
	}
    }
    return 1;
}

static int set_def_format(struct device *dev)
{
    unsigned int i;

    for(i=0; i < sizeof(default_formats)/sizeof(*default_formats); i++) {
	if(match_token(default_formats[i].name)) {
	    if(!dev->ssize)
		dev->ssize = 2;
	    if(!dev->tracks)
		dev->tracks = default_formats[i].tracks;
	    if(!dev->heads)
		dev->heads = default_formats[i].heads;
	    if(!dev->sectors)
		dev->sectors = default_formats[i].sectors;
	    if(!dev->fat_bits)
		dev->fat_bits = default_formats[i].fat_bits;
	    return 0;
	}
    }
    return 1;
}

static void parse_all(int privilege);

void set_cmd_line_image(char *img) {
  char *ofsp;

  prepend();
  devices[cur_dev].drive = ':';
  default_drive = ':';

  ofsp = strstr(img, "@@");
  if (ofsp == NULL) {
    /* no separator => no offset */
    devices[cur_dev].name = strdup(img);
    devices[cur_dev].offset = 0;
  } else {
    devices[cur_dev].name = strndup(img, ofsp - img);
    devices[cur_dev].offset = str_to_offset(ofsp+2);
  }

  devices[cur_dev].fat_bits = 0;
  devices[cur_dev].tracks = 0;
  devices[cur_dev].heads = 0;
  devices[cur_dev].sectors = 0;
  if (strchr(devices[cur_dev].name, '|')) {
    char *pipechar = strchr(devices[cur_dev].name, '|');
    *pipechar = 0;
    strncpy(buffer, pipechar+1, MAX_LINE_LEN);
    buffer[MAX_LINE_LEN] = '\0';
    fp = NULL;
    filename = "{command line}";
    linenumber = 0;
    lastTokenLinenumber = 0;
    pos = buffer;
    token = 0;
    parse_all(0);
  }
}

void check_number_parse_errno(char c, const char *oarg, char *endptr) {
    if(endptr && *endptr) {
	fprintf(stderr, "Bad number %s\n", oarg);
	exit(1);
    }
    if(errno) {
	fprintf(stderr, "Bad number %s for -%c (%s)\n", oarg,
		c, strerror(errno));
	exit(1);
    }
}

static uint16_t tou16(int in, const char *comment) {
    if(in > UINT16_MAX) {
	fprintf(stderr, "Number of %s %d too big\n", comment, in);
	exit(1);
    }
    if(in < 0) {
	fprintf(stderr, "Number of %s %d negative\n", comment, in);
	exit(1);
    }
    return (uint16_t) in;
       
}

static void parse_old_device_line(char drive)
{
    char name[MAXPATHLEN];
    int items;
    long offset;

    int heads, sectors;
    
    /* finish any old drive */
    finish_drive_clause();

    /* purge out data of old configuration files */
    purge(drive, file_nr);
	
    /* reserve slot */
    append();
    items = sscanf(token,"%c %s %i %i %i %i %li",
		   &devices[cur_dev].drive,name,&devices[cur_dev].fat_bits,
		   &devices[cur_dev].tracks,&heads,
		   &sectors, &offset);
    devices[cur_dev].heads = tou16(heads, "heads");
    devices[cur_dev].sectors = tou16(sectors, "sectors");
    
    devices[cur_dev].offset = (off_t) offset;
    switch(items){
	case 2:
	    devices[cur_dev].fat_bits = 0;
	    /* fall thru */
	case 3:
	    devices[cur_dev].sectors = 0;
	    devices[cur_dev].heads = 0;
	    devices[cur_dev].tracks = 0;
	    /* fall thru */
	case 6:
	    devices[cur_dev].offset = 0;
	    /* fall thru */
	default:
	    break;
	case 0:
	case 1:
	case 4:
	case 5:
	    syntax("bad number of parameters", 1);
    }
    if(!devices[cur_dev].tracks){
	devices[cur_dev].sectors = 0;
	devices[cur_dev].heads = 0;
    }
	
    devices[cur_dev].drive = ch_canon_drv(devices[cur_dev].drive);
    maintain_default_drive(devices[cur_dev].drive);
    if (!(devices[cur_dev].name = strdup(name))) {
	printOom();
	exit(1);
    }
    devices[cur_dev].misc_flags |= MFORMAT_ONLY_FLAG;
    finish_drive_clause();
    pos=0;
}

static int parse_one(int privilege)
{
    int action=0;

    get_next_token();
    if(!token)
	return 0;

    if((match_token("drive") && ((action = 1)))||
       (match_token("drive+") && ((action = 2))) ||
       (match_token("+drive") && ((action = 3))) ||
       (match_token("clear_drive") && ((action = 4))) ) {
	/* finish off the previous drive */
	finish_drive_clause();

	get_next_token();
	if(token_length != 1)
	    syntax("drive letter expected", 0);

	if(action==1 || action==4)
	    /* replace existing drive */			
	    purge(token[0], file_nr);
	if(action==4)
	    return 1;
	if(action==3)
	    prepend();
	else
	    append();
	memset((char*)(devices+cur_dev), 0, sizeof(*devices));
	trusted = privilege;
	flag_mask = 0;
	devices[cur_dev].drive = ch_canon_drv(token[0]);
	maintain_default_drive(devices[cur_dev].drive);
	expect_char(':');
	return 1;
    }
    if(token_nr == 1 && token_length == 1) {
	parse_old_device_line(token[0]);
	return 1;
    }

    if((cur_dev < 0 ||
	(set_var(dswitches,
		 sizeof(dswitches)/sizeof(*dswitches),
		 (caddr_t)&devices[cur_dev]) &&
	 set_openflags(&devices[cur_dev]) &&
	 set_misc_flags(&devices[cur_dev]) &&
	 set_def_format(&devices[cur_dev]))) &&
       set_var(global_switches,
	       sizeof(global_switches)/sizeof(*global_switches), 0))
	syntax("unrecognized keyword", 1);
    return 1;
}

static void parse_all(int privilege) {
    errno=0;
    while (parse_one(privilege));
}


static int parse(const char *name, int privilege)
{
    if(fp) {
	fprintf(stderr, "File descriptor already set!\n");
	exit(1);
    }
    fp = fopen(name, "r");
    if(!fp)
	return 0;
    file_nr++;
    filename = name; /* no strdup needed: although lifetime of variable
			exceeds this function (due to dev->cfg_filename),
			we know that the name is always either
			1. a constant
			2. a statically allocate buffer
			3. an environment variable that stays unchanged
		     */
    linenumber = 0;
    lastTokenLinenumber = 0;
    pos = 0;
    token = 0;
    cur_dev = -1; /* no current device */

    parse_all(privilege);
    finish_drive_clause();
    fclose(fp);
    filename = NULL;
    fp = NULL;
    return 1;
}

void read_config(void)
{
    char *homedir;
    char *envConfFile;
    static char conf_file[MAXPATHLEN+sizeof(CFG_FILE1)];

	
    /* copy compiled-in devices */
    file_nr = 0;
    cur_devs = nr_const_devices;
    nr_dev = nr_const_devices + 2;
    devices = NewArray(nr_dev, struct device);
    if(!devices) {
	printOom();
	exit(1);
    }
    if(nr_const_devices)
	memcpy(devices, const_devices,
	       nr_const_devices*sizeof(struct device));

    (void) ((parse(CONF_FILE,1) |
	     parse(LOCAL_CONF_FILE,1) |
	     parse(SYS_CONF_FILE,1)) ||
	    (parse(OLD_CONF_FILE,1) |
	     parse(OLD_LOCAL_CONF_FILE,1)));
    /* the old-name configuration files only get executed if none of the
     * new-name config files were used */

    homedir = get_homedir();
    if ( homedir ){
	strncpy(conf_file, homedir, MAXPATHLEN );
	conf_file[MAXPATHLEN]='\0';
	strcat( conf_file, CFG_FILE1);
	parse(conf_file,0);
    }
    memset((char *)&devices[cur_devs],0,sizeof(struct device));

    envConfFile = getenv("MTOOLSRC");
    if(envConfFile)
	parse(envConfFile,0);

    /* environmental variables */
    get_env_conf();
    if(mtools_skip_check)
	mtools_fat_compatibility=1;
}

void mtoolstest(int argc, char **argv, int type  UNUSEDP) NORETURN;
void mtoolstest(int argc, char **argv, int type  UNUSEDP)
{
    /* testing purposes only */
    struct device *dev;
    char drive='\0';

    if(argc > 1 && argv[1][0] && argv[1][1] == ':') {
	drive = ch_canon_drv(argv[1][0]);
    }

    for (dev=devices; dev->name; dev++) {
	if(drive && drive != dev->drive)
	    continue;
	printf("drive %c:\n", dev->drive);
	printf("\t#fn=%d mode=%d ",
	       dev->file_nr, dev->mode);
	if(dev->cfg_filename)
	    printf("defined in %s\n", dev->cfg_filename);
	else
	    printf("builtin\n");
	printf("\tfile=\"%s\" fat_bits=%d \n",
	       dev->name,dev->fat_bits);
	printf("\ttracks=%d heads=%d sectors=%d hidden=%d\n",
	       dev->tracks, dev->heads, dev->sectors, dev->hidden);
	printf("\toffset=0x%lx\n", (long) dev->offset);
	printf("\tpartition=%d\n", dev->partition);

	if(dev->misc_flags)
	    printf("\t");

	if(DO_SWAP(dev))
	    printf("swap ");
	if(IS_SCSI(dev))
	    printf("scsi ");
	if(IS_PRIVILEGED(dev))
	    printf("privileged");
	if(IS_MFORMAT_ONLY(dev))
	    printf("mformat_only ");
	if(SHOULD_USE_VOLD(dev))
	    printf("vold ");
#ifdef USE_XDF
	if(SHOULD_USE_XDF(dev))
	    printf("use_xdf ");
#endif
	if(dev->misc_flags)
	    printf("\n");

	if(dev->mode)
	    printf("\t");
#ifdef O_SYNC
	if(dev->mode & O_SYNC)
	    printf("sync ");
#endif
#ifdef O_NDELAY
	if((dev->mode & O_NDELAY))
	    printf("nodelay ");
#endif
#ifdef O_EXCL
	if((dev->mode & O_EXCL))
	    printf("exclusive ");
#endif
	if(dev->mode)
	    printf("\n");

	if(dev->precmd)
	    printf("\tprecmd=%s\n", dev->precmd);

	printf("\n");
    }

    printf("mtools_fat_compatibility=%d\n",mtools_fat_compatibility);
    printf("mtools_skip_check=%d\n",mtools_skip_check);
    printf("mtools_lower_case=%d\n",mtools_ignore_short_case);

    exit(0);
}

/*
 * Local Variables:
 * c-basic-offset: 4
 * End:
 */
