Blob


1 #include <u.h>
2 #include <libc.h>
3 #include <ctype.h>
5 static int
6 isme(char *uid)
7 {
8 int n;
9 char *p;
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;
31 if((disp = getenv("DISPLAY")) == nil){
32 werrstr("$DISPLAY not set");
33 return nil;
34 }
36 /* canonicalize: xxx:0.0 => xxx:0 */
37 p = strrchr(disp, ':');
38 if(p){
39 p++;
40 while(isdigit((uchar)*p))
41 p++;
42 if(strcmp(p, ".0") == 0)
43 *p = 0;
44 }
46 /* turn /tmp/launch/:0 into _tmp_launch_:0 (OS X 10.5) */
47 for(p=disp; *p; p++)
48 if(*p == '/')
49 *p = '_';
51 p = smprint("/tmp/ns.%s.%s", getuser(), disp);
52 free(disp);
53 if(p == nil){
54 werrstr("out of memory");
55 return p;
56 }
57 if((fd=create(p, OREAD, DMDIR|0700)) >= 0){
58 close(fd);
59 return p;
60 }
61 if((d = dirstat(p)) == nil){
62 free(d);
63 werrstr("stat %s: %r", p);
64 free(p);
65 return nil;
66 }
67 if((d->mode&0777) != 0700 || !isme(d->uid)){
68 werrstr("bad name space dir %s", p);
69 free(p);
70 free(d);
71 return nil;
72 }
73 free(d);
74 return p;
75 }
77 char*
78 getns(void)
79 {
80 char *ns;
82 ns = getenv("NAMESPACE");
83 if(ns == nil)
84 ns = nsfromdisplay();
85 if(ns == nil){
86 werrstr("$NAMESPACE not set, %r");
87 return nil;
88 }
89 return ns;
90 }