xref: /plan9-contrib/sys/src/libc/9sys/getnetconninfo.c (revision 0b68c76d63d3614e55179bb2b52f8da72437084f)
1 #include <u.h>
2 #include <libc.h>
3 
4 static char *unknown = "???";
5 
6 static void
getendpoint(char * dir,char * file,char ** sysp,char ** servp)7 getendpoint(char *dir, char *file, char **sysp, char **servp)
8 {
9 	int fd, n;
10 	char buf[128];
11 	char *sys, *serv;
12 
13 	sys = serv = 0;
14 
15 	snprint(buf, sizeof buf, "%s/%s", dir, file);
16 	fd = open(buf, OREAD);
17 	if(fd >= 0){
18 		n = read(fd, buf, sizeof(buf)-1);
19 		if(n>0){
20 			buf[n-1] = 0;
21 			serv = strchr(buf, '!');
22 			if(serv){
23 				*serv++ = 0;
24 				serv = strdup(serv);
25 			}
26 			sys = strdup(buf);
27 		}
28 		close(fd);
29 	}
30 	if(serv == 0)
31 		serv = unknown;
32 	if(sys == 0)
33 		sys = unknown;
34 	*servp = serv;
35 	*sysp = sys;
36 }
37 
38 NetConnInfo*
getnetconninfo(char * dir,int fd)39 getnetconninfo(char *dir, int fd)
40 {
41 	NetConnInfo *nci;
42 	char *cp;
43 	Dir *d;
44 	char spec[10];
45 	char path[128];
46 	char netname[128], *p;
47 
48 	/* get a directory address via fd */
49 	if(dir == nil || *dir == 0){
50 		if(fd2path(fd, path, sizeof(path)) < 0)
51 			return nil;
52 		cp = strrchr(path, '/');
53 		if(cp == nil)
54 			return nil;
55 		*cp = 0;
56 		dir = path;
57 	}
58 
59 	nci = mallocz(sizeof *nci, 1);
60 	if(nci == nil)
61 		return nil;
62 
63 	/* copy connection directory */
64 	nci->dir = strdup(dir);
65 	if(nci->dir == nil)
66 		goto err;
67 
68 	/* get netroot */
69 	nci->root = strdup(dir);
70 	if(nci->root == nil)
71 		goto err;
72 	cp = strchr(nci->root+1, '/');
73 	if(cp == nil)
74 		goto err;
75 	*cp = 0;
76 
77 	/* figure out bind spec */
78 	d = dirstat(nci->dir);
79 	if(d != nil){
80 		snprint(spec, sizeof spec, "#%C%d", d->type, d->dev);
81 		nci->spec = strdup(spec);
82 	}
83 	if(nci->spec == nil)
84 		nci->spec = unknown;
85 	free(d);
86 
87 	/* get the two end points */
88 	getendpoint(nci->dir, "local", &nci->lsys, &nci->lserv);
89 	if(nci->lsys == nil || nci->lserv == nil)
90 		goto err;
91 	getendpoint(nci->dir, "remote", &nci->rsys, &nci->rserv);
92 	if(nci->rsys == nil || nci->rserv == nil)
93 		goto err;
94 
95 	strecpy(netname, netname+sizeof netname, nci->dir);
96 	if((p = strrchr(netname, '/')) != nil)
97 		*p = 0;
98 	if(strncmp(netname, "/net/", 5) == 0)
99 		memmove(netname, netname+5, strlen(netname+5)+1);
100 	nci->laddr = smprint("%s!%s!%s", netname, nci->lsys, nci->lserv);
101 	nci->raddr = smprint("%s!%s!%s", netname, nci->rsys, nci->rserv);
102 	if(nci->laddr == nil || nci->raddr == nil)
103 		goto err;
104 	return nci;
105 err:
106 	freenetconninfo(nci);
107 	return nil;
108 }
109 
110 static void
xfree(char * x)111 xfree(char *x)
112 {
113 	if(x == nil || x == unknown)
114 		return;
115 	free(x);
116 }
117 
118 void
freenetconninfo(NetConnInfo * nci)119 freenetconninfo(NetConnInfo *nci)
120 {
121 	if(nci == nil)
122 		return;
123 	xfree(nci->root);
124 	xfree(nci->dir);
125 	xfree(nci->spec);
126 	xfree(nci->lsys);
127 	xfree(nci->lserv);
128 	xfree(nci->rsys);
129 	xfree(nci->rserv);
130 	xfree(nci->laddr);
131 	xfree(nci->raddr);
132 	free(nci);
133 }
134