Esempio n. 1
0
int sp_lockfile(spfile *f, char *path)
{
	f->creat = 0;
	f->fd = open(path, O_CREAT|O_WRONLY, 0600);
	if (spunlikely(f->fd == -1))
		return -1;
	f->file = sp_strdup(f->a, path);
	if (spunlikely(f->file == NULL)) {
		close(f->fd);
		f->fd = -1;
		return -1;
	}
	struct flock l;
	memset(&l, 0, sizeof(l));
	l.l_whence = SEEK_SET;
	l.l_start = 0;
	l.l_len = 0;
	l.l_type = F_WRLCK;
	int rc = fcntl(f->fd, F_SETLK, &l);
	if (spunlikely(rc == -1)) {
		sp_fileclose(f);
		return 1;
	}
	return 0;
}
Esempio n. 2
0
static void
spcfd_check_error(Spcfd *spcfd, Spfcall *rc)
{
	char *ename;

	if (rc && rc->type == Rerror) {
		ename = sp_strdup(&rc->ename);
		if (ename) {
			sp_werror(ename, rc->ecode);
			free(ename);
		}
	}
}
Esempio n. 3
0
int
spc_rpc(Spcfsys *fs, Spfcall *tc, Spfcall **rc)
{
	char *ename;
	Spcrpc r;

	if (fs->fd < 0)
		return -1;

	if (rc)
		*rc = NULL;

	r.fs = fs;
	r.tc = tc;
	r.rc = NULL;
	r.ename = NULL;
	r.ecode = 0;
	
	spc_rpcnb(fs, tc, spc_rpc_cb, &r);
	while (!r.ename && !r.rc)
		sp_poll_once();

	if (r.ename) {
		sp_werror(r.ename, r.ecode);
		goto error;
	}

	if (r.rc && r.rc->type == Rerror) {
		ename = sp_strdup(&r.rc->ename);
		if (ename)
			sp_werror(ename, r.rc->ecode);

		free(ename);
		goto error;
	}

	free(r.ename);
	if (rc)
		*rc = r.rc;
	else
		free(r.rc);

	return 0;

error:
	if (r.ename != Enomem)
		free(r.ename);
	free(r.rc);
	return -1;
}
Esempio n. 4
0
static inline int
sp_logopenof(spfile *f, char *path, int flags)
{
	f->creat = 1;
	f->fd = open(path, flags, 0600);
	if (spunlikely(f->fd == -1))
		return -1;
	f->file = sp_strdup(f->a, path);
	if (spunlikely(f->file == NULL)) {
		close(f->fd);
		f->fd = -1;
		return -1;
	}
	f->size = 0;
	f->used = 0;
	return 0;
}
Esempio n. 5
0
static inline int
sp_mapopenof(spfile *f, char *path, int flags, uint64_t size)
{
#if _MSC_VER
    f->fd = sp_win_openfile(path, flags);
#else
    f->fd = open(path, flags, 0600);
#endif
    if (spunlikely(f->fd == -1))
        return -1;
    f->file = sp_strdup(f->a, path);
    if (spunlikely(f->file == NULL)) {
        close(f->fd);
        f->fd = -1;
        return -1;
    }
    f->used = 0;
    f->creat = (flags & O_CREAT ? 1 : 0);
    int rc;
    if (!f->creat) {
        ssize_t sz = sp_mapsizeof(path);
        if (spunlikely(sz == -1))
            goto err;
        f->size = sz;
        rc = sp_map(f, PROT_READ);
        if (spunlikely(rc == -1))
            goto err;
        return 0;
    }
    f->size = 0;
    rc = sp_mapresize(f, size);
    if (spunlikely(rc == -1))
        goto err;
    rc = sp_map(f, PROT_READ | PROT_WRITE);
    if (spunlikely(rc == -1))
        goto err;
    return 0;
err:
    close(f->fd);
    f->fd = -1;
    sp_free(f->a, f->file);
    f->file = NULL;
    return -1;
}
Esempio n. 6
0
static Spfcall*
npfs_attach(Spfid *nfid, Spfid *nafid, Spstr *uname, Spstr *aname, u32 n_uname)
{
	int err;
	Spfcall* ret;
	Fid *fid;
	Spqid qid;
	char *user;

	user = NULL;
	ret = NULL;

	if (nafid != NULL) {
		sp_werror(Enoauth, EIO);
		goto done;
	}

	fid = npfs_fidalloc();
	fid->omode = -1;
	npfs_change_user(nfid->user);

	fid->omode = -1;
	if (aname->len==0 || *aname->str!='/')
		fid->path = strdup("/");
	else
		fid->path = sp_strdup(aname);
	
	nfid->aux = fid;
	err = fidstat(fid);
	if (err < 0) {
		create_rerror(err);
		goto done;
	}

	ustat2qid(&fid->stat, &qid);
	ret = sp_create_rattach(&qid);
	sp_fid_incref(nfid);

done:
	return ret;
}
Esempio n. 7
0
int sp_lockfile(spfile *f, char *path)
{
    f->creat = 0;
#ifdef _MSC_VER
    f->fd = sp_win_openfileshare(path, O_CREAT | O_WRONLY, 0);
    if (f->fd == -1 && GetLastError() == ERROR_SHARING_VIOLATION)
        return 1;   // already locked
#else
    f->fd = open(path, O_CREAT | O_WRONLY, 0600);
#endif
    if (spunlikely(f->fd == -1))
        return -1;
    f->file = sp_strdup(f->a, path);
    if (spunlikely(f->file == NULL)) {
        close(f->fd);
        f->fd = -1;
        return -1;
    }
#ifdef _MSC_VER
    int rc = LockFile((HANDLE)_get_osfhandle(f->fd), 0, 0, 0xffffffff, 0xffffffff);
    if (spunlikely(rc == 0)) {
        sp_fileclose(f);
        return 1;
    }
    return 0;
#else
    struct flock l;
    memset(&l, 0, sizeof(l));
    l.l_whence = SEEK_SET;
    l.l_start = 0;
    l.l_len = 0;
    l.l_type = F_WRLCK;
    int rc = fcntl(f->fd, F_SETLK, &l);
    if (spunlikely(rc == -1)) {
        sp_fileclose(f);
        return 1;
    }
    return 0;
#endif
}
Esempio n. 8
0
static inline int
sp_filecomplete(spfile *f)
{
    if (f->creat == 0)
        return 0;
    /* remove .incomplete part */
    f->creat = 0;
    char path[1024];
    snprintf(path, sizeof(path), "%s", f->file);
    char *ext = strrchr(path, '.');
    assert(ext != NULL);
    *ext = 0;
    int rc = rename(f->file, path);
    if (spunlikely(rc == -1))
        return -1;
    char *p = sp_strdup(f->a, path);
    if (spunlikely(p == NULL))
        return -1;
    sp_free(f->a, f->file);
    f->file = p;
    return 0;
}
Esempio n. 9
0
Spfcall *
sp_auth(Spreq *req, Spfcall *tc)
{
	int n;
	char *uname, *aname;
	Spconn *conn;
	Spsrv *srv;
	Spfid *afid;
	Spfcall *rc;
	Spuser *user;
	Spqid aqid;

	rc = NULL;
	aname = NULL;
	conn = req->conn;
	srv = conn->srv;
	afid = sp_fid_find(conn, tc->afid);
	if (afid) {
		sp_werror(Einuse, EIO);
		goto done;
	}

	afid = sp_fid_create(conn, tc->afid, NULL);
	if (!afid) 
		goto done;
	else
		sp_fid_incref(afid);

	if (tc->uname.len && tc->n_uname==~0) {
		uname = sp_strdup(&tc->uname);
		if (!uname) 
			goto done;

		user = (*srv->upool->uname2user)(srv->upool, uname);
		free(uname);
		if (!user) {
			sp_werror(Eunknownuser, EIO);
			goto done;
		}
		tc->n_uname = user->uid;
	} else {
		user = (*srv->upool->uid2user)(srv->upool, tc->n_uname);
		if (!user) {
			sp_werror(Eunknownuser, EIO);
			goto done;
		}
	}

	if (tc->aname.len) {
		aname = sp_strdup(&tc->aname);
		if (!aname)
			goto done;
	} else
		aname = NULL;

	afid->user = user;
	afid->type = Qtauth;
	if (srv->auth && srv->auth->startauth)
		n = (*srv->auth->startauth)(afid, aname, &aqid);
	else
		n = 0;

	if (n) {
		assert((aqid.type & Qtauth) != 0);
		rc = sp_create_rauth(&aqid);
	} else
		sp_werror(Enoauth, EIO);
done:
	free(aname);
	if (!rc)
		sp_fid_decref(afid);
	return rc;
}
Esempio n. 10
0
Spfcall *
sp_attach(Spreq *req, Spfcall *tc)
{
	char *uname, *aname;
	Spconn *conn;
	Spsrv *srv;
	Spfid *fid, *afid;
	Spfcall *rc;
	Spuser *user;

	rc = NULL;
	aname = NULL;
	conn = req->conn;
	srv = conn->srv;
	afid = NULL;
	fid = sp_fid_find(conn, tc->fid);
	if (fid) {
		sp_werror(Einuse, EIO);
		goto done;
	}

	fid = sp_fid_create(conn, tc->fid, NULL);
	if (!fid)
		goto done;
	else 
		sp_fid_incref(fid);

	req->fid = fid;
	afid = sp_fid_find(conn, tc->afid);
	if (!afid) {
		if (tc->afid!=NOFID) {
			sp_werror(Eunknownfid, EIO);
			goto done;
		}

		if (!afid->type&Qtauth) {
			sp_werror(Ebadusefid, EIO);
			goto done;
		}
	} else 
		sp_fid_incref(afid);

	if (tc->uname.len && tc->n_uname==~0) {
		uname = sp_strdup(&tc->uname);
		if (!uname) 
			goto done;

		user = srv->upool->uname2user(srv->upool, uname);
		free(uname);
		if (!user) {
			sp_werror(Eunknownuser, EIO);
			goto done;
		}

		tc->n_uname = user->uid;
	} else {
		user = srv->upool->uid2user(srv->upool, tc->n_uname);
		if (!user) {
			sp_werror(Eunknownuser, EIO);
			goto done;
		}
	}

	fid->user = user;
	if (tc->aname.len) {
		aname = sp_strdup(&tc->aname);
		if (!aname)
			goto done;
	} else
		aname = NULL;

	if (conn->srv->auth && conn->srv->auth->checkauth
	&& !(*conn->srv->auth->checkauth)(fid, afid, aname))
		goto done;

	rc = (*conn->srv->attach)(fid, afid, &tc->uname, &tc->aname, tc->n_uname);

done:
	free(aname);
	sp_fid_decref(afid);
	return rc;
}
Esempio n. 11
0
static Spfcall*
npfs_wstat(Spfid *fid, Spstat *stat)
{
	int err;
	Fid *f;
	Spfcall *ret;
	uid_t uid;
	gid_t gid;
	char *npath, *p, *s;
	Spuser *user;
	Spgroup *group;
	struct utimbuf tb;

	ret = NULL;
	f = fid->aux;
	npfs_change_user(fid->user);
	err = fidstat(f);
	if (err < 0) {
		create_rerror(err);
		goto out;
	}

	if (fid->conn->dotu) {
		uid = stat->n_uid;
		gid = stat->n_gid;
	} else {
		uid = (uid_t) -1;
		gid = (gid_t) -1;
	}

	if (uid == -1 && stat->uid.len) {
		s = sp_strdup(&stat->uid);
		user = sp_uname2user(s);
		free(s);
		if (!user) {
			sp_werror(Eunknownuser, EIO);
			goto out;
		}

		uid = user->uid;
	}

	if (gid == -1 && stat->gid.len) {
		s = sp_strdup(&stat->gid);
		group = sp_gname2group(s);
		free(s);
		if (!group) {
			sp_werror(Eunknownuser, EIO);
			goto out;
		}

		gid = group->gid;
	}

	if (stat->mode != (u32)~0) {
		if (stat->mode&Dmdir && !S_ISDIR(f->stat.st_mode)) {
			sp_werror(Edirchange, EIO);
			goto out;
		}

		if (chmod(f->path, npstat2umode(stat, fid->conn->dotu)) < 0) {
			create_rerror(errno);
			goto out;
		}
	}

	if (stat->mtime != (u32)~0) {
		tb.actime = 0;
		tb.modtime = stat->mtime;
		if (utime(f->path, &tb) < 0) {
			create_rerror(errno);
			goto out;
		}
	}

	if (gid != -1) {
		if (chown(f->path, uid, gid) < 0) {
			create_rerror(errno);
			goto out;
		}
	}

	if (stat->name.len != 0) {
		p = strrchr(f->path, '/');
		if (!p)
			p = f->path + strlen(f->path);

		npath = malloc(stat->name.len + (p - f->path) + 2);
		memcpy(npath, f->path, p - f->path);
		npath[p - f->path] = '/';
		memcpy(npath + (p - f->path) + 1, stat->name.str, stat->name.len);
		npath[(p - f->path) + 1 + stat->name.len] = 0;
		if (strcmp(npath, f->path) != 0) {
			if (rename(f->path, npath) < 0) {
				create_rerror(errno);
				goto out;
			}

			free(f->path);
			f->path = npath;
		}
	}

	if (stat->length != ~0) {
		if (truncate(f->path, stat->length) < 0) {
			create_rerror(errno);
			goto out;
		}
	}
	ret = sp_create_rwstat();
	
out:
	return ret;
}
Esempio n. 12
0
static int
npfs_create_special(Spfid *fid, char *path, u32 perm, Spstr *extension)
{
	int nfid, err;
	int nmode, major, minor;
	char ctype;
	mode_t umode;
	Spfid *ofid;
	Fid *f, *of;
	char *ext;

	f = fid->aux;
	if (!perm&Dmnamedpipe && !extension->len) {
		sp_werror(Enoextension, EIO);
		return -1;
	}

	umode = np2umode(perm, extension, fid->conn->dotu);
	ext = sp_strdup(extension);
	if (perm & Dmsymlink) {
		if (symlink(ext, path) < 0) {
			err = errno;
			fprintf(stderr, "symlink %s %s %d\n", ext, path, err);
			create_rerror(err);
			goto error;
		}
	} else if (perm & Dmlink) {
		if (sscanf(ext, "%d", &nfid) == 0) {
			sp_werror(Eformat, EIO);
			goto error;
		}

		ofid = sp_fid_find(fid->conn, nfid);
		if (!ofid) {
			sp_werror(Eunknownfid, EIO);
			goto error;
		}

		of = ofid->aux;
		if (link(of->path, path) < 0) {
			create_rerror(errno);
			goto error;
		}
	} else if (perm & Dmdevice) {
		if (sscanf(ext, "%c %u %u", &ctype, &major, &minor) != 3) {
			sp_werror(Eformat, EIO);
			goto error;
		}

		nmode = 0;
		switch (ctype) {
		case 'c':
			nmode = S_IFCHR;
			break;

		case 'b':
			nmode = S_IFBLK;
			break;

		default:
			sp_werror(Eformat, EIO);
			goto error;
		}

		nmode |= perm & 0777;
		if (mknod(path, nmode, makedev(major, minor)) < 0) {
			create_rerror(errno);
			goto error;
		}
	} else if (perm & Dmnamedpipe) {
		if (mknod(path, S_IFIFO | (umode&0777), 0) < 0) {
			create_rerror(errno);
			goto error;
		}
	}

	f->omode = 0;
	if (!perm&Dmsymlink && chmod(path, umode)<0) {
		create_rerror(errno);
		goto error;
	}

	free(ext);
	return 0;

error:
	free(ext);
	return -1;
}