Пример #1
0
Spcfsys *
spc_netmount(char *address, char *uname, int dfltport)
{
	int fd, port;
	char *addr, *name, *p, *s;
	struct sockaddr_in saddr;
	struct hostent *hostinfo;

	addr = strdup(address);
	if (strncmp(addr, "tcp!", 4) == 0)
		name = addr + 4;
	else
		name = addr;

	port = dfltport;
	p = strrchr(name, '!');
	if (p) {
		*p = '\0';
		p++;
		port = strtol(p, &s, 10);
		if (*s != '\0') {
			sp_werror("invalid port format", EIO);
			goto error;
		}
	}

	fd = socket(PF_INET, SOCK_STREAM, 0);
	if (fd < 0) {
		sp_uerror(errno);
		goto error;
	}

	hostinfo = gethostbyname(name);
	if (!hostinfo) {
		sp_werror("cannot resolve name: %s", EIO, name);
		goto error;
	}

	saddr.sin_family = AF_INET;
	saddr.sin_port = htons(port);
	saddr.sin_addr = *(struct in_addr *) hostinfo->h_addr;

	if (connect(fd, (struct sockaddr *) &saddr, sizeof(saddr)) < 0) {
		sp_uerror(errno);
		goto error;
	}

	free(addr);
	return spc_mount(fd, NULL, uname, 0);

error:
	free(addr);
	return NULL;
}
Пример #2
0
int
pip_addreq(Xfilepipe* p, Spreq *req)
{
	Spfcall *rc;
	Xpipereq *r, *preq, *ppreq;

//	fprintf(stderr, "pip_addreq pip %p fid %d req %p\n", p, req->tcall->fid, req);
//	if (p->err)
//		return 0;

	r = sp_malloc(sizeof(*preq));
	if (!r) 
		return 0;

	r->pip = p;
	r->req = req;
	r->fid = req->fid;
	r->next = NULL;

	for(ppreq = NULL, preq = p->reqs; preq != NULL; ppreq = preq, preq = preq->next)
		if (preq->fid->fid > r->fid->fid)
			break;

	if (!ppreq)
		p->reqs = r;
	else
		ppreq->next = r;

	r->next = preq;
	if (p->lspfd)
		pip_notify(p->lspfd, p);
	else if (p->direction == Read) {
		if (!p->buflen) {
			rc = sp_create_rread(0, NULL);
			sp_respond(req, rc);
		} else
			pip_read_buf(p);
	} else {
		sp_uerror(EPIPE);
		return 0;
	}

	return 1;
}
Пример #3
0
Xfilepipe *
pip_create(int direction)
{
	int pip[2];
	Xfilepipe *p;

	p = sp_malloc(sizeof(*p));
	if (!p)
		return NULL;

	p->err = 0;
	p->direction = direction;
	p->bufsize = 1024;
	p->buf = sp_malloc(p->bufsize);
	if (!p->buf) {
		free(p);
		return NULL;
	}

	p->buflen = 0;
	if (pipe(pip) < 0) {
		sp_uerror(errno);
		free(p->buf);
		free(p);
		return NULL;
	}
	
	if (direction == Read) {
		p->lfd = pip[0];
		p->rfd = pip[1];
	} else {
		p->lfd = pip[1];
		p->rfd = pip[0];
	}

	fcntl(p->lfd, F_SETFD, FD_CLOEXEC);
	p->reqs = NULL;
	p->lspfd = spfd_add(p->lfd, pip_notify, p);
//	fprintf(stderr, "pip_create %p lfd %d rfd %d\n", p, p->lfd, p->rfd);

	return p;
}
Пример #4
0
int
spfd_write(Spfd *spfd, void *buf, int buflen)
{
	int n, ret;

	if (buflen)
		ret = write(spfd->fd, buf, buflen);
	else
		ret = 0;

	spfd->flags &= ~Writable;
	spfd->pfd->events |= POLLOUT;

	if (ret < 0) {
		n = errno;
		if (n != EAGAIN)
			sp_uerror(n);
	}

	return ret;
}
Пример #5
0
int
spfd_read(Spfd *spfd, void *buf, int buflen)
{
	int n, ret;

	if (buflen)
		ret = read(spfd->fd, buf, buflen);
	else
		ret = 0;

	spfd->flags &= ~Readable;
	spfd->pfd->events |= POLLIN;

	if (ret < 0) {
		n = errno;
		if (n != EAGAIN)
			sp_uerror(n);
	}

	return ret;
}
Пример #6
0
int
xp_file_create_from_file(Xpfile **xpf, Spcfsys *fs, char *name, char *path)
{
	int n;
	char *tn, *fn;
	struct stat st;
	DIR *d;
	struct dirent *de;
	Xpfile *f;

	if (stat(path, &st) < 0) {
		sp_uerror(errno);
		return -1;
	}

	f = sp_malloc(sizeof(*f));
	if (!f) 
		return -1;

	f->perm = st.st_mode & 0777;
	if (S_ISDIR(st.st_mode))
		f->perm |= Dmdir;

	if (!name) {
		name = strrchr(path, '/');
		if (name)
			name++;
		else
			name = path;
	}

	f->fs = fs;
	f->name = strdup(name);
	f->path = strdup(path);
	f->create = 1;
	f->buf = NULL;
	f->buflen = 0;
	f->bufsize = 0;
	f->next = NULL;
	f->fd = -1;
	f->fid = NULL;
	f->spcfd = NULL;
	f->pos = 0;

	if (S_ISDIR(st.st_mode)) {
		d = opendir(path);
		if (!d) {
			sp_uerror(errno);
			goto error;
		}

		while ((de = readdir(d)) != NULL) {
			if (de->d_name[0] == '.' && (de->d_name[1] == '.' || de->d_name[1] == '\0'))
				continue;

			fn = malloc(strlen(path) + strlen(de->d_name) + 2);
			tn = malloc(strlen(f->name) + strlen(de->d_name) + 2);
			if (!fn || !tn) {
				free(fn);
				free(tn);
				sp_werror(Enomem, ENOMEM);
				goto error;
			}

			sprintf(fn, "%s/%s", path, de->d_name);
			sprintf(tn, "%s/%s", f->name, de->d_name);
			n = xp_file_create_from_file(&f->next, fs, tn, fn);
			free(fn);
			free(tn);
			if (n < 0) 
				goto error;
		}
		closedir(d);
		d = NULL;
	}

	if (*xpf)
		while (*xpf != NULL)
			xpf = &(*xpf)->next;

	*xpf = f;

	return 0;

error:
	if (d)
		closedir(d);

	xp_file_destroy_all(f);
	return -1;
}
Пример #7
0
static void
xp_file_notify(Spcfd *spcfd, void *a)
{
	int n, ecode;
	char *ename;
	Xpcopy *c;
	Xpfile *f;

	c = a;
	f = c->cfile;

error:
	if (sp_haserror()) {
		sp_rerror(&ename, &ecode);
		if (c->finish)
			(*c->finish)(c, c->finishaux);

//		spcfd_remove(spcfd);
		return;
	}

	if (!spcfd_can_write(spcfd))
		return;

	if (f->pos >= f->buflen) {
		if (!f->path) 
			goto next_file;

		if (f->fd < 0) {
			f->fd = open(f->path, O_RDONLY);
			if (f->fd < 0) {
				sp_uerror(errno);
				goto error;
			}

			f->bufsize = Bufsize;
			f->buf = malloc(f->bufsize);
			if (!f->buf) {
				sp_werror(Enomem, ENOMEM);
				goto error;
			}
		}

		n = read(f->fd, f->buf, f->bufsize);
		if (n < 0) {
			sp_uerror(errno);
			goto error;
		}

		if (n == 0) {
			close(f->fd);
			f->fd = -1;
			free(f->buf);
			f->buf = NULL;
			f->buflen = 0;
			f->bufsize = 0;
			f->pos = 0;
			goto next_file;
		}

		f->buflen = n;
		f->pos = 0;
	}

	n = spcfd_write(spcfd, f->buf + f->pos, f->buflen - f->pos);
	if (n <= 0)
		goto error;

	f->pos += n;
	return;

next_file:
	spcfd_remove(f->spcfd);
	f->spcfd = NULL;
	c->cfile = f->next;
	xp_file_copy(c);
}