|
|
1.1 root 1: #include <stdio.h>
2: #include <errno.h>
3: #include <fio.h>
4: #include <libc.h>
5: #include "ipc.h"
6:
7: extern char *strchr(), *malloc();
8: static Qtuple *tuples();
9: static int nsreply();
10: static int nscall();
11:
12: /*
13: * return a set of tuples
14: */
15: Qset *
16: qset(tuplestr, nameserver)
17: char *tuplestr;
18: char *nameserver;
19: {
20: int fd;
21: char *cp;
22: Qset *top = NULL;
23: Qset *last = NULL;
24: Qset *ps;
25: Qtuple *t;
26:
27: /*
28: * get connection to name server
29: */
30: if((fd = nscall(nameserver))<0)
31: return NULL;
32:
33: /*
34: * send request to name server
35: */
36: fprint(fd, "set %s\n", tuplestr);
37:
38: /*
39: * parse reply code
40: */
41: if(nsreply(fd)<0){
42: close(fd);
43: return NULL;
44: }
45:
46: /*
47: * Parse returned tuples. Each starts with a tab and ends
48: * with a new line.
49: */
50: while((cp = Frdline(fd))!=NULL){
51: errno = 0;
52: if(*cp++!='\t')
53: break;
54: if((t = tuples(cp)) == NULL)
55: break;
56: if(!(ps = (Qset *)malloc(sizeof(Qset)))) {
57: if(ps!=NULL)
58: freeQset(ps);
59: errstr = "no more memory";
60: errno = ENOMEM;
61: break;
62: }
63: ps->this = t;
64: if(last) last->next = ps;
65: else {
66: top = ps;
67: }
68: last = ps;
69: ps->next = NULL;
70: }
71: close(fd);
72: return top;
73: }
74:
75: /*
76: * return a single value
77: */
78: char *
79: qvalue(types, tuplestr, nameserver)
80: char *types;
81: char *tuplestr;
82: char *nameserver;
83: {
84: int fd;
85: static char rv[512];
86: char *vp;
87:
88: /*
89: * get connection to name server
90: */
91: if((fd = nscall(nameserver))<0)
92: return NULL;
93:
94: /*
95: * send request to name server
96: */
97: fprint(fd, "value %s %s\n", types, tuplestr);
98:
99: /*
100: * parse reply code
101: */
102: if(nsreply(fd)<0){
103: close(fd);
104: return NULL;
105: }
106:
107: vp = Frdline(fd);
108: close(fd);
109: if(vp==NULL){
110: errno = EBUSY;
111: errstr = "malfunction";
112: return NULL;
113: }
114: errno = 0;
115: if(*vp++!='\t')
116: return NULL;
117: strcpy(rv, vp);
118: return rv;
119: }
120:
121: /*
122: * get connection to name server
123: */
124: static int
125: nscall(nameserver)
126: char *nameserver;
127: {
128: int fd;
129:
130: if(nameserver && *nameserver)
131: fd = ipcopen(nameserver, "");
132: else
133: fd = ipcopen("/cs/ns", "");
134: if(fd<0) {
135: errstr = "can't contact nameserver";
136: errno = EBUSY;
137: return -1;
138: }
139: return fd;
140: }
141:
142: /*
143: * get and parse reply code
144: */
145: static int
146: nsreply(fd)
147: int fd;
148: {
149: char *cp;
150:
151: Finit(fd, (char *)0);
152: if((cp = Frdline(fd))==NULL) {
153: errstr = "name server gave up";
154: errno = EBUSY;
155: return -1;
156: }
157: if(strncmp("OK", cp, 2)==0){
158: /* all's well */
159: } else if(strncmp("BUSY", cp, 4)==0){
160: errstr = "name server busy";
161: errno = EBUSY;
162: return -1;
163: } else if(strncmp("ILL", cp, 3)==0){
164: errstr = "illegal request";
165: errno = EINVAL;
166: return -1;
167: } else {
168: errstr = "unknown response from name server";
169: errno = EBUSY;
170: return -1;
171: }
172: return 0;
173: }
174:
175: /*
176: * parse a linear tuple into the Qtuple data structure
177: */
178: static Qtuple *
179: tuples(buf)
180: char *buf;
181: {
182: Qtuple *t, *first = NULL, *last = NULL;
183: char *tups[200];
184: register char *value,*type;
185: int n,k;
186: char *oldfields;
187:
188: if((value = strchr(buf,'\n')))
189: *value = 0;
190: oldfields = setfields(" \t");
191: n = getmfields(buf,tups,200);
192: for(k = 0; k < n; k++) {
193: if((type = strchr(tups[k],',')))
194: *type++ = 0;
195: else
196: type = NULL;
197: value = tups[k];
198:
199: if((t = (Qtuple *) malloc(sizeof(Qtuple)))==NULL)
200: goto err;
201: if(first==NULL)
202: first = t;
203: else
204: last->next = t;
205: last = t;
206: if((t->value = strdup(value))==NULL)
207: goto err;
208: if(type && *type){
209: if((t->type = strdup(type))==NULL)
210: goto err;
211: } else {
212: t->type = NULL;
213: }
214: }
215: last->next = 0;
216: setfields(oldfields);
217: return (first);
218: err:
219: if(first!=NULL)
220: freeQtuple(first);
221: errstr = "out of memory";
222: errno = ENOMEM;
223: setfields(oldfields);
224: return NULL;
225: }
226:
227: freeQset(sp)
228: Qset *sp;
229: {
230: register Qset *p;
231:
232: for(p = sp; p; ) {
233: if(p->this)freeQtuple(p->this);
234: sp = p->next;
235: free((char *)p);
236: p = sp;
237: }
238: }
239:
240: freeQtuple(t)
241: Qtuple *t;
242: {
243: Qtuple *p;
244:
245: for(p = t; p;p = t ) {
246: if(p->value) free(p->value);
247: if(p->type) free(p->type);
248: t = p->next;
249: free((char *)p);
250: }
251: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.