/*

/usr/src/ext2ed/general_com.c

A part of the extended file system 2 disk editor.

---------------------
General user commands
---------------------

First written on: April 9 1995

Copyright (C) 1995 Gadi Oxman

*/

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

#include "ext2ed.h"
#include "../version.h"

void help (char *command_line)

{
	int i,max_line=0;
	char argument [80],*ptr;

	werase (show_pad);wmove (show_pad,0,0);

	ptr=parse_word (command_line,argument);

	if (*ptr!=0) {
		 ptr=parse_word (ptr,argument);
		 if (*argument!=0) {		 
			 detailed_help (argument);
			 return;
		}
	}

	if (current_type!=NULL) {
		
		wprintw (show_pad,"Type %s specific commands:\n",current_type->name);max_line++;
		
		if (current_type->type_commands.last_command==-1) {
			wprintw (show_pad,"\nnone\n");max_line+=2;
		}
		else
			for (i=0;i<=current_type->type_commands.last_command;i++) {
				if (i%5==0) {
					wprintw (show_pad,"\n");max_line++;
				}
				wprintw (show_pad,"%-13s",current_type->type_commands.names [i]);
				if (i%5!=4)
					wprintw (show_pad,";  ");				
			}
		
		wprintw (show_pad,"\n\n");max_line+=2;
	}		

	if (ext2_commands.last_command != -1) {
		wprintw (show_pad,"ext2 filesystem general commands: \n");max_line++;
		for (i=0;i<=ext2_commands.last_command;i++) {
			if (i%5==0) {
				wprintw (show_pad,"\n");max_line++;
			}
			wprintw (show_pad,"%-13s",ext2_commands.names [i]);
			if (i%5!=4)
				wprintw (show_pad,";  ");				

		}
		wprintw (show_pad,"\n\n");max_line+=2;
	}

	wprintw (show_pad,"General commands: \n");
	
	for (i=0;i<=general_commands.last_command;i++) {
		if (i%5==0) {
			wprintw (show_pad,"\n");max_line++;
		}
		wprintw (show_pad,"%-13s",general_commands.names [i]);
		if (i%5!=4)
			wprintw (show_pad,";  ");				
	}
	
	wprintw (show_pad,"\n\n");max_line+=2;
	
	wprintw (show_pad,"EXT2ED ver %s (%s)\n",E2FSPROGS_VERSION, E2FSPROGS_DATE);
	wprintw (show_pad,"Copyright (C) 1995 Gadi Oxman\n");
	wprintw (show_pad,"Reviewed 2001 Christian Bac\n");
	wprintw (show_pad,"Modified and enchanced by Theodore Ts'o, 2002\n");
	wprintw (show_pad,"EXT2ED is hereby placed under the terms of the GNU General Public License.\n\n");
	wprintw (show_pad,"EXT2ED was programmed as a student project in the software laboratory\n");
	wprintw (show_pad,"of the faculty of electrical engineering in the\n");
	wprintw (show_pad,"Technion - Israel Institute of Technology\n");
	wprintw (show_pad,"with the guide of Avner Lottem and Dr. Ilana David.\n");

	max_line+=10;
	
	show_pad_info.line=0;show_pad_info.max_line=max_line;

	werase (show_win);wmove (show_win,0,0);
	wprintw (show_win,"EXT2ED help");
	
	refresh_show_win ();
	refresh_show_pad ();
}

void detailed_help (char *text)

{
	int i;
	
	if (current_type != NULL)
		for (i=0;i<=current_type->type_commands.last_command;i++) {
			if (strcmp (current_type->type_commands.names [i],text)==0) {
				wprintw (show_pad,"%s - %s\n",text,current_type->type_commands.descriptions [i]);
				refresh_show_pad ();return;
			}
		}

	for (i=0;i<=ext2_commands.last_command;i++) {
		if (strcmp (ext2_commands.names [i],text)==0) {
				wprintw (show_pad,"%s - %s\n",text,ext2_commands.descriptions [i]);
				refresh_show_pad ();return;
		}
	}

	for (i=0;i<=general_commands.last_command;i++) {
		if (strcmp (general_commands.names [i],text)==0) {
				wprintw (show_pad,"%s - %s\n",text,general_commands.descriptions [i]);
				refresh_show_pad ();return;
		}
	}

	if (strcmp ("quit",text)==0) {
		wprintw (show_pad,"quit - Exists EXT2ED");
		refresh_show_pad ();return;
	}

	wprintw (show_pad,"Error - Command %s not aviable now\n",text);
	refresh_show_pad ();return;
}



void set_device (char *command_line)

{
	char *ptr,new_device [80];
	
	ptr=parse_word (command_line,new_device);
	if (*ptr==0) {
		wprintw (command_win,"Error - Device name not specified\n");
		refresh_command_win ();return;
	}
	parse_word (ptr,new_device);	
	check_mounted (new_device);
	if (mounted && !AllowMountedRead) {
		wprintw (command_win,"Error - Filesystem is mounted, aborting\n");
		wprintw (command_win,"You may wish to use the AllowMountedRead on configuration option\n");
		refresh_command_win ();return;
	}
	
	if (mounted && AllowMountedRead) {
		wprintw (command_win,"Warning - Filesystem is mounted. Displayed data may be unreliable.\n");
		refresh_command_win ();
	}

	if (device_handle!=NULL)
		fclose (device_handle);
		
	if ( (device_handle=fopen (new_device,"rb"))==NULL) {
		wprintw (command_win,"Error - Can not open device %s\n",new_device);refresh_command_win ();
		return;
	}
	else {
		strcpy (device_name,new_device);
		write_access=0;				/* Write access disabled */
		current_type=NULL;			/* There is no type now */
		remember_lifo.entries_count=0;		/* Empty Object memory */
		free_user_commands (&ext2_commands);	/* Free filesystem specific objects */
		free_struct_descriptors ();
		if (!set_file_system_info ()) {		/* Error while getting info --> abort */
			free_user_commands (&ext2_commands);
			free_struct_descriptors ();
			fclose (device_handle);
			device_handle=NULL;		/* Notice that our device is still not set up */
			device_offset=-1;
			return;
		}
		if (*AlternateDescriptors)		/* Check if user defined objects exist */
			set_struct_descriptors (AlternateDescriptors);
		dispatch ("setoffset 0");
		dispatch ("help");			/* Show help screen */
		wprintw (command_win,"Device changed to %s",device_name);refresh_command_win ();
	}
}

void set_offset (char *command_line)

{
	long mult=1;
	long new_offset;
	char *ptr,new_offset_buffer [80];
	
	if (device_handle==NULL) {
		wprintw (command_win,"Error - No device opened\n");refresh_command_win ();
		return;
	}
	
	ptr=parse_word (command_line,new_offset_buffer);
	
	if (*ptr==0) {
		wprintw (command_win,"Error - No argument specified\n");refresh_command_win ();
		return;
	}

	ptr=parse_word (ptr,new_offset_buffer);

	if (strcmp (new_offset_buffer,"block")==0) {
		mult=file_system_info.block_size;
		ptr=parse_word (ptr,new_offset_buffer);
	}

	if (strcmp (new_offset_buffer,"type")==0) {
		if (current_type==NULL) {
			wprintw (command_win,"Error - No type set\n");refresh_command_win ();
			return;
		}

		mult=current_type->length;
		ptr=parse_word (ptr,new_offset_buffer);
	}

	if (*new_offset_buffer==0) {
		wprintw (command_win,"Error - No offset specified\n");refresh_command_win ();
		return;
	}

	if (new_offset_buffer [0]=='+') {
		if (device_offset==-1) {
			wprintw (command_win,"Error - Select a fixed offset first\n");refresh_command_win ();
			return;
		}
		new_offset=device_offset+atol (new_offset_buffer+1)*mult;
	}
	
	else if (new_offset_buffer [0]=='-') {
		if (device_offset==-1) {
			wprintw (command_win,"Error - Select a fixed offset first\n");refresh_command_win ();
			return;
		}
		new_offset=device_offset-atol (new_offset_buffer+1)*mult;
		if (new_offset<0) new_offset=0;
	}
	
	else 
		new_offset=atol (new_offset_buffer)*mult;
	
	if ( (fseek (device_handle,new_offset,SEEK_SET))==-1) {
		wprintw (command_win,"Error - Failed to seek to offset %ld in device %s\n",new_offset,device_name);
		refresh_command_win ();
		return;
	};
	device_offset=new_offset;
	wprintw (command_win,"Device offset changed to %ld\n",device_offset);refresh_command_win ();
	load_type_data ();
	type_data.offset_in_block=0;
}

void set_int(short len, void *ptr, char *name, char *value)
{
	char	*char_ptr;
	short	*short_ptr;
	long	*long_ptr;
	long	v;
	char	*tmp;

	v = strtol(value, &tmp, 0);
	if (*tmp) {
		wprintw( command_win, "Bad value - %s\n", value);
		return;
	}
	switch (len) {
	case 1:
		char_ptr = (char *) ptr;
		*char_ptr = v;
		break;
	case 2:
		short_ptr = (short *) ptr;
		*short_ptr = v;
		break;
	case 4:
		long_ptr = (long *) ptr;
		*long_ptr = v;
		break;
	default:
		wprintw (command_win,
			 "set_int: unsupported length: %d\n", len);
		return;
	}
	wprintw (command_win, "Variable %s set to %s\n",
		 name, value);
}

void set_uint(short len, void *ptr, char *name, char *value)
{
	unsigned char	*char_ptr;
	unsigned short	*short_ptr;
	unsigned long	*long_ptr;
	unsigned long	v;
	char		*tmp;

	v = strtoul(value, &tmp, 0);
	if (*tmp) {
		wprintw( command_win, "Bad value - %s\n", value);
		return;
	}
	switch (len) {
	case 1:
		char_ptr = (unsigned char *) ptr;
		*char_ptr = v;
		break;
	case 2:
		short_ptr = (unsigned short *) ptr;
		*short_ptr = v;
		break;
	case 4:
		long_ptr = (unsigned long *) ptr;
		*long_ptr = v;
		break;
	default:
		wprintw (command_win,
			 "set_uint: unsupported length: %d\n", len);
		return;
	}
	wprintw (command_win, "Variable %s set to %s\n",
		 name, value);
}

void set_char(short len, void *ptr, char *name, char *value)
{
	if (strlen(value)+1 > len) {
		wprintw( command_win, "Value %s too big for field\n",
			name, len);
		return;
	}
	memset(ptr, 0, len);
	strcpy((char *) ptr, value);
	wprintw (command_win, "Variable %s set to %s\n",
		 name, value);
}


void set (char *command_line)

{
	unsigned short *int_ptr;
	unsigned char *char_ptr;
	unsigned long *long_ptr,offset=0;
	int i,len, found=0;
	char *ptr,buffer [80],variable [80],value [80];
	
	if (device_handle==NULL) {
		wprintw (command_win,"Error - No device opened\n");refresh_command_win ();
		return;
	}

	if (current_type==NULL) {
		hex_set (command_line);
		return;
	}

	ptr=parse_word (command_line,buffer);
	if (ptr==NULL || *ptr==0) {
		wprintw (command_win,"Error - Missing arguments\n");refresh_command_win ();
		return;
	}
	parse_word (ptr,buffer);
	ptr=strchr (buffer,'=');
	if (ptr==NULL) {
		wprintw (command_win,"Error - Bad syntax\n");refresh_command_win ();return;
	}
	strncpy (variable,buffer,ptr-buffer);variable [ptr-buffer]=0;
	strcpy (value,++ptr);

	if (current_type==NULL) {
		wprintw (command_win,"Sorry, not yet supported\n");refresh_command_win ();return;
	}
	
	for (i=0;i<current_type->fields_num && !found;i++) {
		if (strcmp (current_type->field_names [i],variable)==0) {
			found=1;
			ptr=type_data.u.buffer+offset;
			len = current_type->field_lengths [i];
			switch (current_type->field_types [i]) {
			case FIELD_TYPE_INT:
				set_int(len, ptr, variable, value);
				break;
			case FIELD_TYPE_UINT:
				set_uint(len, ptr, variable, value);
				break;
			case FIELD_TYPE_CHAR:
				set_char(len, ptr, variable, value);
				break;
			default:
				wprintw (command_win,
					 "set: unhandled type %d\n",
					 current_type->field_types [i]);
				break;
			}
			refresh_command_win ();
		}
		offset+=current_type->field_lengths [i];
	}
	if (found)
		dispatch ("show");
	else {
		wprintw (command_win,"Error - Variable %s not found\n",variable);
		refresh_command_win ();
	}
}

void hex_set (char *command_line)

{
	unsigned char tmp;
	char *ptr,buffer [80],*ch_ptr;
	int mode=HEX;
	
	ptr=parse_word (command_line,buffer);
	if (*ptr==0) {
		wprintw (command_win,"Error - Argument not specified\n");refresh_command_win ();return;
	}

	ptr=parse_word (ptr,buffer);

	if (strcasecmp (buffer,"text")==0) {
		mode=TEXT;
		strcpy (buffer,ptr);
	}

	else if (strcasecmp (buffer,"hex")==0) {
		mode=HEX;
		ptr=parse_word (ptr,buffer);
	}

	if (*buffer==0) {
		wprintw (command_win,"Error - Data not specified\n");refresh_command_win ();return;
	}

	if (mode==HEX) {
		do {
			tmp=(unsigned char) strtol (buffer,NULL,16);
			type_data.u.buffer [type_data.offset_in_block]=tmp;
			type_data.offset_in_block++;
			ptr=parse_word (ptr,buffer);
			if (type_data.offset_in_block==file_system_info.block_size) {
				if (*ptr) {
					wprintw (command_win,"Error - Ending offset outside block, only partial string changed\n");
					refresh_command_win ();
				}
				type_data.offset_in_block--;
			}
		} while (*buffer) ;
	}

	else {
		ch_ptr=buffer;
		while (*ch_ptr) {
			tmp=(unsigned char) *ch_ptr++;
			type_data.u.buffer [type_data.offset_in_block]=tmp;
			type_data.offset_in_block++;
			if (type_data.offset_in_block==file_system_info.block_size) {
				if (*ch_ptr) {
					wprintw (command_win,"Error - Ending offset outside block, only partial string changed\n");
					refresh_command_win ();
				}
				type_data.offset_in_block--;
			}
		}
	}
	
	strcpy (buffer,"show");dispatch (buffer);
}



void set_type (char *command_line)

{
	struct struct_descriptor *descriptor_ptr;
	char *ptr,buffer [80],tmp_buffer [80];
	short found=0;

	if (!load_type_data ())
		return;

	ptr=parse_word (command_line,buffer);
	parse_word (ptr,buffer);
	
	if (strcmp (buffer,"none")==0 || strcmp (buffer,"hex")==0) {
		wprintw (command_win,"Data will be shown as hex dump\n");refresh_command_win ();
		current_type=NULL;
		sprintf (tmp_buffer,"show");dispatch (tmp_buffer);
		return;
	}
	
	descriptor_ptr=first_type;
	while (descriptor_ptr!=NULL && !found) {
		if (strcmp (descriptor_ptr->name,buffer)==0)
			found=1;
		else
			descriptor_ptr=descriptor_ptr->next;
	}
	if (found) {
		wprintw (command_win,"Structure type set to %s\n",buffer);refresh_command_win ();
		current_type=descriptor_ptr;
		sprintf (tmp_buffer,"show");dispatch (tmp_buffer);
	}
	else {
		wprintw (command_win,"Error - %s is not a valid type\n",buffer);refresh_command_win ();
	}
}    

void show_int(short len, void *ptr)
{
	long	temp;
	char	*format;

	switch (len) {
	case 1:
		temp = *((char *) ptr);
		format = "%3d (0x%02x)\n";
		break;
	case 2:
		temp = *((short *) ptr);
		format = "%d (0x%x)\n";
		break;
	case 4:
		temp = *((long *) ptr);
		format = "%d\n";
		break;
	default:
		wprintw (show_pad, "unimplemented\n");
		return;
	}
	wprintw(show_pad, format, temp, temp);
}

void show_uint(short len, void *ptr)
{
	unsigned long	temp;
	char		*format;

	switch (len) {
	case 1:
		temp = *((unsigned char *) ptr);
		temp = temp & 0xFF;
		format = "%3u (0x%02x)\n";
		break;
	case 2:
		temp = *((unsigned short *) ptr);
		temp = temp & 0xFFFF;
		format = "%u (0x%x)\n";
		break;
	case 4:
		temp = (unsigned long) *((unsigned long *) ptr);
		format = "%u\n";
		break;
	default:
		wprintw (show_pad, "unimplemented\n");
		return;
	}
	wprintw(show_pad, format, temp, temp);
}

void show_char(short len, void *ptr)
{
	unsigned char	*cp = (unsigned char *) ptr;
	unsigned char	ch;
	int		i,j;

	wprintw(show_pad, "\"");
	
	for (i=0; i < len; i++) {
		ch = *cp++;
		if (ch == 0) {
			for (j=i+1; j < len; j++)
				if (cp[j-i])
					break;
			if (j == len)
				break;
		}
		if (ch > 128) {
			wprintw(show_pad, "M-");
			ch -= 128;
		}
		if ((ch < 32) || (ch == 0x7f)) {
			wprintw(show_pad, "^");
			ch ^= 0x40; /* ^@, ^A, ^B; ^? for DEL */
		}
		wprintw(show_pad, "%c", ch);
	}
	
	wprintw(show_pad, "\"\n");
}


	
void show (char *command_line)

{
	unsigned int i,l,len,temp_int;
	unsigned long offset=0,temp_long;	
	unsigned char temp_char,*ch_ptr;
	void *ptr;

	if (device_handle==NULL)
		return;

	show_pad_info.line=0;
	
	if (current_type==NULL) {
		wmove (show_pad,0,0);
		ch_ptr=type_data.u.buffer;
		for (l=0;l<file_system_info.block_size/16;l++) {
			wprintw (show_pad,"%08ld :  ",offset);
			for (i=0;i<16;i++) {
				if (type_data.offset_in_block==offset+i)
					wattrset (show_pad,A_REVERSE);
			
				if (ch_ptr [i]>=' ' && ch_ptr [i]<='z')
					wprintw (show_pad,"%c",ch_ptr [i]);
				else
					wprintw (show_pad,".");
				if (type_data.offset_in_block==offset+i)
					wattrset (show_pad,A_NORMAL);
			}
			wprintw (show_pad,"   ");
			for (i=0;i<16;i++) {
				if (type_data.offset_in_block==offset+i)
					wattrset (show_pad,A_REVERSE);
			
				wprintw (show_pad,"%02x",ch_ptr [i]);

				if (type_data.offset_in_block==offset+i) {
					wattrset (show_pad,A_NORMAL);
					show_pad_info.line=l-l % show_pad_info.display_lines;
				}

				wprintw (show_pad," ");
			}
			wprintw (show_pad,"\n");
			offset+=16;
			ch_ptr+=16;
		}
		show_pad_info.max_line=l-1;show_pad_info.max_col=COLS-1;
		refresh_show_pad ();show_info ();
	}
	else {
		wmove (show_pad,0,0);l=0;
		for (i=0;i<current_type->fields_num;i++) {
			wprintw (show_pad,"%-20s = ",current_type->field_names [i]);
			ptr=type_data.u.buffer+offset;
			len = current_type->field_lengths[i];
			switch (current_type->field_types[i]) {
			case FIELD_TYPE_INT:
				show_int(len, ptr);
				break;
			case FIELD_TYPE_UINT:
				show_uint(len, ptr);
				break;
			case FIELD_TYPE_CHAR:
				show_char(len, ptr);
				break;
			default:
				wprintw (show_pad, "unimplemented\n");
				break;
			}
			offset+=len;
			l++;
		}
		current_type->length=offset;
		show_pad_info.max_line=l-1;
		refresh_show_pad ();show_info ();
	}
}

void next (char *command_line)

{
	long offset=1;
	char *ptr,buffer [80];

	ptr=parse_word (command_line,buffer);
	
	if (*ptr!=0) {
		ptr=parse_word (ptr,buffer);
		offset*=atol (buffer);
	}
	
	if (current_type!=NULL) {
		sprintf (buffer,"setoffset type +%ld",offset);
		dispatch (buffer);
		return;
	}

	if (type_data.offset_in_block+offset < file_system_info.block_size) {
		type_data.offset_in_block+=offset;
		sprintf (buffer,"show");dispatch (buffer);
	}
		
	else {
		wprintw (command_win,"Error - Offset out of block\n");refresh_command_win ();
	}
}

void prev (char *command_line)

{
	long offset=1;
	char *ptr,buffer [80];

	ptr=parse_word (command_line,buffer);
	
	if (*ptr!=0) {
		ptr=parse_word (ptr,buffer);
		offset*=atol (buffer);
	}
	
	if (current_type!=NULL) {
		sprintf (buffer,"setoffset type -%ld",offset);
		dispatch (buffer);
		return;
	}

	if (type_data.offset_in_block-offset >= 0) {
		type_data.offset_in_block-=offset;
		sprintf (buffer,"show");dispatch (buffer);
	}
	
	else {
		wprintw (command_win,"Error - Offset out of block\n");refresh_command_win ();
	}
}

void pgdn (char *commnad_line) 

{
	show_pad_info.line+=show_pad_info.display_lines;
	refresh_show_pad ();refresh_show_win ();
}

void pgup (char *command_line)

{
	show_pad_info.line-=show_pad_info.display_lines;
	refresh_show_pad ();refresh_show_win ();
}

void redraw (char *command_line)

{
	redraw_all ();
	dispatch ("show");
}

void remember (char *command_line)

{
	long entry_num;
	char *ptr,buffer [80];
	
	if (device_handle==NULL) {
		wprintw (command_win,"Error - No device opened\n");refresh_command_win ();
		return;
	}

	ptr=parse_word (command_line,buffer);
	
	if (*ptr==0) {
		wprintw (command_win,"Error - Argument not specified\n");refresh_command_win ();
		return;		
	}
	
	ptr=parse_word (ptr,buffer);

	entry_num=remember_lifo.entries_count++;
	if (entry_num>REMEMBER_COUNT-1) {
		entry_num=0;
		remember_lifo.entries_count--;
	}
	
	remember_lifo.offset [entry_num]=device_offset;
	remember_lifo.type [entry_num]=current_type;
	strcpy (remember_lifo.name [entry_num],buffer);
	
	if (current_type!=NULL)
		wprintw (command_win,"Object %s in Offset %ld remembered as %s\n",current_type->name,device_offset,buffer);
	else
		wprintw (command_win,"Offset %ld remembered as %s\n",device_offset,buffer);
			
	refresh_command_win ();
}

void recall (char *command_line)

{
	char *ptr,buffer [80];
	long entry_num;

	if (device_handle==NULL) {
		wprintw (command_win,"Error - No device opened\n");refresh_command_win ();
		return;
	}

	ptr=parse_word (command_line,buffer);

	if (*ptr==0) {
		wprintw (command_win,"Error - Argument not specified\n");refresh_command_win ();
		return;		
	}

	ptr=parse_word (ptr,buffer);

	
	for (entry_num=remember_lifo.entries_count-1;entry_num>=0;entry_num--) {
		if (strcmp (remember_lifo.name [entry_num],buffer)==0)
			break;	
	}
	
	if (entry_num==-1) {
		wprintw (command_win,"Error - Can not recall %s\n",buffer);refresh_command_win ();
		return;
	}

	sprintf (buffer,"setoffset %ld",remember_lifo.offset [entry_num]);dispatch (buffer);
	if (remember_lifo.type [entry_num] != NULL) {
		sprintf (buffer,"settype %s",remember_lifo.type [entry_num]->name);dispatch (buffer);	
	}

	else {
		sprintf (buffer,"settype none");dispatch (buffer);	
	}
			
	wprintw (command_win,"Object %s in Offset %ld recalled\n",current_type->name,device_offset);
	refresh_command_win ();
}

void enable_write (char *command_line)

{
	FILE *fp;

	if (device_handle==NULL) {
		wprintw (command_win,"Error - No device opened\n");refresh_command_win ();
		return;
	}

	if (!AllowChanges) {
		wprintw (command_win,"Sorry, write access is not allowed\n");
    		return;
    	}
    	
    	if (mounted) {
    		wprintw (command_win,"Error - Filesystem is mounted\n");
		return;    		
    	}
    	
	if ( (fp=fopen (device_name,"r+b"))==NULL) {
		wprintw (command_win,"Error - Can not open device %s for reading and writing\n",device_name);refresh_command_win ();
		return;
	}
	fclose (device_handle);
	device_handle=fp;write_access=1;
	wprintw (command_win,"Write access enabled - Be careful\n");refresh_command_win ();
}

void disable_write (char *command_line)

{
	FILE *fp;

	if (device_handle==NULL) {
		wprintw (command_win,"Error - No device opened\n");refresh_command_win ();
		return;
	}

	if ( (fp=fopen (device_name,"rb"))==NULL) {
		wprintw (command_win,"Error - Can not open device %s\n",device_name);refresh_command_win ();
		return;
	}
	
	fclose (device_handle);
	device_handle=fp;write_access=0;
	wprintw (command_win,"Write access disabled\n");refresh_command_win ();
}

void write_data (char *command_line)

{
	write_type_data ();
}
