static bool check_rename(struct file *src, struct file *dst) { file_stat(src); /* If the source file is not present and we are not going to do * the rename anyway there's no point in checking any further. */ if (src->stat_state == FILE_STAT_NOFILE) return false; file_stat(dst); /* * Unfortunately we have to check for write access in both places, * just having +w is not enough, since people do mount things RO, * and we need to fail before we start mucking around with things. * So we open a file with the same name as the diversions but with * an extension that (hopefully) won't overwrite anything. If it * succeeds, we assume a writable filesystem. */ check_writable_dir(src); check_writable_dir(dst); if (src->stat_state == FILE_STAT_VALID && dst->stat_state == FILE_STAT_VALID && !(src->stat.st_dev == dst->stat.st_dev && src->stat.st_ino == dst->stat.st_ino)) ohshit(_("rename involves overwriting '%s' with\n" " different file '%s', not allowed"), dst->name, src->name); return true; }
/* Do a file stat for a psdev uri. */ Bool stat_from_psdev_uri( /*@in@*/ /*@notnull@*/ hqn_uri_t* uri, /*@out@*/ /*@notnull@*/ Bool* exists, /*@out@*/ /*@notnull@*/ STAT* stat) { uint8 *ps_filename; uint32 ps_filename_len ; int32 status; /* Create PS filename from URI */ if ( !psdev_uri_to_ps_filename(uri, &ps_filename, &ps_filename_len) ) { return(FALSE); } /* Stat the PS filename */ oString(snewobj) = ps_filename; theLen(snewobj) = CAST_TO_UINT16(ps_filename_len); status = file_stat(&snewobj, exists, stat); /* Must free memory used for ps filename */ mm_free_with_header(mm_xml_pool, ps_filename); return(status); } /* stat_from_psdev_uri */
int if_file_exists(const char* path) { int exists; file_t file; file_init(&file, path, 1); exists = (file_stat(&file) >= 0); file_cleanup(&file); return exists; }
int sys_fstat(int fd, struct file_stat *stat) { struct file *file = fd_get_file(fd); int r = -1; if (!file) return -1; r = file_stat(file, stat); put_file(file); return r; }
SYSCALL_DEFINE2(stat, char*, path, struct stat*, stat) { int r; // FIXME: max length path = (char*)user_to_kernel_check((uint32_t)path, -1, 0); stat = (struct stat*)user_to_kernel_check((uint32_t)stat, sizeof(struct stat), 1); r = file_stat(path, stat); print_info("stat ok: %d\n", r); return SYSCALL_RETURN(r); }
int is_regular_file(const char* path) { int is_regular = 0; file_t file; file_init(&file, path, 1); if (file_stat(&file) >= 0) { is_regular = FILE_ISREG(&file); } file_cleanup(&file); return is_regular; }
SYSCALL_DEFINE2(lstat, const char*, path, struct stat*, stat) { // FIXME: stat cagrisindan kopyalandi. duzelt int r; // FIXME: max length path = (char*)user_to_kernel_check((uint32_t)path, -1, 0); stat = (struct stat*)user_to_kernel_check((uint32_t)stat, sizeof(struct stat), 1); r = file_stat(path, stat); print_info("stat ok: %d\n", r); return SYSCALL_RETURN(r); }
int sys_fstat(int fd, void* st) { int r = -EBADF; file_t* f = file_get(fd); if (f) { r = file_stat(f, st); file_decref(f); } return r; }
sysret_t sys_fstat(int fd, void* st) { sysret_t r = {-1,EBADF}; file_t* f = file_get(fd); if (f) { r = file_stat(f, st); file_decref(f); } return r; }
NEOIP_NAMESPACE_BEGIN /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// // open/close /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// /** \brief Open a directory dir_path (MUST NOT be null) * * - this is valid to open an already opened file_dir_t * - the content obtained from the previous open(), will be overwritten by the new one */ file_err_t file_dir_t::open(const file_path_t &dir_path) throw() { GError * gerror = NULL; const gchar * name; // sanity check - the dir_path MUST NOT be null DBG_ASSERT( !dir_path.is_null() ); // zero the file database name_db = std::vector<name_t>(); // open the directory GDir * g_dir = g_dir_open(dir_path.to_os_path_string().c_str(), 0, &gerror ); // if the open failed, report the error now if( gerror ) return file_err_t(file_err_t::ERROR, gerror->message ); // scan the directory while( (name = g_dir_read_name(g_dir)) ){ file_stat_t file_stat( dir_path.fullpath() / name ); // if this file can't be stated, skip it if( file_stat.is_null() ) continue; // put the found name in the name_db name_db.push_back( name_t(name, file_stat) ); } // close the directory g_dir_close(g_dir); // copy the dir_path this->dir_path = dir_path; // return no error return file_err_t::OK; }
extern boolean is_recursive_link (const char* const dirName) { boolean result = FALSE; fileStatus *status = file_stat (dirName); if (status->isSymbolicLink) { char* const path = file_get_absolute_name (dirName); while (path [strlen (path) - 1] == PATH_SEPARATOR) path [strlen (path) - 1] = '\0'; while (! result && strlen (path) > (size_t) 1) { char *const separator = strrchr (path, PATH_SEPARATOR); if (separator == NULL) break; else if (separator == path) /* backed up to root directory */ *(separator + 1) = '\0'; else *separator = '\0'; result = is_same_file (path, dirName); } xfree(path); } return result; }
void ACKACKACK() { /* Create a fake root node to bootstrap the filesystem. */ err = treefs_create_node(*fsys, &fake_root); if (err) goto barf; /* Remember stat info for the node we're mounted on. */ bzero (&(*fsys)->underlying_stat, sizeof (struct stat)); file_stat (realnode, &(*fsys)->underlying_stat); /* Note that it points to *FSYS, but *FSYS's root doesn't point to it... If the user wants this to be the real root, it's his responsility to initialize if further and install it. */ fake_root->fsys = *fsys; bcopy (&(*fsys)->underlying_stat, &fake_root->stat); err = treefs_fsys_init (fake_root); if (err) goto barf; /* See if the silly user has in fact done so. */ if ((*fsys)->root != fake_root) treefs_free_node (fake_root); }
/* * Check if the given file exists. If so, try to reuse its record-format when * creating a new version. * * Note: using a '0' protection on VMS C 'open()' tells it to use an existing * file's protection, or (if the file doesn't exist) the user's default * protection. */ int vms_creat(char *filename) { char rfm_option[80]; char rat_option[80]; char len_option[80]; struct stat sb; int my_rfm = b_val(curbp, VAL_RECORD_FORMAT); int my_rat = b_val(curbp, VAL_RECORD_ATTRS); int my_len = b_val(curbp, VAL_RECORD_LENGTH); int fd; /* * Only check for the previous file's record-format if the mode has not * been specified. */ if (my_rfm == FAB$C_UDF) { if (file_stat(filename, &sb) == 0) { my_rfm = sb.st_fab_rfm; my_rat = sb.st_fab_rat; my_len = sb.st_fab_mrs; /* Ignore the old record attributes, since 'cr' is the * only one we know anything about. */ } if (my_rfm == FAB$C_UDF) my_rfm = FAB$C_STMLF; } lsprintf(rfm_option, "rfm=%s", vms_record_format(my_rfm)); lsprintf(rat_option, "rat=%s", vms_record_attrs(my_rat)); lsprintf(len_option, "mrs=%d", my_len); switch (my_rfm) { case FAB$C_FIX: fd = creat(filename, 0, rfm_option, len_option, rat_option); break; case FAB$C_VFC: /* * FIXME: Must specify the fixed-length control field size * (there's no interface for that at the moment, so I * hardwired it at two bytes. Tom, I'm punting this one * back to you. * * C. Morgan 11/29/1998. * * VFC files can only up to 32768 bytes/record, so the control * field size is "always" 2 bytes -TD */ fd = creat(filename, 0, rfm_option, len_option, "fsz=2", /* Fixed-length control field size */ rat_option); break; default: /* * The stmlf and var record-formats are really all that is * required. Other combinations are experimental. */ fd = creat(filename, 0, rfm_option, "rat=cr"); break; } return fd; }
/** \brief Move the files from the partdata_dir/partmeta_dir to the fulldata_dir/fullmeta_dir * * - this copy the metadata_basename and all the data files from the dir_part to the dir_full * - this functions return an error immediatly - aka no support for error * - NOTE: it avoid any race condition aka it remove the source files IIF the destination files * have been successfully copied * - TODO currently the copy is done only by hardlink aka it requires to have the * part_dir on the same partition as the dir_part * - additionnaly it is only on some filesystem and OS * - later support actual copy with a asyncronous function * - TODO sometime the copy do not happen for unknown reason * - investiage the matter * - likely would be nicer to put this file copy into the neoip-_file * - and have a nunit for it * - something similar to the ruby FileUtils */ bt_err_t btcli_swarm_t::move_part2full_dir() throw() { const file_path_t & partmeta_dir = btcli_apps->partmeta_dir(); const file_path_t & partdata_dir = btcli_apps->partdata_dir(); const file_path_t & fullmeta_dir = btcli_apps->fullmeta_dir(); const file_path_t & fulldata_dir = btcli_apps->fulldata_dir(); file_path_arr_t subpath_arr; file_err_t file_err; // if bt_ezswarm current state is NOT share, return now DBG_ASSERT( bt_ezswarm->in_stopped() ); /* * STEP 0: get all the data file subpath in subpath_arr */ // reload the bt_mfile_t from metadata_basename() to populate the subpath_arr file_path_t metadata_fullpath = partmeta_dir / metadata_basename(); bt_mfile_t bt_mfile = bt_mfile_helper_t::from_torrent_file(metadata_fullpath); DBG_ASSERT( !bt_mfile.is_null() ); // go thru the whole bt_mfile_t.subfile_arr() // - TODO should be in bt_mfile_t itself // - something similar is in bt_alloc_t for(size_t i = 0; i < bt_mfile.subfile_arr().size(); i++){ bt_mfile_subfile_t &mfile_subfile = bt_mfile.subfile_arr()[i]; file_path_t file_path; // if this is a multi-file bt_mfile_t, the name() is the top most directory name if( bt_mfile.subfile_arr().size() > 1 ) file_path /= bt_mfile.name(); // add the mfile_path file_path /= mfile_subfile.mfile_path(); // add this file_path into the subpath_arr subpath_arr += file_path; } /* * STEP 1: create all the directory in the destination if needed * - it is needed IIF the bt_mfile_t has several file */ if( bt_mfile.subfile_arr().size() > 1 ){ // create all the destination directories in the fulldata_dir for(size_t i = 0; i < subpath_arr.size(); i++){ file_path_t dirname = fulldata_dir / subpath_arr[i].dirname(); file_stat_t file_stat( dirname ); // if the dirname already exist and is a directory, goto the next if( !file_stat.is_null() && file_stat.is_dir() ) continue; // try to reccursively create the directory file_err = file_utils_t::create_directory(dirname, file_utils_t::DO_RECURSION); if( file_err.failed() ) return bt_err_from_file(file_err); } } /* * STEP 2: copy the files from the source to the destination, meta and data */ // copy the metadata_basename file_err = file_utils_t::create_hardlink(partmeta_dir / metadata_basename(), fullmeta_dir / metadata_basename()); if( file_err.failed() ) return bt_err_from_file(file_err); // copy the file themselves for(size_t i = 0; i < subpath_arr.size(); i++){ file_path_t src_path = partdata_dir / subpath_arr[i]; file_path_t dst_path = fulldata_dir / subpath_arr[i]; // copy this file file_err = file_utils_t::create_hardlink(src_path, dst_path); if( file_err.failed() ) return bt_err_from_file(file_err); } /* * STEP 3: remove all the src files * - at this point, all the files have been successfully linked to the destination directories */ // delete the metadata basename from the partmeta_dir file_err = file_utils_t::remove_file(partmeta_dir / metadata_basename()); if( file_err.failed() ) return bt_err_from_file(file_err); // delete the resumedata from the partmeta_dir file_err = file_utils_t::remove_file(resumedata_path_from_metadata(metadata_basename())); if( file_err.failed() ) return bt_err_from_file(file_err); // delete all the data files in the partdata_dir if( bt_mfile.subfile_arr().size() > 1 ){ file_err = file_utils_t::remove_directory(partdata_dir / bt_mfile.name(), file_utils_t::DO_RECURSION); }else{ file_err = file_utils_t::remove_file(partdata_dir / bt_mfile.name()); } if( file_err.failed() ) return bt_err_from_file(file_err); // return no error return bt_err_t::OK; }
/* TLS: making a conservative guess at which system calls need to be mutexed. I'm doing it whenever I see the process table altered or affected, so this is the data structure that its protecting. At some point, the SET_FILEPTRs should be protected against other threads closing that stream. Perhaps for such things a thread-specific stream table should be used. */ xsbBool sys_system(CTXTdeclc int callno) { // int pid; Integer pid; switch (callno) { case PLAIN_SYSTEM_CALL: /* dumb system call: no communication with XSB */ /* this call is superseded by shell and isn't used */ ctop_int(CTXTc 3, system(ptoc_string(CTXTc 2))); return TRUE; case SLEEP_FOR_SECS: #ifdef WIN_NT Sleep((int)iso_ptoc_int_arg(CTXTc 2,"sleep/1",1) * 1000); #else sleep(iso_ptoc_int_arg(CTXTc 2,"sleep/1",1)); #endif return TRUE; case GET_TMP_FILENAME: ctop_string(CTXTc 2,tempnam(NULL,NULL)); return TRUE; case IS_PLAIN_FILE: case IS_DIRECTORY: case STAT_FILE_TIME: case STAT_FILE_SIZE: return file_stat(CTXTc callno, ptoc_longstring(CTXTc 2)); case EXEC: { #ifdef HAVE_EXECVP /* execs a new process in place of XSB */ char *params[MAX_SUBPROC_PARAMS+2]; prolog_term cmdspec_term; int index = 0; cmdspec_term = reg_term(CTXTc 2); if (islist(cmdspec_term)) { prolog_term temp, head; char *string_head=NULL; if (isnil(cmdspec_term)) xsb_abort("[exec] Arg 1 must not be an empty list."); temp = cmdspec_term; do { head = p2p_car(temp); temp = p2p_cdr(temp); if (isstring(head)) string_head = string_val(head); else xsb_abort("[exec] non-string argument passed in list."); params[index++] = string_head; if (index > MAX_SUBPROC_PARAMS) xsb_abort("[exec] Too many arguments."); } while (!isnil(temp)); params[index] = NULL; } else if (isstring(cmdspec_term)) { char *string = string_val(cmdspec_term); split_command_arguments(string, params, "exec"); } else xsb_abort("[exec] 1st argument should be term or list of strings."); if (execvp(params[0], params)) xsb_abort("[exec] Exec call failed."); #else xsb_abort("[exec] builtin not supported in this architecture."); #endif } case SHELL: /* smart system call: like SPAWN_PROCESS, but returns error code instead of PID. Uses system() rather than execvp. Advantage: can pass arbitrary shell command. */ case SPAWN_PROCESS: { /* spawn new process, reroute stdin/out/err to XSB */ /* +CallNo=2, +ProcAndArgsList, -StreamToProc, -StreamFromProc, -StreamFromProcStderr, -Pid */ static int pipe_to_proc[2], pipe_from_proc[2], pipe_from_stderr[2]; int toproc_stream=-1, fromproc_stream=-1, fromproc_stderr_stream=-1; int pid_or_status; FILE *toprocess_fptr=NULL, *fromprocess_fptr=NULL, *fromproc_stderr_fptr=NULL; char *params[MAX_SUBPROC_PARAMS+2]; /* one for progname--0th member, one for NULL termination*/ prolog_term cmdspec_term, cmdlist_temp_term; prolog_term cmd_or_arg_term; xsbBool toproc_needed=FALSE, fromproc_needed=FALSE, fromstderr_needed=FALSE; char *cmd_or_arg=NULL, *shell_cmd=NULL; int idx = 0, tbl_pos; char *callname=NULL; xsbBool params_are_in_a_list=FALSE; SYS_MUTEX_LOCK( MUTEX_SYS_SYSTEM ); init_process_table(); if (callno == SPAWN_PROCESS) callname = "spawn_process/5"; else callname = "shell/[1,2,5]"; cmdspec_term = reg_term(CTXTc 2); if (islist(cmdspec_term)) params_are_in_a_list = TRUE; else if (isstring(cmdspec_term)) shell_cmd = string_val(cmdspec_term); else if (isref(cmdspec_term)) xsb_instantiation_error(CTXTc callname,1); else xsb_type_error(CTXTc "atom or list e.g. [command, arg, ...]",cmdspec_term,callname,1); // xsb_abort("[%s] Arg 1 must be an atom or a list [command, arg, ...]", // callname); /* the user can indicate that he doesn't want either of the streams created by putting an atom in the corresponding argument position */ if (isref(reg_term(CTXTc 3))) toproc_needed = TRUE; if (isref(reg_term(CTXTc 4))) fromproc_needed = TRUE; if (isref(reg_term(CTXTc 5))) fromstderr_needed = TRUE; /* if any of the arg streams is already used by XSB, then don't create pipes --- use these streams instead. */ if (isointeger(reg_term(CTXTc 3))) { SET_FILEPTR(toprocess_fptr, oint_val(reg_term(CTXTc 3))); } if (isointeger(reg_term(CTXTc 4))) { SET_FILEPTR(fromprocess_fptr, oint_val(reg_term(CTXTc 4))); } if (isointeger(reg_term(CTXTc 5))) { SET_FILEPTR(fromproc_stderr_fptr, oint_val(reg_term(CTXTc 5))); } if (!isref(reg_term(CTXTc 6))) xsb_type_error(CTXTc "variable (to return process id)",reg_term(CTXTc 6),callname,5); // xsb_abort("[%s] Arg 5 (process id) must be a variable", callname); if (params_are_in_a_list) { /* fill in the params[] array */ if (isnil(cmdspec_term)) xsb_abort("[%s] Arg 1 must not be an empty list", callname); cmdlist_temp_term = cmdspec_term; do { cmd_or_arg_term = p2p_car(cmdlist_temp_term); cmdlist_temp_term = p2p_cdr(cmdlist_temp_term); if (isstring(cmd_or_arg_term)) { cmd_or_arg = string_val(cmd_or_arg_term); } else xsb_abort("[%s] Non string list member in the Arg", callname); params[idx++] = cmd_or_arg; if (idx > MAX_SUBPROC_PARAMS) xsb_abort("[%s] Too many arguments passed to subprocess", callname); } while (!isnil(cmdlist_temp_term)); params[idx] = NULL; /* null termination */ } else { /* params are in a string */ if (callno == SPAWN_PROCESS) split_command_arguments(shell_cmd, params, callname); else { /* if callno==SHELL => call system() => don't split shell_cmd */ params[0] = shell_cmd; params[1] = NULL; } } /* -1 means: no space left */ if ((tbl_pos = get_free_process_cell()) < 0) { xsb_warn(CTXTc "Can't create subprocess because XSB process table is full"); SYS_MUTEX_UNLOCK( MUTEX_SYS_SYSTEM ); return FALSE; } /* params[0] is the progname */ pid_or_status = xsb_spawn(CTXTc params[0], params, callno, (toproc_needed ? pipe_to_proc : NULL), (fromproc_needed ? pipe_from_proc : NULL), (fromstderr_needed ? pipe_from_stderr : NULL), toprocess_fptr, fromprocess_fptr, fromproc_stderr_fptr); if (pid_or_status < 0) { xsb_warn(CTXTc "[%s] Subprocess creation failed, Error: %d, errno: %d, Cmd: %s", callname,pid_or_status,errno,params[0]); SYS_MUTEX_UNLOCK( MUTEX_SYS_SYSTEM ); return FALSE; } if (toproc_needed) { toprocess_fptr = fdopen(pipe_to_proc[1], "w"); toproc_stream = xsb_intern_fileptr(CTXTc toprocess_fptr,callname,"pipe","w",CURRENT_CHARSET); ctop_int(CTXTc 3, toproc_stream); } if (fromproc_needed) { fromprocess_fptr = fdopen(pipe_from_proc[0], "r"); fromproc_stream = xsb_intern_fileptr(CTXTc fromprocess_fptr,callname,"pipe","r",CURRENT_CHARSET); ctop_int(CTXTc 4, fromproc_stream); } if (fromstderr_needed) { fromproc_stderr_fptr = fdopen(pipe_from_stderr[0], "r"); fromproc_stderr_stream = xsb_intern_fileptr(CTXTc fromproc_stderr_fptr,callname,"pipe","r",CURRENT_CHARSET); ctop_int(CTXTc 5, fromproc_stderr_stream); } ctop_int(CTXTc 6, pid_or_status); xsb_process_table.process[tbl_pos].pid = pid_or_status; xsb_process_table.process[tbl_pos].to_stream = toproc_stream; xsb_process_table.process[tbl_pos].from_stream = fromproc_stream; xsb_process_table.process[tbl_pos].stderr_stream = fromproc_stderr_stream; concat_array(CTXTc params, " ", xsb_process_table.process[tbl_pos].cmdline,MAX_CMD_LEN); SYS_MUTEX_UNLOCK( MUTEX_SYS_SYSTEM ); return TRUE; } case GET_PROCESS_TABLE: { /* sys_system(3, X). X is bound to the list of the form [process(Pid,To,From,Stderr,Cmdline), ...] */ int i; prolog_term table_term_tail, listHead; prolog_term table_term=reg_term(CTXTc 2); SYS_MUTEX_LOCK( MUTEX_SYS_SYSTEM ); init_process_table(); if (!isref(table_term)) xsb_abort("[GET_PROCESS_TABLE] Arg 1 must be a variable"); table_term_tail = table_term; for (i=0; i<MAX_SUBPROC_NUMBER; i++) { if (!FREE_PROC_TABLE_CELL(xsb_process_table.process[i].pid)) { c2p_list(CTXTc table_term_tail); /* make it into a list */ listHead = p2p_car(table_term_tail); c2p_functor(CTXTc "process", 5, listHead); c2p_int(CTXTc xsb_process_table.process[i].pid, p2p_arg(listHead,1)); c2p_int(CTXTc xsb_process_table.process[i].to_stream, p2p_arg(listHead,2)); c2p_int(CTXTc xsb_process_table.process[i].from_stream, p2p_arg(listHead,3)); c2p_int(CTXTc xsb_process_table.process[i].stderr_stream, p2p_arg(listHead,4)); c2p_string(CTXTc xsb_process_table.process[i].cmdline, p2p_arg(listHead,5)); table_term_tail = p2p_cdr(table_term_tail); } } c2p_nil(CTXTc table_term_tail); /* bind tail to nil */ SYS_MUTEX_UNLOCK( MUTEX_SYS_SYSTEM ); return p2p_unify(CTXTc table_term, reg_term(CTXTc 2)); } case PROCESS_STATUS: { prolog_term pid_term=reg_term(CTXTc 2), status_term=reg_term(CTXTc 3); SYS_MUTEX_LOCK( MUTEX_SYS_SYSTEM ); init_process_table(); if (!(isointeger(pid_term))) xsb_abort("[PROCESS_STATUS] Arg 1 (process id) must be an integer"); pid = (int)oint_val(pid_term); if (!isref(status_term)) xsb_abort("[PROCESS_STATUS] Arg 2 (process status) must be a variable"); switch (process_status(pid)) { case RUNNING: c2p_string(CTXTc "running", status_term); break; case STOPPED: c2p_string(CTXTc "stopped", status_term); break; case EXITED_NORMALLY: c2p_string(CTXTc "exited_normally", status_term); break; case EXITED_ABNORMALLY: c2p_string(CTXTc "exited_abnormally", status_term); break; case ABORTED: c2p_string(CTXTc "aborted", status_term); break; case INVALID: c2p_string(CTXTc "invalid", status_term); break; default: c2p_string(CTXTc "unknown", status_term); } SYS_MUTEX_UNLOCK( MUTEX_SYS_SYSTEM ); return TRUE; } case PROCESS_CONTROL: { /* sys_system(PROCESS_CONTROL, +Pid, +Signal). Signal: wait, kill */ int status; prolog_term pid_term=reg_term(CTXTc 2), signal_term=reg_term(CTXTc 3); SYS_MUTEX_LOCK( MUTEX_SYS_SYSTEM ); init_process_table(); if (!(isointeger(pid_term))) xsb_abort("[PROCESS_CONTROL] Arg 1 (process id) must be an integer"); pid = (int)oint_val(pid_term); if (isstring(signal_term) && strcmp(string_val(signal_term), "kill")==0) { if (KILL_FAILED(pid)) { SYS_MUTEX_UNLOCK( MUTEX_SYS_SYSTEM ); return FALSE; } #ifdef WIN_NT CloseHandle((HANDLE) pid); #endif SYS_MUTEX_UNLOCK( MUTEX_SYS_SYSTEM ); return TRUE; } if (isconstr(signal_term) && strcmp(p2c_functor(signal_term),"wait") == 0 && p2c_arity(signal_term)==1) { int exit_status; if (WAIT(pid, status) < 0) { SYS_MUTEX_UNLOCK( MUTEX_SYS_SYSTEM ); return FALSE; } #ifdef WIN_NT exit_status = status; #else if (WIFEXITED(status)) exit_status = WEXITSTATUS(status); else exit_status = -1; #endif p2p_unify(CTXTc p2p_arg(signal_term,1), makeint(exit_status)); SYS_MUTEX_UNLOCK( MUTEX_SYS_SYSTEM ); return TRUE; } xsb_warn(CTXTc "[PROCESS_CONTROL] Arg 2: Invalid signal specification. Must be `kill' or `wait(Var)'"); return FALSE; } case LIST_DIRECTORY: { /* assume all type- and mode-checking is done in Prolog */ prolog_term handle = reg_term(CTXTc 2); /* ref for handle */ char *dir_name = ptoc_longstring(CTXTc 3); /* +directory name */ prolog_term filename = reg_term(CTXTc 4); /* reference for name of file */ if (is_var(handle)) return xsb_find_first_file(CTXTc handle,dir_name,filename); else return xsb_find_next_file(CTXTc handle,dir_name,filename); } default: xsb_abort("[SYS_SYSTEM] Wrong call number (an XSB bug)"); } /* end case */ return TRUE; }
void DiscoverySingleDirectoryJob::directoryListingIteratedSlot(QString file, const QMap<QString, QString> &map) { if (!_ignoredFirst) { // The first entry is for the folder itself, we should process it differently. _ignoredFirst = true; if (map.contains("permissions")) { auto perm = RemotePermissions::fromServerString(map.value("permissions")); emit firstDirectoryPermissions(perm); _isExternalStorage = perm.hasPermission(RemotePermissions::IsMounted); } if (map.contains("data-fingerprint")) { _dataFingerprint = map.value("data-fingerprint").toUtf8(); if (_dataFingerprint.isEmpty()) { // Placeholder that means that the server supports the feature even if it did not set one. _dataFingerprint = "[empty]"; } } } else { // Remove <webDAV-Url>/folder/ from <webDAV-Url>/folder/subfile.txt file.remove(0, _lsColJob->reply()->request().url().path().length()); // remove trailing slash while (file.endsWith('/')) { file.chop(1); } // remove leading slash while (file.startsWith('/')) { file = file.remove(0, 1); } std::unique_ptr<csync_file_stat_t> file_stat(new csync_file_stat_t); file_stat->path = file.toUtf8(); file_stat->size = -1; propertyMapToFileStat(map, file_stat.get()); if (file_stat->type == ItemTypeDirectory) file_stat->size = 0; if (file_stat->type == ItemTypeSkip || file_stat->size == -1 || file_stat->remotePerm.isNull() || file_stat->etag.isEmpty() || file_stat->file_id.isEmpty()) { _error = tr("The server file discovery reply is missing data."); qCWarning(lcDiscovery) << "Missing properties:" << file << file_stat->type << file_stat->size << file_stat->modtime << file_stat->remotePerm.toString() << file_stat->etag << file_stat->file_id; } if (_isExternalStorage && file_stat->remotePerm.hasPermission(RemotePermissions::IsMounted)) { /* All the entries in a external storage have 'M' in their permission. However, for all purposes in the desktop client, we only need to know about the mount points. So replace the 'M' by a 'm' for every sub entries in an external storage */ file_stat->remotePerm.unsetPermission(RemotePermissions::IsMounted); file_stat->remotePerm.setPermission(RemotePermissions::IsMountedSub); } QStringRef fileRef(&file); int slashPos = file.lastIndexOf(QLatin1Char('/')); if (slashPos > -1) { fileRef = file.midRef(slashPos + 1); } _results.push_back(std::move(file_stat)); } //This works in concerto with the RequestEtagJob and the Folder object to check if the remote folder changed. if (map.contains("getetag")) { _etagConcatenation += map.value("getetag"); if (_firstEtag.isEmpty()) { _firstEtag = map.value("getetag"); // for directory itself } } }
// System call handler: call the appropriate system call according to the nb argument. // Called by the assembly code _syscall_handler int syscall_handler(syscall_t nb, uint32_t arg1, uint32_t arg2, uint32_t arg3, uint32_t arg4, uint32_t caller_tss_selector) { printf("task %d called syscall_handler\n", caller_tss_selector); // Offset for pointers to reach the real address (task thinks it indexes since 0x0 but it really doesn't) task_t* t = get_task(caller_tss_selector); uint32_t offset = FIRST_TASK + t.gdt_tss_sel * TASK_LIMIT; int ret = 0; switch (nb) { case SYSCALL_PUTC: UNUSED(arg2); UNUSED(arg3); UNUSED(arg4); print_char((char) arg1 + offset); break; case SYSCALL_PUTS: UNUSED(arg2); UNUSED(arg3); UNUSED(arg4); print_str((char*) arg1 + offset); break; case SYSCALL_EXEC: UNUSED(arg2); UNUSED(arg3); UNUSED(arg4); ret = exec((char*) arg1 + offset); break; case SYSCALL_GETC: UNUSED(arg1); UNUSED(arg2); UNUSED(arg3); UNUSED(arg4); ret = getc(); break; case SYSCALL_FILE_STAT: UNUSED(arg3); UNUSED(arg4); ret = file_stat((char*) arg1 + offset, (stat_t*) arg2 + offset); break; case SYSCALL_FILE_READ: UNUSED(arg3); UNUSED(arg4); ret = file_read((char*) arg1 + offset, (void*) arg2 + offset); break; case SYSCALL_FILE_REMOVE: UNUSED(arg2); UNUSED(arg3); UNUSED(arg4); ret = file_remove((char*) arg1 + offset); break; case SYSCALL_FILE_ITERATOR: UNUSED(arg2); UNUSED(arg3); UNUSED(arg4); file_iterator_t it = file_iterator(); arg1 = (uint32_t) &it + offset; break; case SYSCALL_FILE_NEXT: UNUSED(arg3); UNUSED(arg4); ret = file_next((char*) arg1 + offset, (file_iterator_t*) arg2 + offset); break; case SYSCALL_GET_TICKS: UNUSED(arg1); UNUSED(arg2); UNUSED(arg3); UNUSED(arg4); ret = get_ticks(); break; default: UNUSED(nb); UNUSED(arg1); UNUSED(arg2); UNUSED(arg3); UNUSED(arg4); break; } // End of routine return ret; }
int main(int argc, char **argv) { if(argc == 1) { usage(); exit(1); } while((cret = getopt(argc,argv,"bwetvf:s:l:u: ")) != EOF) { switch(cret) { case 'f': /* Force factor */ x=atoi(optarg); if(x < 0) x=1; break; case 's': /* Size of files */ sz=atoi(optarg); if(optarg[strlen(optarg)-1]=='k' || optarg[strlen(optarg)-1]=='K') { sz = (1024 * atoi(optarg)); } if(optarg[strlen(optarg)-1]=='m' || optarg[strlen(optarg)-1]=='M') { sz = (1024 * 1024 * atoi(optarg)); } if(sz < 0) sz=1; break; case 'l': /* lower force value */ lower=atoi(optarg); range=1; if(lower < 0) lower=1; break; case 'v': /* version */ splash(); exit(0); break; case 'u': /* upper force value */ upper=atoi(optarg); range=1; if(upper < 0) upper=1; break; case 't': /* verbose */ verbose=1; break; case 'e': /* Excel */ excel=1; break; case 'b': /* Best */ best=1; break; case 'w': /* Worst */ worst=1; break; } } mbuffer=(char *)malloc(sz); memset(mbuffer,'a',sz); if(!excel) printf("\nFileop: File size is %d, Output is in Ops/sec. (A=Avg, B=Best, W=Worst)\n",sz); if(!verbose) { #ifdef Windows printf(" . %6s %6s %6s %6s %6s %6s %6s %6s %6s %6s %6s %12s\n", "mkdir","rmdir","create","read","write","close","stat", "access","chmod","readdir","delete"," Total_files"); #else printf(" . %6s %6s %6s %6s %6s %6s %6s %6s %6s %6s %6s %6s %6s %12s\n", "mkdir","rmdir","create","read","write","close","stat", "access","chmod","readdir","link ","unlink","delete", " Total_files"); #endif } if(x==0) x=1; if(range==0) lower=upper=x; for(i=lower; i<=upper; i++) { clear_stats(); x=i; /* * Dir Create test */ dir_create(x); if(verbose) { printf("mkdir: Dirs = %9lld ",stats[_STAT_DIR_CREATE].counter); printf("Total Time = %12.9f seconds\n", stats[_STAT_DIR_CREATE].total_time); printf(" Avg mkdir(s)/sec = %12.2f (%12.9f seconds/op)\n", stats[_STAT_DIR_CREATE].counter/stats[_STAT_DIR_CREATE].total_time, stats[_STAT_DIR_CREATE].total_time/stats[_STAT_DIR_CREATE].counter); printf(" Best mkdir(s)/sec = %12.2f (%12.9f seconds/op)\n",1/stats[_STAT_DIR_CREATE].best,stats[_STAT_DIR_CREATE].best); printf(" Worst mkdir(s)/sec = %12.2f (%12.9f seconds/op)\n\n",1/stats[_STAT_DIR_CREATE].worst,stats[_STAT_DIR_CREATE].worst); } /* * Dir delete test */ dir_delete(x); if(verbose) { printf("rmdir: Dirs = %9lld ",stats[_STAT_DIR_DELETE].counter); printf("Total Time = %12.9f seconds\n",stats[_STAT_DIR_DELETE].total_time); printf(" Avg rmdir(s)/sec = %12.2f (%12.9f seconds/op)\n", stats[_STAT_DIR_DELETE].counter/stats[_STAT_DIR_DELETE].total_time, stats[_STAT_DIR_DELETE].total_time/stats[_STAT_DIR_DELETE].counter); printf(" Best rmdir(s)/sec = %12.2f (%12.9f seconds/op)\n",1/stats[_STAT_DIR_DELETE].best,stats[_STAT_DIR_DELETE].best); printf(" Worst rmdir(s)/sec = %12.2f (%12.9f seconds/op)\n\n",1/stats[_STAT_DIR_DELETE].worst,stats[_STAT_DIR_DELETE].worst); } /* * Create test */ file_create(x); if(verbose) { printf("create: Files = %9lld ",stats[_STAT_CREATE].counter); printf("Total Time = %12.9f seconds\n", stats[_STAT_CREATE].total_time); printf(" Avg create(s)/sec = %12.2f (%12.9f seconds/op)\n", stats[_STAT_CREATE].counter/stats[_STAT_CREATE].total_time, stats[_STAT_CREATE].total_time/stats[_STAT_CREATE].counter); printf(" Best create(s)/sec = %12.2f (%12.9f seconds/op)\n", 1/stats[_STAT_CREATE].best,stats[_STAT_CREATE].best); printf(" Worst create(s)/sec = %12.2f (%12.9f seconds/op)\n\n", 1/stats[_STAT_CREATE].worst,stats[_STAT_CREATE].worst); printf("write: Files = %9lld ",stats[_STAT_WRITE].counter); printf("Total Time = %12.9f seconds\n", stats[_STAT_WRITE].total_time); printf(" Avg write(s)/sec = %12.2f (%12.9f seconds/op)\n", stats[_STAT_WRITE].counter/stats[_STAT_WRITE].total_time, stats[_STAT_WRITE].total_time/stats[_STAT_WRITE].counter); printf(" Best write(s)/sec = %12.2f (%12.9f seconds/op)\n", 1/stats[_STAT_WRITE].best,stats[_STAT_WRITE].best); printf(" Worst write(s)/sec = %12.2f (%12.9f seconds/op)\n\n", 1/stats[_STAT_WRITE].worst,stats[_STAT_WRITE].worst); printf("close: Files = %9lld ",stats[_STAT_CLOSE].counter); printf("Total Time = %12.9f seconds\n", stats[_STAT_CLOSE].total_time); printf(" Avg close(s)/sec = %12.2f (%12.9f seconds/op)\n", stats[_STAT_CLOSE].counter/stats[_STAT_CLOSE].total_time, stats[_STAT_CLOSE].total_time/stats[_STAT_CLOSE].counter); printf(" Best close(s)/sec = %12.2f (%12.9f seconds/op)\n", 1/stats[_STAT_CLOSE].best,stats[_STAT_CLOSE].best); printf(" Worst close(s)/sec = %12.2f (%12.9f seconds/op)\n\n", 1/stats[_STAT_CLOSE].worst,stats[_STAT_CLOSE].worst); } /* * Stat test */ file_stat(x); if(verbose) { printf("stat: Files = %9lld ",stats[_STAT_STAT].counter); printf("Total Time = %12.9f seconds\n", stats[_STAT_STAT].total_time); printf(" Avg stat(s)/sec = %12.2f (%12.9f seconds/op)\n", stats[_STAT_STAT].counter/stats[_STAT_STAT].total_time, stats[_STAT_STAT].total_time/stats[_STAT_STAT].counter); printf(" Best stat(s)/sec = %12.2f (%12.9f seconds/op)\n", 1/stats[_STAT_STAT].best,stats[_STAT_STAT].best); printf(" Worst stat(s)/sec = %12.2f (%12.9f seconds/op)\n\n", 1/stats[_STAT_STAT].worst,stats[_STAT_STAT].worst); } /* * Read test */ file_read(x); if(verbose) { printf("read: Files = %9lld ",stats[_STAT_READ].counter); printf("Total Time = %12.9f seconds\n", stats[_STAT_READ].total_time); printf(" Avg read(s)/sec = %12.2f (%12.9f seconds/op)\n", stats[_STAT_READ].counter/stats[_STAT_READ].total_time, stats[_STAT_READ].total_time/stats[_STAT_READ].counter); printf(" Best read(s)/sec = %12.2f (%12.9f seconds/op)\n", 1/stats[_STAT_READ].best,stats[_STAT_READ].best); printf(" Worst read(s)/sec = %12.2f (%12.9f seconds/op)\n\n", 1/stats[_STAT_READ].worst,stats[_STAT_READ].worst); } /* * Access test */ file_access(x); if(verbose) { printf("access: Files = %9lld ",stats[_STAT_ACCESS].counter); printf("Total Time = %12.9f seconds\n", stats[_STAT_ACCESS].total_time); printf(" Avg access(s)/sec = %12.2f (%12.9f seconds/op)\n", stats[_STAT_ACCESS].counter/stats[_STAT_ACCESS].total_time, stats[_STAT_ACCESS].total_time/stats[_STAT_ACCESS].counter); printf(" Best access(s)/sec = %12.2f (%12.9f seconds/op)\n", 1/stats[_STAT_ACCESS].best,stats[_STAT_ACCESS].best); printf(" Worst access(s)/sec = %12.2f (%12.9f seconds/op)\n\n", 1/stats[_STAT_ACCESS].worst,stats[_STAT_ACCESS].worst); } /* * Chmod test */ file_chmod(x); if(verbose) { printf("chmod: Files = %9lld ",stats[_STAT_CHMOD].counter); printf("Total Time = %12.9f seconds\n", stats[_STAT_CHMOD].total_time); printf(" Avg chmod(s)/sec = %12.2f (%12.9f seconds/op)\n", stats[_STAT_CHMOD].counter/stats[_STAT_CHMOD].total_time, stats[_STAT_CHMOD].total_time/stats[_STAT_CHMOD].counter); printf(" Best chmod(s)/sec = %12.2f (%12.9f seconds/op)\n", 1/stats[_STAT_CHMOD].best,stats[_STAT_CHMOD].best); printf(" Worst chmod(s)/sec = %12.2f (%12.9f seconds/op)\n\n", 1/stats[_STAT_CHMOD].worst,stats[_STAT_CHMOD].worst); } /* * readdir test */ file_readdir(x); if(verbose) { printf("readdir: Files = %9lld ",stats[_STAT_READDIR].counter); printf("Total Time = %12.9f seconds\n", stats[_STAT_READDIR].total_time); printf(" Avg readdir(s)/sec = %12.2f (%12.9f seconds/op)\n", stats[_STAT_READDIR].counter/stats[_STAT_READDIR].total_time, stats[_STAT_READDIR].total_time/stats[_STAT_READDIR].counter); printf(" Best readdir(s)/sec = %12.2f (%12.9f seconds/op)\n", 1/stats[_STAT_READDIR].best,stats[_STAT_READDIR].best); printf(" Worst readdir(s)/sec = %12.2f (%12.9f seconds/op)\n\n", 1/stats[_STAT_READDIR].worst,stats[_STAT_READDIR].worst); } #if !defined(Windows) /* * link test */ file_link(x); if(verbose) { printf("link: Files = %9lld ",stats[_STAT_LINK].counter); printf("Total Time = %12.9f seconds\n",stats[_STAT_LINK].total_time); printf(" Avg link(s)/sec = %12.2f (%12.9f seconds/op)\n", stats[_STAT_LINK].counter/stats[_STAT_LINK].total_time, stats[_STAT_LINK].total_time/stats[_STAT_LINK].counter); printf(" Best link(s)/sec = %12.2f (%12.9f seconds/op)\n", 1/stats[_STAT_LINK].best,stats[_STAT_LINK].best); printf(" Worst link(s)/sec = %12.2f (%12.9f seconds/op)\n\n", 1/stats[_STAT_LINK].worst,stats[_STAT_LINK].worst); } /* * unlink test */ file_unlink(x); if(verbose) { printf("unlink: Files = %9lld ",stats[_STAT_UNLINK].counter); printf("Total Time = %12.9f seconds\n", stats[_STAT_UNLINK].total_time); printf(" Avg unlink(s)/sec = %12.2f (%12.9f seconds/op)\n", stats[_STAT_UNLINK].counter/stats[_STAT_UNLINK].total_time, stats[_STAT_UNLINK].total_time/stats[_STAT_UNLINK].counter); printf(" Best unlink(s)/sec = %12.2f (%12.9f seconds/op)\n", 1/stats[_STAT_UNLINK].best,stats[_STAT_UNLINK].best); printf(" Worst unlink(s)/sec = %12.2f (%12.9f seconds/op)\n\n", 1/stats[_STAT_UNLINK].worst,stats[_STAT_UNLINK].worst); } #endif /* * Delete test */ file_delete(x); if(verbose) { printf("delete: Files = %9lld ",stats[_STAT_DELETE].counter); printf("Total Time = %12.9f seconds\n", stats[_STAT_DELETE].total_time); printf(" Avg delete(s)/sec = %12.2f (%12.9f seconds/op)\n", stats[_STAT_DELETE].counter/stats[_STAT_DELETE].total_time, stats[_STAT_DELETE].total_time/stats[_STAT_DELETE].counter); printf(" Best delete(s)/sec = %12.2f (%12.9f seconds/op)\n", 1/stats[_STAT_DELETE].best,stats[_STAT_DELETE].best); printf(" Worst delete(s)/sec = %12.2f (%12.9f seconds/op)\n\n", 1/stats[_STAT_DELETE].worst,stats[_STAT_DELETE].worst); } if(!verbose) { printf("%c %4d %6.0f ",'A',x,stats[_STAT_DIR_CREATE].counter/stats[_STAT_DIR_CREATE].total_time); printf("%6.0f ",stats[_STAT_DIR_DELETE].counter/stats[_STAT_DIR_DELETE].total_time); printf("%6.0f ",stats[_STAT_CREATE].counter/stats[_STAT_CREATE].total_time); printf("%6.0f ",stats[_STAT_READ].counter/stats[_STAT_READ].total_time); printf("%6.0f ",stats[_STAT_WRITE].counter/stats[_STAT_WRITE].total_time); printf("%6.0f ",stats[_STAT_CLOSE].counter/stats[_STAT_CLOSE].total_time); printf("%6.0f ",stats[_STAT_STAT].counter/stats[_STAT_STAT].total_time); printf("%6.0f ",stats[_STAT_ACCESS].counter/stats[_STAT_ACCESS].total_time); printf("%6.0f ",stats[_STAT_CHMOD].counter/stats[_STAT_CHMOD].total_time); printf("%6.0f ",stats[_STAT_READDIR].counter/stats[_STAT_READDIR].total_time); #ifndef Windows printf("%6.0f ",stats[_STAT_LINK].counter/stats[_STAT_LINK].total_time); printf("%6.0f ",stats[_STAT_UNLINK].counter/stats[_STAT_UNLINK].total_time); #endif printf("%6.0f ",stats[_STAT_DELETE].counter/stats[_STAT_DELETE].total_time); printf("%12d ",x*x*x); printf("\n"); fflush(stdout); if(best) { printf("%c %4d %6.0f ",'B',x, 1/stats[_STAT_DIR_CREATE].best); printf("%6.0f ",1/stats[_STAT_DIR_DELETE].best); printf("%6.0f ",1/stats[_STAT_CREATE].best); printf("%6.0f ",1/stats[_STAT_READ].best); printf("%6.0f ",1/stats[_STAT_WRITE].best); printf("%6.0f ",1/stats[_STAT_CLOSE].best); printf("%6.0f ",1/stats[_STAT_STAT].best); printf("%6.0f ",1/stats[_STAT_ACCESS].best); printf("%6.0f ",1/stats[_STAT_CHMOD].best); printf("%6.0f ",1/stats[_STAT_READDIR].best); #ifndef Windows printf("%6.0f ",1/stats[_STAT_LINK].best); printf("%6.0f ",1/stats[_STAT_UNLINK].best); #endif printf("%6.0f ",1/stats[_STAT_DELETE].best); printf("%12d ",x*x*x); printf("\n"); fflush(stdout); } if(worst) { printf("%c %4d %6.0f ",'W',x, 1/stats[_STAT_DIR_CREATE].worst); printf("%6.0f ",1/stats[_STAT_DIR_DELETE].worst); printf("%6.0f ",1/stats[_STAT_CREATE].worst); printf("%6.0f ",1/stats[_STAT_READ].worst); printf("%6.0f ",1/stats[_STAT_WRITE].worst); printf("%6.0f ",1/stats[_STAT_CLOSE].worst); printf("%6.0f ",1/stats[_STAT_STAT].worst); printf("%6.0f ",1/stats[_STAT_ACCESS].worst); printf("%6.0f ",1/stats[_STAT_CHMOD].worst); printf("%6.0f ",1/stats[_STAT_READDIR].worst); #ifndef Windows printf("%6.0f ",1/stats[_STAT_LINK].worst); printf("%6.0f ",1/stats[_STAT_UNLINK].worst); #endif printf("%6.0f ",1/stats[_STAT_DELETE].worst); printf("%12d ",x*x*x); printf("\n"); fflush(stdout); } } } return(0); }
static int diversion_add(const char *const *argv) { const char *filename = argv[0]; struct file file_from, file_to; struct fsys_diversion *contest, *altname; struct fsys_namenode *fnn_from, *fnn_to; struct pkgset *pkgset; opt_pkgname_match_any = false; opt_rename_setup(); /* Handle filename. */ if (!filename || argv[1]) badusage(_("--%s needs a single argument"), cipaction->olong); diversion_check_filename(filename); file_init(&file_from, filename); file_stat(&file_from); if (file_from.stat_state == FILE_STAT_VALID && S_ISDIR(file_from.stat.st_mode)) badusage(_("cannot divert directories")); fnn_from = fsys_hash_find_node(filename, 0); /* Handle divertto. */ if (opt_divertto == NULL) opt_divertto = str_fmt("%s.distrib", filename); if (strcmp(filename, opt_divertto) == 0) badusage(_("cannot divert file '%s' to itself"), filename); file_init(&file_to, opt_divertto); fnn_to = fsys_hash_find_node(opt_divertto, 0); /* Handle package name. */ if (opt_pkgname == NULL) pkgset = NULL; else pkgset = pkg_hash_find_set(opt_pkgname); /* Check we are not stomping over an existing diversion. */ if (fnn_from->divert || fnn_to->divert) { if (fnn_to->divert && fnn_to->divert->camefrom && strcmp(fnn_to->divert->camefrom->name, filename) == 0 && fnn_from->divert && fnn_from->divert->useinstead && strcmp(fnn_from->divert->useinstead->name, opt_divertto) == 0 && fnn_from->divert->pkgset == pkgset) { if (opt_verbose > 0) printf(_("Leaving '%s'\n"), diversion_describe(fnn_from->divert)); return 0; } ohshit(_("'%s' clashes with '%s'"), diversion_current(filename), fnn_from->divert ? diversion_describe(fnn_from->divert) : diversion_describe(fnn_to->divert)); } /* Create new diversion. */ contest = nfmalloc(sizeof(*contest)); altname = nfmalloc(sizeof(*altname)); altname->camefrom = fnn_from; altname->camefrom->divert = contest; altname->useinstead = NULL; altname->pkgset = pkgset; contest->useinstead = fnn_to; contest->useinstead->divert = altname; contest->camefrom = NULL; contest->pkgset = pkgset; /* Update database and file system if needed. */ if (opt_verbose > 0) printf(_("Adding '%s'\n"), diversion_describe(contest)); if (opt_rename) opt_rename = check_rename(&file_from, &file_to); /* Check we are not renaming a file owned by the diverting pkgset. */ if (opt_rename && diversion_is_owned_by_self(pkgset, fnn_from)) { if (opt_verbose > 0) printf(_("Ignoring request to rename file '%s' " "owned by diverting package '%s'\n"), filename, pkgset->name); opt_rename = false; } if (opt_rename && diversion_is_essential(fnn_from)) warning(_("diverting file '%s' from an Essential package with " "rename is dangerous, use --no-rename"), filename); if (!opt_test) { divertdb_write(); if (opt_rename) file_rename(&file_from, &file_to); } return 0; }