@@ -73,15 +73,35 @@ impl Updater {
7373 Ok ( self . output_dir . join ( filename) )
7474 }
7575
76+ fn verify_existing_file ( & self , path : & Path , expected_sha1 : & str ) -> Result < bool > {
77+ use sha1:: { Digest , Sha1 } ;
78+
79+ let mut file = fs:: File :: open ( path) ?;
80+ let mut hasher = Sha1 :: new ( ) ;
81+ std:: io:: copy ( & mut file, & mut hasher) ?;
82+ let hash = hasher. finalize ( ) ;
83+ let actual_sha1 = hex:: encode ( hash) ;
84+
85+ Ok ( actual_sha1. eq_ignore_ascii_case ( expected_sha1) )
86+ }
87+
7688 pub fn check_for_update ( & self ) -> Result < bool > {
7789 let ( control, _zsync_url) = self . fetch_control_file ( ) ?;
78-
7990 let output_path = self . resolve_output_path ( & control) ?;
80- if output_path. exists ( ) && !self . overwrite {
81- return Err ( Error :: AppImage ( format ! (
82- "Output file already exists: {}" ,
83- output_path. display( )
84- ) ) ) ;
91+
92+ if output_path. exists ( ) {
93+ if let Some ( ref expected_sha1) = control. sha1
94+ && self . verify_existing_file ( & output_path, expected_sha1) ?
95+ {
96+ return Ok ( false ) ;
97+ }
98+
99+ if !self . overwrite {
100+ return Err ( Error :: AppImage ( format ! (
101+ "Output file already exists: {}" ,
102+ output_path. display( )
103+ ) ) ) ;
104+ }
85105 }
86106
87107 Ok ( true )
@@ -91,11 +111,19 @@ impl Updater {
91111 let ( control, zsync_url) = self . fetch_control_file ( ) ?;
92112 let output_path = self . resolve_output_path ( & control) ?;
93113
94- if output_path. exists ( ) && !self . overwrite {
95- return Err ( Error :: AppImage ( format ! (
96- "Output file already exists: {}" ,
97- output_path. display( )
98- ) ) ) ;
114+ if output_path. exists ( ) {
115+ if let Some ( ref expected_sha1) = control. sha1
116+ && self . verify_existing_file ( & output_path, expected_sha1) ?
117+ {
118+ return Ok ( output_path) ;
119+ }
120+
121+ if !self . overwrite {
122+ return Err ( Error :: AppImage ( format ! (
123+ "Output file already exists: {}" ,
124+ output_path. display( )
125+ ) ) ) ;
126+ }
99127 }
100128
101129 let original_perms = fs:: metadata ( self . appimage . path ( ) )
@@ -130,6 +158,11 @@ impl Updater {
130158 Ok ( output_path)
131159 }
132160
161+ pub fn output_path ( & self ) -> Result < PathBuf > {
162+ let ( control, _zsync_url) = self . fetch_control_file ( ) ?;
163+ self . resolve_output_path ( & control)
164+ }
165+
133166 pub fn progress ( & self ) -> Option < ( u64 , u64 ) > {
134167 None
135168 }
0 commit comments