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

📄 bootmenu.c

📁 linux下从网卡远程启动
💻 C
字号:
#include "stddef.h"#include "string.h"#include "ansiesc.h"#include "printf.h"#include "md5.h"#include "misc.h"#include "etherboot.h"#include "start32.h"static int		menutmo = 10, menudefault  = 0;static unsigned char	*defparams = NULL;static int		defparams_max = 0;#ifdef	MOTD/**************************************************************************SHOW_MOTD - display the message of the day**************************************************************************/void show_motd(unsigned char *motd[]){	unsigned char	*ptr;	int		i, j, k = 0;	for (i = 0; i < RFC1533_VENDOR_NUMOFMOTD; i++) if (motd[i]) {		for (j = TAG_LEN(motd[i]), ptr = motd[i]+2; j-- && *ptr; )			putchar(*ptr++);		putchar('\n');	}}#endif#if	!defined(ANSIESC) || defined(CONSOLE_SERIAL)static const char *const clrline = "                                                                               ";#endifstatic int getoptvalue(unsigned char **ptr, int *len, int *rc){	unsigned char *tmp,*old;	int  i,l;	for (tmp = *ptr, l = *len; *tmp != '='; tmp++, l--);	old = ++tmp; l--;	if (!*tmp || *tmp == ':' || l <= 0)		return (0);	i = getdec(&tmp);	if (i < 0 || (l -= tmp - old) < 0)		return (0);	*rc = i;	*len = l;	*ptr = tmp;	return (1);}/**************************************************************************PARSE_MENUOPTS - parse menu options and set control variables**************************************************************************/void parse_menuopts(unsigned char *opt, int len){	/* This code assumes that "bootpd" terminates the control string	   with a '\000' character */	while (len > 0 && *opt) {		if (!memcmp(opt,"timeout=",8)) {			if (!getoptvalue(&opt, &len, &menutmo))				return; }		else if (!memcmp(opt,"default=",8)) {			if (!getoptvalue(&opt, &len, &menudefault))				return; }		while (len > 0 && *opt != ':') { opt++; len--; }		while (len > 0 && *opt == ':') { opt++; len--; }	}}/**************************************************************************GETPARMS - get user provided parameters**************************************************************************/#ifdef	USRPARMSstatic int getparms(struct bootpd_t *bootp, unsigned char *end_of_rfc1533){	unsigned char *ptr = end_of_rfc1533+2;	int  ch,i = 0, max = &bootp->bootp_extension[MAX_BOOTP_EXTLEN] - ptr - 1;	if (!end_of_rfc1533 || max < 0)		return (0);	else if (max > 255)		max = 255;restart:#if	defined(ANSIESC) && !defined(CONSOLE_SERIAL)	printf("\rParams: \033[K");#else	printf("%s%s%s","\rParams: ",clrline+8,"\rParams: ");#endif	for (ch = i; ch; )		putchar(ptr[-(ch--)]);	for (;;) {#if	defined(ANSIESC) && defined(CONSOLE_CRT)		enable_cursor(1);		ch = getchar();		enable_cursor(0);#else		ch = getchar();#endif		if (ch == '\n')			break;		if (ch == ('U'&0x1F)) {			ptr -= i;			i = 0;			goto restart; }		if (ch == ('H'&0x1F)) {			if (i) {				i--; ptr--;				printf("\010 \010"); }			continue; }		if (ch == ('L'&0x1F))			goto restart;		if (i == max || (signed char)ch < (signed char)' ')			continue;		putchar(*ptr++ = ch);		i++; }	if (i) {		end_of_rfc1533[0] = RFC1533_VENDOR_ADDPARM;		end_of_rfc1533[1] = i;		*ptr++ = '\000';		*ptr   = RFC1533_END;		i += 3; }	putchar('\n');	return (i);}#endif/**************************************************************************GETHEX - compute one hex byte**************************************************************************/#ifdef	PASSWDstatic int gethex(unsigned char *dat){	int  i,j;	i = (j = *dat) > '9' ? (j+9) & 0xF : j - '0';	dat++;	return (16*i + ((j = *dat) > '9' ? (j+9) & 0xF : j - '0'));}#endif/**************************************************************************SELECTIMAGE - interactively ask the user for the boot image**************************************************************************//* Warning! GCC 2.7.2 has difficulties with analyzing the data flow in   the following function; it will sometimes clobber some of the local   variables. If you encounter strange behavior, try to introduce more   temporary variables for storing intermediate results. This might   help GCC... */int selectImage(struct bootpd_t *bootp, unsigned char *imagelist[],	unsigned char *end_of_rfc1533){#ifdef	USRPARMS	int flag_parms = 1;	int modifier_keys = 0;#endif#ifdef	PASSWD	int flag_image = 1;#endif	unsigned char	*e,*s,*d,*p;	int  		i,j,k,m,len;	unsigned long	tmo;	in_addr 	ip;	printf("List of available boot images:\n\n");	for (i = j = 0; i < RFC1533_VENDOR_NUMOFIMG; i++) {		if ((e = imagelist[i]) != NULL) {#if	defined(ANSIESC) && !defined(CONSOLE_SERIAL)#ifdef	SHOW_NUMERIC			printf("\033[4C%c) ",'1'+j++);#else			printf("\033[4C%c) ",'A'+j++);#endif#else#ifdef SHOW_NUMERIC			printf("    %c) ",'1'+j++);#else			printf("    %c) ",'A'+j++);#endif#endif			for (s = e+2, len = TAG_LEN(e)+2;			     (s - e) < len && *s != ':';			     putchar(*s++));			putchar('\n');		}	}	m = j;	putchar('\n');reselect:#if	defined(ANSIESC) && !defined(CONSOLE_SERIAL)	printf("Select: \033[K");#else	printf("%s%s%s","\rSelect: ",clrline+8,"\rSelect: ");#endif	tmo = currticks()/TICKS_PER_SEC + menutmo;	for (;;) {		if (menutmo >= 0) { for (i = -1; !iskey(); ) {			if ((k = tmo - currticks()/TICKS_PER_SEC) <= 0) {selectdefault:				if (menudefault >= 0 && menudefault <				    RFC1533_VENDOR_NUMOFIMG) {					i = menudefault;					goto findimg;				} else if (menudefault >= RFC1533_VENDOR_IMG &&					 menudefault < RFC1533_VENDOR_IMG +					 RFC1533_VENDOR_NUMOFIMG &&					 imagelist[menudefault -						  RFC1533_VENDOR_IMG]) {					j = menudefault-RFC1533_VENDOR_IMG;					goto img;				}				i = ESC;				goto key;			} else if (i != k) {#if	defined(ANSIESC) && !defined(CONSOLE_SERIAL)				printf("\033[s(%d seconds)\033[K\033[u",i = k);#else				printf("%s%s%s(%d seconds)",				       "\rSelect: ",clrline+8,				       "\rSelect: ",i = k);#endif			}		} }#if	defined(ANSIESC) && defined(CONSOLE_CRT)		enable_cursor(1);		i = getchar();		enable_cursor(0);#else		i = getchar();#endif	key:#ifdef	USRPARAMS		modifier_keys = 0;#endif#if	defined(USRPARMS) && defined(CONSOLE_CRT)		modifier_keys |= console_getshift();#endif		if (i == ESC)			return (255);		if (i == '\n') {			goto selectdefault;		}		if (i == '\t' || i == ' ') {			menutmo = -1;			printf("\r");			goto reselect;		}		if ((i >= 'A') && (i < 'A'+m)) {			i -= 'A';#ifdef	USRPARMS			modifier_keys |= 3; /* ShiftL + ShiftR */#endif			break;		} else if ((i >= 'a') && (i < 'a'+m)) {			i -= 'a';			break;		} else if ((i >= '1') && (i < '1'+m)) {			i -= '1';			break;		}	}findimg:	j = 0;	while (i >= 0) {		if (imagelist[j] != NULL) i--;		j++;	}	j--;img:#if	defined(ANSIESC) && !defined(CONSOLE_SERIAL)	printf("\033[K");#else	printf("%s%s%s","\rSelect: ",clrline+8,"\rSelect: ");#endif	for (len = TAG_LEN(e = imagelist[j]) + 2, s = e + 2;	     (s - e) < len && *s != ':';	     putchar(*s++));	putchar('\n');#if	0	/* unimplemented for now */	for (i = ARP_SERVER; i <= ARP_GATEWAY; i++) {		if ((++s - e) >= len) goto local_disk;		if (inet_aton(s, &ip)) {			arptable[i].ipaddr.s_addr = ip.s_addr;			memset(arptable[i].node, 0, ETH_ALEN);			while ((s - e) < len && *s != ':') s++;		}	}#else	/* Just skip the server and gateway components */	s++;	while ((s - e) < len && *s != ':') s++;	s++;	while ((s - e) < len && *s != ':') s++;#endif	if ((++s - e) >= len) goto local_disk;	for (d = s; (d - e) < len && *d != ':'; d++);	for (p = d + 1, j = 0; (p - e) < len && *p && *p != ':'; p++, j++);	for (p++, i = 0; (p - e) < len && *p != ':'; p++) {#if	defined(USRPARMS) || defined(PASSWD)		if (*p >= '0' && *p <= '9')			i = 10*i + *p - '0';		else {			k = *p & ~0x20;#ifdef	USRPARMS			if (k == 'P') {				flag_parms = i;				/* 0 - never interactively accept parameters				 * 1 - require password before accepting parms.				 * 2 - always ask for passwd and parameters				 * 3 - always ask for parameters				 */			}#endif#ifdef	PASSWD			if (k == 'I') {				flag_image = i;				/* 0 - do not require a password for this image				 * 1 - require a password for this image				 */			}#endif			i = 0;		}#endif	}	defparams = p + 1;	defparams_max = len - (defparams - (unsigned char *)e);#ifdef	USRPARMS	if (flag_parms == 1 && modifier_keys)		flag_parms++;#endif#ifdef	PASSWD	if ((flag_image > 0#ifdef	USRPARMS	     || flag_parms == 2#endif	    ) && j == 32) {		unsigned char md5[16];		printf("Passwd: ");#if	defined(ANSIESC) && defined(CONSOLE_CRT)		enable_cursor(1);#endif		while ((i = getchar()) != '\n') {			if (i == ('U'&0x1F)) md5_done(md5);			else                 md5_put(i);		}#if	defined(ANSIESC) && defined(CONSOLE_CRT)		enable_cursor(0);#endif		md5_done(md5);		for (i = 16, p = d+31; i--; p -= 2) {			if (gethex(p) != md5[i]) {#if	defined(ANSIESC) && !defined(CONSOLE_SERIAL)				printf("\r\033[K\033[1A");#else				printf("\r");#endif				goto reselect;			}		}		putchar('\n');	}#endif#ifdef	USRPARMS	if (flag_parms > 1)		i = getparms(bootp, end_of_rfc1533);	else		i = 0;#endif	if ((len = d - s) <= 0 || len > (int)sizeof(bootp->bootp_reply.bp_file)-1 || !*s) {	local_disk:		return (255);	}	if (end_of_rfc1533 != NULL &&	    end_of_rfc1533 + 4 < &bootp->bootp_extension[MAX_BOOTP_EXTLEN]) {#ifdef	USRPARMS		d    = end_of_rfc1533 + i;#else		d    = end_of_rfc1533;#endif		i    = e-d;		*d++ = RFC1533_VENDOR_SELECTION;		*d++ = 1;		*d++ = *e;		*d   = RFC1533_END;	}	/* if name is -, reuse previous filename */        if (!(s[0] == '-' && s[1] == ':')) {            memcpy(bootp->bootp_reply.bp_file, s, len);            bootp->bootp_reply.bp_file[len] = '\0';        }	return (1);}/* * Local variables: *  c-basic-offset: 8 * End: */

⌨️ 快捷键说明

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