/** Change the size of a file */ static int fuse_truncate(const char *path, off_t size) { #ifndef HIDE_COMPLETE tolog(path); tolog(" - truncate "); { char buf[80]; sprintf(buf, "%d\n", (int) size); tolog(buf); } #endif // Fool programs into thinking they can overwite files if (g_strcmp0(path, "/" USAGE_FILE) == 0) { return 0; } if (isOffset(path) || isMetaFilename(path)) { return 0; } return -ENOENT; }
/** Create a directory * * Note that the mode argument may not have the type specification * bits set, i.e. S_ISDIR(mode) can be false. To obtain the * correct directory type bits use mode|S_IFDIR * */ static int fuse_mkdir(const char *path, mode_t dir) { #ifndef HIDE_COMPLETED tolog(path); tolog(" - mkdir\n"); #endif // Get rid of the / at the front path++; if ((g_slist_find_custom(dir_list, path, (GCompareFunc) strcmp) != NULL) || (g_slist_find_custom(link_list, path, (GCompareFunc) linkpathcmp) != NULL)) { return -EEXIST; } // Only allow directories on the first level if (strchr(path, '/') != NULL) { return -EINVAL; } if (isValidDirectoryStructure(path) != 1) { return -EINVAL; } char *p = g_strdup(path); dir_list = g_slist_prepend(dir_list, p); return 0; }
/** * Check file access permissions * * This will be called for the access() system call. If the * 'default_permissions' mount option is given, this method is not * called. * * This method is not called under Linux kernel versions 2.4.x * * Introduced in version 2.5 */ static int fuse_access(const char *path, int mask) { #ifndef HIDE_COMPLETED tolog(path); tolog(" - access\n"); #endif return 0; }
/** Change the owner and group of a file */ static int fuse_chown(const char *path, uid_t uid, gid_t gid) { #ifndef HIDE_UNTESTED tolog(path); tolog(" - chown\n"); #endif return -ENOSYS; }
/** Synchronize directory contents * * If the datasync parameter is non-zero, then only the user data * should be flushed, not the meta data * * Introduced in version 2.3 */ static int fuse_fsyncdir(const char *path, int datasync, struct fuse_file_info *info) { #ifndef HIDE_UNTESTED tolog(path); tolog(" - fsyncdir\n"); #endif return -ENOSYS; }
/** Release an open file * * Release is called when there are no more references to an open * file: all file descriptors are closed and all memory mappings * are unmapped. * * For every open() call there will be exactly one release() call * with the same flags and file descriptor. It is possible to * have a file opened more than once, in which case only the last * release will mean, that no more reads/writes will happen on the * file. The return value of release is ignored. * * Changed in version 2.2 */ static int fuse_release(const char *path, struct fuse_file_info *info) { #ifndef HIDE_COMPLETED tolog(path); tolog(" - release\n"); #endif return 0; }
/** Remove extended attributes */ static int fuse_removexattr(const char *path, const char *name) { #ifndef HIDE_UNTESTED tolog(path); tolog(" - removexattr\n"); #endif return -ENOSYS; }
/** * Create and open a file * * If the file does not exist, first create it with the specified * mode, and then open it. * * If this method is not implemented or under Linux kernel * versions earlier than 2.6.15, the mknod() and open() methods * will be called instead. * * Introduced in version 2.5 */ static int fuse_create(const char *path, mode_t mode, struct fuse_file_info *info) { #ifndef HIDE_UNTESTED tolog(path); tolog(" - create\n"); #endif return -ENOSYS; }
/** * Change the size of an open file * * This method is called instead of the truncate() method if the * truncation was invoked from an ftruncate() system call. * * If this method is not implemented or under Linux kernel * versions earlier than 2.6.15, the truncate() method will be * called instead. * * Introduced in version 2.5 */ static int fuse_ftruncate(const char *path, off_t size, struct fuse_file_info *info) { #ifndef HIDE_UNTESTED tolog(path); tolog(" - ftruncate\n"); #endif return -ENOSYS; }
/** Change the permission bits of a file */ static int fuse_chmod(const char *path, mode_t mode) { #ifndef HIDE_UNTESTED tolog(path); tolog(" - chmod\n"); #endif return -ENOSYS; }
/** * Poll for IO readiness events * * Note: If ph is non-NULL, the client should notify * when IO readiness events occur by calling * fuse_notify_poll() with the specified ph. * * Regardless of the number of times poll with a non-NULL ph * is received, single notification is enough to clear all. * Notifying more times incurs overhead but doesn't harm * correctness. * * The callee is responsible for destroying ph with * fuse_pollhandle_destroy() when no longer in use. * * Introduced in version 2.8 */ static int fuse_poll(const char *path, struct fuse_file_info *info, struct fuse_pollhandle *ph, unsigned *reventsp) { #ifndef HIDE_UNTESTED tolog(path); tolog("poll not implemented\n"); #endif return -ENOSYS; }
/** * Ioctl * * flags will have FUSE_IOCTL_COMPAT set for 32bit ioctls in * 64bit environment. The size and direction of data is * determined by _IOC_*() decoding of cmd. For _IOC_NONE, * data will be NULL, for _IOC_WRITE data is out area, for * _IOC_READ in area and if both are set in/out area. In all * non-NULL cases, the area is of _IOC_SIZE(cmd) bytes. * * Introduced in version 2.8 */ static int fuse_ioctl(const char *path, int cmd, void *arg, struct fuse_file_info *info, unsigned int flags, void *data) { #ifndef HIDE_UNTESTED tolog(path); tolog(" - ioctl\n"); #endif return -ENOSYS; }
/** List extended attributes */ static int fuse_listxattr(const char *path, char *list, size_t size) { #ifndef HIDE_UNTESTED tolog(path); tolog(" - listxattr\n"); #endif return -ENOSYS; }
/** * Map block index within file to block index within device * * Note: This makes sense only for block device backed filesystems * mounted with the 'blkdev' option * * Introduced in version 2.6 */ static int fuse_bmap(const char *path, size_t blocksize, uint64_t * idx) { #ifndef HIDE_UNTESTED tolog(path); tolog(" - bmap\n"); #endif return -ENOSYS; }
/** * Change the access and modification times of a file with * nanosecond resolution * * Introduced in version 2.6 */ static int fuse_utimens(const char *path, const struct timespec tv[2]) { #ifndef HIDE_UNTESTED tolog(path); tolog(" - utimens\n"); #endif return -ENOSYS; }
/** * Perform POSIX file locking operation * * The cmd argument will be either F_GETLK, F_SETLK or F_SETLKW. * * For the meaning of fields in 'struct flock' see the man page * for fcntl(2). The l_whence field will always be set to * SEEK_SET. * * For checking lock ownership, the 'fuse_file_info->owner' * argument must be used. * * For F_GETLK operation, the library will first check currently * held locks, and if a conflicting lock is found it will return * information without calling this method. This ensures, that * for local locks the l_pid field is correctly filled in. The * results may not be accurate in case of race conditions and in * the presence of hard links, but it's unlikly that an * application would rely on accurate GETLK results in these * cases. If a conflicting lock is not found, this method will be * called, and the filesystem may fill out l_pid by a meaningful * value, or it may leave this field zero. * * For F_SETLK and F_SETLKW the l_pid field will be set to the pid * of the process performing the locking operation. * * Note: if this method is not implemented, the kernel will still * allow file locking to work locally. Hence it is only * interesting for network filesystems and similar. * * Introduced in version 2.6 */ static int fuse_lock(const char *path, struct fuse_file_info *info, int cmd, struct flock *lock) { #ifndef HIDE_COMPLETED tolog(path); tolog(" - lock\n"); #endif return -ENOSYS; }
/** * Get attributes from an open file * * This method is called instead of the getattr() method if the * file information is available. * * Currently this is only called after the create() method if that * is implemented(see above). Later it may be called for * invocations of fstat() too. * * Introduced in version 2.5 */ static int fuse_fgetattr(const char *path, struct stat *buf, struct fuse_file_info *info) { #ifndef HIDE_COMPLETED tolog(path); tolog(" - fgetattr\n"); #endif return fuse_getattr(path, buf); }
/** Create a hard link to a file */ static int fuse_link(const char *oldpath, const char *newpath) { #ifndef HIDE_UNTESTED tolog(oldpath); tolog(" - hardlink to "); tolog(newpath); tolog("\n"); #endif return -ENOSYS; }
/** Get extended attributes */ static int fuse_getxattr(const char *path, const char *name, char *value, size_t size) { #ifndef HIDE_COMPLETED tolog(path); tolog(" - getxattr requested: "); tolog(name); tolog("\n"); #endif return -ENOSYS; }
int pid_delete(ctx * Ctx) { if ( close(Ctx->pidfd) < 0){ tolog(Ctx, LOG_ERROR, "can't close pid file %s", strerror(errno)); // perror("can't close pid file"); } size_t res = remove(Ctx->pidfile); if (res != 0) { tolog(Ctx, LOG_ERROR, "can't remove pid file %d" , strerror(errno)); } }
//parallel thread void *mech(void *vptr_args) { tolog("mech start\n"); void allmech(); while (1) { sleep(1); pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); //all mech and animal functions if (VIEW_MENU!=view) allmech(); pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); } tolog("mech finish\n"); }
/** Open directory * * Unless the 'default_permissions' mount option is given, * this method should check if opendir is permitted for this * directory. Optionally opendir may also return an arbitrary * filehandle in the fuse_file_info structure, which will be * passed to readdir, closedir and fsyncdir. * * Introduced in version 2.3 */ static int fuse_opendir(const char *path, struct fuse_file_info *info) { #ifndef HIDE_COMPLETED tolog(path); tolog(" - opendir\n"); #endif if (isDirectory(path)) { return 0; } return -ENOENT; }
/** * Clean up filesystem * * Called on filesystem exit. * * Introduced in version 2.3 */ void f_destroy(void *data) { #ifndef HIDE_COMPLETED tolog("destroy called\n"); #endif g_slist_free_full(link_list, (GDestroyNotify) linkfree); link_list = NULL; g_slist_free_full(dir_list, free); dir_list = NULL; fclose(mappedFile); mappedFile = NULL; if (flog != NULL) { struct timeval tv; gettimeofday(&tv, NULL); fprintf(flog, "===== Log finished at %ld.%06ld =====\n", tv.tv_sec, tv.tv_usec); fclose(flog); flog = NULL; } }
/** Get file system statistics * * The 'f_frsize', 'f_favail', 'f_fsid' and 'f_flag' fields are ignored * * Replaced 'struct statfs' parameter with 'struct statvfs' in * version 2.5 * * struct statvfs { * unsigned long f_bsize; // file system block size * unsigned long f_frsize; // fragment size * fsblkcnt_t f_blocks; // size of fs in f_frsize units * fsblkcnt_t f_bfree; // # free blocks * fsblkcnt_t f_bavail; // # free blocks for unprivileged users * fsfilcnt_t f_files; // # inodes * fsfilcnt_t f_ffree; // # free inodes * fsfilcnt_t f_favail; // # free inodes for unprivileged users * unsigned long f_fsid; // file system ID * unsigned long f_flag; // mount flags * unsigned long f_namemax; // maximum filename length * }; */ static int fuse_statfs(const char *path, struct statvfs *buf) { #ifndef HIDE_COMPLETED tolog(path); tolog(" - statfs\n"); #endif buf->f_bsize = 512; buf->f_blocks = (mappedFile_size + (buf->f_bsize - 1)) / buf->f_bsize; buf->f_bfree = 0; buf->f_files = mappedFile_size; buf->f_ffree = 0; buf->f_favail = 0; buf->f_namemax = 1024 * 1024; return 0; }
/** Read data from an open file * * Read should return exactly the number of bytes requested except * on EOF or error, otherwise the rest of the data will be * substituted with zeroes. An exception to this is when the * 'direct_io' mount option is specified, in which case the return * value of the read system call will reflect the return value of * this operation. * * Changed in version 2.2 */ static int fuse_read(const char *path, char *buf, size_t buf_size, off_t offset, struct fuse_file_info *info) { #ifndef HIDE_COMPLETED tolog(path); tolog(" - read\n"); #endif if (g_strcmp0(path, "/" USAGE_FILE) == 0) { size_t size = buf_size; if (size > (strlen(USAGE_FILE_CONTENT) - offset)) { size = strlen(USAGE_FILE_CONTENT) - offset; } if (size > 0) { memcpy(buf, USAGE_FILE_CONTENT + offset, size); } return size; } if (isOffset(path)) { off_t file_offset = -1; off_t file_length = -1; sscanf(path + 1, "%llu-%llu", (unsigned long long *) &file_offset, (unsigned long long *) &file_length); fseeko(mappedFile, offset + file_offset, SEEK_SET); if ((file_length == -1) || (file_length > buf_size)) { file_length = buf_size; } int ret = fread(buf, 1, file_length, mappedFile); return ret; } if (isMetaFilename(path)) { return 0; } return -ENOENT; }
/** Create a file node * * This is called for creation of all non-directory, non-symlink * nodes. If the filesystem defines a create() method, then for * regular files that will be called instead. */ static int fuse_mknod(const char *path, mode_t mode, dev_t rdev) { #ifndef HIDE_UNTESTED tolog(" - mknod\n"); #endif return -ENOSYS; }
/** File open operation * * No creation(O_CREAT, O_EXCL) and by default also no * truncation(O_TRUNC) flags will be passed to open(). If an * application specifies O_TRUNC, fuse first calls truncate() * and then open(). Only if 'atomic_o_trunc' has been * specified and kernel version is 2.6.24 or later, O_TRUNC is * passed on to open. * * Unless the 'default_permissions' mount option is given, * open should check if the operation is permitted for the * given flags. Optionally open may also return an arbitrary * filehandle in the fuse_file_info structure, which will be * passed to all file operations. * * Changed in version 2.2 * * struct fuse_file_info { * int flags; // Open flags. Available in open() and release() * unsigned long fh_old; // Old file handle, don't use * int writepage; // In case of a write operation indicates if * // this was caused by a writepage * unsigned int direct_io : 1; // Can be filled in by open, to * // use direct I/O on this file. * // Introduced in version 2.4 * unsigned int keep_cache : 1; // Can be filled in by open, to * // indicate, that cached file data * // need not be invalidated. * // Introduced in version 2.4 * unsigned int flush : 1; // Indicates a flush operation. Set * // in flush operation, also maybe set * // in highlevel lock operation and * // lowlevel release operation. * // Introduced in version 2.6 * unsigned int nonseekable : 1; // Can be filled in by open, to * // indicate that the file is not * // seekable. * // Introduced in version 2.8 * unsigned int padding : 28; // Padding. Do not use * uint64_t fh; // File handle. * // May be filled in by filesystem in open(). * // Available in all other file operations * uint64_t lock_owner; // Lock owner id. Available in locking * // operations and flush * }; */ static int fuse_open(const char *path, struct fuse_file_info *info) { #ifndef HIDE_COMPLETED tolog(path); tolog(" - open\n"); #endif if (g_strcmp0(path, "/" USAGE_FILE) == 0) { return 0; } if (isOffset(path) || isMetaFilename(path)) { return 0; } return -ENOENT; }
/** Read directory * * This supersedes the old getdir() interface. New applications * should use this. * * The filesystem may choose between two modes of operation: * * 1) The readdir implementation ignores the offset parameter, and * passes zero to the filler function's offset. The filler * function will not return '1'(unless an error happens), so the * whole directory is read in a single readdir operation. This * works just like the old getdir() method. * * 2) The readdir implementation keeps track of the offsets of the * directory entries. It uses the offset parameter and always * passes non-zero offset to the filler function. When the buffer * is full(or an error happens) the filler function will return * '1'. * * Introduced in version 2.3 */ static int fuse_readdir(const char *path, void *buf, fuse_fill_dir_t filler, off_t offset, struct fuse_file_info *info) { #ifndef HIDE_COMPLETED tolog(path); tolog(" - readdir\n"); #endif if (path[0] != '/') { return -ENOENT; } path++; filler(buf, ".", NULL, 0); filler(buf, "..", NULL, 0); if (g_slist_find_custom(dir_list, path, (GCompareFunc) strcmp) != NULL) { return 0; } filler(buf, USAGE_FILE, NULL, 0); GSList *l = dir_list; while (l != NULL) { filler(buf, l->data, NULL, 0); l = g_slist_next(l); } l = link_list; while (l != NULL) { struct link_pair *p = (struct link_pair *) l->data; filler(buf, p->path, NULL, 0); l = l->next; } return 0; }
int pid_create(ctx * Ctx) { Ctx->pidfd = open(Ctx->pidfile, O_CREAT | O_WRONLY, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH ); if (!Ctx->pidfd) { tolog(Ctx, LOG_ERROR, "can't open pid file %s", strerror(errno)); // perror("can't create pid file"); return 1; } char buf[16]; bzero(buf,16); sprintf(buf,"%ld",(long)getpid()); if (write( Ctx->pidfd,buf, strlen(buf)+1) < 1) { close(Ctx->pidfd); tolog(Ctx, LOG_ERROR, "can't write to pid file %s" , strerror(errno)); // perror("can't write to pid file"); return 1; } return 0; }
/** Write data to an open file * * Write should return exactly the number of bytes requested * except on error. An exception to this is when the 'direct_io' * mount option is specified(see read operation). * * Changed in version 2.2 */ static int fuse_write(const char *path, const char *buf, size_t size, off_t offset, struct fuse_file_info *info) { #ifndef HIDE_COMPLETE tolog(path); tolog(" - write\n"); #endif // Fool programs into thinking they can write if (g_strcmp0(path, "/" USAGE_FILE) == 0) { return size; } if (isOffset(path) || isMetaFilename(path)) { return size; } return -ENOENT; }