/* this not the way to parse xml but hey */ static char *rxmltext(const char *xml, char *tag, char *def) { static char *d = NULL; char *start; char *stop; char *s; if(d) { cc_xfree(d); d = NULL; } s = rconcat("<", tag, ">"); start = strstr(xml, s); if(!start) return def; start += strlen(s); stop = strstr(start, rconcat("</", tag, ">")); if(!stop) return def; s = strndup(start, stop - start); d = cc_xstream_xml_decode(s); free(s); return d; }
unsigned char *cc_xstream_client_read_data(CcXstreamServerConnection s, size_t len, unsigned long timeout_ms) { unsigned char *buf; size_t done; CC_XSTREAM_SOCKET_FD_TYPE sock; int rv; struct timeval tv; fd_set fds; /* Convert the conenction handle to simple file descriptor. */ sock = (CC_XSTREAM_SOCKET_FD_TYPE)s; /* We terminate incoming buffer just to make code safer. Caller should not count on it anyway. */ buf = cc_xmalloc(len + 1); buf[len] = '\0'; for (done = 0; done < len; /*NOTHING*/) { if (timeout_ms > 0) { tv.tv_sec = timeout_ms / 1000U; tv.tv_usec = (timeout_ms % 1000U) * 1000U; FD_ZERO(&fds); FD_SET(sock, &fds); if (select(sock + 1, &fds, NULL, NULL, &tv) != 1) { /* Timeout or error, we don't really care. */ cc_xfree(buf); return NULL; } } rv = CC_XSTREAM_SOCKET_READ(sock, buf + done, len - done); if (rv < 1) { cc_xfree(buf); return NULL; } done += rv; } return buf; }
static int ccx_getattr(const char *path, struct stat *stbuf) { char *info; memset(stbuf, 0, sizeof(struct stat)); stbuf->st_uid = uid; stbuf->st_gid = gid; if(strcmp(path, "/") == 0) { stbuf->st_mode = S_IFDIR | 0755; stbuf->st_nlink = 3; /* . + .. + fake node */ return 0; } if(!cwd(rdirname(path))) { return -ENOENT; } if(cc_xstream_client_file_info(ccxconn, rbasename(path), &info) != CC_XSTREAM_CLIENT_OK) { return -ENOENT; } if(strcmp(rxmltext(info, "ATTRIB", ""), "file") == 0) { stbuf->st_mode = S_IFREG | 0444; stbuf->st_nlink = 1; stbuf->st_size = atoll(rxmltext(info, "SIZE", "0")); /* seams to only be sent for files */ stbuf->st_atime = atoll(rxmltext(info, "ACCESS", "0")); stbuf->st_mtime = atoll(rxmltext(info, "MODIFICATION", "0")); stbuf->st_ctime = atoll(rxmltext(info, "CHANGE", "0")); } else { stbuf->st_mode = S_IFDIR | 0755; stbuf->st_nlink = 3; /* . + .. + fake node */ stbuf->st_size = 1; stbuf->st_atime = stbuf->st_mtime = stbuf->st_ctime = now; } cc_xfree(info); return 0; }
static int ccx_access(const char *path, int mask) { char *info; if(strcmp(path, "/") == 0) return 0; if(!cwd(rdirname(path))) { return -ENOENT; } if(cc_xstream_client_file_info(ccxconn, rbasename(path), &info) != CC_XSTREAM_CLIENT_OK) { return -ENOENT; } cc_xfree(info); return 0; }
static int ccx_read(const char *path, char *buf, size_t size, off_t offset, struct fuse_file_info *fi) { ccxfile_t *cf = (ccxfile_t *)(uint32_t)fi->fh; unsigned char *data; size_t data_len = 0; if(offset > cf->offset) { if(cc_xstream_client_file_forward(ccxconn, cf->handle, offset - cf->offset, 0) != CC_XSTREAM_CLIENT_OK) { return -EINVAL; } } else if(offset < cf->offset) { if(cc_xstream_client_file_backwards(ccxconn, cf->handle, cf->offset - offset, 0) != CC_XSTREAM_CLIENT_OK) { return -EINVAL; } } else { /* equal, no seek needed */ } if(cc_xstream_client_file_read(ccxconn, cf->handle, size, &data, &data_len) != CC_XSTREAM_CLIENT_OK) { return -EINVAL; } assert(size >= data_len); memcpy(buf, data, data_len); cc_xfree(data); cf->offset = offset + data_len; return data_len; }
static int ccx_readdir(const char *path, void *buf, fuse_fill_dir_t filler, off_t offset, struct fuse_file_info *fi) { unsigned long handle; char *name, *info; if(!cwd(path)) { return -ENOENT; } if(cc_xstream_client_dir_open(ccxconn, &handle) != CC_XSTREAM_CLIENT_OK) { return -ENOTDIR; } while(1) { struct stat st; if(cc_xstream_client_dir_read(ccxconn, handle, &name, &info) != CC_XSTREAM_CLIENT_OK) { return -ENOENT; } cc_xfree(info); if(strlen(name) == 0) return 0; memset(&st, 0, sizeof(st)); if (filler(buf, name, &st, 0)) break; } cc_xstream_client_close(ccxconn, handle); return 0; }
int cc_xstream_client_write_data(CcXstreamServerConnection s, unsigned char *buf, size_t len, unsigned long timeout_ms) { size_t done; CC_XSTREAM_SOCKET_FD_TYPE sock; int rv; struct timeval tv; fd_set fds; /* Convert the conenction handle to simple file descriptor. */ sock = (CC_XSTREAM_SOCKET_FD_TYPE)s; for (done = 0; done < len; /*NOTHING*/) { if (timeout_ms > 0) { tv.tv_sec = timeout_ms / 1000U; tv.tv_usec = (timeout_ms % 1000U) * 1000U; FD_ZERO(&fds); FD_SET(sock, &fds); if (select(sock + 1, NULL, &fds, NULL, &tv) != 1) { /* Timeout or error, we don't really care. */ cc_xfree(buf); return 0; } } rv = CC_XSTREAM_SOCKET_WRITE(sock, buf + done, len - done); if (rv < 1) return 0; done += rv; } return 1; }