13e12c5d1SDavid du Colombier #include <u.h> 23e12c5d1SDavid du Colombier #include <libc.h> 33e12c5d1SDavid du Colombier #include <bio.h> 43e12c5d1SDavid du Colombier #include <ctype.h> 5*219b2ee8SDavid du Colombier #include <ndb.h> 63e12c5d1SDavid du Colombier #include "ndbhf.h" 73e12c5d1SDavid du Colombier 83e12c5d1SDavid du Colombier /* 93e12c5d1SDavid du Colombier * Parse a data base entry. Entries may span multiple 103e12c5d1SDavid du Colombier * lines. An entry starts on a left margin. All subsequent 113e12c5d1SDavid du Colombier * lines must be indented by white space. An entry consists 123e12c5d1SDavid du Colombier * of tuples of the forms: 133e12c5d1SDavid du Colombier * attribute-name 143e12c5d1SDavid du Colombier * attribute-name=value 153e12c5d1SDavid du Colombier * attribute-name="value with white space" 163e12c5d1SDavid du Colombier * 173e12c5d1SDavid du Colombier * The parsing returns a 2-dimensional structure. The first 183e12c5d1SDavid du Colombier * dimension joins all tuples. All tuples on the same line 193e12c5d1SDavid du Colombier * form a ring along the second dimension. 203e12c5d1SDavid du Colombier */ 213e12c5d1SDavid du Colombier 223e12c5d1SDavid du Colombier /* 233e12c5d1SDavid du Colombier * parse the next entry in the file 243e12c5d1SDavid du Colombier */ 253e12c5d1SDavid du Colombier Ndbtuple* 263e12c5d1SDavid du Colombier ndbparse(Ndb *db) 273e12c5d1SDavid du Colombier { 283e12c5d1SDavid du Colombier char *line; 293e12c5d1SDavid du Colombier Ndbtuple *t; 303e12c5d1SDavid du Colombier Ndbtuple *first, *last; 313e12c5d1SDavid du Colombier int len; 323e12c5d1SDavid du Colombier 333e12c5d1SDavid du Colombier first = last = 0; 343e12c5d1SDavid du Colombier for(;;){ 35*219b2ee8SDavid du Colombier if((line = Brdline(&db->b, '\n')) == 0) 363e12c5d1SDavid du Colombier break; 37*219b2ee8SDavid du Colombier len = Blinelen(&db->b); 38bd389b36SDavid du Colombier if(line[len-1] != '\n') 39bd389b36SDavid du Colombier break; 40*219b2ee8SDavid du Colombier if(first && !ISWHITE(*line) && *line != '#'){ 41*219b2ee8SDavid du Colombier Bseek(&db->b, -len, 1); 423e12c5d1SDavid du Colombier return first; 433e12c5d1SDavid du Colombier } 44*219b2ee8SDavid du Colombier t = _ndbparseline(line); 453e12c5d1SDavid du Colombier if(t == 0) 463e12c5d1SDavid du Colombier continue; 473e12c5d1SDavid du Colombier if(first) 483e12c5d1SDavid du Colombier last->entry = t; 493e12c5d1SDavid du Colombier else 503e12c5d1SDavid du Colombier first = t; 513e12c5d1SDavid du Colombier last = t; 523e12c5d1SDavid du Colombier while(last->entry) 533e12c5d1SDavid du Colombier last = last->entry; 543e12c5d1SDavid du Colombier } 553e12c5d1SDavid du Colombier return first; 563e12c5d1SDavid du Colombier } 573e12c5d1SDavid du Colombier 583e12c5d1SDavid du Colombier 593e12c5d1SDavid du Colombier /* 603e12c5d1SDavid du Colombier * free the hash files belonging to a db 613e12c5d1SDavid du Colombier */ 623e12c5d1SDavid du Colombier static void 633e12c5d1SDavid du Colombier hffree(Ndb *db) 643e12c5d1SDavid du Colombier { 653e12c5d1SDavid du Colombier Ndbhf *hf, *next; 663e12c5d1SDavid du Colombier 673e12c5d1SDavid du Colombier for(hf = db->hf; hf; hf = next){ 683e12c5d1SDavid du Colombier next = hf->next; 693e12c5d1SDavid du Colombier close(hf->fd); 703e12c5d1SDavid du Colombier free(hf); 713e12c5d1SDavid du Colombier } 723e12c5d1SDavid du Colombier db->hf = 0; 733e12c5d1SDavid du Colombier } 743e12c5d1SDavid du Colombier 753e12c5d1SDavid du Colombier int 763e12c5d1SDavid du Colombier ndbreopen(Ndb *db) 773e12c5d1SDavid du Colombier { 783e12c5d1SDavid du Colombier int fd; 793e12c5d1SDavid du Colombier Dir d; 803e12c5d1SDavid du Colombier 813e12c5d1SDavid du Colombier /* forget what we know about the open files */ 823e12c5d1SDavid du Colombier if(db->mtime){ 833e12c5d1SDavid du Colombier hffree(db); 84*219b2ee8SDavid du Colombier close(Bfildes(&db->b)); 85*219b2ee8SDavid du Colombier Bterm(&db->b); 863e12c5d1SDavid du Colombier db->mtime = 0; 873e12c5d1SDavid du Colombier } 883e12c5d1SDavid du Colombier 893e12c5d1SDavid du Colombier /* try the open again */ 903e12c5d1SDavid du Colombier fd = open(db->file, OREAD); 913e12c5d1SDavid du Colombier if(fd < 0) 923e12c5d1SDavid du Colombier return -1; 933e12c5d1SDavid du Colombier if(dirfstat(fd, &d) < 0){ 943e12c5d1SDavid du Colombier close(fd); 953e12c5d1SDavid du Colombier return -1; 963e12c5d1SDavid du Colombier } 973e12c5d1SDavid du Colombier 983e12c5d1SDavid du Colombier db->qid = d.qid; 993e12c5d1SDavid du Colombier db->mtime = d.mtime; 100*219b2ee8SDavid du Colombier db->length = d.length; 101*219b2ee8SDavid du Colombier Binits(&db->b, fd, OREAD, db->buf, sizeof(db->buf)); 1023e12c5d1SDavid du Colombier return 0; 1033e12c5d1SDavid du Colombier } 1043e12c5d1SDavid du Colombier 105*219b2ee8SDavid du Colombier static char *deffile = "/lib/ndb/local"; 1063e12c5d1SDavid du Colombier 107*219b2ee8SDavid du Colombier /* 108*219b2ee8SDavid du Colombier * lookup the list of files to use in the specified database file 109*219b2ee8SDavid du Colombier */ 110*219b2ee8SDavid du Colombier static Ndb* 111*219b2ee8SDavid du Colombier doopen(char *file) 112*219b2ee8SDavid du Colombier { 113*219b2ee8SDavid du Colombier Ndb *db; 1143e12c5d1SDavid du Colombier 1153e12c5d1SDavid du Colombier db = (Ndb*)malloc(sizeof(Ndb)); 1163e12c5d1SDavid du Colombier if(db == 0) 1173e12c5d1SDavid du Colombier return 0; 1183e12c5d1SDavid du Colombier strncpy(db->file, file, sizeof(db->file)-1); 1193e12c5d1SDavid du Colombier db->next = 0; 1203e12c5d1SDavid du Colombier db->hf = 0; 1213e12c5d1SDavid du Colombier db->mtime = 0; 1223e12c5d1SDavid du Colombier 1233e12c5d1SDavid du Colombier if(ndbreopen(db) < 0){ 1243e12c5d1SDavid du Colombier free(db); 1253e12c5d1SDavid du Colombier return 0; 1263e12c5d1SDavid du Colombier } 1273e12c5d1SDavid du Colombier 1283e12c5d1SDavid du Colombier return db; 1293e12c5d1SDavid du Colombier } 130*219b2ee8SDavid du Colombier Ndb* 131*219b2ee8SDavid du Colombier ndbopen(char *file) 132*219b2ee8SDavid du Colombier { 133*219b2ee8SDavid du Colombier Ndb *db, *first, *last; 134*219b2ee8SDavid du Colombier Ndbs s; 135*219b2ee8SDavid du Colombier Ndbtuple *t, *nt; 136*219b2ee8SDavid du Colombier 137*219b2ee8SDavid du Colombier if(file == 0) 138*219b2ee8SDavid du Colombier file = deffile; 139*219b2ee8SDavid du Colombier db = doopen(file); 140*219b2ee8SDavid du Colombier if(db == 0) 141*219b2ee8SDavid du Colombier return 0; 142*219b2ee8SDavid du Colombier first = last = db; 143*219b2ee8SDavid du Colombier t = ndbsearch(db, &s, "database", ""); 144*219b2ee8SDavid du Colombier Bseek(&db->b, 0, 0); 145*219b2ee8SDavid du Colombier if(t == 0) 146*219b2ee8SDavid du Colombier return db; 147*219b2ee8SDavid du Colombier for(nt = t; nt; nt = nt->entry){ 148*219b2ee8SDavid du Colombier if(strcmp(nt->attr, "file") != 0) 149*219b2ee8SDavid du Colombier continue; 150*219b2ee8SDavid du Colombier if(strcmp(nt->val, file) == 0){ 151*219b2ee8SDavid du Colombier /* default file can be reordered in the list */ 152*219b2ee8SDavid du Colombier if(first->next == 0) 153*219b2ee8SDavid du Colombier continue; 154*219b2ee8SDavid du Colombier if(strcmp(first->file, file) == 0){ 155*219b2ee8SDavid du Colombier db = first; 156*219b2ee8SDavid du Colombier first = first->next; 157*219b2ee8SDavid du Colombier last->next = db; 158*219b2ee8SDavid du Colombier db->next = 0; 159*219b2ee8SDavid du Colombier last = db; 160*219b2ee8SDavid du Colombier } 161*219b2ee8SDavid du Colombier continue; 162*219b2ee8SDavid du Colombier } 163*219b2ee8SDavid du Colombier db = doopen(nt->val); 164*219b2ee8SDavid du Colombier if(db == 0) 165*219b2ee8SDavid du Colombier continue; 166*219b2ee8SDavid du Colombier last->next = db; 167*219b2ee8SDavid du Colombier last = db; 168*219b2ee8SDavid du Colombier } 169*219b2ee8SDavid du Colombier return first; 170*219b2ee8SDavid du Colombier } 1713e12c5d1SDavid du Colombier 1723e12c5d1SDavid du Colombier void 1733e12c5d1SDavid du Colombier ndbclose(Ndb *db) 1743e12c5d1SDavid du Colombier { 1753e12c5d1SDavid du Colombier Ndb *nextdb; 1763e12c5d1SDavid du Colombier 1773e12c5d1SDavid du Colombier for(; db; db = nextdb){ 1783e12c5d1SDavid du Colombier nextdb = db->next; 1793e12c5d1SDavid du Colombier hffree(db); 180*219b2ee8SDavid du Colombier close(Bfildes(&db->b)); 181*219b2ee8SDavid du Colombier Bterm(&db->b); 1823e12c5d1SDavid du Colombier free(db); 1833e12c5d1SDavid du Colombier } 1843e12c5d1SDavid du Colombier } 185