]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/Python/UPT/Core/FileHook.py
BaseTools: Clean up source files
[mirror_edk2.git] / BaseTools / Source / Python / UPT / Core / FileHook.py
CommitLineData
421ccda3
HC
1## @file\r
2# This file hooks file and directory creation and removal\r
3#\r
f7496d71 4# Copyright (c) 2014 - 2018, Intel Corporation. All rights reserved.<BR>\r
421ccda3 5#\r
f7496d71
LG
6# This program and the accompanying materials are licensed and made available\r
7# under the terms and conditions of the BSD License which accompanies this\r
8# distribution. The full text of the license may be found at\r
421ccda3
HC
9# http://opensource.org/licenses/bsd-license.php\r
10#\r
11# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
12# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
13#\r
14\r
15'''\r
16File hook\r
17'''\r
18\r
19import os\r
20import stat\r
21import time\r
22import zipfile\r
23from time import sleep\r
24from Library import GlobalData\r
25\r
26__built_in_remove__ = os.remove\r
27__built_in_mkdir__ = os.mkdir\r
28__built_in_rmdir__ = os.rmdir\r
29__built_in_chmod__ = os.chmod\r
30__built_in_open__ = open\r
31\r
32_RMFILE = 0\r
33_MKFILE = 1\r
34_RMDIR = 2\r
35_MKDIR = 3\r
36_CHMOD = 4\r
37\r
38gBACKUPFILE = 'file.backup'\r
39gEXCEPTION_LIST = ['Conf'+os.sep+'DistributionPackageDatabase.db', '.tmp', gBACKUPFILE]\r
40\r
41class _PathInfo:\r
42 def __init__(self, action, path, mode=-1):\r
43 self.action = action\r
44 self.path = path\r
45 self.mode = mode\r
46\r
47class RecoverMgr:\r
48 def __init__(self, workspace):\r
49 self.rlist = []\r
50 self.zip = None\r
51 self.workspace = os.path.normpath(workspace)\r
52 self.backupfile = gBACKUPFILE\r
53 self.zipfile = os.path.join(self.workspace, gBACKUPFILE)\r
54\r
55 def _createzip(self):\r
56 if self.zip:\r
57 return\r
58 self.zip = zipfile.ZipFile(self.zipfile, 'w', zipfile.ZIP_DEFLATED)\r
59\r
60 def _save(self, tmp, path):\r
61 if not self._tryhook(path):\r
62 return\r
63 self.rlist.append(_PathInfo(tmp, path))\r
64\r
65 def bkrmfile(self, path):\r
66 arc = self._tryhook(path)\r
67 if arc and os.path.isfile(path):\r
68 self._createzip()\r
69 self.zip.write(path, arc.encode('utf_8'))\r
70 sta = os.stat(path)\r
71 oldmode = stat.S_IMODE(sta.st_mode)\r
72 self.rlist.append(_PathInfo(_CHMOD, path, oldmode))\r
73 self.rlist.append(_PathInfo(_RMFILE, path))\r
74 __built_in_remove__(path)\r
75\r
76 def bkmkfile(self, path, mode, bufsize):\r
77 if not os.path.exists(path):\r
78 self._save(_MKFILE, path)\r
79 return __built_in_open__(path, mode, bufsize)\r
80\r
81 def bkrmdir(self, path):\r
82 if os.path.exists(path):\r
83 sta = os.stat(path)\r
84 oldmode = stat.S_IMODE(sta.st_mode)\r
85 self.rlist.append(_PathInfo(_CHMOD, path, oldmode))\r
86 self._save(_RMDIR, path)\r
87 __built_in_rmdir__(path)\r
88\r
89 def bkmkdir(self, path, mode):\r
90 if not os.path.exists(path):\r
91 self._save(_MKDIR, path)\r
92 __built_in_mkdir__(path, mode)\r
93\r
94 def bkchmod(self, path, mode):\r
95 if self._tryhook(path) and os.path.exists(path):\r
96 sta = os.stat(path)\r
97 oldmode = stat.S_IMODE(sta.st_mode)\r
98 self.rlist.append(_PathInfo(_CHMOD, path, oldmode))\r
99 __built_in_chmod__(path, mode)\r
100\r
101 def rollback(self):\r
102 if self.zip:\r
103 self.zip.close()\r
104 self.zip = None\r
105 index = len(self.rlist) - 1\r
106 while index >= 0:\r
107 item = self.rlist[index]\r
108 exist = os.path.exists(item.path)\r
109 if item.action == _MKFILE and exist:\r
110 #if not os.access(item.path, os.W_OK):\r
111 # os.chmod(item.path, S_IWUSR)\r
112 __built_in_remove__(item.path)\r
113 elif item.action == _RMFILE and not exist:\r
114 if not self.zip:\r
115 self.zip = zipfile.ZipFile(self.zipfile, 'r', zipfile.ZIP_DEFLATED)\r
116 arcname = os.path.normpath(item.path)\r
117 arcname = arcname[len(self.workspace)+1:].encode('utf_8')\r
118 if os.sep != "/" and os.sep in arcname:\r
119 arcname = arcname.replace(os.sep, '/')\r
120 mtime = self.zip.getinfo(arcname).date_time\r
121 content = self.zip.read(arcname)\r
122 filep = __built_in_open__(item.path, "wb")\r
123 filep.write(content)\r
124 filep.close()\r
125 intime = time.mktime(mtime + (0, 0, 0))\r
126 os.utime(item.path, (intime, intime))\r
127 elif item.action == _MKDIR and exist:\r
128 while True:\r
129 try:\r
130 __built_in_rmdir__(item.path)\r
131 break\r
132 except IOError:\r
133 # Sleep a short time and try again\r
134 # The anti-virus software may delay the file removal in this directory\r
135 sleep(0.1)\r
136 elif item.action == _RMDIR and not exist:\r
137 __built_in_mkdir__(item.path)\r
138 elif item.action == _CHMOD and exist:\r
139 try:\r
140 __built_in_chmod__(item.path, item.mode)\r
141 except EnvironmentError:\r
142 pass\r
143 index -= 1\r
144 self.commit()\r
145\r
146 def commit(self):\r
147 if self.zip:\r
148 self.zip.close()\r
149 __built_in_remove__(self.zipfile)\r
150\r
151 # Check if path needs to be hooked\r
152 def _tryhook(self, path):\r
153 path = os.path.normpath(path)\r
154 works = self.workspace if str(self.workspace).endswith(os.sep) else (self.workspace + os.sep)\r
155 if not path.startswith(works):\r
156 return ''\r
157 for exceptdir in gEXCEPTION_LIST:\r
158 full = os.path.join(self.workspace, exceptdir)\r
159 if full == path or path.startswith(full + os.sep) or os.path.split(full)[0] == path:\r
160 return ''\r
161 return path[len(self.workspace)+1:]\r
162\r
163def _hookrm(path):\r
164 if GlobalData.gRECOVERMGR:\r
165 GlobalData.gRECOVERMGR.bkrmfile(path)\r
166 else:\r
167 __built_in_remove__(path)\r
168\r
2617a73c 169def _hookmkdir(path, mode=0o777):\r
421ccda3
HC
170 if GlobalData.gRECOVERMGR:\r
171 GlobalData.gRECOVERMGR.bkmkdir(path, mode)\r
172 else:\r
173 __built_in_mkdir__(path, mode)\r
174\r
175def _hookrmdir(path):\r
176 if GlobalData.gRECOVERMGR:\r
177 GlobalData.gRECOVERMGR.bkrmdir(path)\r
178 else:\r
179 __built_in_rmdir__(path)\r
180\r
181def _hookmkfile(path, mode='r', bufsize=-1):\r
182 if GlobalData.gRECOVERMGR:\r
183 return GlobalData.gRECOVERMGR.bkmkfile(path, mode, bufsize)\r
184 return __built_in_open__(path, mode, bufsize)\r
185\r
186def _hookchmod(path, mode):\r
187 if GlobalData.gRECOVERMGR:\r
188 GlobalData.gRECOVERMGR.bkchmod(path, mode)\r
189 else:\r
190 __built_in_chmod__(path, mode)\r
191\r
192def SetRecoverMgr(mgr):\r
193 GlobalData.gRECOVERMGR = mgr\r
194\r
195os.remove = _hookrm\r
196os.mkdir = _hookmkdir\r
197os.rmdir = _hookrmdir\r
198os.chmod = _hookchmod\r
199__FileHookOpen__ = _hookmkfile\r