|  | #include <u.h> | 
|  | #include <libc.h> | 
|  | #include <ctype.h> | 
|  |  | 
|  | static int | 
|  | isme(char *uid) | 
|  | { | 
|  | int n; | 
|  | char *p; | 
|  |  | 
|  | n = strtol(uid, &p, 10); | 
|  | if(*p == 0 && p > uid) | 
|  | return n == getuid(); | 
|  | return strcmp(getuser(), uid) == 0; | 
|  | } | 
|  | /* | 
|  | * Absent other hints, it works reasonably well to use | 
|  | * the X11 display name as the name space identifier. | 
|  | * This is how sam's B has worked since the early days. | 
|  | * Since most programs using name spaces are also using X, | 
|  | * this still seems reasonable.  Terminal-only sessions | 
|  | * can set $NAMESPACE. | 
|  | */ | 
|  | static char* | 
|  | nsfromdisplay(void) | 
|  | { | 
|  | int fd; | 
|  | Dir *d; | 
|  | char *disp, *p; | 
|  |  | 
|  | if((disp = getenv("DISPLAY")) == nil){ | 
|  | #ifdef __APPLE__ | 
|  | // Might be running native GUI on OS X. | 
|  | disp = strdup(":0.0"); | 
|  | if(disp == nil) | 
|  | return nil; | 
|  | #else | 
|  | werrstr("$DISPLAY not set"); | 
|  | return nil; | 
|  | #endif | 
|  | } | 
|  |  | 
|  | /* canonicalize: xxx:0.0 => xxx:0 */ | 
|  | p = strrchr(disp, ':'); | 
|  | if(p){ | 
|  | p++; | 
|  | while(isdigit((uchar)*p)) | 
|  | p++; | 
|  | if(strcmp(p, ".0") == 0) | 
|  | *p = 0; | 
|  | } | 
|  |  | 
|  | /* turn /tmp/launch/:0 into _tmp_launch_:0 (OS X 10.5) */ | 
|  | for(p=disp; *p; p++) | 
|  | if(*p == '/') | 
|  | *p = '_'; | 
|  |  | 
|  | p = smprint("/tmp/ns.%s.%s", getuser(), disp); | 
|  | free(disp); | 
|  | if(p == nil){ | 
|  | werrstr("out of memory"); | 
|  | return p; | 
|  | } | 
|  | if((fd=create(p, OREAD, DMDIR|0700)) >= 0){ | 
|  | close(fd); | 
|  | return p; | 
|  | } | 
|  | if((d = dirstat(p)) == nil){ | 
|  | free(d); | 
|  | werrstr("stat %s: %r", p); | 
|  | free(p); | 
|  | return nil; | 
|  | } | 
|  | if((d->mode&0777) != 0700 || !isme(d->uid)){ | 
|  | werrstr("bad name space dir %s", p); | 
|  | free(p); | 
|  | free(d); | 
|  | return nil; | 
|  | } | 
|  | free(d); | 
|  | return p; | 
|  | } | 
|  |  | 
|  | char* | 
|  | getns(void) | 
|  | { | 
|  | char *ns; | 
|  |  | 
|  | ns = getenv("NAMESPACE"); | 
|  | if(ns == nil) | 
|  | ns = nsfromdisplay(); | 
|  | if(ns == nil){ | 
|  | werrstr("$NAMESPACE not set, %r"); | 
|  | return nil; | 
|  | } | 
|  | return ns; | 
|  | } |