/** * @brief Searches for well known locked files * and applies their dispositions to the map. * @details Resets f->disp structure of locked files. */ static void redraw_well_known_locked_files(udefrag_job_parameters *jp) { winx_file_info *f; ULONGLONG time; ULONGLONG n = 0; winx_dbg_print_header(0,0,I"searching for well known locked files..."); time = winx_xtime(); for(f = jp->filelist; f; f = f->next){ if(f->disp.blockmap){ /* otherwise nothing to redraw */ if(is_well_known_locked_file(f,jp)){ if(!is_file_locked(f,jp)){ /* possibility of this case should be reduced */ dtrace("file wasn't locked: %ws",f->path); } else { itrace("locked file DETECTED: %ws",f->path); n ++; } } } if(f->next == jp->filelist) break; } itrace("%I64u locked files found",n); winx_dbg_print_header(0,0,I"well known locked files search completed in %I64u ms", winx_xtime() - time); }
/** * @brief Searches for the first movable file block * after the specified cluster on the volume. * @param[in] jp job parameters. * @param[in,out] min_lcn pointer to variable containing * minimum LCN - file blocks below it will be ignored. * @param[in] flags one of SKIP_xxx flags defined in udefrag.h * @param[out] first_file pointer to variable receiving information * about the file the first block belongs to. * @return Pointer to the first block. NULL indicates failure. */ winx_blockmap *find_first_block(udefrag_job_parameters *jp, ULONGLONG *min_lcn, int flags, winx_file_info **first_file) { winx_file_info *found_file; winx_blockmap *first_block; winx_blockmap b; struct file_block fb, *item; struct prb_traverser t; int movable_file; ULONGLONG tm = winx_xtime(); if(min_lcn == NULL || first_file == NULL) return NULL; found_file = NULL; first_block = NULL; b.lcn = *min_lcn; fb.block = &b; prb_t_init(&t,jp->file_blocks); item = prb_t_insert(&t,jp->file_blocks,&fb); if(item == &fb){ /* block at min_lcn not found */ item = prb_t_next(&t); if(prb_delete(jp->file_blocks,&fb) == NULL){ etrace("cannot remove block from the tree"); winx_flush_dbg_log(0); /* 'cause error is critical */ } } if(item){ found_file = item->file; first_block = item->block; } while(!jp->termination_router((void *)jp)){ if(found_file == NULL) break; if(flags & SKIP_PARTIALLY_MOVABLE_FILES){ movable_file = can_move_entirely(found_file,jp); } else { movable_file = can_move(found_file,jp); } if(is_file_locked(found_file,jp)) movable_file = 0; if(movable_file){ if(jp->is_fat && is_directory(found_file) && first_block == found_file->disp.blockmap){ /* skip first fragments of FAT directories */ } else { /* desired block found */ *min_lcn = first_block->lcn + 1; /* the current block will be skipped later anyway in this case */ *first_file = found_file; jp->p_counters.searching_time += winx_xtime() - tm; return first_block; } } /* skip current block */ *min_lcn = *min_lcn + 1; /* and go to the next one */ item = prb_t_next(&t); if(item == NULL) break; found_file = item->file; first_block = item->block; } *first_file = NULL; jp->p_counters.searching_time += winx_xtime() - tm; return NULL; }
static void sock_lock (conf_t conf) { /* Ensures exclusive access to the unix domain socket. */ struct stat st; mode_t mask; int rv; assert (conf != NULL); assert (conf->lockfile_name == NULL); assert (conf->lockfile_fd == -1); assert (conf->socket_name != NULL); if (!(conf->lockfile_name = strdupf ("%s.lock", conf->socket_name))) { log_errno (EMUNGE_NO_MEMORY, LOG_ERR, "Failed to create lockfile string"); } if (conf->got_force) { if ((unlink (conf->lockfile_name) < 0) && (errno != ENOENT)) { log_errno (EMUNGE_SNAFU, LOG_ERR, "Failed to remove \"%s\"", conf->lockfile_name); } } else if (lstat (conf->lockfile_name, &st) < 0) { if (errno != ENOENT) { log_errno (EMUNGE_SNAFU, LOG_ERR, "Failed to stat \"%s\"", conf->lockfile_name); } } else if (!S_ISREG(st.st_mode)) { log_err (EMUNGE_SNAFU, LOG_ERR, "Lockfile is suspicious: \"%s\" should be a regular file", conf->lockfile_name); } else if (st.st_uid != geteuid()) { log_err (EMUNGE_SNAFU, LOG_ERR, "Lockfile is suspicious: \"%s\" should be owned by UID %u", conf->lockfile_name, (unsigned) geteuid()); } else if ((st.st_mode & 07777) != S_IWUSR) { log_err (EMUNGE_SNAFU, LOG_ERR, "Lockfile is suspicious: \"%s\" should be writable only by user", conf->lockfile_name); } mask = umask (0); conf->lockfile_fd = creat (conf->lockfile_name, S_IWUSR); umask (mask); if (conf->lockfile_fd < 0) { log_errno (EMUNGE_SNAFU, LOG_ERR, "Failed to create \"%s\"", conf->lockfile_name); } if ((rv = set_file_lock (conf->lockfile_fd)) < 0) { if (!conf->got_force) log_errno (EMUNGE_SNAFU, LOG_ERR, "Failed to lock \"%s\"", conf->lockfile_name); else log_msg (LOG_WARNING, "Failed to lock \"%s\"", conf->lockfile_name); } else if (rv > 0) { pid_t pid = is_file_locked (conf->lockfile_fd); if (pid < 0) { log_errno (EMUNGE_SNAFU, LOG_ERR, "Failed to test lock \"%s\"", conf->lockfile_name); } else if (pid > 0) { log_err (EMUNGE_SNAFU, LOG_ERR, "Found pid %d bound to socket \"%s\"", pid, conf->socket_name); } else { log_err (EMUNGE_SNAFU, LOG_ERR, "Found inconsistent state for lock \"%s\"", conf->lockfile_name); } } if (unlink (conf->socket_name) == 0) { log_msg (LOG_INFO, "Removed existing socket \"%s\"", conf->socket_name); } else if (errno != ENOENT) { log_errno (EMUNGE_SNAFU, LOG_ERR, "Failed to remove \"%s\"", conf->socket_name); } return; }