henesyinit from p9f47575dc5 years agoHistory
123 lines · 2.1 KB · C
RawDownload
#include <u.h>#include <libc.h> voiderror(char* msg){	fprint(2, "newkernel: %s\n", msg);	exits(msg);} intoutin(char *prompt, char *def, int len){	int n;	char buf[256]; 	do{		print("%s[%s]: ", prompt, def);		n = read(0, buf, len);	}while(n==0);	if(n < 0)		error("can't read stdin; please reboot");	if(n != 1){		buf[n-1] = 0;		strcpy(def, buf);	}	return n;} voidnewkernel(char *file){	Dir this;	Dir installed;	char *partition;	char prompt[8];	long x, i;	int in, out;	char *p; 	/* this kernel's link time */	if(dirstat("/boot", &this) < 0){		print("can't stat /boot\n");		return;	} 	/* the installed kernel's installation time */	if(dirstat(file, &installed) < 0){		print("can't stat %s\n", file);		return;	} 	/*  if the current kernel is 10 minutes older than the	 *  installed kernel, ask user if he wants to update.	 */	if(installed.mtime < this.mtime + 10*60)		return; 	/*	 *  find a boot partition	 */	if(dirstat("/dev/hd0boot", &this) < 0){		if(dirstat("/dev/hd1boot", &this) < 0)			return;		partition = "/dev/hd1boot";	} else		partition = "/dev/hd0boot"; 	strcpy(prompt, "y/n");	outin("\nThis kernel is out of date.  Copy a new one to disk?",		prompt, sizeof(prompt));	if(*prompt != 'y')		return; 	/* copy all kernel into memory, then to disk */	x = ((installed.length + 511)/512)*512;	p = sbrk(x);	if(p == (char*)-1){		print("sbrk %d failed\n", x);		return;	}	in = open(file, OREAD);	if(in < 0){		print("can't open %s\n", file);		return;	}	out = open(partition, OWRITE);	if(out < 0){		print("can't open %s\n", partition);		close(in);		return;	}	if(read(in, p, installed.length) != installed.length){		print("couldn't read %s\n", file);		close(in);		close(out);		return;	}	for(; x > 0; x -= i){		i = x > 4*1024 ? 4*1024 : x;		if(write(out, p, i) != i){			print("error writing %s, you may be in deep trouble!\n",				partition);			return;		}		p += i;	}	close(in);	close(out); 	for(;;){		print("new kernel loaded, please reboot\n");		sleep(2);	}} voidmain(int argc, char **argv){	if(argc > 1)		newkernel(argv[1]);	exits(0);}