xref: /plan9/sys/src/9/boot/bootcache.c (revision ec59a3ddbfceee0efe34584c2c9981a5e5ff1ec4)
1 #include <u.h>
2 #include <libc.h>
3 #include <../boot/boot.h>
4 
5 uchar statbuf[Statsz];
6 
7 int
8 cache(int fd)
9 {
10 	int argc, i, p[2];
11 	char *argv[5], bd[32], buf[256], partition[64], *pp;
12 
13 	if(stat("/boot/cfs", statbuf, sizeof statbuf) < 0)
14 		return fd;
15 
16 	*partition = 0;
17 
18 	readfile("#e/cfs", buf, sizeof(buf));
19 	if(*buf){
20 		argc = tokenize(buf, argv, 4);
21 		for(i = 0; i < argc; i++){
22 			if(strcmp(argv[i], "off") == 0)
23 				return fd;
24 			else if(stat(argv[i], statbuf, sizeof statbuf) >= 0){
25 				strncpy(partition, argv[i], sizeof(partition)-1);
26 				partition[sizeof(partition)-1] = 0;
27 			}
28 		}
29 	}
30 
31 	if(*partition == 0){
32 		readfile("#e/bootdisk", bd, sizeof(bd));
33 		if(*bd){
34 			if(pp = strchr(bd, ':'))
35 				*pp = 0;
36 			/* damned artificial intelligence */
37 			i = strlen(bd);
38 			if(strcmp("disk", &bd[i-4]) == 0)
39 				bd[i-4] = 0;
40 			else if(strcmp("fs", &bd[i-2]) == 0)
41 				bd[i-2] = 0;
42 			else if(strcmp("fossil", &bd[i-6]) == 0)
43 				bd[i-6] = 0;
44 			sprint(partition, "%scache", bd);
45 			if(stat(partition, statbuf, sizeof statbuf) < 0)
46 				*bd = 0;
47 		}
48 		if(*bd == 0){
49 			sprint(partition, "%scache", bootdisk);
50 			if(stat(partition, statbuf, sizeof statbuf) < 0)
51 				return fd;
52 		}
53 	}
54 
55 	print("cfs...");
56 	if(pipe(p)<0)
57 		fatal("pipe");
58 	switch(fork()){
59 	case -1:
60 		fatal("fork");
61 	case 0:
62 		close(p[1]);
63 		dup(fd, 0);
64 		close(fd);
65 		dup(p[0], 1);
66 		close(p[0]);
67 		if(fflag)
68 			execl("/boot/cfs", "bootcfs", "-rs", "-f", partition, 0);
69 		else
70 			execl("/boot/cfs", "bootcfs", "-s", "-f", partition, 0);
71 		break;
72 	default:
73 		close(p[0]);
74 		close(fd);
75 		fd = p[1];
76 		break;
77 	}
78 	return fd;
79 }
80