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

📄 eliloalt.c

📁 EFI(Extensible Firmware Interface)是下一代BIOS
💻 C
字号:
/* * eliloalt.c * * Copyright (C) 2002-2003 Hewlett-Packard Co * Contributed by Stephane Eranian <eranian@hpl.hp.com> * * This file is part of the ELILO, the EFI Linux boot loader. * *  ELILO 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 2, or (at your option) *  any later version. * *  ELILO 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 ELILO; see the file COPYING.  If not, write to the Free *  Software Foundation, 59 Temple Place - Suite 330, Boston, MA *  02111-1307, USA. * *//* * This program is used to set the EliloAlt EFI variable to influence * how elilo will behave at the next reboot. This variable is used * to boot a certain kernel/configuration only once (debug, for instance). * * This is is supposed to be installed in /usr/sbin/eliloalt and must only * be run by root. */#include <sys/types.h>#include <stdio.h>#include <stdlib.h>#include <stdarg.h>#include <fcntl.h>#include <unistd.h>#include <getopt.h>#include <errno.h>#include <stdint.h>#include <string.h>#include <dirent.h>#define ELILOALT_VERSION	"0.02"#define ELILO_ALT_NAME	"EliloAlt"#define EFIVAR_DIR	"/proc/efi/vars"#define ELILO_ALTVAR	EFIVAR_DIR"/"ELILO_ALT_NAME"-00000000-0000-0000-0000-000000000000"#define EFI_VARIABLE_NON_VOLATILE 0x0000000000000001#define EFI_VARIABLE_BOOTSERVICE_ACCESS 0x0000000000000002#define EFI_VARIABLE_RUNTIME_ACCESS 0x0000000000000004typedef unsigned long efi_status_t;typedef uint8_t  efi_bool_t;typedef uint16_t efi_char16_t;		/* UNICODE character *//* * EFI GUID type definition */typedef struct {	uint32_t data1;	uint16_t data2;	uint16_t data3;	uint8_t  data4[8];} efi_guid_t;/* * EFI variable structure  */typedef struct _efi_variable_t {        efi_char16_t	variablename[1024/sizeof(efi_char16_t)];        efi_guid_t	vendorguid;        uint64_t	datasize;        uint8_t         data[1024];	efi_status_t	status;        uint32_t        attributes;} __attribute__((packed)) efi_variable_t;static char *elilo_alt_name = ELILO_ALT_NAME;static struct option cmd_options[]={	{ "version", 0, 0, 1},	{ "help", 0, 0, 2},	{ "delete", 0, 0, 3},	{ "print", 0, 0, 4},	{ "set", 1, 0, 5},	{ 0, 0, 0, 0}};static void fatal_error(char *fmt,...) __attribute__((noreturn));static voidfatal_error(char *fmt, ...) {	va_list ap;	va_start(ap, fmt);	vfprintf(stderr, fmt, ap);	va_end(ap);	exit(1);}static voidusage(char **argv){	printf("Usage: %s [OPTIONS] cmdline\n", argv[0]);	printf(	"-h, --help\t\tdisplay this help and exit\n"		"--version\t\toutput version information and exit\n"		"-s, --set cmdline\tset elilo alternate variable to cmdline\n"		"-p, --print\t\tprint elilo alternate variable\n"		"-d, --delete\t\tprint elilo alternate variable\n"	);}static char *check_proc_efi(int find_entry){	DIR *efi_vars;	struct dirent *entry;	static char name[1024];	if (getuid() != 0) {		fatal_error("This program must be run as root\n");	}	efi_vars = opendir(EFIVAR_DIR);	if (efi_vars == NULL) {		fatal_error("Cannot access %s\n", EFIVAR_DIR);	}	if (!find_entry) {		closedir(efi_vars);		return NULL;	}	/* Find one entry we can open */	while ((entry = readdir(efi_vars)) != NULL) {		if (strcmp(entry->d_name, ".") && strcmp(entry->d_name, ".."))			break;	}	if (entry == NULL) {		fatal_error("Cannot find entry in %s\n", EFIVAR_DIR);	}	sprintf(name, "%s/%s", EFIVAR_DIR, entry->d_name);	closedir(efi_vars);	return name;}static voiddelete_var(void){	efi_variable_t var;	int fd, r, i;	check_proc_efi(0);	fd = open(ELILO_ALTVAR, O_WRONLY);	if (fd == -1) {		fatal_error("variable not defined\n");	}	memset(&var, 0, sizeof(var));	for (i=0; i < sizeof(elilo_alt_name); i++) {		var.variablename[i] = (efi_char16_t)elilo_alt_name[i];	}	/* 	 * we use NULL GUID so no need to initialize it now memset() did it	 * writing with a datasize=0 will effectively delete the variable.	 */		r = write(fd, &var, sizeof(var));	if (r != sizeof(var)) {		fatal_error("Variable %s defined but invalid content\n", ELILO_ALTVAR);	}	close(fd);}static voidprint_var(void){	efi_variable_t var;	int fd, r, i;	check_proc_efi(0);	fd = open(ELILO_ALTVAR, O_RDONLY);	if (fd == -1) {		fatal_error("variable not defined\n");	}	memset(&var, 0, sizeof(var));	r = read(fd, &var, sizeof(var));	if (r != sizeof(var)) {		fatal_error("Variable %s defined but invalid content\n", ELILO_ALTVAR);	}	printf("EliloAlt=\"");	for(i=0; i < var.datasize; i+=1){		printf("%c", var.data[i]);	}	printf("\"\n");	close(fd);}static voidset_var(char *cmdline){	efi_variable_t var;	int fd, r, i, j, l;	char *name;	name = check_proc_efi(1);	if (cmdline == NULL) {		fatal_error("invalid cmdline argument\n");	}	l = strlen(cmdline);	if (l >= 1024) {		fatal_error("Variable content is too long, must be <= 512 characters\n");	}	fd = open(name, O_WRONLY);	if (fd == -1) {		fatal_error("can't open %s: %s\n", ELILO_ALTVAR, strerror(errno));	}	memset(&var, 0, sizeof(var));	for (i=0; i < sizeof(elilo_alt_name); i++) {		var.variablename[i] = (efi_char16_t)elilo_alt_name[i];	}	for (i=0, j=0; i < l; i++, j+=2) {		var.data[j] = (efi_char16_t)cmdline[i];	}	/* +2 = include char16 for null termination */	var.datasize   = j+2;	var.attributes =  EFI_VARIABLE_NON_VOLATILE 			| EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS;	/* 	 * we use NULL GUID so no need to initialize it now memset() did it	 * writing with a datasize=0 will effectively delete the variable.	 */		r = write(fd, &var, sizeof(var));	if (r != sizeof(var)) {		fatal_error("Variable %s defined but invalid content %d\n", ELILO_ALTVAR, r);	}	close(fd);}intmain(int argc, char **argv){	int c;	while ((c=getopt_long(argc, argv,"hdps:", cmd_options, 0)) != -1) {		switch(c) {			case   0: continue; /* fast path for options */			case   1:				printf("Version %s Date: %s\n", ELILOALT_VERSION, __DATE__);				exit(0);			case   2:			case 'h':				usage(argv);				exit(0);			case   3:			case 'd':				delete_var();				exit(0);			case   4:			case 'p':				print_var();				exit(0);			case   5:			case 's':				set_var(optarg);				exit(0);			default:				fatal_error("Unknown option\n");		}	}	print_var();	return 0;}

⌨️ 快捷键说明

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