1583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o/*
2583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o
3583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o/usr/src/ext2ed/main.c
4583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o
5583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'oA part of the extended file system 2 disk editor.
6583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o
7583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o------------
8583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'oMain program
9583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o------------
10583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o
11583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'oThis file mostly contains:
12583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o
13583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o1.	A list of global variables used through the entire program.
14583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o2.	The parser, which asks the command line from the user.
15583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o3.	The dispatcher, which analyzes the command line and calls the appropriate handler function.
16583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o4.	A command pattern matcher which is used along with the readline completion feature.
17583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o5.	A function which tells the user that an internal error has occured.
18583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o
19583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'oFirst written on: March 30 1995
20583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o
21583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'oCopyright (C) 1995 Gadi Oxman
22583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o
23583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o*/
245e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o
25583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o#include <stdio.h>
26583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o#include <stdlib.h>
27583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o#include <string.h>
285e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o#include <signal.h>
29583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o
305e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o#ifdef HAVE_READLINE
31583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o#include <readline.h>
32583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o#include <history.h>
335e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o#endif
345e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o
355e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o#ifdef HAVE_GETOPT_H
365e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o#include <getopt.h>
375e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o#else
385e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'oextern int optind;
395e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'oextern char *optarg;
405e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o#endif
41583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o
42583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o#include "ext2ed.h"
43583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o
44583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o/* Global variables */
45583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o
46583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o/*
47583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o
48583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'oConfiguration file options
49583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o
50583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'oThe following variables will be set by init.c to the values selected in the user configuration file.
51583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'oThey are initialized below to some logical defaults.
52583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o
53583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o*/
54583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o
55583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o
56583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'ochar Ext2Descriptors [200]="ext2.descriptors";	/* The location of the ext2 filesystem object definition */
57583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'ochar AlternateDescriptors [200]="";		/* We allow the user to define additional structures */
58583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'ochar LogFile [200]="ext2ed.log";		/* The location of the log file - Each write will be logged there */
59583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'oint LogChanges=1;				/* 1 enables logging, 0 diables logging */
60583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'oint AllowChanges=0;				/* When set, the enablewrite command will fail */
61583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'oint AllowMountedRead=0;				/* Behavior when trying to open a mounted filesystem read-only */
62583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'oint ForceExt2=0;				/* When set, ext2 autodetection is overridden */
63583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'oint DefaultBlockSize=1024;
64583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'ounsigned long DefaultTotalBlocks=2097151;
65583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'ounsigned long DefaultBlocksInGroup=8192;	/* The default values are used when an ext2 filesystem is not */
66583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'oint ForceDefault=0;				/* detected, or ForceDefault is set */
67583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o
68583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'ochar last_command_line [80];			/* A simple one command cache, in addition to the readline history */
69583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o
70583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'ochar device_name [80];				/* The location of the filesystem */
71583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'oFILE *device_handle=NULL;			/* This is passed to the fopen / fread ... commands */
72583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'olong device_offset;				/* The current position in the filesystem */
73583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o						/* Note that we have a 2 GB limitation */
74efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o
75583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'oint mounted=0;					/* This is set when we find that the filesystem is mounted */
76583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o
77583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'ostruct struct_commands general_commands,ext2_commands;		/* Used to define the general and ext2 commands */
78583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'ostruct struct_descriptor *first_type,*last_type,*current_type;	/* Used to access the double linked list */
79583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'ostruct struct_type_data type_data;				/* The current data is sometimes stored here */
80583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'ostruct struct_file_system_info file_system_info;		/* Essential information on the filesystem */
81583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'ostruct struct_file_info file_info,first_file_info;		/* Used by file_com.c to access files */
82583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'ostruct struct_group_info group_info;				/* Used by group_com.c */
83583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'ostruct struct_super_info super_info;				/* Used by super_com.c */
84583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'ostruct struct_remember_lifo remember_lifo;			/* A circular memory of objects */
85583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'ostruct struct_block_bitmap_info block_bitmap_info;		/* Used by blockbitmap_com.c */
86583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'ostruct struct_inode_bitmap_info inode_bitmap_info;		/* Used by inodebitmap_com.c */
87583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o
88583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'oint redraw_request=0;						/* Is set by a signal handler to handle terminal */
89583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o								/* screen size change. */
90583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o
91583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o
925e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o/*
935e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o * We just call the parser to get commands from the user. We quit when
945e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o * parser returns.
955e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o */
965e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'oint main (int argc, char **argv)
97583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o{
985e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o	int	write_priv = 0;
995e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o	int	c;
1005e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o	char	*buf;
101efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o
1025e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o	if (!init ())
1035e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o		return (1);
1045e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o	while ((c = getopt (argc, argv, "w")) != EOF) {
1055e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o		switch (c) {
1065e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o		case 'w':
1075e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o			write_priv++;
1085e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o			break;
1095e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o		}
1105e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o	}
1115e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o	if (optind < argc) {
1125e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o		buf = malloc(strlen(argv[optind]) + 32);
1135e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o		if (!buf) {
1145e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o			fprintf(stderr, "Couldn't allocate filename buffer\n");
1155e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o			exit(1);
1165e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o		}
1175e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o		strcpy(buf, "set_device ");
1185e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o		strcat(buf, argv[optind]);
1195e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o		set_device(buf);
1205e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o		free(buf);
1215e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o		if (write_priv) {
122efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o			wprintw (command_win,"\n");
1235e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o			enable_write("enable_write");
1245e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o		}
1255e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o	}
1265e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o	parser ();			/* Get and parse user commands */
1275e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o	prepare_to_close();		/* Do some cleanup */
1285e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o	printf("Quitting ...\n");
1295e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o	return(0);
130583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o}
131583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o
132583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o
133583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o/*
1345e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o * Read a character from the command window
1355e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o */
1365e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'oint command_read_key()
1375e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o{
1385e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o	int	key = 0;
139583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o
1405e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o	while (!key) {
1415e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o		if (redraw_request) {
1425e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o			redraw_all();
1435e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o			redraw_request=0;
1445e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o		}
1455e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o		key = wgetch(command_win);
1465e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o		switch (key) {
1475e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o		case 0x1A:
1485e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o			key = 0;
1495e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o			kill(getpid(), SIGTSTP);
1505e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o			break;
151efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o
1525e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o		case KEY_NPAGE:
1535e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o			pgdn("");
1545e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o			refresh_command_win ();
1555e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o			break;
1565e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o
1575e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o		case KEY_PPAGE:
1585e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o			pgup("");
1595e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o			refresh_command_win ();
1605e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o			break;
1615e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o		case ERR:
1625e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o			key = 0;
1635e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o			break;
164efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o
1655e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o		case KEY_BACKSPACE:
1665e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o			key = '\b';
1675e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o		}
1685e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o		if ((key < 32 && key != '\b' && key != '\n') ||
1695e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o		    (key > 127))
1705e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o			key = 0;
1715e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o	}
1725e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o	return key;
1735e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o}
174583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o
1755e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o#ifdef HAVE_READLINE
1765e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'oint rl_getc_replacement(FILE *f)
1775e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o{
1785e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o	int	key = command_read_key();
1795e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o
1805e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o	if (key == '\b') {
1815e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o		if (rl_point > 0)
1825e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o			wprintw(command_win, "\b \b");
1835e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o	} else
1845e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o		wprintw(command_win, "%c", key);
1855e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o	return key;
1865e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o}
187583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o
1885e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o/*
1895e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o * This function asks the user for a command and calls the dispatcher
1905e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o * function, dispatch, to analyze it.  We use the readline library
1915e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o * function readline to read the command, hence all the usual readline
1925e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o * keys are available.  The new command is saved both in the
1935e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o * readline's history and in our tiny one-command cache, so that only
1945e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o * the enter key is needed to retype it.
1955e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o */
1965e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'ovoid parser (void)
197583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o{
198583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o	char *ptr,command_line [80];
199583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o	int quit=0;
200583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o
2015e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o#if 0
2025e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o	noecho();
2035e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o	cbreak();
2045e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o	keypad(command_win, 1);
2055e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o	wtimeout(command_win, 100);
206efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o
2075e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o	rl_getc_function = rl_getc_replacement;
2085e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o#endif
209efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o
210583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o	while (!quit) {
2115e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o		/* Terminal screen size has changed */
2125e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o		if (redraw_request) {
2135e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o			redraw_all();
2145e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o			redraw_request=0;
215583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o		}
216583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o
2175e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o		wmove (command_win,0,0);
2185e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o		wclrtoeol (command_win);
2195e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o		wprintw (command_win,"ext2ed > ");
2205e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o		refresh_command_win ();
221583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o
2225e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o		/*
2235e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o		 * The ncurses library optimizes cursor movement by
2245e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o		 * keeping track of the cursor position. However, by
2255e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o		 * using the readline library I'm breaking its
2265e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o		 * assumptions. The double -1 arguments tell ncurses
2275e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o		 * to disable cursor movement optimization this
2285e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o		 * time.
2295e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o		 */
2305e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o		mvcur (-1,-1,LINES-COMMAND_WIN_LINES,0);
231efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o
2325e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o		/* echo (); */
2335e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o		ptr=readline ("ext2ed > ");
2345e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o		/* noecho (); */
2355e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o
2365e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o		/*
2375e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o		 * Readline allocated the buffer - Copy the string
2385e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o		 * and free the allocated buffer
2395e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o		 * XXX WHY???
2405e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o		 */
2415e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o		strcpy (command_line,ptr);
242efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o		free (ptr);
243583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o
244583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o		if (*command_line != 0)
2455e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o			add_history (command_line);
246583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o
2475e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o		/* If only enter was pressed, recall the last command */
248efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o		if (*command_line==0)
249583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o			strcpy (command_line,last_command_line);
250efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o
2515e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o		/* Emulate readline's actions for ncurses */
2525e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o		mvcur (-1,-1,LINES-COMMAND_WIN_LINES,0);
253583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o		werase (command_win);
2545e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o		wprintw (command_win,"ext2ed > ");
2555e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o		wprintw (command_win,command_line);
2565e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o		wprintw (command_win,"\n");
2575e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o		refresh_command_win ();
258583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o
2595e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o		/* Save this command in our tiny cache */
2605e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o		strcpy (last_command_line,command_line);
261583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o
2625e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o		/* And call dispatch to do the actual job */
2635e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o		quit=dispatch (command_line);
264efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o	}
265583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o}
2665e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o#else
2675e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'ovoid read_line(char * foo) {
2685e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o	char * chptr = foo;
2695e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o	int ch;
2705e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o	int done = 0;
2715e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o
2725e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o	while (!done && (ch = command_read_key())) {
2735e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o		switch (ch) {
2745e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o		case '\n':
2755e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o			done = 1;
2765e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o			break;
2775e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o
2785e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o		case '\b':
2795e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o			if (chptr > foo) {
2805e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o				wprintw(command_win, "\b \b");
2815e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o				chptr--;
2825e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o			}
2835e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o			break;
2845e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o
2855e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o		default:
2865e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o			if (ch > 256)
2875e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o				break;
2885e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o			if (ch == '\n') break;
2895e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o			*chptr++ = ch;
2905e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o			wprintw(command_win, "%c", ch);
2915e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o			break;
2925e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o		}
2935e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o	}
2945e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o	*chptr = '\0';
2955e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o}
296583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o
2975e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'ovoid parser (void)
2985e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o{
2995e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o	char command_line [80];
3005e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o	int quit=0;
301583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o
3025e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o	noecho();
3035e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o	cbreak();
3045e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o	wtimeout(command_win, 100);
3055e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o	keypad(command_win, 1);
306583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o
3075e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o	while (!quit) {
3085e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o		/* Terminal screen size has changed */
3095e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o		if (redraw_request) {
3105e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o			redraw_all();
3115e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o			redraw_request=0;
3125e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o		}
313583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o
3145e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o		wmove (command_win,0,0);wclrtoeol (command_win);
315583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o
3165e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o		wmove(command_win, 0, 0);
3175e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o		wprintw(command_win, "ext2ed > ");
3185e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o		read_line(command_line);
319583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o
3205e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o		/* If only enter was pressed, recall the last command */
3215e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o 		if (*command_line==0)
3225e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o 			strcpy (command_line,last_command_line);
3235e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o
324efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o		mvcur (-1,-1,LINES-COMMAND_WIN_LINES + 1,0);
3255e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o
3265e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o 		strcpy (last_command_line,command_line);	/* Save this command in our tiny cache */
327efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o
3285e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o		/* And call dispatch to do the actual job */
3295e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o		quit=dispatch (command_line);
330efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o	}
3315e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o}
3325e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o#endif
333583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o
334583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o
3355e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o/*
3365e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o * This is a very important function. Its task is to recieve a command
3375e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o * name and link it to a C function.  There are three types of commands:
338efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o *
3395e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o * 1.	General commands - Always available and accessed through
340efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o * general_commands.
3415e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o * 2.	Ext2 specific commands - Available when editing an ext2
342efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o * filesystem, accessed through ext2_commands.
3435e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o * 3.	Type specific commands - Those are changing according to the
3445e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o * current type. The global variable current_type points to the
3455e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o * current object definition (of type struct_descriptor). In it, the
346efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o * struct_commands entry contains the type specific commands links.
347efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o *
3485e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o * Overriding is an important feature - Much like in C++ : The same
3495e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o * command name can dispatch to different functions. The overriding
3505e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o * priority is 3,2,1; That is - A type specific command will always
3515e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o * override a general command. This is used through the program to
352efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o * allow fine tuned operation.
353efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o *
3545e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o * When an handling function is found, it is called along with the
3555e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o * command line that was passed to us. The handling function is then
356efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o * free to interpert the arguments in its own style.
3575e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o */
3585e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'oint dispatch (char *command_line)
359583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o{
360583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o	int i,found=0;
361efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o
362583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o	char command [80];
363583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o
364583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o	parse_word (command_line,command);
365efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o
366efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o	if (strcasecmp (command,"quit")==0) return (1);
367583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o
3685e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o	/* 1. Search for type specific commands FIRST - Allows
3695e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o	overriding of a general command */
370583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o
371583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o	if (current_type != NULL)
3725e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o		for (i=0;
3735e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o		     i<=current_type->type_commands.last_command && !found;
3745e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o		     i++) {
375583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o			if (strcasecmp (command,current_type->type_commands.names [i])==0) {
376583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o				(*current_type->type_commands.callback [i]) (command_line);
377583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o				found=1;
378583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o			}
379583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o		}
380583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o
381583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o	/* 2. Now search for ext2 filesystem general commands */
382583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o
383583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o	if (!found)
384583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o		for (i=0;i<=ext2_commands.last_command && !found;i++) {
385583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o			if (strcasecmp (command,ext2_commands.names [i])==0) {
386583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o				(*ext2_commands.callback [i]) (command_line);
387583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o				found=1;
388583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o			}
389583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o		}
390583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o
391efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o
392583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o	/* 3. If not found, search the general commands */
393efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o
394583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o	if (!found)
395583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o		for (i=0;i<=general_commands.last_command && !found;i++) {
396583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o			if (strcasecmp (command,general_commands.names [i])==0) {
397583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o				(*general_commands.callback [i]) (command_line);
398583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o				found=1;
399583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o			}
400583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o		}
401583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o
402583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o	/* 4. If not found, issue an error message and return */
403efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o
404583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o	if (!found) {
405583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o		wprintw (command_win,"Error: Unknown command\n");
406583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o		refresh_command_win ();
407583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o	}
408efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o
409583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o	return (0);
410583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o}
411583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o
412583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o
413583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o/*
414efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o *
4155e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o * This function copies the next word in source to the variable dest,
4165e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o * ignoring whitespaces.  It returns a pointer to the next word in
4175e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o * source.  It is used to split the command line into command and arguments.
4185e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o */
4195e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'ochar *parse_word (char *source,char *dest)
420583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o{
421583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o	char ch,*source_ptr,*target_ptr;
422efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o
423583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o	if (*source==0) {
424583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o		*dest=0;
425583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o		return (source);
426583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o	};
427efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o
428583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o	source_ptr=source;target_ptr=dest;
429583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o	do {
430583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o		ch=*source_ptr++;
431583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o	} while (! (ch>' ' && ch<='z') && ch!=0);
432583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o
433583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o	while (ch>' ' && ch<='z') {
434583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o		*target_ptr++=ch;
435efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o		ch=*source_ptr++;
436583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o	}
437583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o
438583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o	*target_ptr=0;
439583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o
440583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o	source_ptr--;
441583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o	do {
442583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o		ch=*source_ptr++;
443583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o	} while (! (ch>' ' && ch<='z') && ch!=0);
444583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o
445583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o	return (--source_ptr);
446583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o}
447583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o
448583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o/*
4495e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o * text is the partial command entered by the user; We assume that it
4505e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o * is a part of a command - I didn't write code for smarter completion.
451efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o *
4525e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o * The state variable is an index which tells us how many possible
453efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o * completions we already returned to readline.
454efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o *
4555e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o * We return only one possible completion or (char *) NULL if there
4565e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o * are no more completions. This function will be called by readline
457efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o * over and over until we tell it to stop.
458efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o *
4595e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o * While scanning for possible completions, we use the same priority
460efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o * definition which was used in dispatch.
4615e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o */
4625e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o#if HAVE_READLINE
4635e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'ochar *complete_command (char *text,int state)
464583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o{
465583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o	int state_index=-1;
466583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o	int i,len;
467efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o
468583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o	len=strlen (text);
469583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o
470583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o	/* Is the command type specific ? */
471583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o
472583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o	if (current_type != NULL)
473583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o		for (i=0;i<=current_type->type_commands.last_command;i++) {
474583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o			if (strncmp (current_type->type_commands.names [i],text,len)==0) {
475583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o				state_index++;
476583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o				if (state==state_index) {
477583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o					return (dupstr (current_type->type_commands.names [i]));
478583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o				}
479583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o			}
480583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o		}
481583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o
482583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o	/* No, pehaps ext2 specific command then ? */
483efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o
484583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o	for (i=0;i<=ext2_commands.last_command;i++) {
485583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o		if (strncmp (ext2_commands.names [i],text,len)==0) {
486583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o			state_index++;
487583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o			if (state==state_index)
488583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o			return (dupstr (ext2_commands.names [i]));
489583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o		}
490583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o	}
491583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o
492efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o
493583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o	/* Check for a general command */
494efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o
495583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o	for (i=0;i<=general_commands.last_command;i++) {
496583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o		if (strncmp (general_commands.names [i],text,len)==0) {
497583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o				state_index++;
498583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o				if (state==state_index)
499583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o					return (dupstr (general_commands.names [i]));
500583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o		}
501583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o	}
502583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o
503583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o	/* quit is handled differently */
504efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o
505583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o	if (strncmp ("quit",text,len)==0) {
506583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o		state_index++;
507583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o		if (state==state_index)
508efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o			return (dupstr ("quit"));
509583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o	}
510583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o
511583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o	/* No more completions */
512efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o
513583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o	return ((char *) NULL);
514583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o}
5155e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o#endif
516583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o
517583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o
518efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o/*
5195e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o * Nothing special - Just allocates enough space and copy the string.
5205e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o */
5215e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'ochar *dupstr (char *src)
522583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o{
523583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o	char *ptr;
524efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o
525583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o	ptr=(char *) malloc (strlen (src)+1);
526583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o	strcpy (ptr,src);
527583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o	return (ptr);
528583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o}
529583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o
530583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o#ifdef DEBUG
531583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o/*
5325e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o * This function reports an internal error. It is almost not used. One
5335e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o * place in which I do check for internal errors is disk.c.
534efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o *
5355e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o * We just report the error, and try to continue ...
5365e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'o */
5375e941d2979aeab97929de6c0682425dead3bae74Theodore Ts'ovoid internal_error (char *description,char *source_name,char *function_name)
538583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o{
539583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o	wprintw (command_win,"Internal error - Found by source: %s.c , function: %s\n",source_name,function_name);
540efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o	wprintw (command_win,"\t%s\n",description);
541583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o	wprintw (command_win,"Press enter to (hopefully) continue\n");
542583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o	refresh_command_win ();getch ();werase (command_win);
543583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o}
544583a1ce5d1b225a6b01fc2b30a3bcb21fd0d48c9Theodore Ts'o
5450f31c737dbf999c90a0842e6a499416b8e1f0cb4Theodore Ts'o#endif
546