1 #include <u.h> 2 #include <libc.h> 3 #include <auth.h> 4 #include "../boot/boot.h" 5 6 #define DEFSYS "bootes" 7 typedef struct Net Net; 8 typedef struct Flavor Flavor; 9 10 int printcol; 11 12 char cputype[NAMELEN]; 13 char terminal[NAMELEN]; 14 char sys[2*NAMELEN]; 15 char username[NAMELEN]; 16 char bootfile[3*NAMELEN]; 17 char conffile[NAMELEN]; 18 19 int mflag; 20 int fflag; 21 int kflag; 22 int afd = -1; 23 24 static void swapproc(void); 25 static Method *rootserver(char*); 26 27 static int 28 rconv(void *o, Fconv *fp) 29 { 30 char s[ERRLEN]; 31 32 USED(o); 33 34 s[0] = 0; 35 errstr(s); 36 strconv(s, fp); 37 return 0; 38 } 39 40 void 41 boot(int argc, char *argv[]) 42 { 43 int fd; 44 Method *mp; 45 char cmd[64]; 46 char flags[6]; 47 int islocal, ishybrid; 48 char rootdir[3*NAMELEN]; 49 50 sleep(1000); 51 52 fmtinstall('r', rconv); 53 54 open("#c/cons", OREAD); 55 open("#c/cons", OWRITE); 56 open("#c/cons", OWRITE); 57 /* print("argc=%d\n", argc); 58 for(fd = 0; fd < argc; fd++) 59 print("%s ", argv[fd]); 60 print("\n");/**/ 61 62 ARGBEGIN{ 63 case 'u': 64 strcpy(username, ARGF()); 65 break; 66 case 'k': 67 kflag = 1; 68 break; 69 case 'm': 70 mflag = 1; 71 break; 72 case 'f': 73 fflag = 1; 74 break; 75 }ARGEND 76 77 readfile("#e/cputype", cputype, sizeof(cputype)); 78 readfile("#e/terminal", terminal, sizeof(terminal)); 79 getconffile(conffile, terminal); 80 81 /* 82 * pick a method and initialize it 83 */ 84 mp = rootserver(argc ? *argv : 0); 85 (*mp->config)(mp); 86 islocal = strcmp(mp->name, "local") == 0; 87 ishybrid = (mp->name[0] == 'h' || mp->name[0] == 'H') && 88 strcmp(&mp->name[1], "ybrid") == 0; 89 90 /* 91 * get/set key or password 92 */ 93 (*pword)(islocal, mp); 94 95 /* 96 * connect to the root file system 97 */ 98 fd = (*mp->connect)(); 99 if(fd < 0) 100 fatal("can't connect to file server"); 101 if(!islocal && !ishybrid){ 102 if(cfs) 103 fd = (*cfs)(fd); 104 doauthenticate(fd, mp); 105 } 106 srvcreate("boot", fd); 107 108 /* 109 * create the name space 110 */ 111 if(bind("/", "/", MREPL) < 0) 112 fatal("bind"); 113 if(mount(fd, "/", MAFTER|MCREATE, "") < 0) 114 fatal("mount"); 115 close(fd); 116 117 /* 118 * hack to let us have the logical root in a 119 * subdirectory - useful when we're the 'second' 120 * OS along with some other like DOS. 121 */ 122 readfile("#e/rootdir", rootdir, sizeof(rootdir)); 123 if(rootdir[0]) 124 if(bind(rootdir, "/", MREPL|MCREATE) >= 0) 125 bind("#/", "/", MBEFORE); 126 127 /* 128 * if a local file server exists and it's not 129 * running, start it and mount it onto /n/kfs 130 */ 131 if(access("#s/kfs", 0) < 0){ 132 for(mp = method; mp->name; mp++){ 133 if(strcmp(mp->name, "local") != 0) 134 continue; 135 (*mp->config)(mp); 136 fd = (*mp->connect)(); 137 if(fd < 0) 138 break; 139 mount(fd, "/n/kfs", MAFTER|MCREATE, "") ; 140 close(fd); 141 break; 142 } 143 } 144 145 settime(islocal); 146 close(afd); 147 swapproc(); 148 remove("#e/password"); 149 150 sprint(cmd, "/%s/init", cputype); 151 sprint(flags, "-%s%s", cpuflag ? "c" : "t", mflag ? "m" : ""); 152 execl(cmd, "init", flags, 0); 153 fatal(cmd); 154 } 155 156 /* 157 * ask user from whence cometh the root file system 158 */ 159 Method* 160 rootserver(char *arg) 161 { 162 char prompt[256]; 163 char reply[64]; 164 Method *mp; 165 char *cp, *goodarg; 166 int n, j; 167 168 goodarg = 0; 169 mp = method; 170 n = sprint(prompt, "root is from (%s", mp->name); 171 if(arg && strncmp(arg, mp->name, strlen(mp->name)) == 0) 172 goodarg = arg; 173 for(mp++; mp->name; mp++){ 174 n += sprint(prompt+n, ", %s", mp->name); 175 if(arg && strncmp(arg, mp->name, strlen(mp->name)) == 0) 176 goodarg = arg; 177 } 178 sprint(prompt+n, ")"); 179 180 if(goodarg) 181 strcpy(reply, goodarg); 182 else { 183 strcpy(reply, method->name); 184 } 185 for(;;){ 186 outin(cpuflag, prompt, reply, sizeof(reply)); 187 cp = strchr(reply, '!'); 188 if(cp) 189 j = cp - reply; 190 else 191 j = strlen(reply); 192 for(mp = method; mp->name; mp++) 193 if(strncmp(reply, mp->name, j) == 0){ 194 if(cp) 195 strcpy(sys, cp+1); 196 return mp; 197 } 198 if(mp->name == 0) 199 continue; 200 } 201 return 0; /* not reached */ 202 } 203 204 static void 205 swapproc(void) 206 { 207 int fd; 208 209 fd = open("#c/swap", OWRITE); 210 if(fd < 0){ 211 warning("opening #c/swap"); 212 return; 213 } 214 if(write(fd, "start", 5) <= 0) 215 warning("starting swap kproc"); 216 } 217