1implement Emuinit; 2include "sys.m"; 3 sys: Sys; 4include "draw.m"; 5include "sh.m"; 6include "arg.m"; 7 arg: Arg; 8 9Emuinit: module 10{ 11 init: fn(); 12}; 13 14init() 15{ 16 sys = load Sys Sys->PATH; 17 sys->bind("#e", "/env", sys->MREPL|sys->MCREATE); # if #e not configured, that's fine 18 args := getenv("emuargs"); 19 arg = load Arg Arg->PATH; 20 if (arg == nil) 21 sys->fprint(sys->fildes(2), "emuinit: cannot load %s: %r\n", Arg->PATH); 22 else{ 23 arg->init(args); 24 while((c := arg->opt()) != 0) 25 case c { 26 'g' or 'c' or 'C' or 'm' or 'p' or 'f' or 'r' or 'd' => 27 arg->arg(); 28 } 29 args = arg->argv(); 30 } 31 mod: Command; 32 (mod, args) = loadmod(args); 33 mod->init(nil, args); 34} 35 36loadmod(args: list of string): (Command, list of string) 37{ 38 path := Command->PATH; 39 if(args != nil) 40 path = hd args; 41 else 42 args = "-l" :: nil; # add startup option 43 44 # try loading the module directly. 45 mod: Command; 46 if (path != nil && path[0] == '/') 47 mod = load Command path; 48 else { 49 mod = load Command "/dis/"+path; 50 if (mod == nil) 51 mod = load Command "/"+path; 52 } 53 if(mod != nil) 54 return (mod, args); 55 56 # if we can't load the module directly, try getting the shell to run it. 57 err := sys->sprint("%r"); 58 mod = load Command Command->PATH; 59 if(mod == nil){ 60 sys->fprint(sys->fildes(2), "emuinit: unable to load %s: %s\n", path, err); 61 raise "fail:error"; 62 } 63 return (mod, "sh" :: "-c" :: "$*" :: args); 64} 65 66getenv(v: string): list of string 67{ 68 fd := sys->open("#e/"+v, Sys->OREAD); 69 if (fd == nil) 70 return nil; 71 (ok, d) := sys->fstat(fd); 72 if(ok == -1) 73 return nil; 74 buf := array[int d.length] of byte; 75 n := sys->read(fd, buf, len buf); 76 if (n <= 0) 77 return nil; 78 return unquoted(string buf[0:n]); 79} 80 81unquoted(s: string): list of string 82{ 83 args: list of string; 84 word: string; 85 inquote := 0; 86 for(j := len s; j > 0;){ 87 c := s[j-1]; 88 if(c == ' ' || c == '\t' || c == '\n'){ 89 j--; 90 continue; 91 } 92 for(i := j-1; i >= 0 && ((c = s[i]) != ' ' && c != '\t' && c != '\n' || inquote); i--){ # collect word 93 if(c == '\''){ 94 word = s[i+1:j] + word; 95 j = i; 96 if(!inquote || i == 0 || s[i-1] != '\'') 97 inquote = !inquote; 98 else 99 i--; 100 } 101 } 102 args = (s[i+1:j]+word) :: args; 103 word = nil; 104 j = i; 105 } 106 # if quotes were unbalanced, balance them and try again. 107 if(inquote) 108 return unquoted(s + "'"); 109 return args; 110} 111