13e12c5d1SDavid du Colombier #include "u.h" 23e12c5d1SDavid du Colombier #include "../port/lib.h" 33e12c5d1SDavid du Colombier #include "mem.h" 43e12c5d1SDavid du Colombier #include "dat.h" 53e12c5d1SDavid du Colombier #include "fns.h" 63e12c5d1SDavid du Colombier #include "../port/error.h" 73e12c5d1SDavid du Colombier #define DEVTAB 83e12c5d1SDavid du Colombier #include "devtab.h" 93e12c5d1SDavid du Colombier 103e12c5d1SDavid du Colombier extern ulong kerndate; 113e12c5d1SDavid du Colombier 123e12c5d1SDavid du Colombier int 133e12c5d1SDavid du Colombier devno(int c, int user) 143e12c5d1SDavid du Colombier { 15bd389b36SDavid du Colombier Rune *s; 16bd389b36SDavid du Colombier int i; 173e12c5d1SDavid du Colombier 18bd389b36SDavid du Colombier s = devchar; 19bd389b36SDavid du Colombier i = 0; 20bd389b36SDavid du Colombier while(*s){ 21bd389b36SDavid du Colombier if(c == *s) 22bd389b36SDavid du Colombier return i; 23bd389b36SDavid du Colombier i++; 24bd389b36SDavid du Colombier s++; 25bd389b36SDavid du Colombier } 26bd389b36SDavid du Colombier 273e12c5d1SDavid du Colombier if(user) 283e12c5d1SDavid du Colombier return -1; 29bd389b36SDavid du Colombier panic("devno %C 0x%ux", c, c); 30bd389b36SDavid du Colombier return 0; 313e12c5d1SDavid du Colombier } 323e12c5d1SDavid du Colombier 333e12c5d1SDavid du Colombier void 343e12c5d1SDavid du Colombier devdir(Chan *c, Qid qid, char *n, long length, char *user, long perm, Dir *db) 353e12c5d1SDavid du Colombier { 363e12c5d1SDavid du Colombier strcpy(db->name, n); 373e12c5d1SDavid du Colombier db->qid = qid; 383e12c5d1SDavid du Colombier db->type = devchar[c->type]; 393e12c5d1SDavid du Colombier db->dev = c->dev; 403e12c5d1SDavid du Colombier if(qid.path & CHDIR) 413e12c5d1SDavid du Colombier db->mode = CHDIR|perm; 423e12c5d1SDavid du Colombier else 433e12c5d1SDavid du Colombier db->mode = perm; 44*219b2ee8SDavid du Colombier if(c->flag&CMSG) 45*219b2ee8SDavid du Colombier db->mode |= CHMOUNT; 463e12c5d1SDavid du Colombier db->atime = seconds(); 473e12c5d1SDavid du Colombier db->mtime = kerndate; 483e12c5d1SDavid du Colombier db->hlength = 0; 493e12c5d1SDavid du Colombier db->length = length; 50*219b2ee8SDavid du Colombier memmove(db->uid, user, NAMELEN); 51*219b2ee8SDavid du Colombier memmove(db->gid, eve, NAMELEN); 523e12c5d1SDavid du Colombier } 533e12c5d1SDavid du Colombier 543e12c5d1SDavid du Colombier int 553e12c5d1SDavid du Colombier devgen(Chan *c, Dirtab *tab, int ntab, int i, Dir *dp) 563e12c5d1SDavid du Colombier { 573e12c5d1SDavid du Colombier if(tab==0 || i>=ntab) 583e12c5d1SDavid du Colombier return -1; 593e12c5d1SDavid du Colombier tab += i; 603e12c5d1SDavid du Colombier devdir(c, tab->qid, tab->name, tab->length, eve, tab->perm, dp); 613e12c5d1SDavid du Colombier return 1; 623e12c5d1SDavid du Colombier } 633e12c5d1SDavid du Colombier 643e12c5d1SDavid du Colombier Chan * 653e12c5d1SDavid du Colombier devattach(int tc, char *spec) 663e12c5d1SDavid du Colombier { 673e12c5d1SDavid du Colombier Chan *c; 683e12c5d1SDavid du Colombier 693e12c5d1SDavid du Colombier USED(spec); 703e12c5d1SDavid du Colombier c = newchan(); 713e12c5d1SDavid du Colombier c->qid = (Qid){CHDIR, 0}; 723e12c5d1SDavid du Colombier c->type = devno(tc, 0); 733e12c5d1SDavid du Colombier return c; 743e12c5d1SDavid du Colombier } 753e12c5d1SDavid du Colombier 763e12c5d1SDavid du Colombier Chan * 773e12c5d1SDavid du Colombier devclone(Chan *c, Chan *nc) 783e12c5d1SDavid du Colombier { 793e12c5d1SDavid du Colombier if(c->flag & COPEN) 80bd389b36SDavid du Colombier panic("clone of open file type %C\n", devchar[c->type]); 813e12c5d1SDavid du Colombier if(nc == 0) 823e12c5d1SDavid du Colombier nc = newchan(); 833e12c5d1SDavid du Colombier nc->type = c->type; 843e12c5d1SDavid du Colombier nc->dev = c->dev; 853e12c5d1SDavid du Colombier nc->mode = c->mode; 863e12c5d1SDavid du Colombier nc->qid = c->qid; 873e12c5d1SDavid du Colombier nc->offset = c->offset; 883e12c5d1SDavid du Colombier nc->flag = c->flag; 893e12c5d1SDavid du Colombier nc->mnt = c->mnt; 903e12c5d1SDavid du Colombier nc->mountid = c->mountid; 913e12c5d1SDavid du Colombier nc->aux = c->aux; 923e12c5d1SDavid du Colombier nc->mchan = c->mchan; 933e12c5d1SDavid du Colombier nc->mqid = c->mqid; 943e12c5d1SDavid du Colombier return nc; 953e12c5d1SDavid du Colombier } 963e12c5d1SDavid du Colombier 973e12c5d1SDavid du Colombier int 983e12c5d1SDavid du Colombier devwalk(Chan *c, char *name, Dirtab *tab, int ntab, Devgen *gen) 993e12c5d1SDavid du Colombier { 1003e12c5d1SDavid du Colombier long i; 1013e12c5d1SDavid du Colombier Dir dir; 1023e12c5d1SDavid du Colombier 1033e12c5d1SDavid du Colombier isdir(c); 1043e12c5d1SDavid du Colombier if(name[0]=='.' && name[1]==0) 1053e12c5d1SDavid du Colombier return 1; 1063e12c5d1SDavid du Colombier for(i=0;; i++) 1073e12c5d1SDavid du Colombier switch((*gen)(c, tab, ntab, i, &dir)){ 1083e12c5d1SDavid du Colombier case -1: 1093e12c5d1SDavid du Colombier strncpy(u->error, Enonexist, NAMELEN); 1103e12c5d1SDavid du Colombier return 0; 1113e12c5d1SDavid du Colombier case 0: 1123e12c5d1SDavid du Colombier continue; 1133e12c5d1SDavid du Colombier case 1: 1143e12c5d1SDavid du Colombier if(strcmp(name, dir.name) == 0){ 1153e12c5d1SDavid du Colombier c->qid = dir.qid; 1163e12c5d1SDavid du Colombier return 1; 1173e12c5d1SDavid du Colombier } 1183e12c5d1SDavid du Colombier continue; 1193e12c5d1SDavid du Colombier } 1203e12c5d1SDavid du Colombier return 1; /* not reached */ 1213e12c5d1SDavid du Colombier } 1223e12c5d1SDavid du Colombier 1233e12c5d1SDavid du Colombier void 1243e12c5d1SDavid du Colombier devstat(Chan *c, char *db, Dirtab *tab, int ntab, Devgen *gen) 1253e12c5d1SDavid du Colombier { 1263e12c5d1SDavid du Colombier int i; 1273e12c5d1SDavid du Colombier Dir dir; 1283e12c5d1SDavid du Colombier 1293e12c5d1SDavid du Colombier for(i=0;; i++) 1303e12c5d1SDavid du Colombier switch((*gen)(c, tab, ntab, i, &dir)){ 1313e12c5d1SDavid du Colombier case -1: 1323e12c5d1SDavid du Colombier /* 1333e12c5d1SDavid du Colombier * given a channel, we cannot derive the directory name 1343e12c5d1SDavid du Colombier * that the channel was generated from since it was lost 1353e12c5d1SDavid du Colombier * by namec. 1363e12c5d1SDavid du Colombier */ 1373e12c5d1SDavid du Colombier if(c->qid.path & CHDIR){ 138*219b2ee8SDavid du Colombier devdir(c, c->qid, ".", 0L, eve, CHDIR|0775, &dir); 1393e12c5d1SDavid du Colombier convD2M(&dir, db); 1403e12c5d1SDavid du Colombier return; 1413e12c5d1SDavid du Colombier } 142bd389b36SDavid du Colombier print("%s %s: devstat %C %lux\n", u->p->text, u->p->user, 1433e12c5d1SDavid du Colombier devchar[c->type], c->qid.path); 1443e12c5d1SDavid du Colombier error(Enonexist); 1453e12c5d1SDavid du Colombier case 0: 1463e12c5d1SDavid du Colombier break; 1473e12c5d1SDavid du Colombier case 1: 1483e12c5d1SDavid du Colombier if(eqqid(c->qid, dir.qid)){ 149*219b2ee8SDavid du Colombier if(c->flag&CMSG) 150*219b2ee8SDavid du Colombier dir.mode |= CHMOUNT; 1513e12c5d1SDavid du Colombier convD2M(&dir, db); 1523e12c5d1SDavid du Colombier return; 1533e12c5d1SDavid du Colombier } 1543e12c5d1SDavid du Colombier break; 1553e12c5d1SDavid du Colombier } 1563e12c5d1SDavid du Colombier } 1573e12c5d1SDavid du Colombier 1583e12c5d1SDavid du Colombier long 1593e12c5d1SDavid du Colombier devdirread(Chan *c, char *d, long n, Dirtab *tab, int ntab, Devgen *gen) 1603e12c5d1SDavid du Colombier { 1613e12c5d1SDavid du Colombier long k, m; 1623e12c5d1SDavid du Colombier Dir dir; 1633e12c5d1SDavid du Colombier 1643e12c5d1SDavid du Colombier k = c->offset/DIRLEN; 1653e12c5d1SDavid du Colombier for(m=0; m<n; k++) 1663e12c5d1SDavid du Colombier switch((*gen)(c, tab, ntab, k, &dir)){ 1673e12c5d1SDavid du Colombier case -1: 1683e12c5d1SDavid du Colombier return m; 1693e12c5d1SDavid du Colombier 1703e12c5d1SDavid du Colombier case 0: 1713e12c5d1SDavid du Colombier c->offset += DIRLEN; 1723e12c5d1SDavid du Colombier break; 1733e12c5d1SDavid du Colombier 1743e12c5d1SDavid du Colombier case 1: 1753e12c5d1SDavid du Colombier convD2M(&dir, d); 1763e12c5d1SDavid du Colombier m += DIRLEN; 1773e12c5d1SDavid du Colombier d += DIRLEN; 1783e12c5d1SDavid du Colombier break; 1793e12c5d1SDavid du Colombier } 1803e12c5d1SDavid du Colombier return m; 1813e12c5d1SDavid du Colombier } 1823e12c5d1SDavid du Colombier 1833e12c5d1SDavid du Colombier Chan * 1843e12c5d1SDavid du Colombier devopen(Chan *c, int omode, Dirtab *tab, int ntab, Devgen *gen) 1853e12c5d1SDavid du Colombier { 1863e12c5d1SDavid du Colombier int i; 1873e12c5d1SDavid du Colombier Dir dir; 1883e12c5d1SDavid du Colombier ulong t, mode; 1893e12c5d1SDavid du Colombier static int access[] = { 0400, 0200, 0600, 0100 }; 1903e12c5d1SDavid du Colombier 1913e12c5d1SDavid du Colombier for(i=0;; i++) 1923e12c5d1SDavid du Colombier switch((*gen)(c, tab, ntab, i, &dir)){ 1933e12c5d1SDavid du Colombier case -1: 1943e12c5d1SDavid du Colombier goto Return; 1953e12c5d1SDavid du Colombier case 0: 1963e12c5d1SDavid du Colombier break; 1973e12c5d1SDavid du Colombier case 1: 1983e12c5d1SDavid du Colombier if(eqqid(c->qid, dir.qid)) { 1993e12c5d1SDavid du Colombier if(strcmp(u->p->user, dir.uid) == 0) /* User */ 2003e12c5d1SDavid du Colombier mode = dir.mode; 2013e12c5d1SDavid du Colombier else if(strcmp(u->p->user, eve) == 0) /* eve is group */ 2023e12c5d1SDavid du Colombier mode = dir.mode<<3; 2033e12c5d1SDavid du Colombier else 2043e12c5d1SDavid du Colombier mode = dir.mode<<6; /* Other */ 2053e12c5d1SDavid du Colombier 2063e12c5d1SDavid du Colombier t = access[omode&3]; 2073e12c5d1SDavid du Colombier if((t & mode) == t) 2083e12c5d1SDavid du Colombier goto Return; 2093e12c5d1SDavid du Colombier error(Eperm); 2103e12c5d1SDavid du Colombier } 2113e12c5d1SDavid du Colombier break; 2123e12c5d1SDavid du Colombier } 2133e12c5d1SDavid du Colombier Return: 2143e12c5d1SDavid du Colombier c->offset = 0; 2153e12c5d1SDavid du Colombier if((c->qid.path&CHDIR) && omode!=OREAD) 2163e12c5d1SDavid du Colombier error(Eperm); 2173e12c5d1SDavid du Colombier c->mode = openmode(omode); 2183e12c5d1SDavid du Colombier c->flag |= COPEN; 2193e12c5d1SDavid du Colombier return c; 2203e12c5d1SDavid du Colombier } 221