⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ui.c

📁 fdisk 实现源码,可以查询Linux下系统的分区信息
💻 C
📖 第 1 页 / 共 2 页
字号:
/*    fdisk - Linux fdisk clone    This file originally from GNU Parted.    Copyright (C) 1999, 2000, 2001, 2002, 2006 Free Software Foundation, Inc.    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, write to the Free Software    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA*/#include <parted/parted.h>#include <parted/debug.h>#include <ctype.h>#include <signal.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <setjmp.h>#include "config.h"#include "command.h"#include "strlist.h"#include "ui.h"#define N_(String) String#if ENABLE_NLS#  include <libintl.h>#  include <locale.h>#  define _(String) dgettext (PACKAGE, String)#else#  define _(String) (String)#endif /* ENABLE_NLS */#ifdef HAVE_LIBREADLINE#ifdef HAVE_TERMCAP_H#include <termcap.h>#elseextern int tgetnum (char* key);#endif#include <readline/readline.h>#include <readline/history.h>#ifndef HAVE_RL_COMPLETION_MATCHES#define rl_completion_matches completion_matches#endif#ifndef rl_compentry_func_t#define rl_compentry_func_t void#endif#endif /* HAVE_LIBREADLINE */char* interface_name = "GNU Fdisk " VERSION;static char* banner_msg = N_("Copyright (C) 1998 - 2006 Free Software Foundation, Inc.\n""This program is free software, covered by the GNU General Public License.\n""\n""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.\n\n");static char* usage_msg = N_("Usage: fdisk [OPTION]... [DEVICE]\n"); static char* bug_msg = N_("You found a bug in GNU Fdisk.\n""This may have been fixed in the last version of GNU Parted that you can find at:\n""\thttp://ftp.gnu.org/gnu/parted/\n\n""Please check this version prior to bug reporting.\n\n""If this has not been fixed yet or if you don't know how to check, please email:\n""\tbug-parted@gnu.org\n""or (preferably) file a bug report at:\n""\thttp://parted.alioth.debian.org/bugs/\n\n""Your report should contain the version of this release (%s) along with the\n""error message below, the output of\n""\tparted DEVICE unit co print unit s print\n""and additional information about your setup you consider important.\n");#define MAX_WORDS	1024static StrList*		command_line;static FdiskCommand**	commands;static StrList*		ex_opt_str [64];static StrList*		on_list;static StrList*		off_list;static StrList*		on_off_list;static StrList*		fs_type_list;static StrList*		disk_type_list;static struct {	const StrList*	possibilities;	const StrList*	cur_pos;	int		in_readline;	sigjmp_buf	jmp_state;} readline_state;static PedExceptionOption	current_exception_opt = 0;/* If we don't want the possibilities to appear on the prompt, this    should be set to 0. TODO: Making this without a global variable   might be a good idea */static prompt_possibilities = 1;#ifdef HAVE_LIBREADLINE/* returns matching commands for text */static char*command_generator (char* text, int state){	if (!state)		readline_state.cur_pos = readline_state.possibilities;	while (readline_state.cur_pos) {		const StrList*	cur = readline_state.cur_pos;		readline_state.cur_pos = cur->next;		if (str_list_match_node (cur, text))			return str_list_convert_node (cur);	}	return NULL;}/* completion function for readline() */char**fdisk_complete_function (char* text, int start, int end){	return rl_completion_matches (text,		(rl_compentry_func_t*) command_generator);}static void_add_history_unique (const char* line){	HIST_ENTRY*	last_entry = current_history ();	if (!strlen (line))		return;	if (!last_entry || strcmp (last_entry->line, line))		add_history ((char*) line);}#endif /* HAVE_LIBREADLINE */static voidinterrupt_handler (int signum){	int	in_readline = readline_state.in_readline;	readline_state.in_readline = 0;	signal (signum, &interrupt_handler);	if (in_readline) {		printf ("\n");		siglongjmp (readline_state.jmp_state, 1);	}}static char*_readline (const char* prompt, const StrList* possibilities){	char*		line;	readline_state.possibilities = possibilities;	readline_state.cur_pos = NULL;	readline_state.in_readline = 1;	if (sigsetjmp (readline_state.jmp_state, 1))		return NULL;	fdisk_wipe_line ();#ifdef HAVE_LIBREADLINE	if (!fdisk_opt_script_mode) {		/* XXX: why isn't prompt const? */		line = readline ((char*) prompt);		if (line)			_add_history_unique (line);	} else#endif	{		printf ("%s", prompt);		fflush (stdout);		line = (char*) malloc (256);		if (fgets (line, 256, stdin) && strcmp (line, "") != 0) {			line [strlen (line) - 1] = 0;	/* kill trailing CR */		} else {			free (line);			line = NULL;		}	}	readline_state.in_readline = 0;	return line;}static PedExceptionOptionoption_get_next (PedExceptionOption options, PedExceptionOption current){	PedExceptionOption	i;	if (current == 0)		i = PED_EXCEPTION_OPTION_FIRST;	else		i = current * 2;	for (; i <= options; i *= 2) {		if (options & i)			return i;	}	return 0;}static void_print_exception_text (PedException* ex){	StrList*		text;	fdisk_wipe_line ();	if (ex->type == PED_EXCEPTION_BUG) {		printf (bug_msg, VERSION);		text = str_list_create ("\n", ex->message, "\n", NULL);	} else {		text = str_list_create (			   _(ped_exception_get_type_string (ex->type)),			   ": ", ex->message, "\n", NULL);	}	str_list_print_wrap (text, fdisk_screen_width (), 0, 0);	str_list_destroy (text);}static PedExceptionOptionexception_handler (PedException* ex){	PedExceptionOption	opt;	_print_exception_text (ex);	/* only one choice?  Take it ;-) */	opt = option_get_next (ex->options, 0);	if (!option_get_next (ex->options, opt))		return opt;	/* script-mode: don't handle the exception */	if (fdisk_opt_script_mode)		return PED_EXCEPTION_UNHANDLED;	do {		opt = fdisk_command_line_get_ex_opt ("", ex->options);	} while (opt == PED_EXCEPTION_UNHANDLED && isatty (0));	return opt;}static int_str_is_spaces (const char* str){	while (isspace (*str)) str++;	return *str == 0;}static char*realloc_and_cat (char* str, const char* append){	int	length = strlen (str) + strlen (append) + 1;	char*	new_str = realloc (str, length);	strcat (new_str, append);	return new_str;}static char*_construct_prompt (const char* head, const char* def,		   const StrList* possibilities){	char*	prompt = strdup (head);	if (def && possibilities)		PED_ASSERT (str_list_match_any (possibilities, def),			    return NULL);	if (possibilities && prompt_possibilities && 	    str_list_length (possibilities) < 8) {		const StrList*	walk;		if (strlen (prompt))			prompt = realloc_and_cat (prompt, " ");		for (walk = possibilities; walk; walk = walk->next) {			if (walk != possibilities)				prompt = realloc_and_cat (prompt, "/");			if (def && str_list_match_node (walk, def) == 2) {				prompt = realloc_and_cat (prompt, "[");				prompt = realloc_and_cat (prompt, def);				prompt = realloc_and_cat (prompt, "]");			} else {				char*	text = str_list_convert_node (walk);				prompt = realloc_and_cat (prompt, text);				free (text);			}		}		prompt = realloc_and_cat (prompt, ": ");	} else if (def) {		size_t len = strlen (prompt);		if (len && prompt[len-1] != '\n')			prompt = realloc_and_cat (prompt, "  ");		prompt = realloc_and_cat (prompt, "(default ");		prompt = realloc_and_cat (prompt, def);		prompt = realloc_and_cat (prompt, "): ");	} else {		size_t len = strlen (prompt);		if (len && prompt[--len] != '\n') {			if (prompt[len] == ':' || prompt[len] == '?')				prompt = realloc_and_cat (prompt, " ");			else				prompt = realloc_and_cat (prompt, ": ");		}	}	return prompt;}static int_can_create_primary (const PedDisk* disk){	int	i;	for (i = 1; i <= ped_disk_get_max_primary_partition_count (disk); i++) {		if (!ped_disk_get_partition (disk, i))			return 1;	}	return 0;}static int_can_create_extended (const PedDisk* disk){	if (!_can_create_primary (disk))		return 0;	if (!ped_disk_type_check_feature (disk->type, PED_DISK_TYPE_EXTENDED))		return 0;	if (ped_disk_extended_partition (disk))		return 0;	return 1;}static int_can_create_logical (const PedDisk* disk){	if (!ped_disk_type_check_feature (disk->type, PED_DISK_TYPE_EXTENDED))		return 0;	return ped_disk_extended_partition (disk) != 0;}static intinit_ex_opt_str (){	int			i;	PedExceptionOption	opt;	for (i = 0; (1 << i) <= PED_EXCEPTION_OPTION_LAST; i++) {		opt = (1 << i);		ex_opt_str [i]			= str_list_create (				ped_exception_get_option_string (opt),				_(ped_exception_get_option_string (opt)),				NULL);		if (!ex_opt_str [i])			return 0;	}	ex_opt_str [i] = NULL;	return 1;}static voiddone_ex_opt_str (){	int	i;	for (i=0; ex_opt_str [i]; i++)		str_list_destroy (ex_opt_str [i]);}static intinit_state_str (){	on_list = str_list_create_unique (_("on"), "on", NULL);	off_list = str_list_create_unique (_("off"), "off", NULL);	on_off_list = str_list_join (str_list_duplicate (on_list),				     str_list_duplicate (off_list));	return 1;}static voiddone_state_str (){	str_list_destroy (on_list);	str_list_destroy (off_list);	str_list_destroy (on_off_list);}static intinit_fs_type_str (){	PedFileSystemType*	walk;	fs_type_list = NULL;	for (walk = ped_file_system_type_get_next (NULL); walk;	     walk = ped_file_system_type_get_next (walk))	{		fs_type_list = str_list_insert (fs_type_list, walk->name);		if (!fs_type_list)			return 0;	}	return 1;}static intinit_disk_type_str (){	PedDiskType*	walk;	disk_type_list = NULL;	for (walk = ped_disk_type_get_next (NULL); walk;	     walk = ped_disk_type_get_next (walk))	{		disk_type_list = str_list_insert (disk_type_list, walk->name);		if (!disk_type_list)			return 0;	}	return 1;}void fdisk_usage_msg() {        printf (_(usage_msg));}voidfdisk_help_msg (){        fdisk_usage_msg();	printf ("\n%s\n", _("OPTIONs:"));	fdisk_print_options_help ();/*	printf ("\n%s\n", _("COMMANDs:"));	fdisk_print_commands_help ((FdiskCommand**)NULL);*/	exit (0);}intfdisk_interactive_mode (PedDisk** disk, FdiskCommand* cmd_list[]){	char*		line;	StrList*	list;	StrList*	command_names = fdisk_command_get_names (cmd_list);	printf ("%s\n", interface_name);	list = str_list_create (_(banner_msg), NULL);	str_list_print_wrap (list, fdisk_screen_width (), 0, 0);	str_list_destroy (list);	fdisk_print_using_dev ((*disk)->dev);	while (1) {		char*		word;		FdiskCommand*	cmd;		commands = cmd_list;	/* FIXME yucky, nasty, evil hack */		while (!fdisk_command_line_get_word_count ()) {			if (feof (stdin)) {				printf ("\n");				return 1;			}			prompt_possibilities = 0;			fdisk_command_line_prompt_words ("Command (m for help):", NULL,							 command_names, 1);			prompt_possibilities = 1;		}		word = fdisk_command_line_pop_word ();		if (word) {			cmd = fdisk_command_get (commands, word);			free (word);			if (cmd) {				if (!fdisk_command_run (cmd, disk))					fdisk_command_line_flush ();			} else {				fdisk_print_commands_help (commands);			}		}	}	return 1;}/* If menu equals: * 0 - expert menu. * 1 - filesystem menu.  * 2 - bsd menu */intfdisk_interactive_menu (PedDisk** disk, FdiskCommand* cmd_list[], int menu){	char*		line;	StrList*	list;	StrList*	command_names = fdisk_command_get_names (cmd_list);	/* FIXME yucky, nasty, evil hack */	FdiskCommand **saved_commands = commands;	commands = cmd_list;		while (1) {		char*		word;		FdiskCommand*	cmd;		while (!fdisk_command_line_get_word_count ()) {			if (feof (stdin)) {				printf ("\n");				commands = saved_commands;				return 1;			}			prompt_possibilities = 0;			if (!menu)			  fdisk_command_line_prompt_words ("Expert command (m for help)", NULL,							   command_names, 1);			else if (menu == 1)			  fdisk_command_line_prompt_words ("Filesystem (m for help)", NULL,							   command_names, 1);			else if (menu == 2)			  fdisk_command_line_prompt_words ("BSD disklabel command (m for help)", NULL,							   command_names, 1);			prompt_possibilities = 1;		}		word = fdisk_command_line_pop_word ();		if (word) {			cmd = fdisk_command_get (commands, word);			free (word);			if (cmd) {				if (strcmp ((char *)cmd->names->str, "r")) {			    		if (!fdisk_command_run (cmd, disk))			      			fdisk_command_line_flush ();			  		} else {						commands = saved_commands;			    			return 1;			  		}			} else {				fdisk_print_commands_help ((FdiskCommand **)NULL);			}		}	}	commands = saved_commands;	return 1;}/* Prompt the user to answer a yes or no question. */intcommand_line_prompt_boolean_question (const char* prompt) {	char        *user_ans;	StrList *possibilities = str_list_create (_("yes"), _("no"), NULL);	user_ans = fdisk_command_line_get_word (_(prompt), _("no"), possibilities, 0);	if (strcmp (user_ans, _("yes")) == 0)		return 1;	/* user answered no */	return 0;}intfdisk_screen_width (){	int	width = 0;	if (fdisk_opt_script_mode)		return 32768;	/* no wrapping ;) *//* HACK: don't specify termcap separately - it'll annoy the users. */#ifdef HAVE_LIBREADLINE	width = tgetnum ("co");#endif	if (width <= 0)		width = 80;	return width;}voidfdisk_wipe_line (){	if (fdisk_opt_script_mode)		return;	/* yuck */	printf ("\r                                                                          \r"	);}PedExceptionOptionfdisk_command_line_get_ex_opt (const char* prompt, PedExceptionOption options){	Option			optlist[10];	PedExceptionOption	opt;	const char*		opt_name;	int			i = 0, result;	for (opt = option_get_next (options, 0); opt && i < sizeof(optlist) - 1; 	     opt = option_get_next (options, opt), i++) {		opt_name = ped_exception_get_option_string (opt);		optlist[i].option = tolower(opt_name[0]);		/* FIXME: Localization here won't work this way */		optlist[i].description = _(ped_exception_get_option_string (opt));	}	optlist[i].option = 0;	result = fdisk_command_line_get_option (prompt, optlist);	if (!result)		return PED_EXCEPTION_UNHANDLED;	for (opt = option_get_next (options, 0); opt; 	     opt = option_get_next (options, opt)) {		opt_name = ped_exception_get_option_string (opt);		if (result == tolower(opt_name[0])) 			break;	}	return opt;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -