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

📄 cfdisk.c

📁 fdisk 实现源码,可以查询Linux下系统的分区信息
💻 C
📖 第 1 页 / 共 5 页
字号:
/*    GNU fdisk - a clone of Linux fdisk.    Copyright (C) 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 "../config.h"#include "common.h"#include "hacks.h"/*#include "command.h"*//*#include "ui.h"*/#define N_(String) String#if ENABLE_NLS#  include <libintl.h>#  include <locale.h>/* TODO: Fix some localizing issues */#  define _(String) dgettext (PACKAGE, String)/* FIXME: This doesn't seem to work */#  define P_(String) dgettext ("parted", String)#else#  define _(String) (String)#  define P_(String) (String)#endif /* ENABLE_NLS */#include <parted/parted.h>#include <parted/debug.h>#if HAVE_NCURSES_H  #include <ncurses.h>#else  #include <curses.h>#endif/* FIXME: I'm not sure when these are available, and what portability issues they will raise          Most likely this is not needed at all */#ifdef KEY_MIN#define USE_KEYPAD 1#else#define USE_KEYPAD 0/* Like Linux cfdisk */#define KEY_UP 1#define KEY_DOWN 2#define KEY_LEFT 3#define KEY_RIGHT 4#define KEY_BACKSPACE '\b'#define KEY_DC '\177'#endif#include <ctype.h>#include <stdarg.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#ifdef HAVE_GETOPT_H#include <getopt.h>#endifstatic const char* prog_name = "cfdisk (GNU fdisk) " VERSION "\n";static const char* license_msg = N_(	"Copyright (C) 2006 Free Software Foundation, Inc.\n"	"This is free software.  You may redistribute copies of it under the terms of\n"	"the GNU General Public License <http://www.gnu.org/licenses/gpl.html>.\n"	"There is NO WARRANTY, to the extent permitted by law.\n");static const char* usage_msg = N_(	"Usage: cfdisk [OPTION]... [DEVICE]\n");/* TODO: Should we move to argp? */static struct { const char* lopt; const char opt; const char *arg; const char *help; } options_help[] = {	{"help",	'h', NULL,	N_("displays this help message")},	{"version",	'v', NULL,	N_("displays the version")},	{"arrow-cursor", 'a', NULL, 	N_("use an arrow cursor instead of reverse video")},	{"new-table",	'z', NULL,	N_("create a new partition table on the disk")},	{"units",	'u', N_("UNIT"),N_("sets the default display units to UNIT")},	{"list-partition-types", 't', NULL, N_("displays a list of supported partition types")},        {NULL, 0, NULL, NULL}};/* Help should go here */static const char *help = N_(	"This is a curses-based disk partition manipulation program, which "	"allows you create, destroy, resize, move and copy partitions on "	"a hard drive.\n\n"	"Copyright (C) 2006 Free Software Foundation, Inc.\n\n"	"Key\tFunction\n"	"---\t--------\n\n"	" n\tCreate a new partition residing on the free space.\n"	" d\tDelete the selected partition.\n"	" c\tCheck the selected partition for consistency.\n"	" r\tResize the selected partition or change the size of the "	"entry in the partition table\n"	" o\tMove the partition to another place on the drive.\n"	" y\tCopies another partition over the selected one.\n"	" s\tLook for deleted file systems in the selected free space.\n"	" b\tDisplay or change partition flags, such as the bootable flag.\n"	" t\tChange the system type on the partition in the partition "	"in case it is currently wrong.\n"	" m\tChange the partition name, if supported.\n"	" x\tMaximize the extended partition.\n"	" z\tMinimize the extended partition.\n"	" u\tChange the display units.\n"	" i\tDisplay partition info.\n"	" w\tWrite the changes to the disk.\n"	" q\tQuit the program.\n"	" h\tDisplay this help.\n");#define MAX(X,Y) ((X) > (Y) ? (X) : (Y))#define MIN(X,Y) ((X) < (Y) ? (X) : (Y))/* Keys */#define BELL	'\007'	/* ^G */#define TAB	'\011'	/* ^I */#define CR	'\015'	/* ^M */#define ESC	'\033'	/* ^[ */#define CTRL_L	'\014'	/* ^L */#define CTRL_P	'\020'	/* ^P */#define CTRL_N	'\016'	/* ^N */#define CTRL_R	'\022'	/* ^R */#define MENUSIZE 3#define INFOSIZE 5#define MENUDIV 1enum _MenuOptions {	MENU_DEFAULT = 0,	MENU_TITLE = 1,  /* Leave one row for menu title */	MENU_LIST = 2,   /* Unimplemented */	MENU_ANYKEY = 4,	MENU_BUTTON = 8,	MENU_LEAVE_WARNING = 16, /* Don't clear the warning line */	MENU_NOHIGHLIGHT = 32, /* Do not highlight the selected element in the menu */	MENU_ARROWS = 64 /* Accept arrow keys as valid */};typedef enum _MenuOptions MenuOptions;#define TINYBUF 16	/* NOTE: Changing this may lead to buffer overflows. Double-check. */#define FSBUF 19	/* Don't touch unless you know what you are doing!! */#define SMALLBUF 512#define MAXFLAGS 63/* struct for a menu item. I got the idea from Linux cfdisk. Every action is bound to a key. */struct _MenuItem {	char key;	const char *name;	const char *desc; };typedef struct _MenuItem MenuItem;/* Struct for the opened device */struct _Context {	PedDevice *dev;	PedDisk *disk;	int is_devicefile;	char *devname;	char *info_size;	char *info_sectorsize;	char *info_model;	char *info_heads;	char *info_cylinders;	char *info_sectors;	char *info_cylsize;};typedef struct _Context Context;Context *init_disk(int new_table, char *devname, PedDevice *dev, PedDiskType *type);int new_table = 0;int arrow_cursor = 0;static voiddo_quit(int status, const char *message) {	endwin();	if (message) {		printf("%s\n",message);	}	exit(status);}static intget_center(const char *string) {	int x = strlen(string);	x = MIN(x,COLS);	x = (COLS-x)/2;	return x;}static voidclear_lines(int start, int end) {	int y = start;	do {		move (y,0);		clrtoeol();	} while(y++ < end);}/* Define these as macros */#define clear_status(warn) clear_lines(LINES - 1 - ((warn) != 0),0)#define clear_menu() clear_lines(LINES - 2 - MENUSIZE, LINES - 1);static voidset_status(const char *status, int warn_line) {	clear_status(warn_line);	/*attron(A_REVERSE);*/	move(LINES-1-warn_line,0);	mvaddstr(LINES-1-warn_line, get_center(status) ,status);	/*attroff(A_REVERSE);*/}static voidprint_warning(const char *status, int status_line) {	set_status(status,!status_line);	putchar(BELL);}static voidmenu_title (const char *title) {	move(LINES - 2 - MENUSIZE, 0);	clrtoeol();	mvaddstr(LINES - 2 - MENUSIZE, MENUDIV, title);	}enum _MsgOpts {	DOUBLE_NEW_LINE = 1,	/* Ignore space at the beginning of the line */	IGNORE_SPACE = 2,	/* Use \t to indent the whole text, even after newline */	TAB_TO_INDENT = 4	};typedef enum _MsgOpts MsgOpts;/* This is an ancient magic that turns a char* into a StrList, so we can display it */static StrList*_message_display_strlist(const char *msg, int *lines, MsgOpts opts) {	int x = 0, y = 0, lastword = 0, isnewline = 0, i, indent = 0;	StrList *message = NULL;	char buf[SMALLBUF];	/* We save the lines in a string list, counting them */	/* TODO: It doesn't deal with tabs correctly, this is currently           only with tabs in the beginning of the text. */	/* NOTE: We calculate indent, even when we don't use it */	for (i = 0; msg[i]; i++) {		/* If we reached the end of the line, move to the next line */		if (x >= SMALLBUF - 1 || x >= COLS-2) {			if (isblank(msg[i]) || msg[i] == '\r' ||			    msg[i] == '\n' || !lastword) {				buf[x] = '\0';				message = str_list_append(message,buf);				y++;				/* Real new line is two lines. */				if (msg[i] == '\n') { 					if (opts & DOUBLE_NEW_LINE)						message = str_list_append(								message,"");					y++;					isnewline = 1;				}			}			/* If this is not the end of the word, go back to the beginning of the word. */			else {				buf[lastword-1] = '\0';				message = str_list_append(message,buf);				y++;				i = i-x+lastword;			}			lastword = 0;			x = 0;			/* If the text was indented, move it right */			if (msg[i] == '\n')				indent = 0;			else if ((opts & TAB_TO_INDENT) && indent > 0) {				/* If the line is indented */				for (; x <= indent && x < SMALLBUF - 1 ; x++) {					buf[x] = ' ';				}			}		}		/* We ignore carriage returns */		if (msg[i] == '\r') {			continue;		}		/* We indent the text right, if we see a tab */		else if (msg[i] == '\t') {			lastword = x+1;			int n = ((x+9)/9)*9;			n = MIN(COLS-2,n);			for (; x <= n && x < SMALLBUF - 1; x++) {				buf[x] = ' ';			}			indent += 9;			continue;		}		/* If the line begins with a blank, skip it */		else if (isblank(msg[i])) {			if ((opts & IGNORE_SPACE) && x == 0) continue;			else lastword = x+1;		}		else if (msg[i] == '\n') {			if (!isnewline) {				buf[x] = '\0';				message = str_list_append(message,buf);				if (opts & DOUBLE_NEW_LINE)					message = str_list_append(message,"");				y += 2;			}			x = 0;			lastword = 0;			indent = 0;			continue;		}						isnewline = 0;		buf[x] = msg[i];		x++;	}	buf[x] = '\0'; /* This doesn't produce an error, trust me */	if (strlen(buf)) { 		message = str_list_append(message,buf);		y++;	}	if (lines) *lines = y;	return message;}static voidstrlist_draw (const char *prompt, const StrList *strlist, int opts, const StrList* selected,               int selnum, int *start);static const StrList*do_strlist (const char *prompt, const StrList *strlist, int opts);static void_display_strlist (const char* title, const StrList *message, int y) {	int x, i;	/* TODO: Write this, for now I will test it this way */	y=LINES-3-MENUSIZE-y;	if (y < INFOSIZE+4)		y = INFOSIZE+4;	i=INFOSIZE+1;	move(i++,0); clrtoeol();	mvaddch(i,0,' ');	for (x = 1; x < COLS-1; x++) {		mvaddch(i,x,'-');         }	mvaddch(i,0,' ');	for (i++; i < y; i++) {		move(i,0); clrtoeol();	}	mvaddstr(y-3,1,title);	for (x = 1; title[x-1]; x++) {		mvaddch(y-2,x,'=');	}		const StrList *current;	for (current = message; current && y < LINES-MENUSIZE-3; current = current->next, y++) {		char *temp = str_list_convert_node(current);		move(y,0); clrtoeol();		mvaddstr(y,1,temp);		free(temp);	}}static void display_message (const char* title, const char *msg) {	int lines;	StrList *message;	message = _message_display_strlist(msg,&lines,IGNORE_SPACE | DOUBLE_NEW_LINE);	_display_strlist(title, message, lines);	str_list_destroy(message);	}/* Menu drawing function */static voidmenu_draw (const MenuItem *items, int item_len, MenuOptions opts, const char *keys, int selected) {	int i, y = LINES - 2 - MENUSIZE + (opts & MENU_TITLE ? 1 : 0), x = MENUDIV;	int item_size = item_len + (opts & MENU_BUTTON ? 2 : 0);	const char *desc;	move(y,0);	clrtoeol();	for (i = 0; items[i].name; i++) {		/* NOTE: Was tolower(items[i].key) */		if (strchr(keys, items[i].key)) {			char buf[item_size+2];			int name_len;			const char *name;				/* Localize the text. Translate empty string to empty string. */			name = (items[i].name[0] ? _(items[i].name) : "");				name_len = strlen(name);			/* Enclose the text if the type is a button. If it is too long, cut. */			if (name_len >= item_len) {				snprintf(buf,item_size+1, (opts & MENU_BUTTON) ? "[%s]" : "%s" , name);				if (opts & MENU_BUTTON) {					buf[item_size-1] = ']';					buf[item_size] = '\0';				}			}			else {				snprintf(buf,item_size+1, (opts & MENU_BUTTON) ? "[%*s%s%*s]" : "%*s%s%*s" ,				(item_len - name_len)/2, "", name, (item_len - name_len + 1)/2 , "");			}				/* Write the button. Highlight if is selected. */						if (i == selected && !(opts & MENU_NOHIGHLIGHT)) attron(A_STANDOUT);			//else if (strchr(keys,tolower(items[i].key))) attron(A_BOLD);				mvaddstr(y,x,buf);				if (i == selected && !(opts & MENU_NOHIGHLIGHT)) attroff(A_STANDOUT);			//else if (strchr(keys,tolower(items[i].key))) attroff(A_BOLD);						if (x + 2*item_size + 2*MENUDIV < COLS) {				x += item_size + MENUDIV;			}			else if (y + 3 < LINES) { /* y + 1 < LINES - 2 */				y++;				x = MENUDIV;				move(y,0);				clrtoeol();			}			/* If we can't draw all the menu items, end. */			else break;		}	}	while (++y < LINES-2) {		move(y,0);		clrtoeol();	}	if (!(opts & MENU_LEAVE_WARNING)) {		move(LINES-2,0);

⌨️ 快捷键说明

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