getns.c (1702B)
1 #include <u.h> 2 #include <libc.h> 3 #include <ctype.h> 4 5 static int 6 isme(char *uid) 7 { 8 int n; 9 char *p; 10 11 n = strtol(uid, &p, 10); 12 if(*p == 0 && p > uid) 13 return n == getuid(); 14 return strcmp(getuser(), uid) == 0; 15 } 16 /* 17 * Absent other hints, it works reasonably well to use 18 * the X11 display name as the name space identifier. 19 * This is how sam's B has worked since the early days. 20 * Since most programs using name spaces are also using X, 21 * this still seems reasonable. Terminal-only sessions 22 * can set $NAMESPACE. 23 */ 24 static char* 25 nsfromdisplay(void) 26 { 27 int fd; 28 Dir *d; 29 char *disp, *p; 30 31 if((disp = getenv("DISPLAY")) == nil){ 32 #ifdef __APPLE__ 33 // Might be running native GUI on OS X. 34 disp = strdup(":0.0"); 35 if(disp == nil) 36 return nil; 37 #else 38 werrstr("$DISPLAY not set"); 39 return nil; 40 #endif 41 } 42 43 /* canonicalize: xxx:0.0 => xxx:0 */ 44 p = strrchr(disp, ':'); 45 if(p){ 46 p++; 47 while(isdigit((uchar)*p)) 48 p++; 49 if(strcmp(p, ".0") == 0) 50 *p = 0; 51 } 52 53 /* turn /tmp/launch/:0 into _tmp_launch_:0 (OS X 10.5) */ 54 for(p=disp; *p; p++) 55 if(*p == '/') 56 *p = '_'; 57 58 p = smprint("/tmp/ns.%s.%s", getuser(), disp); 59 free(disp); 60 if(p == nil){ 61 werrstr("out of memory"); 62 return p; 63 } 64 if((fd=create(p, OREAD, DMDIR|0700)) >= 0){ 65 close(fd); 66 return p; 67 } 68 if((d = dirstat(p)) == nil){ 69 free(d); 70 werrstr("stat %s: %r", p); 71 free(p); 72 return nil; 73 } 74 if((d->mode&0777) != 0700 || !isme(d->uid)){ 75 werrstr("bad name space dir %s", p); 76 free(p); 77 free(d); 78 return nil; 79 } 80 free(d); 81 return p; 82 } 83 84 char* 85 getns(void) 86 { 87 char *ns; 88 89 ns = getenv("NAMESPACE"); 90 if(ns == nil) 91 ns = nsfromdisplay(); 92 if(ns == nil){ 93 werrstr("$NAMESPACE not set, %r"); 94 return nil; 95 } 96 return ns; 97 }