static int firefuse_readdir(const char *path, void *buf, fuse_fill_dir_t filler, off_t offset, struct fuse_file_info *fi) { LOGTRACE1("firefuse_readdir(%s)", path); if (is_cv_path(path) || is_cnc_path(path) || 0==strcmp(path, FIREREST_SYNC)) { return firerest_readdir(path, buf, filler, offset, fi); } (void) offset; (void) fi; LOGDEBUG1("firefuse_readdir(%s)", path); if (strcmp(path, "/") == 0) { filler(buf, ".", NULL, 0); filler(buf, "..", NULL, 0); filler(buf, STATUS_PATH + 1, NULL, 0); filler(buf, CONFIG_PATH + 1, NULL, 0); filler(buf, HOLES_PATH + 1, NULL, 0); filler(buf, FIRELOG_PATH + 1, NULL, 0); filler(buf, ECHO_PATH + 1, NULL, 0); filler(buf, FIRESTEP_PATH + 1, NULL, 0); filler(buf, FIREREST_CV + 1, NULL, 0); filler(buf, FIREREST_CNC + 1, NULL, 0); filler(buf, FIREREST_SYNC + 1, NULL, 0); } else { LOGERROR1("firefuse_readdir(%s) Unknown path", path); return -ENOENT; } return 0; }
static int firefuse_truncate(const char *path, off_t size) { LOGTRACE2("firefuse_truncate(%s,%ld)", path, size); if (is_cv_path(path)) { return cve_truncate(path, size); } if (is_cnc_path(path)) { return cnc_truncate(path, size); } (void) size; if (strcmp(path, "/") == 0) { // directory } else if (strcmp(path, ECHO_PATH) == 0) { // NOP } else if (strcmp(path, FIRELOG_PATH) == 0) { // NOP } else if (strcmp(path, FIRESTEP_PATH) == 0) { // NOP } else { LOGERROR1("firefuse_truncate(%s) -> ENOENT", path); return -ENOENT; } LOGDEBUG1("firefuse_truncate %s", path); return 0; }
int firefuse_write(const char *path, const char *buf, size_t bufsize, off_t offset, struct fuse_file_info *fi) { LOGTRACE1("firefuse_write(%s)", path); if (!buf) { LOGERROR1("firefuse_write %s -> null buffer", path); return EINVAL; } if (is_cv_path(path)) { return cve_write(path, buf, bufsize, offset, fi); } if (offset) { LOGERROR2("firefuse_write %s -> non-zero offset:%ld", path, (long) offset); return EINVAL; } if (is_cnc_path(path)) { return cnc_write(path, buf, bufsize, offset, fi); } if (strcmp(path, ECHO_PATH) == 0) { if (bufsize > MAX_ECHO) { sprintf(echoBuf, "firefuse_write %s -> string too long (%ld > %d bytes)", path, bufsize, MAX_ECHO); LOGERROR1("%s", echoBuf); return EINVAL; } memcpy(echoBuf, buf, bufsize); echoBuf[bufsize] = 0; LOGINFO2("firefuse_write %s -> %s", path, echoBuf); } else if (strcmp(path, FIRELOG_PATH) == 0) { switch (buf[0]) { case 'E': case 'e': case '0': firelog_level(FIRELOG_ERROR); break; case 'W': case 'w': case '1': firelog_level(FIRELOG_WARN); break; case 'I': case 'i': case '2': firelog_level(FIRELOG_INFO); break; case 'D': case 'd': case '3': firelog_level(FIRELOG_DEBUG); break; case 'T': case 't': case '4': firelog_level(FIRELOG_TRACE); break; } } else if (strcmp(path, FIRESTEP_PATH) == 0) { firestep_write(buf, bufsize); } return bufsize; }
int firefuse_open(const char *path, struct fuse_file_info *fi) { if (is_cv_path(path)) { return cve_open(path, fi); } if (is_cnc_path(path)) { return cnc_open(path, fi); } LOGDEBUG1("firefuse_open(%s)", path); int result = 0; if (strcmp(path, STATUS_PATH) == 0) // "/status" { verifyOpenR_(path, fi, &result); } else if (strcmp(path, CONFIG_PATH) == 0) // "/config.json" { verifyOpenR_(path, fi, &result); } else if (strcmp(path, HOLES_PATH) == 0) // "/holes" { verifyOpenR_(path, fi, &result); fi->fh = (uint64_t) (size_t) fopen("/var/firefuse/config.json", "r"); if (!fi->fh) { result = -ENOENT; } } else if (strcmp(path, ECHO_PATH) == 0) // "/echo" { verifyOpenRW(path, fi, &result); } else if (strcmp(path, FIRELOG_PATH) == 0) // "/firelog" { verifyOpenRW(path, fi, &result); } else if (strcmp(path, FIRESTEP_PATH) == 0) // "/firestep" { verifyOpenRW(path, fi, &result); } else { result = -ENOENT; } switch (-result) { case ENOENT: LOGERROR1("firefuse_open(%s) error ENOENT", path); break; case EACCES: LOGERROR1("firefuse_open(%s) error EACCES", path); break; default: if (fi->fh) { fi->direct_io = 1; } LOGDEBUG2("firefuse_open(%s) OK flags:%0x", path, fi->flags); break; } return result; }
int firefuse_read(const char *path, char *buf, size_t size, off_t offset, struct fuse_file_info *fi) { if (is_cv_path(path)) { int res = cve_read(path, buf, size, offset, fi); if (res > 0) { bytes_read += res; } return res; } if (is_cnc_path(path)) { int res = cnc_read(path, buf, size, offset, fi); if (res > 0) { bytes_read += res; } return res; } LOGTRACE1("firefuse_read(%s)", path); size_t sizeOut = size; size_t len; (void) fi; if (strcmp(path, STATUS_PATH) == 0) { const char *status_str = firepick_status(); sizeOut = firefuse_readBuffer(buf, status_str, size, offset, strlen(status_str)); } else if (strcmp(path, CONFIG_PATH) == 0) { sizeOut = firefuse_readBuffer(buf, pConfigJson, size, offset, strlen(pConfigJson)); } else if (strcmp(path, HOLES_PATH) == 0) { const char *holes_str = "holes"; sizeOut = firefuse_readBuffer(buf, holes_str, size, offset, strlen(holes_str)); } else if (strcmp(path, ECHO_PATH) == 0) { sizeOut = firefuse_readBuffer(buf, echoBuf, size, offset, strlen(echoBuf)); } else if (strcmp(path, FIRELOG_PATH) == 0) { char *str = "Actual log is " FIRELOG_FILE "\n"; sizeOut = firefuse_readBuffer(buf, str, size, offset, strlen(str)); } else if (strcmp(path, FIRESTEP_PATH) == 0) { const char *json = firestep_json(); sizeOut = firefuse_readBuffer(buf, json, size, offset, strlen(json)); } else { LOGERROR2("firefuse_read(%s, %ldB) ENOENT", path, size); return -ENOENT; } LOGTRACE3("firefuse_read(%s, %ldB) -> %ldB", path, size, sizeOut); bytes_read += sizeOut; return sizeOut; }
int firefuse_release(const char *path, struct fuse_file_info *fi) { if (is_cv_path(path)) { return cve_release(path, fi); } if (is_cnc_path(path)) { return cnc_release(path, fi); } LOGTRACE1("firefuse_release(%s)", path); if (strcmp(path, STATUS_PATH) == 0) { // NOP } else if (strcmp(path, CONFIG_PATH) == 0) { // NOP } else if (strcmp(path, HOLES_PATH) == 0) { firefuse_freeDataBuffer(path, fi); } else if (strcmp(path, ECHO_PATH) == 0) { // NOP } else if (strcmp(path, FIRELOG_PATH) == 0) { // NOP } else if (strcmp(path, FIRESTEP_PATH) == 0) { // NOP } return 0; }
int firefuse_getattr(const char *path, struct stat *stbuf) { if (is_cv_path(path)) { return cve_getattr(path, stbuf); } if (is_cnc_path(path)) { return cnc_getattr(path, stbuf); } int res = 0; struct stat st; memset(stbuf, 0, sizeof(struct stat)); stbuf->st_uid = getuid(); stbuf->st_gid = getgid(); stbuf->st_atime = stbuf->st_mtime = stbuf->st_ctime = time(NULL); if (strcmp(path, "/") == 0) { stbuf->st_mode = S_IFDIR | 0755; stbuf->st_nlink = 2; stbuf->st_nlink = 1; // Safe default value } else if (strcmp(path, FIREREST_SYNC) == 0) { stbuf->st_mode = S_IFDIR | 0755; stbuf->st_nlink = 2; stbuf->st_nlink = 1; // Safe default value } else if (strcmp(path, CONFIG_PATH) == 0) { stbuf->st_mode = S_IFREG | 0444; stbuf->st_nlink = 1; stbuf->st_size = strlen(pConfigJson); } else if (strcmp(path, STATUS_PATH) == 0) { const char *status_str = firepick_status(); stbuf->st_mode = S_IFREG | 0444; stbuf->st_nlink = 1; stbuf->st_size = strlen(status_str); } else if (strcmp(path, HOLES_PATH) == 0) { memcpy(&headcam_image_fstat, &headcam_image, sizeof(FuseDataBuffer)); stbuf->st_mode = S_IFREG | 0666; stbuf->st_nlink = 1; stbuf->st_size = 1; stbuf->st_size = headcam_image_fstat.length; } else if (strcmp(path, ECHO_PATH) == 0) { stbuf->st_mode = S_IFREG | 0666; stbuf->st_nlink = 1; stbuf->st_size = strlen(echoBuf); } else if (strcmp(path, FIRELOG_PATH) == 0) { stbuf->st_mode = S_IFREG | 0666; stbuf->st_nlink = 1; stbuf->st_size = 10000; } else if (strcmp(path, FIRESTEP_PATH) == 0) { stbuf->st_mode = S_IFREG | 0666; stbuf->st_nlink = 1; stbuf->st_size = strlen(firestep_json()); } else { res = -ENOENT; } if (res == -ENOENT) { LOGERROR1("firefuse_getattr(%s) ENOENT", path); } else if (res) { LOGERROR3("firefuse_getattr(%s) st_size:%ldB -> %d", path, (long) stbuf->st_size, res); } else { LOGTRACE3("firefuse_getattr(%s) st_size:%ldB -> %d OK", path, (long) stbuf->st_size, res); } return res; }