ssize_t npc_listxattr (Npcfid *root, char *path, char *buf, size_t size) { Npcfid *fid = NULL; Npcfid *attrfid = NULL; ssize_t ret = -1; size_t n, tot; if (!(fid = npc_walk (root, path))) goto done; if (!(attrfid = npc_fid_alloc(fid->fsys))) goto done; ret = npc_xattrwalk (fid, attrfid, NULL); if (ret < 0) goto done; if (buf == NULL || size == 0) goto done; if (ret > size) { np_uerror (ERANGE); goto done; } for (tot = 0; tot < size; ) { n = npc_read (attrfid, buf + tot, size - tot); if (n <= 0) break; tot += n; } ret = tot; done: if (fid) (void)npc_clunk (fid); if (attrfid) (void)npc_clunk (attrfid); return ret; }
char * npc_aget(Npcfid *root, char *path) { int n, len; Npcfid *fid = NULL; char *s = NULL;; int ssize = 0; if (!(fid = npc_open_bypath(root, path, O_RDONLY))) goto error; len = 0; do { if (!s) { ssize = AGET_CHUNK; s = malloc (ssize); } else if (ssize - len == 1) { ssize += AGET_CHUNK; s = realloc (s, ssize); } if (!s) { np_uerror (ENOMEM); goto error; } n = npc_read(fid, s + len, ssize - len - 1); if (n > 0) { len += n; if ((fid->fsys->flags & NPC_SHORTREAD_EOF) && (len - n < ssize - len - 1)) break; } } while (n > 0); if (n < 0) goto error; if (npc_clunk (fid) < 0) goto error; s[len] = '\0'; return s; error: if (s) free (s); if (fid) (void)npc_clunk (fid); return NULL; }
int npc_get(Npcfid *root, char *path, void *buf, u32 count) { int n, len = 0; Npcfid *fid; if (!(fid = npc_open_bypath(root, path, O_RDONLY))) return -1; while (len < count) { n = npc_read(fid, buf + len, count - len); if (n < 0) return -1; if (n == 0) break; len += n; if ((fid->fsys->flags & NPC_SHORTREAD_EOF) && (len - n < count - len)) break; } if (npc_clunk (fid) < 0) return -1; return len; }
int main(int argc, char **argv) { int sfd, i, n, off; int c, port; char *addr, *s; char *uname, *path; Npuser *user; Npcfsys *fs; Npcfid *fid; struct sockaddr_in saddr; struct hostent *hostinfo; char buf[512]; port = 564; // npc_chatty = 1; user = np_uid2user(geteuid()); if (!user) { fprintf(stderr, "cannot retrieve user %d\n", geteuid()); exit(1); } uname = user->uname; while ((c = getopt(argc, argv, "dp:")) != -1) { switch (c) { case 'd': npc_chatty = 1; break; case 'p': port = strtol(optarg, &s, 10); if (*s != '\0') usage(); break; case 'u': uname = optarg; break; default: usage(); } } if (argc - optind < 2) usage(); addr = argv[optind]; path = argv[optind+1]; sfd = socket(PF_INET, SOCK_STREAM, 0); if (sfd < 0) { perror("socket"); exit(1); } hostinfo = gethostbyname (addr); if (!hostinfo) { perror("gethostbyname"); exit(1); } saddr.sin_family = AF_INET; saddr.sin_port = htons(port); saddr.sin_addr = *(struct in_addr *) hostinfo->h_addr; if (connect(sfd, (struct sockaddr *) &saddr, sizeof(saddr)) < 0) { perror("connect"); exit(1); } fs = npc_mount(sfd, NULL, "lucho"); fid = npc_open(fs, path, Oread); if (!fid) { fprintf(stderr, "cannot open\n"); exit(1); } off = 0; while ((n = npc_read(fid, (u8*) buf, sizeof(buf), off)) > 0) { i = write(1, buf, n); if (i != n) { fprintf(stderr, "error writing\n"); exit(1); } off += n; } npc_close(fid); npc_umount(fs); exit(0); }
int npc_dirread(Npcfid *fid, Npwstat **statpp) { int i, n, m, buflen, statsz, slen, count; u8 *buf; char *sbuf; Npstat stat; Npwstat *statp; buflen = fid->fsys->msize - IOHDRSZ; buf = malloc(buflen); if (!buf) return -1; n = npc_read(fid, buf, buflen, fid->offset); if (n < 0) { free(buf); return n; } fid->offset += n; count = 0; i = 0; slen = 0; while (i < n) { statsz = np_deserialize_stat(&stat, buf + i, buflen - i, fid->fsys->dotu); if (!statsz) { np_werror("stat error", EIO); free(buf); return -1; } count++; slen += npc_wstatlen(&stat); i += statsz; } statp = malloc(slen); if (!statp) { np_werror(Ennomem, ENOMEM); free(buf); } sbuf = ((char *) statp) + count * sizeof(Npwstat); i = 0; m = 0; while (i < n) { statsz = np_deserialize_stat(&stat, buf + i, buflen - i, fid->fsys->dotu); if (!statsz) break; npc_stat2wstat(&stat, &statp[m], &sbuf); m++; i += statsz; } free(buf); *statpp = statp; return count; }