Exemple #1
0
 def _differs(self, data1, data2, start=0, stop=None):
     with open(self._path("file1"), "wb") as f:
         f.write(data1.encode("ascii"))
     with open(self._path("file2"), "wb") as f:
         f.write(data2.encode("ascii"))
     return files_differ(self._path("file1"), self._path("file2"), start,
                         stop)
Exemple #2
0
 def _unpack_bootstrap_env(self, target, trn):
     """Unpack the bootstrap env from the given target directory."""
     vdir = os.path.basename(target)
     #  Move new bootrapping environment into main app dir.
     #  Be sure to move dependencies before executables.
     bootstrap = os.path.join(target, ESKY_CONTROL_DIR, "bootstrap")
     for nm in self._version_manifest(vdir):
         bssrc = os.path.join(bootstrap, nm)
         bsdst = os.path.join(self.appdir, nm)
         if os.path.exists(bssrc):
             #  On windows we can't atomically replace files.
             #  If they differ in a "safe" way we put them aside
             #  to overwrite at a later time.
             if sys.platform == "win32" and os.path.exists(bsdst):
                 if not files_differ(bssrc, bsdst):
                     trn.remove(bssrc)
                 elif esky.winres.is_safe_to_overwrite(bssrc, bsdst):
                     ovrdir = os.path.join(target, ESKY_CONTROL_DIR)
                     ovrdir = os.path.join(ovrdir, "overwrite")
                     if not os.path.exists(ovrdir):
                         os.mkdir(ovrdir)
                     trn.move(bssrc, os.path.join(ovrdir, nm))
                 else:
                     trn.move(bssrc, bsdst)
             else:
                 trn.move(bssrc, bsdst)
         if os.path.isdir(os.path.dirname(bssrc)):
             if not os.listdir(os.path.dirname(bssrc)):
                 trn.remove(os.path.dirname(bssrc))
     #  Remove the bootstrap dir; the new version is now installed
     trn.remove(bootstrap)
Exemple #3
0
 def copy(self,source,target):
     source = self._check_path(source)
     target = self._check_path(target)
     if os.path.isdir(source):
         if os.path.isdir(target):
             s_names = os.listdir(source)
             for nm in s_names:
                 self.copy(os.path.join(source,nm),
                           os.path.join(target,nm))
             for nm in os.listdir(target):
                 if nm not in s_names:
                     self._remove(os.path.join(target,nm))
         else:
             self._copy(source,target)
     else:
         if os.path.isdir(target) or files_differ(source,target):
             self._copy(source,target)
Exemple #4
0
 def copy(self,source,target):
     source = self._check_path(source)
     target = self._check_path(target)
     if os.path.isdir(source):
         if os.path.isdir(target):
             s_names = os.listdir(source)
             for nm in s_names:
                 self.copy(os.path.join(source,nm),
                           os.path.join(target,nm))
             for nm in os.listdir(target):
                 if nm not in s_names:
                     self.remove(os.path.join(target,nm))
         else:
             self.pending.append(("_copy",source,target))
     else:
         if os.path.isdir(target) or files_differ(source,target):
             self.pending.append(("_copy",source,target))
Exemple #5
0
def is_safe_to_overwrite(source,target):
    """Check whether it is safe to overwrite target exe with source exe.

    This function checks whether two exe files 'source' and 'target' differ
    only in the contents of certain non-critical resource segments.  If so,
    then overwriting the target file with the contents of the source file
    should be safe even in the face of system crashes or power outages; the
    worst outcome would be a corrupted resource such as an icon.
    """
    if not source.endswith(".exe") or not target.endswith(".exe"):
        return False
    #  Check if they're the same size
    s_sz = os.stat(source).st_size
    t_sz = os.stat(target).st_size
    if s_sz != t_sz:
        return False
    #  Find each safe resource, and confirm that either (1) it's in the same
    #  location in both executables, or (2) it's missing in both executables.
    #  TODO: do this by enumerating resources
    safe_res = ((RT_VERSION,1),(RT_ICON,1),(RT_ICON,2))
    locs = []
    for (rtype,rid) in safe_res:
        try:
            s_loc = find_resource(source,rtype,rid)
        except WindowsError:
            s_loc = None
        try: 
            t_loc = find_resource(target,rtype,rid)
        except WindowsError:
            t_loc = None
        if s_loc != t_loc:
            return False
        if s_loc is not None:
            locs.append(s_loc)
    #  Confirm that no other portions of the file have changed
    if locs:
        locs.extend(((0,0),(s_sz,s_sz)))
        locs.sort()
        for (_,start),(stop,_) in pairwise(locs):
            if files_differ(source,target,start,stop):
                return False
    #  Looks safe to me!
    return True
Exemple #6
0
 def move(self,source,target):
     source = self._check_path(source)
     target = self._check_path(target)
     if os.path.isdir(source):
         if os.path.isdir(target):
             s_names = os.listdir(source)
             for nm in s_names:
                 self.move(os.path.join(source,nm),
                           os.path.join(target,nm))
             for nm in os.listdir(target):
                 if nm not in s_names:
                     self.remove(os.path.join(target,nm))
             self.remove(source)
         else:
             self.pending.append(("_move",source,target))
     else:
         if os.path.isdir(target) or files_differ(source,target):
             self.pending.append(("_move",source,target))
         else:
             self.pending.append(("_remove",source))
Exemple #7
0
def is_safe_to_overwrite(source,target):
    """Check whether it is safe to overwrite target exe with source exe.

    This function checks whether two exe files 'source' and 'target' differ
    only in the contents of certain non-critical resource segments.  If so,
    then overwriting the target file with the contents of the source file
    should be safe even in the face of system crashes or power outages; the
    worst outcome would be a corrupted resource such as an icon.
    """
    if not source.endswith(".exe") or not target.endswith(".exe"):
        return False
    #  Check if they're the same size
    s_sz = os.stat(source).st_size
    t_sz = os.stat(target).st_size
    if s_sz != t_sz:
        return False
    #  Find each safe resource, and confirm that either (1) it's in the same
    #  location in both executables, or (2) it's missing in both executables.
    locs = []
    for (rtype,rid,rlang) in COMMON_SAFE_RESOURCES:
        try:
            s_loc = find_resource(source,rtype,rid,rlang)
        except WindowsError:
            s_loc = None
        try: 
            t_loc = find_resource(target,rtype,rid,rlang)
        except WindowsError:
            t_loc = None
        if s_loc != t_loc:
            return False
        if s_loc is not None:
            locs.append(s_loc)
    #  Confirm that no other portions of the file have changed
    if locs:
        locs.extend(((0,0),(s_sz,s_sz)))
        locs.sort()
        for (_,start),(stop,_) in pairwise(locs):
            if files_differ(source,target,start,stop):
                return False
    #  Looks safe to me!
    return True
Exemple #8
0
 def _differs(self, data1, data2, start=0, stop=None):
     with open(self._path("file1"), "wb") as f:
         f.write(data1.encode("ascii"))
     with open(self._path("file2"), "wb") as f:
         f.write(data2.encode("ascii"))
     return files_differ(self._path("file1"), self._path("file2"), start, stop)