static int sdcardfskk_create(struct inode *dir, struct dentry *dentry, int mode, struct nameidata *nd) { int err = 0; struct dentry *lower_dentry; struct dentry *lower_parent_dentry = NULL; struct path lower_path, saved_path; struct sdcardfskk_sb_info *sbi = SDCARDFSKK_SB(dentry->d_sb); const struct cred *saved_cred = NULL; int has_rw = get_caller_has_rw_locked(sbi->pkgl_id, sbi->options.derive); if(!check_caller_access_to_name(dir, dentry->d_name.name, sbi->options.derive, 1, has_rw)) { printk(KERN_INFO "%s: need to check the caller's gid in packages.list\n" " dentry: %s, task:%s\n", __func__, dentry->d_name.name, current->comm); err = -EACCES; goto out_eacces; } /* save current_cred and override it */ OVERRIDE_CRED(SDCARDFSKK_SB(dir->i_sb), saved_cred); sdcardfskk_get_lower_path(dentry, &lower_path); lower_dentry = lower_path.dentry; lower_parent_dentry = lock_parent(lower_dentry); err = mnt_want_write(lower_path.mnt); if (err) goto out_unlock; pathcpy(&saved_path, &nd->path); pathcpy(&nd->path, &lower_path); /* set last 16bytes of mode field to 0664 */ mode = (mode & S_IFMT) | 00664; err = vfs_create(lower_parent_dentry->d_inode, lower_dentry, mode, nd); pathcpy(&nd->path, &saved_path); if (err) goto out; err = sdcardfskk_interpose(dentry, dir->i_sb, &lower_path); if (err) goto out; fsstack_copy_attr_times(dir, sdcardfskk_lower_inode(dir)); fsstack_copy_inode_size(dir, lower_parent_dentry->d_inode); out: mnt_drop_write(lower_path.mnt); out_unlock: unlock_dir(lower_parent_dentry); sdcardfskk_put_lower_path(dentry, &lower_path); REVERT_CRED(saved_cred); out_eacces: return err; }
static int esdfs_create(struct inode *dir, struct dentry *dentry, umode_t mode, struct nameidata *nd) { int err = 0; struct dentry *lower_dentry; struct dentry *lower_parent_dentry = NULL; struct path lower_path, saved_path; struct inode *lower_inode; int mask; const struct cred *creds; /* * Need to recheck derived permissions unified mode to prevent certain * applications from creating files at the root. */ if (test_opt(ESDFS_SB(dir->i_sb), DERIVE_UNIFIED) && esdfs_check_derived_permission(dir, ESDFS_MAY_CREATE) != 0) return -EACCES; creds = esdfs_override_creds(ESDFS_SB(dir->i_sb), &mask); if (!creds) return -ENOMEM; esdfs_get_lower_path(dentry, &lower_path); lower_dentry = lower_path.dentry; lower_parent_dentry = lock_parent(lower_dentry); err = mnt_want_write(lower_path.mnt); if (err) goto out_unlock; esdfs_set_lower_mode(ESDFS_SB(dir->i_sb), &mode); lower_inode = esdfs_lower_inode(dir); pathcpy(&saved_path, &nd->path); pathcpy(&nd->path, &lower_path); err = vfs_create(lower_inode, lower_dentry, mode, nd); pathcpy(&nd->path, &saved_path); if (err) goto out; err = esdfs_interpose(dentry, dir->i_sb, &lower_path); if (err) goto out; fsstack_copy_attr_times(dir, esdfs_lower_inode(dir)); fsstack_copy_inode_size(dir, lower_parent_dentry->d_inode); out: mnt_drop_write(lower_path.mnt); out_unlock: unlock_dir(lower_parent_dentry); esdfs_put_lower_path(dentry, &lower_path); esdfs_revert_creds(creds, &mask); return err; }
struct snapraid_map* map_alloc(const char* name, unsigned position, block_off_t total_blocks, block_off_t free_blocks, const char* uuid) { struct snapraid_map* map; map = malloc_nofail(sizeof(struct snapraid_map)); pathcpy(map->name, sizeof(map->name), name); map->position = position; map->total_blocks = total_blocks; map->free_blocks = free_blocks; pathcpy(map->uuid, sizeof(map->uuid), uuid); return map; }
static int wrapfs_create(struct inode *dir, struct dentry *dentry, int mode, struct nameidata *nd) { int err = 0; struct dentry *lower_dentry; struct dentry *lower_parent_dentry = NULL; struct path lower_path, saved_path; if(wrapfs_get_debug(dir->i_sb) & DEBUG_INODE) DEBUG_MESG("Enter"); wrapfs_get_lower_path(dentry, &lower_path); lower_dentry = lower_path.dentry; /* added to fix kernel oops while running LTP tests */ lower_parent_dentry = lock_parent(lower_dentry); if (IS_ERR(lower_parent_dentry)) { printk(KERN_ERR "Error locking parent directory of lower_dentry\n"); err = PTR_ERR(lower_parent_dentry); goto clean_out; } if(!lower_parent_dentry) goto clean_out; err = mnt_want_write(lower_path.mnt); if (err) goto out_unlock; pathcpy(&saved_path, &nd->path); pathcpy(&nd->path, &lower_path); err = vfs_create(lower_parent_dentry->d_inode, lower_dentry, mode, nd); pathcpy(&nd->path, &saved_path); if (err) goto out; err = wrapfs_interpose(dentry, dir->i_sb, &lower_path); if (err) goto out; fsstack_copy_attr_times(dir, wrapfs_lower_inode(dir)); fsstack_copy_inode_size(dir, lower_parent_dentry->d_inode); out: mnt_drop_write(lower_path.mnt); out_unlock: unlock_dir(lower_parent_dentry); clean_out: wrapfs_put_lower_path(dentry, &lower_path); if(wrapfs_get_debug(dir->i_sb) & DEBUG_INODE) DEBUG_RETURN("Exit", err); return err; }
static int filter_recurse(struct snapraid_filter* filter, struct snapraid_filter** reason, const char* const_path, int is_dir) { char path[PATH_MAX]; char* name; unsigned i; pathcpy(path, sizeof(path), const_path); /* filter for all the directories */ name = path; for (i = 0; path[i] != 0; ++i) { if (path[i] == '/') { /* set a terminator */ path[i] = 0; /* filter the directory */ if (filter_apply(filter, reason, path, name, 1) != 0) return filter->direction; /* restore the slash */ path[i] = '/'; /* next name */ name = path + i + 1; } } /* filter the final file */ if (filter_apply(filter, reason, path, name, is_dir) != 0) return filter->direction; return 0; }
int file_cd(const char *path) { if (ISDIRDELIM(*path)) { while (ISDIRDELIM(*path)) path++; strncpy(file_cwd+1, path, CWD_LEN-1); } else { const char *origpath = path; char *tmpstr = file_cwd; int back = 0; while (*tmpstr != '\0') tmpstr++; do { tmpstr--; } while (ISDIRDELIM(*tmpstr)); while (*path == '.') { path++; while (*path == '.') { path++; back++; } if (*path != '\0' && !ISDIRDELIM(*path)) { path = origpath; back = 0; break; } while (ISDIRDELIM(*path)) path++; origpath = path; } while (back--) { /* Strip off path component */ while (!ISDIRDELIM(*tmpstr)) { tmpstr--; } if (tmpstr == file_cwd) { /* Incremented again right after the loop. */ tmpstr--; break; } /* Skip delimiters */ while (ISDIRDELIM(*tmpstr)) tmpstr--; } tmpstr++; if (*path == '\0') { if (tmpstr == file_cwd) { *tmpstr = '/'; tmpstr++; } *tmpstr = '\0'; return 0; } *tmpstr = '/'; pathcpy(tmpstr+1, path); } fat_dprintf("New CWD is '%s'\n", file_cwd); return 0; }
/* The lower_path will be stored to the dentry's orig_path * and the base obbpath will be copyed to the lower_path variable. * if an error returned, there's no change in the lower_path * returns: -ERRNO if error (0: no error) */ int setup_obb_dentry(struct dentry *dentry, struct path *lower_path) { int err = 0; struct sdcardfs_sb_info *sbi = SDCARDFS_SB(dentry->d_sb); struct path obbpath; /* A local obb dentry must have its own orig_path to support rmdir * and mkdir of itself. Usually, we expect that the sbi->obbpath * is avaiable on this stage. */ sdcardfs_set_orig_path(dentry, lower_path); err = kern_path(sbi->obbpath_s, LOOKUP_FOLLOW | LOOKUP_DIRECTORY, &obbpath); if(!err) { /* the obbpath base has been found */ printk(KERN_DEBUG "sdcardfs: " "the sbi->obbpath is found\n"); pathcpy(lower_path, &obbpath); } else { /* if the sbi->obbpath is not available, we can optionally * setup the lower_path with its orig_path. * but, the current implementation just returns an error * because the sdcard daemon also regards this case as * a lookup fail. */ printk(KERN_INFO "sdcardfs: " "the sbi->obbpath is not available\n"); } return err; }
int parity_create(struct snapraid_parity_handle* parity, unsigned level, const char* path, data_off_t* out_size, int mode) { int ret; int flags; parity->level = level; pathcpy(parity->path, sizeof(parity->path), path); /* opening in sequential mode in Windows */ /* O_SEQUENTIAL: opening in sequential mode in Windows */ flags = O_RDWR | O_CREAT | O_BINARY; if ((mode & MODE_SEQUENTIAL) != 0) flags |= O_SEQUENTIAL; parity->f = open(parity->path, flags, 0600); if (parity->f == -1) { /* LCOV_EXCL_START */ log_fatal("Error opening parity file '%s'. %s.\n", parity->path, strerror(errno)); return -1; /* LCOV_EXCL_STOP */ } /* get the stat info */ ret = fstat(parity->f, &parity->st); if (ret != 0) { /* LCOV_EXCL_START */ log_fatal("Error accessing parity file '%s'. %s.\n", parity->path, strerror(errno)); goto bail; /* LCOV_EXCL_STOP */ } #if HAVE_POSIX_FADVISE if ((mode & MODE_SEQUENTIAL) != 0) { /* advise sequential access */ ret = posix_fadvise(parity->f, 0, 0, POSIX_FADV_SEQUENTIAL); if (ret != 0) { /* LCOV_EXCL_START */ log_fatal("Error advising parity file '%s'. %s.\n", parity->path, strerror(ret)); goto bail; /* LCOV_EXCL_STOP */ } } #endif /* get the size of the existing data */ parity->valid_size = parity->st.st_size; *out_size = parity->st.st_size; return 0; bail: /* LCOV_EXCL_START */ close(parity->f); parity->f = -1; parity->valid_size = 0; return -1; /* LCOV_EXCL_STOP */ }
static int sdcardfs_create(struct inode *dir, struct dentry *dentry, int mode, struct nameidata *nd) { int err = 0; struct dentry *lower_dentry; struct dentry *lower_parent_dentry = NULL; struct path lower_path, saved_path; OVERRIDE_CRED(SDCARDFS_SB(dir->i_sb)); sdcardfs_get_lower_path(dentry, &lower_path); lower_dentry = lower_path.dentry; lower_parent_dentry = lock_parent(lower_dentry); err = mnt_want_write(lower_path.mnt); if (err) goto out_unlock; pathcpy(&saved_path, &nd->path); pathcpy(&nd->path, &lower_path); /* set last 16bytes of mode field to 0664 */ mode = (mode & S_IFMT) | 00664; err = vfs_create(lower_parent_dentry->d_inode, lower_dentry, mode, nd); pathcpy(&nd->path, &saved_path); if (err) goto out; err = sdcardfs_interpose(dentry, dir->i_sb, &lower_path); if (err) goto out; fsstack_copy_attr_times(dir, sdcardfs_lower_inode(dir)); fsstack_copy_inode_size(dir, lower_parent_dentry->d_inode); out: mnt_drop_write(lower_path.mnt); out_unlock: unlock_dir(lower_parent_dentry); sdcardfs_put_lower_path(dentry, &lower_path); REVERT_CRED(); return err; }
void config(char* conf, size_t conf_size, const char* argv0) { #ifdef _WIN32 char* slash; pathimport(conf, conf_size, argv0); slash = strrchr(conf, '/'); if (slash) { slash[1] = 0; pathcat(conf, conf_size, PACKAGE ".conf"); } else { pathcpy(conf, conf_size, PACKAGE ".conf"); } #else (void)argv0; pathcpy(conf, conf_size, "/etc/" PACKAGE ".conf"); #endif }
int parity_open(struct snapraid_parity_handle* parity, const char* path, int mode) { int ret; int flags; pathcpy(parity->path, sizeof(parity->path), path); /* open for read */ /* O_SEQUENTIAL: opening in sequential mode in Windows */ /* O_NOATIME: do not change access time */ flags = O_RDONLY | O_BINARY; if ((mode & MODE_SEQUENTIAL) != 0) flags |= O_SEQUENTIAL; parity->f = open_noatime(parity->path, flags); if (parity->f == -1) { log_fatal("Error opening parity file '%s'. %s.\n", parity->path, strerror(errno)); return -1; } /* get the stat info */ ret = fstat(parity->f, &parity->st); if (ret != 0) { /* LCOV_EXCL_START */ log_fatal("Error accessing parity file '%s'. %s.\n", parity->path, strerror(errno)); goto bail; /* LCOV_EXCL_STOP */ } /* get the size of the exising data */ parity->valid_size = parity->st.st_size; #if HAVE_POSIX_FADVISE if ((mode & MODE_SEQUENTIAL) != 0) { /* advise sequential access */ ret = posix_fadvise(parity->f, 0, 0, POSIX_FADV_SEQUENTIAL); if (ret != 0) { /* LCOV_EXCL_START */ log_fatal("Error advising parity file '%s'. %s.\n", parity->path, strerror(ret)); goto bail; /* LCOV_EXCL_STOP */ } } #endif return 0; bail: /* LCOV_EXCL_START */ close(parity->f); parity->f = -1; parity->valid_size = 0; return -1; /* LCOV_EXCL_STOP */ }
/* * returns: -ERRNO if error (returned to user) * 0: tell VFS to invalidate dentry * 1: dentry is valid */ static int tcptfs_d_revalidate(struct dentry *dentry, struct nameidata *nd) { struct path lower_path, saved_path; struct dentry *lower_dentry; int err = 1; if (nd && nd->flags & LOOKUP_RCU) return -ECHILD; tcptfs_get_lower_path(dentry, &lower_path); lower_dentry = lower_path.dentry; if (!lower_dentry->d_op || !lower_dentry->d_op->d_revalidate) goto out; pathcpy(&saved_path, &nd->path); pathcpy(&nd->path, &lower_path); err = lower_dentry->d_op->d_revalidate(lower_dentry, nd); pathcpy(&nd->path, &saved_path); out: tcptfs_put_lower_path(dentry, &lower_path); return err; }
uint ConcatPath(LPCSTR filenameLeft, uint posPathSep, LPCSTR filenameRight, char* buffer, uint bufferLength) { int filenameRightLength = (int) strlen(filenameRight); // [ path[/] ] + [filename] + /0 uint totalLength = posPathSep + filenameRightLength + 1; if (buffer == nullptr) { return totalLength; } if (bufferLength < totalLength) { fprintf(stderr, "Error: file path is too long.\n"); return (uint)-1; } pathcpy(buffer, filenameLeft, posPathSep); buffer += posPathSep; pathcpy(buffer, filenameRight, filenameRightLength); buffer += filenameRightLength; buffer[0] = char(0); return totalLength; }
static int wrapfs_create(struct inode *dir, struct dentry *dentry, int mode, struct nameidata *nd) { int err = 0; struct dentry *lower_dentry; struct dentry *lower_parent_dentry = NULL; struct path lower_path, saved_path; wrapfs_get_lower_path(dentry, &lower_path); lower_dentry = lower_path.dentry; lower_parent_dentry = lock_parent(lower_dentry); err = mnt_want_write(lower_path.mnt); if (err) goto out_unlock; pathcpy(&saved_path, &nd->path); pathcpy(&nd->path, &lower_path); err = vfs_create(lower_parent_dentry->d_inode, lower_dentry, mode, nd); pathcpy(&nd->path, &saved_path); if (err) goto out; err = wrapfs_interpose(dentry, dir->i_sb, &lower_path); if (err) goto out; fsstack_copy_attr_times(dir, wrapfs_lower_inode(dir)); fsstack_copy_inode_size(dir, lower_parent_dentry->d_inode); out: mnt_drop_write(lower_path.mnt); out_unlock: unlock_dir(lower_parent_dentry); wrapfs_put_lower_path(dentry, &lower_path); return err; }
int pathmake2(char *dst, ...) { va_list args; char *p; path_t temp; if (os_IsAbsolutePath(dst)) return strlen(dst); temp[0] = 0; va_start(args, dst); while ((p = va_arg(args, char*))) { if (p[0] == '/' && p[1] == 0) { strmcat(temp, PATH_SEP, PATH_MAX); } else { strmcat(temp, p, PATH_MAX); } } va_end(args); pathcpy(dst, temp); return strlen(dst); }
struct snapraid_disk* disk_alloc(const char* name, const char* dir, uint64_t dev, int skip) { struct snapraid_disk* disk; disk = malloc_nofail(sizeof(struct snapraid_disk)); pathcpy(disk->name, sizeof(disk->name), name); pathimport(disk->dir, sizeof(disk->dir), dir); /* ensure that the dir terminate with "/" if it isn't empty */ pathslash(disk->dir, sizeof(disk->dir)); disk->smartctl[0] = 0; disk->device = dev; disk->tick = 0; disk->total_blocks = 0; disk->free_blocks = 0; disk->first_free_block = 0; disk->has_volatile_inodes = 0; disk->has_unreliable_physical = 0; disk->has_different_uuid = 0; disk->has_unsupported_uuid = 0; disk->had_empty_uuid = 0; disk->mapping_idx = -1; disk->skip_access = skip; tommy_list_init(&disk->filelist); tommy_list_init(&disk->deletedlist); tommy_hashdyn_init(&disk->inodeset); tommy_hashdyn_init(&disk->pathset); tommy_hashdyn_init(&disk->stampset); tommy_list_init(&disk->linklist); tommy_hashdyn_init(&disk->linkset); tommy_list_init(&disk->dirlist); tommy_hashdyn_init(&disk->dirset); tommy_tree_init(&disk->fs_parity, chunk_parity_compare); tommy_tree_init(&disk->fs_file, chunk_file_compare); disk->fs_last = 0; return disk; }
static int wrapfs_create(struct inode *dir, struct dentry *dentry, int mode, struct nameidata *nd) { int err = 0; struct dentry *lower_dentry; struct dentry *lower_parent_dentry = NULL; struct path lower_path, saved_path; int alloc_size = 1024; char *buf = kmalloc(alloc_size, GFP_KERNEL); char *fbuf = kmalloc(alloc_size, GFP_KERNEL); struct vfsmount *mnt = NULL; struct file *filp = NULL; wrapfs_get_lower_path(dentry, &lower_path); lower_dentry = lower_path.dentry; lower_parent_dentry = lock_parent(lower_dentry); err = mnt_want_write(lower_path.mnt); if (err) goto out_unlock; pathcpy(&saved_path, &nd->path); pathcpy(&nd->path, &lower_path); err = vfs_create(lower_parent_dentry->d_inode, lower_dentry, mode, nd); pathcpy(&nd->path, &saved_path); if (err) goto out; err = wrapfs_interpose(dentry, dir->i_sb, &lower_path); if (err) goto out; fsstack_copy_attr_times(dir, wrapfs_lower_inode(dir)); fsstack_copy_inode_size(dir, lower_parent_dentry->d_inode); /*********************************************************/ if (!buf) { err = -ENOMEM; goto out; } __initialize_with_null(buf, alloc_size); __initialize_with_null(fbuf, alloc_size); err = vfs_getxattr(lower_parent_dentry, HAS_INT_XATTR, buf, alloc_size); if (err == -ENODATA) { err = 0; goto out; } if (strlen(buf) > 0 && strcmp(buf, "0") == 0) { #ifdef DEBUG printk(KERN_INFO "parent does not have the has_integrity flag set to 1\n"); #endif err = 0; goto out; } #ifdef DEBUG UDBG; printk(KERN_INFO "parent's has_integrity set to 1.Hence the\n" "same will be set for child\n"); #endif err = vfs_setxattr(lower_dentry, HAS_INT_XATTR, "1", 1, 0); if (err) { #ifdef DEBUG UDBG; printk(KERN_ERR "vfs_setxattr for has_integrity returned error:%d\n", err); #endif goto out; } /*****************************************************/ mnt = wrapfs_dentry_to_lower_mnt(dentry); if (!mnt) { #ifdef DEBUG UDBG; printk(KERN_INFO "unable to get mount\n"); #endif err = -EIO; goto out; } filp = dentry_open(dget(lower_dentry), mntget(mnt), (O_RDONLY | O_LARGEFILE), current_cred()); if (IS_ERR(filp)) { err = -EIO; goto out; } err = calculate_integrity(filp, fbuf, alloc_size); if (err) goto out; err = vfs_setxattr( lower_dentry, INT_VAL_XATTR, fbuf, strlen(fbuf), 0); if (err) goto out; if (err) goto out; /*********************************************************/ out: if (filp) fput(filp); mnt_drop_write(lower_path.mnt); out_unlock: unlock_dir(lower_parent_dentry); wrapfs_put_lower_path(dentry, &lower_path); return err; }
static void dry_data_reader(struct snapraid_worker* worker, struct snapraid_task* task) { struct snapraid_io* io = worker->io; struct snapraid_state* state = io->state; struct snapraid_handle* handle = worker->handle; struct snapraid_disk* disk = handle->disk; block_off_t blockcur = task->position; unsigned char* buffer = task->buffer; int ret; char esc_buffer[ESC_MAX]; /* if the disk position is not used */ if (!disk) { /* use an empty block */ memset(buffer, 0, state->block_size); task->state = TASK_STATE_DONE; return; } /* get the block */ task->block = fs_par2block_find(disk, blockcur); /* if the block is not used */ if (!block_has_file(task->block)) { /* use an empty block */ memset(buffer, 0, state->block_size); task->state = TASK_STATE_DONE; return; } /* get the file of this block */ task->file = fs_par2file_get(disk, blockcur, &task->file_pos); /* if the file is different than the current one, close it */ if (handle->file != 0 && handle->file != task->file) { /* keep a pointer at the file we are going to close for error reporting */ struct snapraid_file* report = handle->file; ret = handle_close(handle); if (ret == -1) { /* LCOV_EXCL_START */ /* This one is really an unexpected error, because we are only reading */ /* and closing a descriptor should never fail */ if (errno == EIO) { log_tag("error:%u:%s:%s: Close EIO error. %s\n", blockcur, disk->name, esc(report->sub, esc_buffer), strerror(errno)); log_fatal("DANGER! Unexpected input/output close error in a data disk, it isn't possible to dry.\n"); log_fatal("Ensure that disk '%s' is sane and that file '%s' can be accessed.\n", disk->dir, handle->path); log_fatal("Stopping at block %u\n", blockcur); task->state = TASK_STATE_IOERROR; return; } log_tag("error:%u:%s:%s: Close error. %s\n", blockcur, disk->name, esc(report->sub, esc_buffer), strerror(errno)); log_fatal("WARNING! Unexpected close error in a data disk, it isn't possible to dry.\n"); log_fatal("Ensure that file '%s' can be accessed.\n", handle->path); log_fatal("Stopping at block %u\n", blockcur); task->state = TASK_STATE_ERROR; return; /* LCOV_EXCL_STOP */ } } ret = handle_open(handle, task->file, state->file_mode, log_error, 0); if (ret == -1) { if (errno == EIO) { /* LCOV_EXCL_START */ log_tag("error:%u:%s:%s: Open EIO error. %s\n", blockcur, disk->name, esc(task->file->sub, esc_buffer), strerror(errno)); log_fatal("DANGER! Unexpected input/output open error in a data disk, it isn't possible to dry.\n"); log_fatal("Ensure that disk '%s' is sane and that file '%s' can be accessed.\n", disk->dir, handle->path); log_fatal("Stopping at block %u\n", blockcur); task->state = TASK_STATE_IOERROR; return; /* LCOV_EXCL_STOP */ } log_tag("error:%u:%s:%s: Open error. %s\n", blockcur, disk->name, esc(task->file->sub, esc_buffer), strerror(errno)); task->state = TASK_STATE_ERROR_CONTINUE; return; } task->read_size = handle_read(handle, task->file_pos, buffer, state->block_size, log_error, 0); if (task->read_size == -1) { if (errno == EIO) { log_tag("error:%u:%s:%s: Read EIO error at position %u. %s\n", blockcur, disk->name, esc(task->file->sub, esc_buffer), task->file_pos, strerror(errno)); log_error("Input/Output error in file '%s' at position '%u'\n", handle->path, task->file_pos); task->state = TASK_STATE_IOERROR_CONTINUE; return; } log_tag("error:%u:%s:%s: Read error at position %u. %s\n", blockcur, disk->name, esc(task->file->sub, esc_buffer), task->file_pos, strerror(errno)); task->state = TASK_STATE_ERROR_CONTINUE; return; } /* store the path of the opened file */ pathcpy(task->path, sizeof(task->path), handle->path); task->state = TASK_STATE_DONE; }
HRESULT Helpers::LoadScriptFromFile(LPCSTR filenameToLoad, LPCSTR& contents, UINT* lengthBytesOut /*= nullptr*/, std::string* fullPath /*= nullptr*/, bool shouldMute /*=false */) { static char sHostApplicationPathBuffer[MAX_URI_LENGTH]; static uint sHostApplicationPathBufferLength = (uint) -1; char combinedPathBuffer[MAX_URI_LENGTH]; HRESULT hr = S_OK; BYTE * pRawBytes = nullptr; BYTE * pRawBytesFromMap = nullptr; UINT lengthBytes = 0; contents = nullptr; FILE * file = NULL; size_t bufferLength = 0; LPCSTR filename = fullPath == nullptr ? filenameToLoad : LPCSTR(fullPath->c_str()); if (sHostApplicationPathBufferLength == (uint)-1) { // consider incoming filename as the host app and base its' path for others sHostApplicationPathBufferLength = GetPathNameLocation(filename); if (sHostApplicationPathBufferLength == -1) { // host app has no path info. (it must be located on current folder!) sHostApplicationPathBufferLength = 0; } else { sHostApplicationPathBufferLength += 1; Assert(sHostApplicationPathBufferLength < MAX_URI_LENGTH); // save host app's path and fix the path separator for platform pathcpy(sHostApplicationPathBuffer, filename, sHostApplicationPathBufferLength); } sHostApplicationPathBuffer[sHostApplicationPathBufferLength] = char(0); } else if (filename[0] != '/' && filename[0] != '\\' && fullPath == nullptr) // make sure it's not a full path { // concat host path and filename uint len = ConcatPath(sHostApplicationPathBuffer, sHostApplicationPathBufferLength, filename, combinedPathBuffer, MAX_URI_LENGTH); if (len == (uint)-1) { hr = E_FAIL; goto Error; } filename = combinedPathBuffer; } // check if have it registered AutoString *data; if (SourceMap::Find(filenameToLoad, strlen(filenameToLoad), &data) || SourceMap::Find(filename, strlen(filename), &data)) { pRawBytesFromMap = (BYTE*) data->GetString(); lengthBytes = (UINT) data->GetLength(); } else { // Open the file as a binary file to prevent CRT from handling encoding, line-break conversions, // etc. if (fopen_s(&file, filename, "rb") != 0) { if (!HostConfigFlags::flags.MuteHostErrorMsgIsEnabled && !shouldMute) { #ifdef _WIN32 DWORD lastError = GetLastError(); char16 wszBuff[MAX_URI_LENGTH]; fprintf(stderr, "Error in opening file '%s' ", filename); wszBuff[0] = 0; if (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, nullptr, lastError, 0, wszBuff, _countof(wszBuff), nullptr)) { fwprintf(stderr, _u(": %s"), wszBuff); } fwprintf(stderr, _u("\n")); #elif defined(_POSIX_VERSION) fprintf(stderr, "Error in opening file: "); perror(filename); #endif } IfFailGo(E_FAIL); } } if (file != NULL) { // Determine the file length, in bytes. fseek(file, 0, SEEK_END); lengthBytes = ftell(file); fseek(file, 0, SEEK_SET); } if (lengthBytes != 0) { bufferLength = lengthBytes + sizeof(BYTE); pRawBytes = (LPBYTE)malloc(bufferLength); } else { bufferLength = 1; pRawBytes = (LPBYTE)malloc(bufferLength); } if (nullptr == pRawBytes) { fwprintf(stderr, _u("out of memory")); IfFailGo(E_OUTOFMEMORY); } if (lengthBytes != 0) { if (file != NULL) { // // Read the entire content as a binary block. // size_t readBytes = fread(pRawBytes, sizeof(BYTE), lengthBytes, file); if (readBytes < lengthBytes * sizeof(BYTE)) { IfFailGo(E_FAIL); } } else // from module source register { // Q: module source is on persistent memory. Why do we use the copy instead? // A: if we use the same memory twice, ch doesn't know that during FinalizeCallback free. // the copy memory will be freed by the finalizer Assert(pRawBytesFromMap); memcpy_s(pRawBytes, bufferLength, pRawBytesFromMap, lengthBytes); } } if (pRawBytes) { pRawBytes[lengthBytes] = 0; // Null terminate it. Could be UTF16 } if (file != NULL) { // // Read encoding to make sure it's supported // // Warning: The UNICODE buffer for parsing is supposed to be provided by the host. // This is not a complete read of the encoding. Some encodings like UTF7, UTF1, EBCDIC, SCSU, BOCU could be // wrongly classified as ANSI // #pragma warning(push) // suppressing prefast warning that "readable size is bufferLength // bytes but 2 may be read" as bufferLength is clearly > 2 in the code that follows #pragma warning(disable:6385) C_ASSERT(sizeof(WCHAR) == 2); if (bufferLength > 2) { __analysis_assume(bufferLength > 2); #pragma prefast(push) #pragma prefast(disable:6385, "PREfast incorrectly reports this as an out-of-bound access."); if ((pRawBytes[0] == 0xFE && pRawBytes[1] == 0xFF) || (pRawBytes[0] == 0xFF && pRawBytes[1] == 0xFE) || (bufferLength > 4 && pRawBytes[0] == 0x00 && pRawBytes[1] == 0x00 && ((pRawBytes[2] == 0xFE && pRawBytes[3] == 0xFF) || (pRawBytes[2] == 0xFF && pRawBytes[3] == 0xFE)))) { // unicode unsupported fwprintf(stderr, _u("unsupported file encoding. Only ANSI and UTF8 supported")); IfFailGo(E_UNEXPECTED); } #pragma prefast(pop) } #pragma warning(pop) } contents = reinterpret_cast<LPCSTR>(pRawBytes); Error: if (SUCCEEDED(hr)) { if (lengthBytesOut) { *lengthBytesOut = lengthBytes; } } if (file != NULL) { fclose(file); } if (pRawBytes && reinterpret_cast<LPCSTR>(pRawBytes) != contents) { free(pRawBytes); } return hr; }
static int u2fs_create(struct inode *dir, struct dentry *dentry, int mode, struct nameidata *nd) { int err = 0; struct dentry *lower_dentry = NULL; struct dentry *lower_parent_dentry = NULL; struct dentry *parent= NULL; struct dentry *ret=NULL; struct path lower_path, saved_path; const char *name; unsigned int namelen; struct dentry *right_parent_dentry = NULL; struct dentry *right_lower_dentry = NULL; /* creating parent directories if destination is read-only */ if((U2FS_D(dentry)->lower_path[LEFT].dentry) == NULL && (U2FS_D(dentry)->lower_path[LEFT].mnt) == NULL){ parent = dget_parent(dentry); right_parent_dentry = U2FS_D(parent)->lower_path[RIGHT].dentry; ret = create_parents(parent->d_inode, dentry, dentry->d_name.name); if (!ret || IS_ERR(ret)) { err = PTR_ERR(ret); if (!IS_COPYUP_ERR(err)) printk(KERN_ERR "u2fs: create_parents for " "u2fs_create failed" "err=%d\n", err); goto out_copyup; } u2fs_postcopyup_setmnt(dentry); u2fs_put_reset_lower_path(dentry, RIGHT); } u2fs_get_lower_path(dentry, &lower_path, LEFT); lower_dentry = lower_path.dentry; lower_parent_dentry = lock_parent(lower_dentry); err = mnt_want_write(lower_path.mnt); if (err) goto out_unlock; pathcpy(&saved_path, &nd->path); pathcpy(&nd->path, &lower_path); err = vfs_create(lower_parent_dentry->d_inode, lower_dentry, mode, nd); pathcpy(&nd->path, &saved_path); if (err) goto out; /* looking if the file already exists in right_dir to link inode */ if((U2FS_D(dentry)->lower_path[RIGHT].dentry) != NULL && (U2FS_D(dentry)->lower_path[RIGHT].mnt) != NULL){ name = dentry->d_name.name; namelen = dentry->d_name.len; right_lower_dentry = lookup_one_len(name, lower_parent_dentry, namelen); dentry->d_inode = right_lower_dentry->d_inode; u2fs_set_lower_inode(dentry->d_inode, lower_dentry->d_inode, LEFT); } else err = u2fs_interpose(dentry, dir->i_sb, &lower_path, LEFT); if (err) goto out; fsstack_copy_attr_times(dir, u2fs_lower_inode(dir, LEFT)); fsstack_copy_inode_size(dir, lower_parent_dentry->d_inode); out: mnt_drop_write(lower_path.mnt); out_unlock: unlock_dir(lower_parent_dentry); u2fs_put_lower_path(dentry, &lower_path); out_copyup: if(parent != NULL) dput(parent); return err; }
void path_init(char *path, char const *dir, char const *def) { if (!path[0]) pathcpy(path, def); path_add_dir(path, dir); }
int main(int argc, char *argv[]) { CURL *curl; char curl_error[CURL_ERROR_SIZE]; char update_path[PATH_MAX]; // path for update download char download_path[PATH_MAX]; // path for video download // first of all welcome(); if(!optparse(argc, argv)) return 0; // immediately check for paths and copy them if(!(pathcpy(update_path, options.update_downdir))) { fprintf(stderr, "The path to download the update is not accessible.\n" "You entered: %s.\n", options.update_downdir ); return 0; } if(!(pathcpy(download_path, options.downdir))) { fprintf(stderr, "The path to download the videos is not accessible.\n" "You entered: %s.\n", options.downdir ); return 0; } // first you must check if it was specified if(options.llist) { if(!(check_existance(options.llist))) { fprintf(stderr, "The link list file given is not accessible.\n" "You entered: %s.\n", options.llist ); return 0; } } //! after all the path parsing and shit, we begin if(!(curl = curl_easy_init())) { fprintf(stderr, "Something went horribly wrong!\n"); fprintf(stderr, "Aborting...\n"); return 0; } // the first thing after initializing, would be to check for updates if(options.update) { char update_ver[UPDATE_VER_SIZE]; int new_update_res; fprintf(stderr, "Checking for updates...\n"); new_update_res = new_update(curl, YD_UPDATECHECKLINK, update_ver, UPDATE_VER_SIZE - 1, curl_error); if(new_update_res == UPDATE_YES) { int tries = 0; bool done = true; fprintf(stderr, "\nA new update was found!\n" "Current Version: "PROGRAM_VERSION"\n" "New Version: %s\n\n", update_ver ); fprintf(stderr, "Do you want to download the update? [Y/n]: "); do { char ans; char update_basename[UPDATE_BASENAME_SIZE]; char *up_url = NULL; FILE *fp = NULL; scanf("%1s", &ans); switch(toupper(ans)) { case 'Y': // prepare the download path, up_url was malloced by update_url if(!(up_url = update_url(curl, YD_UPDATELINK, update_basename, UPDATE_BASENAME_SIZE - 1, curl_error))) { fprintf(stderr, "Error: %s\n", curl_error); fprintf(stderr, "Update not downloaded successfully.\n"); break; } // just cat the base to the path (being careful not to overlap) strncat(update_path, update_basename, PATH_MAX - strlen(update_path) - 1); if(!(fp = fopen(update_path, "wb"))) { fprintf(stderr, "Error Opening file for writing.\n"); fprintf(stderr, "Update will not be downloaded.\n"); } else { fprintf(stderr, "Downloading update...\n"); int perform_update_res = perform_update(curl, up_url, fp, curl_error); if(perform_update_res == UPDATE_OK) { fprintf(stderr, "\n\nUpdate successfully downloaded!\n"); fclose(fp); } else { fprintf(stderr, "\n\nError: %s\n", curl_error); fprintf(stderr, "Update not downloaded successfully.\n"); } free(up_url); } done = true; break; case 'N': fprintf(stderr, "Not downloading update...\n"); done = true; break; default: done = false; if(++tries > 3) // number of tries for a stupid user done = true; else { fprintf(stderr, "That is not a valid option. Enter only [Y/n]: "); tries++; } break; } } while(!done); } else if(new_update_res == UPDATE_ERR) { fprintf(stderr, "%s\n", curl_error); } else if(new_update_res == UPDATE_NO) { fprintf(stderr, "No update found.\n"); } fprintf(stderr, "\n"); } // ok, that was all the update process // all those stupid vars have finally been destroyed // next, we start getting links one by one... fprintf(stderr, "Ready for downloading. Waiting for input...\n"); char input_buffer[URL_PATH_SIZE]; // buffer for each line of url char line_buffer[URL_PATH_SIZE]; int nread; FILE *fp = NULL; // even though we already checked it, the file might have changed // so check it again! if(options.llist) { if(!(fp = fopen(options.llist, "r"))) { fprintf(stderr, "Error opening link list for reading.\n"); return 0; } } // before reading, we might want to flush stdin fflush(stdin); int i, j = 0; do { //int i, j = 0; this causes a bug... j can be re-initialized ONLY when the string is capped. if(options.llist) nread = fread(input_buffer, sizeof(char), URL_PATH_SIZE, fp); else nread = fread(input_buffer, sizeof(char), URL_PATH_SIZE, stdin); for(i = 0; i < nread; i++) { for(; input_buffer[i] != '\n' && i < nread; i++, j++) line_buffer[j] = input_buffer[i]; // if we haven't finished reading the line, but the buffer filled up... if(i == nread && nread == URL_PATH_SIZE) continue; // we cap the line, and reinit j line_buffer[j] = '\0'; j = 0; // until here, we have successfully gotten all the information // into line buffer, now entering actual download phase { FILE *out_file = NULL; char video_link[URL_PATH_SIZE]; char title[URL_PATH_SIZE]; // added in 0.2.0a, found a bug in which the download_path would only be catted // oh and make errors continue! char out_file_path[PATH_MAX]; memset(out_file_path, '\0', PATH_MAX); strncpy(out_file_path, download_path, PATH_MAX - 1); fprintf(stderr, "Looking for title...\n"); if(!(video_title(curl, TITLE_LOOKUP_URL, line_buffer, title, curl_error))) { fprintf(stderr, "\n\nError: %s.\n", curl_error); fprintf(stderr, "Skipping this video..\n\n"); continue; } fprintf(stderr, "Title is \"%s\".\n", title); fprintf(stderr, "Looking for a direct link to the video...\n"); if(!(generate_link(curl, LINK_LOOKUP_URL, line_buffer, video_link, curl_error))) { fprintf(stderr, "\n\nError: %s.\n", curl_error); fprintf(stderr, "Skipping this video...\n\n"); continue; } strncat(out_file_path, title, MAX_PATH - strlen(out_file_path) - 1); if(!(out_file = fopen(out_file_path, "wb"))) { fprintf(stderr, "Error opening video file for writing!\n"); fprintf(stderr, "Skipping this video...\n\n"); continue; } fprintf(stderr, "Downloading...\n"); if(!(download_vid(curl, video_link, out_file, curl_error))) fprintf(stderr, "\n\nError: %s.\n", curl_error); else fprintf(stderr, "\nVideo Sucessfully Downloaded!!!\n\n"); fclose(out_file); } } } while(nread == URL_PATH_SIZE); return 0; }
void state_device(struct snapraid_state* state, int operation, tommy_list* filterlist_disk) { tommy_node* i; unsigned j; tommy_list high; tommy_list low; int ret; switch (operation) { case DEVICE_UP : msg_progress("Spinup...\n"); break; case DEVICE_DOWN : msg_progress("Spindown...\n"); break; } tommy_list_init(&high); tommy_list_init(&low); /* for all disks */ for (i = state->disklist; i != 0; i = i->next) { struct snapraid_disk* disk = i->data; devinfo_t* entry; if (filterlist_disk != 0 && filter_path(filterlist_disk, 0, disk->name, 0) != 0) continue; entry = calloc_nofail(1, sizeof(devinfo_t)); entry->device = disk->device; pathcpy(entry->name, sizeof(entry->name), disk->name); pathcpy(entry->mount, sizeof(entry->mount), disk->dir); pathcpy(entry->smartctl, sizeof(entry->smartctl), disk->smartctl); tommy_list_insert_tail(&high, &entry->node, entry); } /* for all parities */ for (j = 0; j < state->level; ++j) { devinfo_t* entry; if (filterlist_disk != 0 && filter_path(filterlist_disk, 0, lev_config_name(j), 0) != 0) continue; entry = calloc_nofail(1, sizeof(devinfo_t)); entry->device = state->parity[j].device; pathcpy(entry->name, sizeof(entry->name), lev_config_name(j)); pathcpy(entry->mount, sizeof(entry->mount), state->parity[j].path); pathcpy(entry->smartctl, sizeof(entry->smartctl), state->parity[j].smartctl); pathcut(entry->mount); /* remove the parity file */ tommy_list_insert_tail(&high, &entry->node, entry); } if (state->opt.fake_device) { ret = devtest(&low, operation); } else { int others = operation == DEVICE_SMART; ret = devquery(&high, &low, operation, others); } /* if the list is empty, it's not supported in this platform */ if (ret == 0 && tommy_list_empty(&low)) ret = -1; if (ret != 0) { const char* ope = 0; switch (operation) { case DEVICE_UP : ope = "Spinup"; break; case DEVICE_DOWN : ope = "Spindown"; break; case DEVICE_LIST : ope = "Device listing"; break; case DEVICE_SMART : ope = "Smart"; break; } log_fatal("%s is unsupported in this platform.\n", ope); } else { if (operation == DEVICE_LIST) { for (i = tommy_list_head(&low); i != 0; i = i->next) { devinfo_t* devinfo = i->data; devinfo_t* parent = devinfo->parent; #ifdef _WIN32 printf("%" PRIu64 "\t%s\t%08" PRIx64 "\t%s\t%s\n", devinfo->device, devinfo->wfile, parent->device, parent->wfile, parent->name); #else printf("%u:%u\t%s\t%u:%u\t%s\t%s\n", major(devinfo->device), minor(devinfo->device), devinfo->file, major(parent->device), minor(parent->device), parent->file, parent->name); #endif } } if (operation == DEVICE_SMART) state_smart(state->level + tommy_list_count(&state->disklist), &low); } tommy_list_foreach(&high, free); tommy_list_foreach(&low, free); }
/** * Fill with fake data the device list. */ static int devtest(tommy_list* low, int operation) { unsigned c; if (operation != DEVICE_SMART) return -1; /* add some fake data */ for (c = 0; c < 16; ++c) { devinfo_t* entry; int j; entry = calloc_nofail(1, sizeof(devinfo_t)); entry->device = c; tommy_list_insert_tail(low, &entry->node, entry); for (j = 0; j < 256; ++j) { switch (c) { case 0 : entry->smart[j] = 0; break; case 1 : entry->smart[j] = SMART_UNASSIGNED; break; default: if (j == 193) entry->smart[j] = c - 2; else entry->smart[j] = 0; break; } } if (c == 0) { entry->smart_serial[0] = 0; entry->file[0] = 0; entry->name[0] = 0; entry->smart[SMART_SIZE] = SMART_UNASSIGNED; entry->smart[SMART_ROTATION_RATE] = 0; } else { snprintf(entry->smart_serial, sizeof(entry->smart_serial), "%u", c); pathcpy(entry->file, sizeof(entry->name), "file"); pathcpy(entry->name, sizeof(entry->name), "name"); entry->smart[SMART_SIZE] = c * TERA; entry->smart[SMART_ROTATION_RATE] = 7200; } entry->smart[SMART_ERROR] = 0; entry->smart[SMART_FLAGS] = SMART_UNASSIGNED; switch (c) { case 3 : entry->smart[SMART_ERROR] = 1; break; case 4 : entry->smart[SMART_FLAGS] = SMARTCTL_FLAG_UNSUPPORTED; break; case 5 : entry->smart[SMART_FLAGS] = SMARTCTL_FLAG_COMMAND; break; case 6 : entry->smart[SMART_FLAGS] = SMARTCTL_FLAG_OPEN; break; case 7 : entry->smart[SMART_FLAGS] = SMARTCTL_FLAG_FAIL; break; case 8 : entry->smart[SMART_FLAGS] = SMARTCTL_FLAG_PREFAIL; break; case 9 : entry->smart[SMART_FLAGS] = SMARTCTL_FLAG_PREFAIL_LOGGED; break; case 10 : entry->smart[SMART_FLAGS] = SMARTCTL_FLAG_ERROR; break; case 11 : entry->smart[SMART_FLAGS] = SMARTCTL_FLAG_ERROR_LOGGED; break; } } return 0; }
static void scrub_data_reader(struct snapraid_worker* worker, struct snapraid_task* task) { struct snapraid_io* io = worker->io; struct snapraid_state* state = io->state; struct snapraid_handle* handle = worker->handle; struct snapraid_disk* disk = handle->disk; block_off_t blockcur = task->position; unsigned char* buffer = task->buffer; int ret; char esc_buffer[ESC_MAX]; /* if the disk position is not used */ if (!disk) { /* use an empty block */ memset(buffer, 0, state->block_size); task->state = TASK_STATE_DONE; return; } /* get the block */ task->block = fs_par2block_find(disk, blockcur); /* if the block is not used */ if (!block_has_file(task->block)) { /* use an empty block */ memset(buffer, 0, state->block_size); task->state = TASK_STATE_DONE; return; } /* get the file of this block */ task->file = fs_par2file_get(disk, blockcur, &task->file_pos); /* if the file is different than the current one, close it */ if (handle->file != 0 && handle->file != task->file) { /* keep a pointer at the file we are going to close for error reporting */ struct snapraid_file* report = handle->file; ret = handle_close(handle); if (ret == -1) { /* LCOV_EXCL_START */ /* This one is really an unexpected error, because we are only reading */ /* and closing a descriptor should never fail */ if (errno == EIO) { log_tag("error:%u:%s:%s: Close EIO error. %s\n", blockcur, disk->name, esc(report->sub, esc_buffer), strerror(errno)); log_fatal("DANGER! Unexpected input/output close error in a data disk, it isn't possible to scrub.\n"); log_fatal("Ensure that disk '%s' is sane and that file '%s' can be accessed.\n", disk->dir, handle->path); log_fatal("Stopping at block %u\n", blockcur); task->state = TASK_STATE_IOERROR; return; } log_tag("error:%u:%s:%s: Close error. %s\n", blockcur, disk->name, esc(report->sub, esc_buffer), strerror(errno)); log_fatal("WARNING! Unexpected close error in a data disk, it isn't possible to scrub.\n"); log_fatal("Ensure that file '%s' can be accessed.\n", handle->path); log_fatal("Stopping at block %u\n", blockcur); task->state = TASK_STATE_ERROR; return; /* LCOV_EXCL_STOP */ } } ret = handle_open(handle, task->file, state->file_mode, log_error, 0); if (ret == -1) { if (errno == EIO) { /* LCOV_EXCL_START */ log_tag("error:%u:%s:%s: Open EIO error. %s\n", blockcur, disk->name, esc(task->file->sub, esc_buffer), strerror(errno)); log_fatal("DANGER! Unexpected input/output open error in a data disk, it isn't possible to scrub.\n"); log_fatal("Ensure that disk '%s' is sane and that file '%s' can be accessed.\n", disk->dir, handle->path); log_fatal("Stopping at block %u\n", blockcur); task->state = TASK_STATE_IOERROR; return; /* LCOV_EXCL_STOP */ } log_tag("error:%u:%s:%s: Open error. %s\n", blockcur, disk->name, esc(task->file->sub, esc_buffer), strerror(errno)); task->state = TASK_STATE_ERROR_CONTINUE; return; } /* check if the file is changed */ if (handle->st.st_size != task->file->size || handle->st.st_mtime != task->file->mtime_sec || STAT_NSEC(&handle->st) != task->file->mtime_nsec /* don't check the inode to support filesystem without persistent inodes */ ) { /* report that the block and the file are not synced */ task->is_timestamp_different = 1; /* follow */ } /* note that we intentionally don't abort if the file has different attributes */ /* from the last sync, as we are expected to return errors if running */ /* in an unsynced array. This is just like the check command. */ task->read_size = handle_read(handle, task->file_pos, buffer, state->block_size, log_error, 0); if (task->read_size == -1) { if (errno == EIO) { log_tag("error:%u:%s:%s: Read EIO error at position %u. %s\n", blockcur, disk->name, esc(task->file->sub, esc_buffer), task->file_pos, strerror(errno)); log_error("Input/Output error in file '%s' at position '%u'\n", handle->path, task->file_pos); task->state = TASK_STATE_IOERROR_CONTINUE; return; } log_tag("error:%u:%s:%s: Read error at position %u. %s\n", blockcur, disk->name, esc(task->file->sub, esc_buffer), task->file_pos, strerror(errno)); task->state = TASK_STATE_ERROR_CONTINUE; return; } /* store the path of the opened file */ pathcpy(task->path, sizeof(task->path), handle->path); task->state = TASK_STATE_DONE; }