19a747e4fSDavid du Colombier #include "all.h"
29a747e4fSDavid du Colombier
39a747e4fSDavid du Colombier static char *tnames[] = {
49a747e4fSDavid du Colombier [Tversion] "version",
59a747e4fSDavid du Colombier [Tauth] "auth",
69a747e4fSDavid du Colombier [Tattach] "attach",
79a747e4fSDavid du Colombier [Tflush] "flush",
89a747e4fSDavid du Colombier [Twalk] "walk",
99a747e4fSDavid du Colombier [Topen] "open",
109a747e4fSDavid du Colombier [Tcreate] "create",
119a747e4fSDavid du Colombier [Tread] "read",
129a747e4fSDavid du Colombier [Twrite] "write",
139a747e4fSDavid du Colombier [Tclunk] "clunk",
149a747e4fSDavid du Colombier [Tremove] "remove",
159a747e4fSDavid du Colombier [Tstat] "stat",
169a747e4fSDavid du Colombier [Twstat] "wstat",
179a747e4fSDavid du Colombier };
189a747e4fSDavid du Colombier
199a747e4fSDavid du Colombier int messagesize = IOHDRSZ+Maxfdata;
209a747e4fSDavid du Colombier
219a747e4fSDavid du Colombier int
xmesg(Session * s,int t)229a747e4fSDavid du Colombier xmesg(Session *s, int t)
239a747e4fSDavid du Colombier {
249a747e4fSDavid du Colombier int n;
259a747e4fSDavid du Colombier
269a747e4fSDavid du Colombier if(chatty){
279a747e4fSDavid du Colombier if(0 <= t && t < nelem(tnames) && tnames[t])
289a747e4fSDavid du Colombier chat("T%s...", tnames[t]);
299a747e4fSDavid du Colombier else
309a747e4fSDavid du Colombier chat("T%d...", t);
319a747e4fSDavid du Colombier }
329a747e4fSDavid du Colombier s->f.type = t;
339a747e4fSDavid du Colombier s->f.tag = ++s->tag;
349a747e4fSDavid du Colombier if(p9debug)
359a747e4fSDavid du Colombier fprint(2, "xmseg\tsend %F\n", &s->f);
369a747e4fSDavid du Colombier n = convS2M(&s->f, s->data, messagesize);
379a747e4fSDavid du Colombier if(niwrite(s->fd, s->data, n) != n){
389a747e4fSDavid du Colombier clog("xmesg write error on %d: %r\n", s->fd);
399a747e4fSDavid du Colombier return -1;
409a747e4fSDavid du Colombier }
419a747e4fSDavid du Colombier again:
429a747e4fSDavid du Colombier n = read9pmsg(s->fd, s->data, messagesize);
439a747e4fSDavid du Colombier if(n < 0){
449a747e4fSDavid du Colombier clog("xmesg read error: %r\n");
459a747e4fSDavid du Colombier return -1;
469a747e4fSDavid du Colombier }
479a747e4fSDavid du Colombier if(convM2S(s->data, n, &s->f) <= 0){
489a747e4fSDavid du Colombier clog("xmesg bad convM2S %d %.2x %.2x %.2x %.2x\n",
499a747e4fSDavid du Colombier n, ((uchar*)s->data)[0], ((uchar*)s->data)[1],
509a747e4fSDavid du Colombier ((uchar*)s->data)[2], ((uchar*)s->data)[3]);
519a747e4fSDavid du Colombier return -1;
529a747e4fSDavid du Colombier }
539a747e4fSDavid du Colombier if(p9debug)
549a747e4fSDavid du Colombier fprint(2, "\trecv %F\n", &s->f);
559a747e4fSDavid du Colombier if(s->f.tag != s->tag){
569a747e4fSDavid du Colombier clog("xmesg tag %d for %d\n", s->f.tag, s->tag);
579a747e4fSDavid du Colombier goto again;
589a747e4fSDavid du Colombier }
599a747e4fSDavid du Colombier if(s->f.type == Rerror){
609a747e4fSDavid du Colombier if(t == Tclunk)
619a747e4fSDavid du Colombier clog("xmesg clunk: %s", s->f.ename);
629a747e4fSDavid du Colombier chat("xmesg %d error %s...", t, s->f.ename);
639a747e4fSDavid du Colombier return -1;
649a747e4fSDavid du Colombier }
659a747e4fSDavid du Colombier if(s->f.type != t+1){
669a747e4fSDavid du Colombier clog("xmesg type mismatch: %d, expected %d\n", s->f.type, t+1);
679a747e4fSDavid du Colombier return -1;
689a747e4fSDavid du Colombier }
699a747e4fSDavid du Colombier return 0;
709a747e4fSDavid du Colombier }
719a747e4fSDavid du Colombier
729a747e4fSDavid du Colombier int
clunkfid(Session * s,Fid * f)739a747e4fSDavid du Colombier clunkfid(Session *s, Fid *f)
749a747e4fSDavid du Colombier {
759a747e4fSDavid du Colombier putfid(s, f);
769a747e4fSDavid du Colombier if(s == 0 || f == 0)
779a747e4fSDavid du Colombier return 0;
789a747e4fSDavid du Colombier s->f.fid = f - s->fids;
799a747e4fSDavid du Colombier return xmesg(s, Tclunk);
809a747e4fSDavid du Colombier }
819a747e4fSDavid du Colombier
829a747e4fSDavid du Colombier #define UNLINK(p) ((p)->prev->next = (p)->next, (p)->next->prev = (p)->prev)
839a747e4fSDavid du Colombier
849a747e4fSDavid du Colombier #define LINK(h, p) ((p)->next = (h)->next, (p)->prev = (h), \
859a747e4fSDavid du Colombier (h)->next->prev = (p), (h)->next = (p))
869a747e4fSDavid du Colombier
879a747e4fSDavid du Colombier #define TOFRONT(h, p) ((h)->next != (p) ? (UNLINK(p), LINK(h,p)) : 0)
889a747e4fSDavid du Colombier
899a747e4fSDavid du Colombier Fid *
newfid(Session * s)909a747e4fSDavid du Colombier newfid(Session *s)
919a747e4fSDavid du Colombier {
929a747e4fSDavid du Colombier Fid *f, *fN;
939a747e4fSDavid du Colombier
949a747e4fSDavid du Colombier chat("newfid..");
959a747e4fSDavid du Colombier if(s->list.prev == 0){
969a747e4fSDavid du Colombier chat("init..");
979a747e4fSDavid du Colombier s->list.prev = &s->list;
989a747e4fSDavid du Colombier s->list.next = &s->list;
999a747e4fSDavid du Colombier s->free = s->fids;
1009a747e4fSDavid du Colombier if(0 && chatty)
1019a747e4fSDavid du Colombier fN = &s->fids[25];
1029a747e4fSDavid du Colombier else
1039a747e4fSDavid du Colombier fN = &s->fids[nelem(s->fids)];
1049a747e4fSDavid du Colombier for(f=s->fids; f<fN; f++){
1059a747e4fSDavid du Colombier f->owner = 0;
1069a747e4fSDavid du Colombier f->prev = 0;
1079a747e4fSDavid du Colombier f->next = f+1;
1089a747e4fSDavid du Colombier }
1099a747e4fSDavid du Colombier (f-1)->next = 0;
1109a747e4fSDavid du Colombier }
1119a747e4fSDavid du Colombier if(s->free){
1129a747e4fSDavid du Colombier f = s->free;
1139a747e4fSDavid du Colombier s->free = f->next;
1149a747e4fSDavid du Colombier LINK(&s->list, f);
1159a747e4fSDavid du Colombier }else{
1169a747e4fSDavid du Colombier for(f=s->list.prev; f!=&s->list; f=f->prev)
1179a747e4fSDavid du Colombier if(f->owner)
1189a747e4fSDavid du Colombier break;
1199a747e4fSDavid du Colombier if(f == &s->list){
1209a747e4fSDavid du Colombier clog("fid leak");
1219a747e4fSDavid du Colombier return 0;
1229a747e4fSDavid du Colombier }
1239a747e4fSDavid du Colombier setfid(s, f);
1249a747e4fSDavid du Colombier if(xmesg(s, Tclunk) < 0){
1259a747e4fSDavid du Colombier clog("clunk failed, no fids?");
1269a747e4fSDavid du Colombier /*return 0;*/
1279a747e4fSDavid du Colombier }
1289a747e4fSDavid du Colombier *(f->owner) = 0;
1299a747e4fSDavid du Colombier f->owner = 0;
1309a747e4fSDavid du Colombier }
1319a747e4fSDavid du Colombier chat("%ld...", f - s->fids);
1329a747e4fSDavid du Colombier f->tstale = nfstime + staletime;
1339a747e4fSDavid du Colombier return f;
1349a747e4fSDavid du Colombier }
1359a747e4fSDavid du Colombier
1369a747e4fSDavid du Colombier void
setfid(Session * s,Fid * f)1379a747e4fSDavid du Colombier setfid(Session *s, Fid *f)
1389a747e4fSDavid du Colombier {
139*453ee12cSDavid du Colombier /*
140*453ee12cSDavid du Colombier * TOFRONT(&s->list, f);
141*453ee12cSDavid du Colombier */
142*453ee12cSDavid du Colombier if(s->list.next != f){
143*453ee12cSDavid du Colombier UNLINK(f);
144*453ee12cSDavid du Colombier LINK(&s->list, f);
145*453ee12cSDavid du Colombier }
146*453ee12cSDavid du Colombier
1479a747e4fSDavid du Colombier f->tstale = nfstime + staletime;
1489a747e4fSDavid du Colombier s->f.fid = f - s->fids;
1499a747e4fSDavid du Colombier }
1509a747e4fSDavid du Colombier
1519a747e4fSDavid du Colombier void
putfid(Session * s,Fid * f)1529a747e4fSDavid du Colombier putfid(Session *s, Fid *f)
1539a747e4fSDavid du Colombier {
1549a747e4fSDavid du Colombier chat("putfid %ld...", f-s->fids);
1559a747e4fSDavid du Colombier if(s == 0 || f == 0){
1569a747e4fSDavid du Colombier clog("putfid(0x%p, 0x%p) %s", s, f, (s ? s->service : "?"));
1579a747e4fSDavid du Colombier return;
1589a747e4fSDavid du Colombier }
1599a747e4fSDavid du Colombier UNLINK(f);
1609a747e4fSDavid du Colombier if(f->owner)
1619a747e4fSDavid du Colombier *(f->owner) = 0;
1629a747e4fSDavid du Colombier f->owner = 0;
1639a747e4fSDavid du Colombier f->prev = 0;
1649a747e4fSDavid du Colombier f->next = s->free;
1659a747e4fSDavid du Colombier s->free = f;
1669a747e4fSDavid du Colombier }
1679a747e4fSDavid du Colombier
1689a747e4fSDavid du Colombier void
fidtimer(Session * s,long now)1699a747e4fSDavid du Colombier fidtimer(Session *s, long now)
1709a747e4fSDavid du Colombier {
1719a747e4fSDavid du Colombier Fid *f, *t;
1729a747e4fSDavid du Colombier int n;
1739a747e4fSDavid du Colombier
1749a747e4fSDavid du Colombier f = s->list.next;
1759a747e4fSDavid du Colombier n = 0;
1769a747e4fSDavid du Colombier while(f != &s->list){
1779a747e4fSDavid du Colombier t = f;
1789a747e4fSDavid du Colombier f = f->next;
1799a747e4fSDavid du Colombier if(t->owner && now >= t->tstale)
1809a747e4fSDavid du Colombier ++n, clunkfid(s, t);
1819a747e4fSDavid du Colombier }
1829a747e4fSDavid du Colombier if(n > 0)
1839a747e4fSDavid du Colombier chat("fidtimer %s\n", s->service);
1849a747e4fSDavid du Colombier }
185