// // aegis - project change supervisor // Copyright (C) 1999, 2002-2008 Peter Miller // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see // . // #include #include // for assert #include #include #include #include #include #include static bool source_file_whiteout(change::pointer cp) { pconf_ty *pconf_data = change_pconf_get(cp, 0); work_area_style_ty *s = pconf_data->development_directory_style; assert(s); return (s && s->source_file_whiteout); } void change_file_whiteout_write(change::pointer cp, string_ty *filename, user_ty::pointer up) { string_ty *dd; string_ty *s2; dd = change_development_directory_get(cp, 0); // // Remove any existing file (this cleans up junk, and // breaks the link if we are using symlink trees). // s2 = os_path_join(dd, filename); up->become_begin(); if (os_exists(s2)) os_unlink(s2); up->become_end(); // // The whiteout is controlled by the development_directory_style's // source_file_whiteout field, except if overridden by the command line. // int whiteout_default = source_file_whiteout(cp); if (up->whiteout(whiteout_default)) { string_ty *content; content = change_file_whiteout(cp, filename); if (content) { int umask; int mode; fstate_src_ty *p_src_data; // // create a junk file in the change // umask = ~change_umask(cp); up->become_begin(); os_mkdir_between(dd, filename, 02755); undo_unlink_errok(s2); mode = 0644 & ~umask; file_from_string(s2, content, mode); str_free(content); up->become_end(); // // update the mod-time to match the project // (if exists in project) // p_src_data = project_file_find(cp->pp, filename, view_path_extreme); if (p_src_data) { string_ty *s3; time_t mtime_old; time_t mtime_young; time_t when; // // Make sure the whiteout file is // younger than the baseline file. // This ensures that a build (which // will fail) is triggered if the file // is still being referred to. // when = now(); s3 = project_file_path(cp->pp, filename); assert(s3); user_ty::become scoped(up); os_mtime_range(s3, &mtime_old, &mtime_young); str_free(s3); if (when <= mtime_old) when = mtime_old + 60; if (when <= mtime_young) when = mtime_young + 60; os_mtime_set_errok(s2, when); } } } str_free(s2); }