#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);}
#include <u.h>
#include <libc.h>
void
error(char* msg)
{
fprint(2, "newkernel: %s\n", msg);
exits(msg);
}
int
outin(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;
}
void
newkernel(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);
}
}
void
main(int argc, char **argv)
{
if(argc > 1)
newkernel(argv[1]);
exits(0);
}