conf.c (5175B)
1 #include "u.h" 2 #include "lib.h" 3 #include "mem.h" 4 #include "dat.h" 5 #include "fns.h" 6 7 #include "fs.h" 8 9 #include "conf.h" 10 11 #include "netif.h" 12 #include "etherif.h" 13 #include "vether.h" 14 15 char filebuf[BOOTARGSLEN]; 16 17 static void 18 addether(char *name, char *value) 19 { 20 char *p, *q; 21 int ctlrno; 22 23 ctlrno = atoi(&name[5]); 24 if(ctlrno > MaxEther) 25 return; 26 p = value; 27 /* default ea = 00:00:09:00:00:xx */ 28 memset(ve[ctlrno].ea, 0, 6); 29 ve[ctlrno].ea[2] = 9; 30 ve[ctlrno].ea[5] = ctlrno; 31 while(*p){ 32 while(*p == ' ' || *p == '\t') 33 p++; 34 if(*p == '\0') 35 break; 36 if(strncmp(p, "type=", 5) == 0){ 37 p += 5; 38 if(strncmp(p, "tap", 3) == 0) 39 ve[ctlrno].tap = 1; 40 else if(strncmp(p, "pcap", 4) == 0) 41 ve[ctlrno].tap = 0; 42 else 43 return; 44 } 45 else if(strncmp(p, "dev=", 4) == 0){ 46 p += 4; 47 q = p; 48 while(*q && *q != ' ' && *q != '\t') 49 q++; 50 ve[ctlrno].dev = malloc(q - p + 1); 51 strncpy(ve[ctlrno].dev, p, q - p); 52 ve[ctlrno].dev[q-p] = '\0'; 53 continue; 54 } 55 else if(strncmp(p, "ea=", 3) == 0){ 56 if(parseether(ve[ctlrno].ea, p+3) == -1) 57 memset(ve[ctlrno].ea, 0, 6); 58 } 59 while(*p && *p != ' ' && *p != '\t') 60 p++; 61 } 62 nve++; 63 } 64 65 void 66 setinioptions() 67 { 68 static int i; 69 char *name, *value; 70 71 for(; i < MAXCONF; i++){ 72 if(!inifield[i]) 73 break; 74 name = inifield[i]; 75 if(*name == '*') 76 name++; 77 value = strchr(inifield[i], '='); 78 if(value == 0) 79 continue; 80 *value++ = 0; 81 if(strcmp(name, "cpulimit") == 0) 82 cpulimit = atoi(value); 83 else if(strcmp(name, "memsize") == 0) 84 memsize = atoi(value); 85 else if(strcmp(name, "canopenpath") == 0) 86 canopen = value; 87 else if(strncmp(name, "ether", 5) == 0) 88 addether(name, value); 89 else if(strcmp(name, "initarg") == 0) 90 initarg = value; 91 else if(strcmp(name, "localroot") == 0) 92 localroot = value; 93 else if(strcmp(name, "user") == 0) 94 username = value; 95 /* Restore '=' for setinienv and printconfig */ 96 *(--value) = '='; 97 } 98 } 99 100 void 101 addini(char *buf) 102 { 103 static int n = 0; 104 int blankline, incomment, inspace, inquote; 105 char *p, *q; 106 107 /* 108 * Strip out '\r', change '\t' -> ' '. 109 * Change runs of spaces into single spaces. 110 * Strip out trailing spaces, blank lines. 111 * The text between single quotes is not touched. 112 * 113 * We do this before we make the copy so that if we 114 * need to change the copy, it is already fairly clean. 115 * The main need is in the case when plan9.ini has been 116 * padded with lots of trailing spaces, as is the case 117 * for those created during a distribution install. 118 */ 119 p = buf; 120 blankline = 1; 121 incomment = inquote =inspace = 0; 122 for(q = buf; *q; q++){ 123 if(inquote){ 124 if(*q == '\'') 125 inquote = 0; 126 *p++ = *q; 127 continue; 128 } 129 if(!incomment && *q == '\'') 130 inquote = 1; 131 if(*q == '\r') 132 continue; 133 if(*q == '\t') 134 *q = ' '; 135 if(*q == ' '){ 136 inspace = 1; 137 continue; 138 } 139 if(*q == '\n'){ 140 if(!blankline){ 141 if(!incomment) 142 *p++ = '\n'; 143 blankline = 1; 144 } 145 incomment = inspace = 0; 146 continue; 147 } 148 if(inspace){ 149 if(!blankline && !incomment) 150 *p++ = ' '; 151 inspace = 0; 152 } 153 if(blankline && *q == '#') 154 incomment = 1; 155 blankline = 0; 156 if(!incomment) 157 *p++ = *q; 158 } 159 *p++ = 0; 160 161 n += gettokens(buf, &inifield[n], MAXCONF-n, "\n"); 162 setinioptions(); 163 } 164 165 int 166 addinifile(char *file) 167 { 168 static char *fb = filebuf; 169 char *buf; 170 int n, fd; 171 172 if(strcmp(file, "-") == 0) 173 fd = fileno(stdin); 174 else if((fd = open(file, OREAD)) < 0) 175 return -1; 176 177 buf = fb; 178 *buf = 0; 179 while((n = read(fd, buf, BOOTARGSLEN-1)) > 0) 180 if(n<0) 181 return -1; 182 else 183 buf += n; 184 close(fd); 185 *buf = 0; 186 addini(fb); 187 fb = buf; 188 return n; 189 } 190 191 char* 192 fullpath(char *root) { 193 char cwd[1024]; 194 195 if(root[0] != '/'){ 196 if(getcwd(cwd, sizeof cwd) == nil) 197 panic("getcwd: %r"); 198 root = cleanname(smprint("%s/%s", cwd, root)); 199 } 200 return root; 201 } 202 203 /* 204 * Poor man's quotestrdup to avoid needing quote.c 205 */ 206 char* 207 quoted(char *in) { 208 char *out, *p; 209 int i, n; 210 211 n = 0; 212 for(i = 0; i < strlen(in); i++) 213 if(in[i] == '\'') 214 n++; 215 out = malloc(strlen(in) + n + 2); 216 p = out; 217 if(*in != '\'') 218 *p++ = '\''; 219 for(i = 0; i < strlen(in); i++){ 220 if(in[i] == '\'') 221 *p++ = in[i]; 222 *p++ = in[i]; 223 } 224 *p++ = '\''; 225 *p = 0; 226 return out; 227 } 228 229 void 230 setinienv() 231 { 232 int i; 233 char *name, *value; 234 235 for(i = 0; i < MAXCONF; i++){ 236 if(!inifield[i]) 237 break; 238 name = inifield[i]; 239 value = strchr(inifield[i], '='); 240 if(*name == '*' || value == 0 || value[0] == 0) 241 continue; 242 *value++ = 0; 243 ksetenv(name, value, 0); 244 } 245 if(initarg){ 246 if(*initarg != '\'') 247 initarg = quoted(initarg); 248 value = smprint("/386/init -t %s", initarg); 249 ksetenv("init", value, 0); 250 } 251 if(localroot){ 252 value = smprint("local!#Z%s", fullpath(localroot)); 253 ksetenv("nobootprompt", value, 0); 254 } 255 ksetenv("user", username, 0); 256 } 257 258 /* 259 * Debugging: tell user what options we guessed. 260 */ 261 void 262 printconfig(char *argv0){ 263 int i; 264 265 print(argv0); 266 if(usetty) 267 print(" -%c", nogui ? 'g' : 't'); 268 print(" \n"); 269 for(i = 0; i < MAXCONF; i++){ 270 if(!inifield[i]) 271 break; 272 print("\t%s\n", inifield[i]); 273 } 274 if(initarg) 275 print("\tinit=/386/init -t %s\n", initarg); 276 if(localroot) 277 print("\tnobootprompt=#Z%s\n", localroot); 278 print("\tuser=%s\n", username); 279 }