|
|
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.