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; }
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; }
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; }
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; }
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; }
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; }
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); }