int nametonum(char *s) { char *p; int i, lo, hi, m, rv; s = estrdup(s); strlower(s); for(p=s; *p; p++) if(*p=='_') *p = ' '; currentmap(0); rlock(&maplock); lo = 0; hi = map->nel; while(hi-lo > 1){ m = (lo+hi)/2; i = strcmp(s, map->el[m].s); if(i < 0) hi = m; else lo = m; } if(hi-lo == 1 && strcmp(s, map->el[lo].s)==0) rv = map->el[lo].n; else rv = -1; runlock(&maplock); free(s); return rv; }
char* numtoname(int n) { int i; char *s; currentmap(0); rlock(&maplock); for(i=0; i<map->nel; i++){ if(map->el[i].n==n) break; } if(i==map->nel){ runlock(&maplock); return nil; } s = estrdup(map->el[i].s); runlock(&maplock); return s; }
static void fsopen(Req *r) { int t; uvlong path; Aux *a; Fid *fid; Whist *wh; fid = r->fid; path = fid->qid.path; t = qidtype(fid->qid.path); if((r->ifcall.mode != OREAD && t != Fnew && t != Fmap) || (r->ifcall.mode&ORCLOSE)){ respond(r, "permission denied"); return; } a = fid->aux; switch(t){ case Droot: currentmap(0); rlock(&maplock); a->map = map; incref(map); runlock(&maplock); respond(r, nil); break; case D1st: if((wh = gethistory(qidnum(path))) == nil){ respond(r, "file does not exist"); return; } closewhist(a->w); a->w = wh; a->n = a->w->ndoc-1; r->ofcall.qid.vers = wh->doc[a->n].time; r->fid->qid = r->ofcall.qid; respond(r, nil); break; case D2nd: respond(r, nil); break; case Fnew: a->s = s_copy(""); respond(r, nil); break; case Fmap: case F1st: case F2nd: respond(r, nil); break; default: respond(r, "programmer error"); break; } }
int allocnum(char *title, int mustbenew) { char *p, *q; int lfd, fd, n; Biobuf b; if(strcmp(title, "map")==0 || strcmp(title, "new")==0){ werrstr("reserved title name"); return -1; } if(title[0]=='\0' || strpbrk(title, "/<>:?")){ werrstr("invalid character in name"); return -1; } if((n = nametonum(title)) >= 0){ if(mustbenew){ werrstr("duplicate title"); return -1; } return n; } title = estrdup(title); strcondense(title, 1); strlower(title); if(strchr(title, '\n') || strlen(title) > 200){ werrstr("bad title"); free(title); return -1; } if((lfd = getlock("d/L.map")) < 0){ free(title); return -1; } if((fd = wopen("d/map", ORDWR)) < 0){ // LOG? close(lfd); free(title); return -1; } /* * What we really need to do here is make sure the * map is up-to-date, then make sure the title isn't * taken, and then add it, all without dropping the locks. * * This turns out to be a mess when you start adding * all the necessary dolock flags, so instead we just * read through the file ourselves, and let our * map catch up on its own. */ Binit(&b, fd, OREAD); n = 0; while(p = Brdline(&b, '\n')){ p[Blinelen(&b)-1] = '\0'; n = atoi(p)+1; q = strchr(p, ' '); if(q == nil) continue; if(strcmp(q+1, title) == 0){ free(title); close(fd); close(lfd); if(mustbenew){ werrstr("duplicate title"); return -1; }else return n; } } seek(fd, 0, 2); /* just in case it's not append only */ fprint(fd, "%d %s\n", n, title); close(fd); close(lfd); free(title); /* kick the map */ currentmap(1); return n; }