xref: /plan9/sys/src/libndb/csgetval.c (revision 1a4050f5b2ddf426a278e3233ccd7b6bcb0639b8)
1 #include <u.h>
2 #include <libc.h>
3 #include <bio.h>
4 #include <ndb.h>
5 #include <ndbhf.h>
6 
7 /*
8  *  search for a tuple that has the given 'attr=val' and also 'rattr=x'.
9  *  copy 'x' into 'buf' and return the whole tuple.
10  *
11  *  return 0 if not found.
12  */
13 char*
csgetvalue(char * netroot,char * attr,char * val,char * rattr,Ndbtuple ** pp)14 csgetvalue(char *netroot, char *attr, char *val, char *rattr, Ndbtuple **pp)
15 {
16 	Ndbtuple *t, *first, *last;
17 	int n, linefound;
18 	char line[1024];
19 	int fd;
20 	int oops = 0;
21 	char *rv;
22 
23 	if(pp)
24 		*pp = nil;
25 	rv = nil;
26 
27 	if(netroot)
28 		snprint(line, sizeof(line), "%s/cs", netroot);
29 	else
30 		strcpy(line, "/net/cs");
31 	fd = open(line, ORDWR);
32 	if(fd < 0)
33 		return 0;
34 	seek(fd, 0, 0);
35 	snprint(line, sizeof(line), "!%s=%s %s=*", attr, val, rattr);
36 	if(write(fd, line, strlen(line)) < 0){
37 		close(fd);
38 		return 0;
39 	}
40 	seek(fd, 0, 0);
41 
42 	first = last = 0;
43 	linefound = 0;
44 	for(;;){
45 		n = read(fd, line, sizeof(line)-2);
46 		if(n <= 0)
47 			break;
48 		line[n] = '\n';
49 		line[n+1] = 0;
50 
51 		t = _ndbparseline(line);
52 		if(t == 0)
53 			continue;
54 		if(first)
55 			last->entry = t;
56 		else
57 			first = t;
58 		last = t;
59 
60 		while(last->entry)
61 			last = last->entry;
62 
63 		for(; t; t = t->entry){
64 			if(linefound == 0){
65 				if(strcmp(rattr, t->attr) == 0){
66 					linefound = 1;
67 					rv = strdup(t->val);
68 				}
69 			}
70 		}
71 	}
72 	close(fd);
73 
74 	if(oops){
75 		werrstr("buffer too short");
76 		ndbfree(first);
77 		return nil;
78 	}
79 
80 	if(pp){
81 		setmalloctag(first, getcallerpc(&netroot));
82 		*pp = first;
83 	} else
84 		ndbfree(first);
85 
86 	return rv;
87 }
88 
89 Ndbtuple*
csgetval(char * netroot,char * attr,char * val,char * rattr,char * buf)90 csgetval(char *netroot, char *attr, char *val, char *rattr, char *buf)
91 {
92 	Ndbtuple *t;
93 	char *p;
94 
95 	p = csgetvalue(netroot, attr, val, rattr, &t);
96 	if(p == nil){
97 		if(buf != nil)
98 			*buf = 0;
99 	} else {
100 		if(buf != nil){
101 			strncpy(buf, p, Ndbvlen-1);
102 			buf[Ndbvlen-1] = 0;
103 		}
104 		free(p);
105 	}
106 	ndbsetmalloctag(t, getcallerpc(&netroot));
107 	return t;
108 }
109