Ejemplo n.º 1
0
Archivo: main.c Proyecto: 99years/plan9
int
rdonly(Session *s, Share *sp, char *path, int rdonly)
{
	int rc;
	FInfo fi;

	if(Sess->caps & CAP_NT_SMBS)
		rc = T2queryall(s, sp, path, &fi);
	else
		rc = T2querystandard(s, sp, path, &fi);
	if(rc == -1)
		return -1;

	if((rdonly && !(fi.attribs & ATTR_READONLY)) ||
	    (!rdonly && (fi.attribs & ATTR_READONLY))){
		fi.attribs &= ~ATTR_READONLY;
		fi.attribs |= rdonly? ATTR_READONLY: 0;
		rc = CIFSsetinfo(s, sp, path, &fi);
	}
	return rc;
}
Ejemplo n.º 2
0
static int
smbcreateopen(Aux *a, char *path, int mode, int perm, int is_create,
	int is_dir, FInfo *fip)
{
	int rc, action, attrs, access, result;

	if(is_create && is_dir){
		if(CIFScreatedirectory(Sess, a->sp, path) == -1)
			return -1;
		return 0;
	}

	if(mode & DMAPPEND) {
		werrstr("filesystem does not support DMAPPEND");
		return -1;
	}

	if(is_create)
		action = 0x12;
	else if(mode & OTRUNC)
		action = 0x02;
	else
		action = 0x01;

	if(perm & 0222)
		attrs = ATTR_NORMAL;
	else
		attrs = ATTR_NORMAL|ATTR_READONLY;

	switch (mode & OMASK){
	case OREAD:
		access = 0;
		break;
	case OWRITE:
		access = 1;
		break;
	case ORDWR:
		access = 2;
		break;
	case OEXEC:
		access = 3;
		break;
	default:
		werrstr("%d bad open mode", mode & OMASK);
		return -1;
		break;
	}

	if(mode & DMEXCL == 0)
		access |= 0x10;
	else
		access |= 0x40;

	if((a->fh = CIFS_SMB_opencreate(Sess, a->sp, path, access, attrs,
	    action, &result)) == -1)
		return -1;

	if(Sess->caps & CAP_NT_SMBS)
		rc = T2queryall(Sess, a->sp, mapfile(a->path), fip);
	else
		rc = T2querystandard(Sess, a->sp, mapfile(a->path), fip);
	if(rc == -1){
		fprint(2, "internal error: stat of newly open/created file failed\n");
		return -1;
	}

	if((mode & OEXCL) && (result & 0x8000) == 0){
		werrstr("%d bad open mode", mode & OMASK);
		return -1;
	}
	return 0;
}
Ejemplo n.º 3
0
static char*
fswalk1(Fid *fid, char *name, Qid *qid)
{
	FInfo fi;
	int rc, n, i;
	Aux *a = fid->aux;
	static char e[ERRMAX];
	char *p, *npath, *winpath;

	*e = 0;
	npath = newpath(a->path, name);
	if(strcmp(npath, "/") == 0){			/* root dir */
		*qid = mkqid("/", 1, 1, Proot, 0);
		free(a->path);
		a->path = npath;
		fid->qid = *qid;
		return nil;
	}

	if(strrchr(npath, '/') == npath){		/* top level dir */
		if((n = walkinfo(name)) != -1){		/* info file */
			*qid = mkqid(npath, 0, 1, Pinfo, n);
		}
		else {					/* volume name */
			for(i = 0; i < Nshares; i++){
				n = strlen(Shares[i].name);
				if(cistrncmp(npath+1, Shares[i].name, n) != 0)
					continue;
				if(Checkcase && strncmp(npath+1, Shares[i].name, n) != 0)
					continue;
				if(npath[n+1] != 0 && npath[n+1] != '/')
					continue;
				break;
			}
			if(i >= Nshares){
				free(npath);
				return "not found";
			}
			a->sp = Shares+i;
			*qid = mkqid(npath, 1, 1, Pshare, i);
		}
		free(a->path);
		a->path = npath;
		fid->qid = *qid;
		return nil;
	}

	/* must be a vanilla file or directory */
again:
	if(mapshare(npath, &a->sp) == -1){
		rerrstr(e, sizeof(e));
		free(npath);
		return e;
	}

	winpath = mapfile(npath);
	memset(&fi, 0, sizeof fi);
	if(Sess->caps & CAP_NT_SMBS)
		rc = T2queryall(Sess, a->sp, winpath, &fi);
	else
		rc = T2querystandard(Sess, a->sp, winpath, &fi);

	if(rc == -1){
		rerrstr(e, sizeof(e));
		free(npath);
		return e;
	}

	if((a->sp->options & SMB_SHARE_IS_IN_DFS) != 0 &&
	    (fi.attribs & ATTR_REPARSE) != 0){
		if(redirect(Sess, a->sp, npath) != -1)
			goto again;
	}

	if((p = strrchr(fi.name, '/')) == nil && (p = strrchr(fi.name, '\\')) == nil)
		p = fi.name;
	else
		p++;

	if(! validfile(p, name, winpath, a->sp)){
		free(npath);
		return "not found";

	}
	*qid = mkqid(npath, fi.attribs & ATTR_DIRECTORY, fi.changed, 0, 0);

	free(a->path);
	a->path = npath;
	fid->qid = *qid;
	return nil;
}