📄 potemkin.c
字号:
fid_ent_t *root; if (!RootFid) { root = fid_create(".", NULL); CODA_ASSERT(ds_hash_insert(FidTab, root)); root->type = C_VDIR; RootFep = root; RootFid = &(root->fid); } out->coda_root.VFid.Volume = RootFid->Volume; out->coda_root.VFid.Vnode = RootFid->Vnode; out->coda_root.VFid.Unique = RootFid->Unique; out->oh.result = 0; if (verbose) { printf("Returning root: fid (%x.%x.%x)\n",RootFid->Volume, RootFid->Vnode, RootFid->Unique); } *reply = VC_OUTSIZE(coda_root_out); return;}voidDoOpen(union inputArgs *in, union outputArgs *out, int *reply){ ViceFid *fp; int *flags; fid_ent_t *fep; fid_ent_t dummy; char *path=NULL; struct stat sbuf; fp = &(in->coda_open.VFid); flags = &(in->coda_open.flags); dummy.fid = *fp; CODA_ASSERT((fep = ds_hash_member(FidTab, &dummy)) != NULL); path = fid_fullname(fep); if (verbose) { printf("Geting dev,inode for fid (%x.%x.%x): %s",fp->Volume, fp->Vnode, fp->Unique, path); fflush(stdout); } if (lstat(path,&sbuf)) { out->oh.result = errno; goto exit; } out->coda_open.dev = sbuf.st_dev; out->coda_open.inode = sbuf.st_ino; out->oh.result = 0; if (verbose) { printf("....found\n"); fflush(stdout); } exit: if (path) free(path); *reply = VC_OUTSIZE(coda_open_out); return;}voidDoOpenByPath(union inputArgs *in, union outputArgs *out, int *reply){ ViceFid *fp; int *flags; fid_ent_t *fep; fid_ent_t dummy; char *path=NULL; struct stat sbuf; char *slash; char *begin; fp = &(in->coda_open_by_path.VFid); flags = &(in->coda_open_by_path.flags); dummy.fid = *fp; CODA_ASSERT((fep = ds_hash_member(FidTab, &dummy)) != NULL); path = fid_fullname(fep); if (verbose) { printf("Geting name for fid (%x.%x.%x): %s",fp->Volume, fp->Vnode, fp->Unique, path); fflush(stdout); } if (lstat(path,&sbuf)) { out->oh.result = errno; goto exit; } begin = (char *)(&out->coda_open_by_path.path + 1); out->coda_open_by_path.path = begin - (char *)out; if (verbose) printf("Rootdir %s path %s, total %s\n", RootDir, path, begin); sprintf(begin, "%s/%s", RootDir, path);#if defined(DJGPP) || defined(__CYGWIN32__) slash = begin; for (slash = begin ; *slash ; slash++ ) { if ( *slash == '/' ) *slash='\\'; } printf("Rootdir %s path %s, total %s\n", RootDir, path, begin);#endif out->oh.result = 0; if (verbose) { printf("....found\n"); fflush(stdout); } exit: if (path) free(path); *reply = sizeof (struct coda_open_by_path_out) + strlen(begin) + 1; return;}voidDoClose(union inputArgs *in, union outputArgs *out, int *reply){ ViceFid *fp; fp = &(in->coda_close.VFid); /* Close always succeeds */ if (verbose) { printf("Trival close for fid (%x.%x.%x)\n", fp->Volume, fp->Vnode, fp->Unique); fflush(stdout); } out->oh.result = 0; *reply = VC_OUT_NO_DATA; return;}voidDoAccess(union inputArgs *in, union outputArgs *out, int *reply){ ViceFid *fp; fp = &(in->coda_close.VFid); /* Access always succeeds, for now */ if (verbose) { printf("Trival access for fid (%x.%x.%x)\n", fp->Volume, fp->Vnode, fp->Unique); fflush(stdout); } out->oh.result = 0; *reply = VC_OUT_NO_DATA; return;}voidDoLookup(union inputArgs *in, union outputArgs *out, int *reply){ ViceFid *fp; char *name; fid_ent_t *fep; fid_ent_t *childp=NULL; bool created=FALSE; fid_ent_t dummy; ds_list_iter_t *iter; char *path=NULL; struct stat sbuf; fp = &(in->coda_lookup.VFid); CODA_ASSERT((int)in->coda_lookup.name == VC_INSIZE(coda_lookup_in)); name = (char*)in + (int)in->coda_lookup.name; if (verbose) { printf("Doing lookup of (%s) in fid (%x.%x.%x)\n", name, fp->Volume, fp->Vnode, fp->Unique); fflush(stdout); } /* We'd better be looking up in a directory */ dummy.fid = *fp; CODA_ASSERT((fep = (fid_ent_t *) ds_hash_member (FidTab, &dummy)) != NULL); if (fep->type != C_VDIR) { out->oh.result = ENOTDIR; goto exit; } /* Step 0: Special case '.' and '..' */ if (!strcmp(name, ".")) { childp = fep; goto found; } if (!strcmp(name, "..")) { if (fep == RootFep) { fprintf(stderr,"AACK! DoLookup of '..' through root!\n"); out->oh.result = EBADF; goto exit; } childp = fep->parent; goto found; } /* Step 0.5: Special case '@sys' */ if (!strcmp(name, "@sys")) { name = SYS_STRING; } /* Begin normal pathname lookup. */ /* Step 1: have we resolved it before? */ iter = ds_list_iter_create(fep->kids); while ((childp = ds_list_iter_next(iter)) != NULL) { if (!strcmp(childp->name, name)) break; } ds_list_iter_destroy(iter); if (!childp) { /* Didn't find it */ /* Step 2: look in the actual directory for the child */ path = fid_fullname(fep); if (!child_exists(path,name)) { /* No such child */ out->oh.result = ENOENT; goto exit; } /* Create a fid entry for this child */ childp = fid_create(name, fep); created = TRUE; if (path) free(path); path = fid_fullname(childp); if (lstat(path,&sbuf)) { /* Can't read? */ out->oh.result = ENOENT; goto exit; } if (fid_assign_type(childp, &sbuf)) { out->oh.result = ENOENT; goto exit; } /* Remember that we have this vnode */ CODA_ASSERT(ds_hash_insert(FidTab, childp)); CODA_ASSERT(ds_list_insert(fep->kids, childp)); } found: /* Okay. We now have a valid vnode in childp, we'll succeed */ out->coda_lookup.VFid = childp->fid; out->coda_lookup.vtype = childp->type; out->oh.result = 0; if (verbose) { printf("....found\n"); fflush(stdout); } exit: if (out->oh.result && created && childp) { /* Error -- We don't want the child */ free(childp); } if (path) free(path); *reply = VC_OUTSIZE(coda_lookup_out); return;}/* Phase 2a: Reading/Writing */voidDoGetattr(union inputArgs *in, union outputArgs *out, int *reply){ ViceFid *fp; fid_ent_t *fep; fid_ent_t dummy; struct stat st; struct coda_vattr *vbuf; char *path = NULL; fp = &(in->coda_getattr.VFid); vbuf = &(out->coda_getattr.attr); if (verbose) { printf("Doing getattr for fid (%x.%x.%x)\n", fp->Volume, fp->Vnode, fp->Unique); } dummy.fid = *fp; CODA_ASSERT((fep = (fid_ent_t *) ds_hash_member (FidTab, &dummy)) != NULL); path = fid_fullname(fep); if (lstat(path,&st)) { out->oh.result = errno; } else { if (fid_assign_type(fep, &st)) { out->oh.result = ENOENT; goto exit; } fill_vattr(&st, fep, vbuf); } out->oh.result = 0; exit: if (path) free(path); *reply = VC_OUTSIZE(coda_getattr_out); return;}voidDoReaddir(union inputArgs *in, union outputArgs *out, int *reply){ /* Do nothing: it's handled by FFS/LFS */ out->oh.result = EOPNOTSUPP; return;}voidDoRdwr(union inputArgs *in, union outputArgs *out, int *reply){ /* Do nothing: it's handled by FFS/LFS */ out->oh.result = EOPNOTSUPP; return;}/* Phase 2b - namespace changes */voidDoCreate(union inputArgs *in, union outputArgs *out, int *reply){ ViceFid *fp; fid_ent_t *fep; ViceFid *newFp; fid_ent_t *newFep=NULL; fid_ent_t dummy; struct coda_vattr *attr; struct coda_vattr *newAttr; struct coda_cred *cred; int exclp; int mode; int readp; int writep; int truncp; int oflags=0; int omode; /* Shouldn't this be just mode? */ bool created=FALSE; char *name=NULL; char *path=NULL; ds_list_iter_t *iter; struct stat sbuf; int fd; uid_t suid; gid_t sgid; fp = &(in->coda_create.VFid); attr = &(in->coda_create.attr); cred = &(in->ih.cred); exclp = in->coda_create.excl; mode = in->coda_create.mode; readp = mode & C_M_READ; writep = mode & C_M_WRITE; truncp = (attr->va_size == 0); CODA_ASSERT((int)in->coda_create.name == VC_INSIZE(coda_create_in)); name = (char*)in + (int)in->coda_create.name; newFp = &(out->coda_create.VFid); newAttr = &(out->coda_create.attr); if (verbose) { printf("Doing create of (%s) in fid (%x.%x.%x) mode 0%o %s\n", name, fp->Volume, fp->Vnode, fp->Unique, mode, (exclp ? "excl" : "")); } /* Where are we creating this? */ dummy.fid = *fp; CODA_ASSERT((fep = (fid_ent_t *) ds_hash_member(FidTab, &dummy)) != NULL); if (fep->type != C_VDIR) { printf("Ack! Trying to create in a non-directory!\n"); out->oh.result = ENOTDIR; goto exit; } /* Step 0: Is the name-to-be-created okay? */ /* Don't allow any creation of '.', '..', ''; they already must exist. */ if ((!strcmp(name, ".")) || (!strcmp(name, "..")) || (!strcmp(name, ""))) { printf("CREATE: create of '.', '..' or ''\n"); out->oh.result = EINVAL; goto exit; } /* Don't allow names of the form @XXXXXXXX.XXXXXXXX.XXXXXXXX */ if ((strlen(name) == 27) && (name[0] == '@') && (name[9] == '.') && (name[18] == '.')) { out->oh.result = EINVAL; goto exit; } /* Step 1: does this child already exist? */ path = fid_fullname(fep); /*I'm not currently checking to see that * previously-existing-files continue to have the same vtype. * (I'll just reset it if it's different, which would be a * rather serious disaster.) */ if (child_exists(path, name)) { if (exclp) { out->oh.result = EEXIST; goto exit; } /* Do we know about the child yet? */ iter = ds_list_iter_create(fep->kids); while ((newFep = ds_list_iter_next(iter)) != NULL) { if (!strcmp(newFep->name, name)) { break; } } ds_list_iter_destroy(iter); } if (!newFep) { /* * XXX This is either a completely new file, or a file that we * have not yet created a fid for. We should create a new * fid_ent_t for it. */ newFep = fid_create(name, fep); created = TRUE; } /* * Now, we have to set the path to it so that the open-for-create * and later stat will happen correctly. (We'll need to do the * stat to correctly set the type of the fep. */ if (path) free (path); path = fid_fullname(newFep); /* * Okay, now do the create. * I'll be lazy and do so with an actual open. (Which we have * to do eventually anyway if we are truncating. Should I worry * about this here? Not sure...) */ /* Set the open flags */ /* XXX - this code assumes O_RDONLY is 0 */ if (writep) { if (readp) { oflags |= O_RDWR; } else { oflags |= O_WRONLY; } } oflags |= O_CREAT; if (truncp) { oflags |= O_TRUNC; } if (exclp) { oflags |= O_EXCL; } /* Set the mode bits */ omode = mode & 0777; /* XXX - but that's what the man page says */ /* Set the creator for this file */ suid = getuid(); sgid = getgid(); CODA_ASSERT(!setgid(cred->cr_groupid)); CODA_ASSERT(!seteuid(cred->cr_uid)); /* Do the open */ if ((fd = open(path, oflags, omode)) < 0) { out->oh.result = errno; CODA_ASSERT(!seteuid(suid)); CODA_ASSERT(!setgid(sgid)); goto exit; } else { close(fd); } /* Reset our effective uid/gid */ CODA_ASSERT(!seteuid(suid)); CODA_ASSERT(!setgid(sgid)); /* Stat the thing so that we can set it's type correctly. */ /* Complain miserably if it isn't a plain file! */ if (lstat(path,&sbuf)) { out->oh.result = errno; goto exit; } if (fid_assign_type(newFep, &sbuf)) { out->oh.result = ENOENT; goto exit; } if (newFep->type != C_VREG) { printf("AACK! Create is 'creating' a non-file file of type %d!\n", newFep->type); } /* We are now doomed to succeed :-) */ /* Record this fid, and finish off */ out->oh.result = 0; CODA_ASSERT(ds_hash_insert(FidTab, newFep)); CODA_ASSERT(ds_list_insert(fep->kids, newFep)); /* Set the return values for the create call */ *newFp = newFep->fid; fill_vattr(&sbuf, newFep, newAttr); exit: if (out->oh.result && created && newFep) { /* We don't keep the newFep if there was an error */ free(newFep); } if (path) free(path); *reply = VC_OUTSIZE(coda_create_out); return;}voidDoRemove(union inputArgs *in, union outputArgs *out, int *reply){ ViceFid *fp; fid_ent_t *fep; fid_ent_t *victimFep=NULL; bool created=FALSE; struct coda_cred *cred; fid_ent_t dummy; char *name=NULL; char *path=NULL; ds_list_iter_t *iter; struct stat sbuf; uid_t suid; gid_t sgid; fp = &(in->coda_remove.VFid); cred = &(in->ih.cred); CODA_ASSERT((int)in->coda_remove.name == VC_INSIZE(coda_remove_in)); name = (char*)in + (int)in->coda_remove.name; if (verbose) { printf("Doing remove of (%s) in fid (%x.%x.%x)\n", name, fp->Volume, fp->Vnode, fp->Unique); } /* Get the directory from which we are removing */ dummy.fid = *fp; CODA_ASSERT((fep = (fid_ent_t *) ds_hash_member(FidTab, &dummy)) != NULL); if (fep->type != C_VDIR) { printf("REMOVE: parent not directory!\n"); out->oh.result = ENOTDIR; goto exit; } /* Step 0: Check to ensure that removes don't happen to '.', '..', or '' */ if ((!strcmp(name, ".")) || (!strcmp(name, "..")) || (!strcmp(name, ""))) { printf("REMOVE: remove of '.', '..' or ''\n"); out->oh.result = EINVAL; goto exit; } /* Don't allow names of the form @XXXXXXXX.XXXXXXXX.XXXXXXXX */ if ((strlen(name) == 27) && (name[0] == '@') && (name[9] == '.') && (name[18] == '.')) { out->oh.result = EINVAL; goto exit; } path = fid_fullname(fep); /* Step 1: find the child */ if (!child_exists(path,name)) { printf("REMOVE: child didn't exist!\n"); out->oh.result = ENOENT; goto exit; } /* Do we know about the child yet? */ iter = ds_list_iter_create(fep->kids); while ((victimFep = ds_list_iter_next(iter)) != NULL) { if (!strcmp(victimFep->name, name)) { break; } } ds_list_iter_destroy(iter); if (!victimFep) { /* * We're going to create a victimFep as a temporary; this is * only to make the code simpler. I know that it isn't * that efficient, but... */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -