static int sd2gen(Chan* c, int i, Dir* dp) { Qid q; uvlong l; SDpart *pp; SDperm *perm; SDunit *unit; SDev *sdev; int rv; sdev = sdgetdev(DEV(c->qid)); assert(sdev); unit = sdev->unit[UNIT(c->qid)]; rv = -1; switch(i){ case Qctl: mkqid(&q, QID(DEV(c->qid), UNIT(c->qid), PART(c->qid), Qctl), unit->vers, QTFILE); perm = &unit->ctlperm; if(emptystr(perm->user)){ kstrdup(&perm->user, eve); perm->perm = 0644; /* nothing secret in ctl */ } devdir(c, q, "ctl", 0, perm->user, perm->perm, dp); rv = 1; break; case Qraw: mkqid(&q, QID(DEV(c->qid), UNIT(c->qid), PART(c->qid), Qraw), unit->vers, QTFILE); perm = &unit->rawperm; if(emptystr(perm->user)){ kstrdup(&perm->user, eve); perm->perm = DMEXCL|0600; } devdir(c, q, "raw", 0, perm->user, perm->perm, dp); rv = 1; break; case Qpart: pp = &unit->part[PART(c->qid)]; l = (pp->end - pp->start) * unit->secsize; mkqid(&q, QID(DEV(c->qid), UNIT(c->qid), PART(c->qid), Qpart), unit->vers+pp->vers, QTFILE); if(emptystr(pp->user)) kstrdup(&pp->user, eve); devdir(c, q, pp->name, l, pp->user, pp->perm, dp); rv = 1; break; } decref(&sdev->r); return rv; }
static int sdwstat(Chan* c, uchar* dp, int n) { Dir *d; SDpart *pp; SDperm *perm; SDunit *unit; SDev *sdev; if(c->qid.type & QTDIR) error(Eperm); sdev = sdgetdev(DEV(c->qid)); if(sdev == nil) error(Enonexist); unit = sdev->unit[UNIT(c->qid)]; qlock(&unit->ctl); d = nil; if(waserror()){ free(d); qunlock(&unit->ctl); decref(&sdev->r); nexterror(); } switch(TYPE(c->qid)){ default: error(Eperm); case Qctl: perm = &unit->ctlperm; break; case Qraw: perm = &unit->rawperm; break; case Qpart: pp = &unit->part[PART(c->qid)]; if(unit->vers+pp->vers != c->qid.vers) error(Enonexist); perm = &pp->SDperm; break; } if(strcmp(up->env->user, perm->user) && !iseve()) error(Eperm); d = smalloc(sizeof(Dir)+n); n = convM2D(dp, n, &d[0], (char*)&d[1]); if(n == 0) error(Eshortstat); if(!emptystr(d[0].uid)) kstrdup(&perm->user, d[0].uid); if(d[0].mode != ~0UL) perm->perm = (perm->perm & ~0777) | (d[0].mode & 0777); free(d); qunlock(&unit->ctl); decref(&sdev->r); poperror(); return n; }
static int pipewstat(struct chan *c, uint8_t *dp, int n) { ERRSTACK(2); struct dir *d; Pipe *p; int d1; if (c->qid.type & QTDIR) error(EPERM, ERROR_FIXME); p = c->aux; if (strcmp(current->user, p->user) != 0) error(EPERM, ERROR_FIXME); d = kzmalloc(sizeof(*d) + n, 0); if (waserror()) { kfree(d); nexterror(); } n = convM2D(dp, n, d, (char *)&d[1]); if (n == 0) error(ENODATA, ERROR_FIXME); d1 = NETTYPE(c->qid.path) == Qdata1; if (!emptystr(d->name)) { validwstatname(d->name); if (strlen(d->name) >= KNAMELEN) error(ENAMETOOLONG, ERROR_FIXME); if (strncmp(p->pipedir[1 + !d1].name, d->name, KNAMELEN) == 0) error(EEXIST, ERROR_FIXME); strncpy(p->pipedir[1 + d1].name, d->name, KNAMELEN); } if (d->mode != ~0UL) p->pipedir[d1 + 1].perm = d->mode & 0777; poperror(); kfree(d); return n; }
int32_t netifwstat(Netif *nif, Chan *c, uint8_t *db, int32_t n) { Proc *up = externup(); Dir *dir; Netfile *f; int l; f = nif->f[NETID(c->qid.path)]; if(f == 0) error(Enonexist); if(netown(f, up->user, OWRITE) < 0) error(Eperm); dir = smalloc(sizeof(Dir)+n); l = convM2D(db, n, &dir[0], (char*)&dir[1]); if(l == 0){ free(dir); error(Eshortstat); } if(!emptystr(dir[0].uid)) strncpy(f->owner, dir[0].uid, KNAMELEN); if(dir[0].mode != (uint32_t)~0UL) f->mode = dir[0].mode; free(dir); return l; }
static long segmentwstat(Chan *c, uchar *dp, long n) { Globalseg *g; Dir *d; if(c->qid.type == QTDIR) error(Eperm); g = getgseg(c); if(waserror()){ putgseg(g); nexterror(); } if(strcmp(g->uid, up->user)!=0 && !iseve()) error(Eperm); d = smalloc(sizeof(Dir)+n); if(waserror()){ free(d); nexterror(); } n = convM2D(dp, n, &d[0], (char*)&d[1]); if(!emptystr(d->uid) && strcmp(d->uid, g->uid) != 0) kstrdup(&g->uid, d->uid); if(d->mode != ~0UL) g->perm = d->mode & 0777; poperror(); free(d); poperror(); putgseg(g); return n; }
int netifwstat(struct ether *nif, struct chan *c, uint8_t * db, int n) { struct dir *dir; struct netfile *f; int m; f = nif->f[NETID(c->qid.path)]; if (f == 0) { set_errno(ENOENT); error(Enonexist); } if (netown(f, current->user, OWRITE) < 0) error(Eperm); dir = kzmalloc(sizeof(struct dir) + n, 0); m = convM2D(db, n, &dir[0], (char *)&dir[1]); if (m == 0) { kfree(dir); error(Eshortstat); } if (!emptystr(dir[0].uid)) strncpy(f->owner, dir[0].uid, KNAMELEN); if (dir[0].mode != ~0UL) f->mode = dir[0].mode; kfree(dir); return m; }
static int rootwstat(struct chan *c, uint8_t *m_buf, int m_buf_sz) { struct dirtab *file = &roottab[c->qid.path]; struct dir *dir; int m_sz; /* TODO: some security check, Eperm on error */ /* common trick in wstats. we want the dir and any strings in the M. the * strings are smaller than entire M (strings plus other M). the strings * will be placed right after the dir (dir[1]) */ dir = kzmalloc(sizeof(struct dir) + m_buf_sz, KMALLOC_WAIT); m_sz = convM2D(m_buf, m_buf_sz, &dir[0], (char*)&dir[1]); if (!m_sz) { kfree(dir); error(ENODATA, ERROR_FIXME); } /* TODO: handle more things than just the mode */ if (!emptystr(dir->name)) printk("[%s] attempted rename of %s to %s\n", __FUNCTION__, file->name, dir->name); /* strncpy for this btw */ if (dir->mode != ~0UL) file->perm = dir->mode | (file->qid.type == QTDIR ? DMDIR : 0); kfree(dir); return m_sz; }
static int pipewstat(Chan *c, uchar *dp, int n) { Dir *d; Pipe *p; int d1; if (c->qid.type&QTDIR) error(Eperm); p = c->aux; if(strcmp(up->env->user, p->user) != 0) error(Eperm); d = smalloc(sizeof(*d)+n); if(waserror()){ free(d); nexterror(); } n = convM2D(dp, n, d, (char*)&d[1]); if(n == 0) error(Eshortstat); d1 = NETTYPE(c->qid.path) == Qdata1; if(!emptystr(d->name)){ validwstatname(d->name); if(strlen(d->name) >= KNAMELEN) error(Efilename); if(strcmp(p->pipedir[1+!d1].name, d->name) == 0) error(Eexist); kstrcpy(p->pipedir[1+d1].name, d->name, KNAMELEN); } if(d->mode != ~0U) p->pipedir[d1 + 1].perm = d->mode & 0777; poperror(); free(d); return n; }
static int pipewstat(Chan* c, uchar* db, int n) { int m; Dir *dir; Pipe *p; p = c->aux; if(strcmp(up->user, eve) != 0) error(Eperm); if(NETTYPE(c->qid.path) == Qdir) error(Eisdir); dir = smalloc(sizeof(Dir)+n); if(waserror()){ free(dir); nexterror(); } m = convM2D(db, n, &dir[0], (char*)&dir[1]); if(m == 0) error(Eshortstat); if(!emptystr(dir[0].uid)) error("can't change owner"); if(dir[0].mode != ~0UL) p->perm = dir[0].mode; poperror(); free(dir); return m; }
bool _ELC_::Project :: compileSources(_ELENA_::Compiler& compiler, _ELENA_::Parser& parser) { bool debugMode = BoolSetting(_ELENA_::opDebugMode); _ELENA_::Unresolveds unresolveds(_ELENA_::Unresolved(), NULL); for (_ELENA_::SourceIterator it = _sources.start(); !it.Eof(); it++) { _ELENA_::Map<_ELENA_::ident_t, _ELENA_::ProjectSettings::VItem>* source = *it; // create module _ELENA_::ident_t name = source->get(ELC_NAMESPACE_KEY); _ELENA_::ModuleInfo moduleInfo = compiler.createModule(name, *this, debugMode); _ELENA_::ident_t target = source->get(ELC_TARGET_NAME); int type = !emptystr(target) ? _targets.get(target, ELC_TYPE_NAME, 1) : 1; if (type == 1) { // if it is a normal ELENA source file _ELENA_::ForwardIterator file_it = source->getIt(ELC_INCLUDE); while (!file_it.Eof()) { // compile a source file compile(*file_it, compiler, parser, moduleInfo, unresolveds); file_it = source->nextIt(ELC_INCLUDE, file_it); } } else if (type == 2) { // if it is a script file _ELENA_::ScriptParser scriptParser; // load options _ELENA_::Map<_ELENA_::ident_t, _ELENA_::TargetSettings::VItem>* targetInfo = _targets.get(target, (_ELENA_::Map<_ELENA_::ident_t, _ELENA_::TargetSettings::VItem>*)NULL); _ELENA_::TargetIterator option_it = targetInfo->getIt(ELC_OPTION); while (!option_it.Eof()) { if (!scriptParser.setOption(*option_it, StrSetting(_ELENA_::opProjectPath))) { raiseError(errInvalidTargetOption, *option_it); } option_it = targetInfo->nextIt(ELC_OPTION, option_it); } // compile script files _ELENA_::ForwardIterator file_it = source->getIt(ELC_INCLUDE); while (!file_it.Eof()) { compile(*file_it, compiler, scriptParser, moduleInfo, unresolveds); file_it = source->nextIt(ELC_INCLUDE, file_it); } } saveModule(moduleInfo.codeModule, "nl"); if (moduleInfo.debugModule) saveModule(moduleInfo.debugModule, "dnl"); } // validate the unresolved forward refereces if unresolved reference warning is enabled compiler.validateUnresolved(unresolveds, *this); return !HasWarnings(); }
static int cmdwstat(Chan *c, uchar *dp, int n) { Dir *d; Conv *cv; switch(TYPE(c->qid)){ default: error(Eperm); case Qctl: case Qdata: case Qstderr: d = malloc(sizeof(*d)+n); if(d == nil) error(Enomem); if(waserror()){ free(d); nexterror(); } n = convM2D(dp, n, d, (char*)&d[1]); if(n == 0) error(Eshortstat); cv = cmd.conv[CONV(c->qid)]; if(!iseve() && strcmp(up->env->user, cv->owner) != 0) error(Eperm); if(!emptystr(d->uid)) kstrdup(&cv->owner, d->uid); if(d->mode != ~0UL) cv->perm = d->mode & 0777; poperror(); free(d); break; } return n; }
bool _ELC_::Project :: loadProject(_ELENA_::path_t path) { if (emptystr(projectName)) { projectName.copy(_ELENA_::IdentifierString(path)); loadConfig(path); _ELENA_::Path projectPath; projectPath.copySubPath(path); _settings.add(_ELENA_::opProjectPath, _ELENA_::IdentifierString::clonePath(projectPath.c_str())); return true; } else return false; }
static int efilegen(Chan *c, SDunit *unit, int i, Dir *dp) { Qid q; SDfile *e; i -= SDnpart; if(unit->nefile == 0 || i >= unit->nefile) return -1; if(i < 0) return 0; e = unit->efile + i; if(emptystr(e->user)) kstrdup(&e->user, eve); mkqid(&q, QID(DEV(c->qid), UNIT(c->qid), i, Qextra), unit->vers, QTFILE); devdir(c, q, e->name, 0, e->user, e->perm, dp); return 1; }
static int srvwstat(Chan *c, uchar *dp, int n) { Dir *d; SrvFile *sf, *f; sf = c->aux; if(strcmp(up->env->user, sf->user) != 0) error(Eperm); d = smalloc(sizeof(*d)+n); if(waserror()){ free(d); nexterror(); } n = convM2D(dp, n, d, (char*)&d[1]); if(n == 0) error(Eshortstat); if(!emptystr(d->name)){ if(sf->dir == nil) error(Eperm); validwstatname(d->name); qlock(&dev.l); for(f = sf->dir; f != nil; f = f->entry) if(strcmp(f->name, d->name) == 0){ qunlock(&dev.l); error(Eexist); } kstrdup(&sf->name, d->name); qunlock(&dev.l); } if(d->mode != ~0UL) sf->perm = d->mode & (DMEXCL|DMAPPEND|0777); if(d->length != (vlong)-1) sf->length = d->length; poperror(); free(d); return n; }
static int ipwstat(Chan *c, uchar *dp, int n) { Dir *d; Conv *cv; Proto *p; Fs *f; f = ipfs[c->dev]; switch(TYPE(c->qid)) { default: error(Eperm); break; case Qctl: case Qdata: break; } d = smalloc(sizeof(*d)+n); if(waserror()){ free(d); nexterror(); } n = convM2D(dp, n, d, (char*)&d[1]); if(n == 0) error(Eshortstat); p = f->p[PROTO(c->qid)]; cv = p->conv[CONV(c->qid)]; if(!iseve() && strcmp(up->env->user, cv->owner) != 0) error(Eperm); if(!emptystr(d->uid)) kstrdup(&cv->owner, d->uid); if(d->mode != ~0UL) cv->perm = d->mode & 0777; poperror(); free(d); return n; }
Chan* fsattach(char *spec) { Chan *c; Dir *d; char *root; Qid rootqid; static int devno; static Lock l; if(!emptystr(spec)){ if(strcmp(spec, "*") != 0) error(Ebadspec); root = "/"; }else root = rootdir; d = dirstat(root); if(d == nil) fserr(nil); rootqid = d->qid; free(d); c = devattach('U', spec); lock(&l); c->dev = devno++; c->qid = rootqid; unlock(&l); c->aux = smalloc(sizeof(Fsinfo)); FS(c)->name = newcname(root); FS(c)->rootqid = rootqid; FS(c)->fd = -1; FS(c)->root = root; return c; }
static int sdgen(Chan* c, char*, Dirtab*, int, int s, Dir* dp) { Qid q; uvlong l; int i, r; SDpart *pp; SDunit *unit; SDev *sdev; switch(TYPE(c->qid)){ case Qtopdir: if(s == DEVDOTDOT){ mkqid(&q, QID(0, 0, 0, Qtopdir), 0, QTDIR); snprint(up->genbuf, sizeof up->genbuf, "#%C", sddevtab.dc); devdir(c, q, up->genbuf, 0, eve, 0555, dp); return 1; } if(s+Qtopbase < Qunitdir) return sd1gen(c, s+Qtopbase, dp); s -= (Qunitdir-Qtopbase); qlock(&devslock); for(i=0; i<nelem(devs); i++){ if(devs[i]){ if(s < devs[i]->nunit) break; s -= devs[i]->nunit; } } if(i == nelem(devs)){ /* Run off the end of the list */ qunlock(&devslock); return -1; } if((sdev = devs[i]) == nil){ qunlock(&devslock); return 0; } incref(&sdev->r); qunlock(&devslock); if((unit = sdev->unit[s]) == nil) if((unit = sdgetunit(sdev, s)) == nil){ decref(&sdev->r); return 0; } mkqid(&q, QID(sdev->idno, s, 0, Qunitdir), 0, QTDIR); if(emptystr(unit->user)) kstrdup(&unit->user, eve); devdir(c, q, unit->name, 0, unit->user, unit->perm, dp); decref(&sdev->r); return 1; case Qunitdir: if(s == DEVDOTDOT){ mkqid(&q, QID(0, 0, 0, Qtopdir), 0, QTDIR); snprint(up->genbuf, sizeof up->genbuf, "#%C", sddevtab.dc); devdir(c, q, up->genbuf, 0, eve, 0555, dp); return 1; } if((sdev = sdgetdev(DEV(c->qid))) == nil){ devdir(c, c->qid, "unavailable", 0, eve, 0, dp); return 1; } unit = sdev->unit[UNIT(c->qid)]; qlock(&unit->ctl); /* * Check for media change. * If one has already been detected, sectors will be zero. * If there is one waiting to be detected, online * will return > 1. * Online is a bit of a large hammer but does the job. */ if(unit->sectors == 0 || (unit->dev->ifc->online && unit->dev->ifc->online(unit) > 1)) sdinitpart(unit); i = s+Qunitbase; if(i < Qpart){ r = sd2gen(c, i, dp); qunlock(&unit->ctl); decref(&sdev->r); return r; } i -= Qpart; if(unit->part == nil || i >= unit->npart){ qunlock(&unit->ctl); decref(&sdev->r); break; } pp = &unit->part[i]; if(!pp->valid){ qunlock(&unit->ctl); decref(&sdev->r); return 0; } l = (pp->end - pp->start) * unit->secsize; mkqid(&q, QID(DEV(c->qid), UNIT(c->qid), i, Qpart), unit->vers+pp->vers, QTFILE); if(emptystr(pp->user)) kstrdup(&pp->user, eve); devdir(c, q, pp->name, l, pp->user, pp->perm, dp); qunlock(&unit->ctl); decref(&sdev->r); return 1; case Qraw: case Qctl: case Qpart: if((sdev = sdgetdev(DEV(c->qid))) == nil){ devdir(c, q, "unavailable", 0, eve, 0, dp); return 1; } unit = sdev->unit[UNIT(c->qid)]; qlock(&unit->ctl); r = sd2gen(c, TYPE(c->qid), dp); qunlock(&unit->ctl); decref(&sdev->r); return r; case Qtopctl: return sd1gen(c, TYPE(c->qid), dp); default: break; } return -1; }