getns.c - 9base - revived minimalist port of Plan 9 userland to Unix | |
git clone git://git.suckless.org/9base | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
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 } |