The MinGW.org Installation Manager Tool
Revisión | d4df04d04b0ed0c42dbd7974749d011df390e938 (tree) |
---|---|
Tiempo | 2013-06-28 18:01:06 |
Autor | Keith Marshall <keithmarshall@user...> |
Commiter | Keith Marshall |
Avoid inadvertent overwrite of existing files.
@@ -1,3 +1,20 @@ | ||
1 | +2013-06-28 Keith Marshall <keithmarshall@users.sourceforge.net> | |
2 | + | |
3 | + Avoid inadvertent overwrite of existing files. | |
4 | + | |
5 | + * src/mkpath.c (_O_NEWFILE): Conditionally specify attributes... | |
6 | + [IMPLEMENTATION_LEVEL == SETUP_TOOL_COMPONENT]: ...as they were... | |
7 | + [IMPLEMENTATION_LEVEL != SETUP_TOOL_COMPONENT]: ...else, include | |
8 | + _O_EXCL in the specified set; exclude _O_TRUNC. | |
9 | + | |
10 | + * src/tarproc.cpp (dmh_notify_extraction_failed): New static inline | |
11 | + function; it encapsulates the diagnostic message factored out from... | |
12 | + (pkgArchiveProcessor::ExtractFile): ...here, whence use it. | |
13 | + (create_output_stream): Also used in this new static inline function; | |
14 | + it adds an appropriate diagnostic wrapper around set_output_stream(), | |
15 | + when _O_EXCL prevents overwrite of an existing file. | |
16 | + (pkgArchiveProcessor::SetOutputStream): Use it. | |
17 | + | |
1 | 18 | 2013-06-27 Keith Marshall <keithmarshall@users.sourceforge.net> |
2 | 19 | |
3 | 20 | Improve diagnostics for tar archive processing faults. |
@@ -4,7 +4,7 @@ | ||
4 | 4 | * $Id$ |
5 | 5 | * |
6 | 6 | * Written by Keith Marshall <keithmarshall@users.sourceforge.net> |
7 | - * Copyright (C) 2009, 2011, MinGW Project | |
7 | + * Copyright (C) 2009, 2011, 2013, MinGW.org Project | |
8 | 8 | * |
9 | 9 | * |
10 | 10 | * Helper functions for constructing path names, creating directory |
@@ -27,6 +27,7 @@ | ||
27 | 27 | * |
28 | 28 | */ |
29 | 29 | #include "mkpath.h" |
30 | +#include "pkgimpl.h" | |
30 | 31 | |
31 | 32 | #include <stdio.h> |
32 | 33 | #include <stdlib.h> |
@@ -46,9 +47,18 @@ | ||
46 | 47 | /* |
47 | 48 | * MS-Windows _O_BINARY vs. _O_TEXT discrimination can't be explicitly |
48 | 49 | * resolved in a simple `creat()' call; instead, we will use `_open()', |
49 | - * with the following explicit attribute set... | |
50 | + * with one of the following explicit attribute sets... | |
50 | 51 | */ |
51 | -# define _O_NEWFILE _O_RDWR | _O_CREAT | _O_TRUNC | _O_BINARY | |
52 | +# if IMPLEMENTATION_LEVEL == SETUP_TOOL_COMPONENT | |
53 | + /* | |
54 | + * ...allowing overwrite in the setup tool implementation... | |
55 | + */ | |
56 | +# define _O_NEWFILE _O_RDWR | _O_CREAT | _O_TRUNC | _O_BINARY | |
57 | +# else | |
58 | + /* ...but not in the standard mingw-get implementation... | |
59 | + */ | |
60 | +# define _O_NEWFILE _O_RDWR | _O_CREAT | _O_EXCL | _O_BINARY | |
61 | +# endif | |
52 | 62 | # define creat(P,M) _open( P, _O_NEWFILE, _map_posix_mode(M) ) |
53 | 63 | |
54 | 64 | /* Furthermore, MS-Windows protection modes are naive, in comparison |
@@ -68,6 +68,13 @@ int pkgArchiveProcessor::CreateExtractionDirectory( const char *pathname ) | ||
68 | 68 | return status; |
69 | 69 | } |
70 | 70 | |
71 | +static inline int dmh_notify_extraction_failed( const char *name ) | |
72 | +{ | |
73 | + /* Helper function to emit archive "extraction failed" diagnostics. | |
74 | + */ | |
75 | + return dmh_notify( DMH_ERROR, "%s: extraction failed\n", name ); | |
76 | +} | |
77 | + | |
71 | 78 | static inline int dmh_notify_archive_data_exhausted( const char *context ) |
72 | 79 | { |
73 | 80 | /* Helper function to emit "premature end of archive" diagnostics. |
@@ -77,13 +84,30 @@ static inline int dmh_notify_archive_data_exhausted( const char *context ) | ||
77 | 84 | ); |
78 | 85 | } |
79 | 86 | |
87 | +static int create_output_stream( const char *name, int mode ) | |
88 | +{ | |
89 | + /* Wrapper encapsulating the set_output_stream() function, while | |
90 | + * protecting against inadvertently overwriting any unexpectedly | |
91 | + * pre-existing file. | |
92 | + */ | |
93 | + int fd = set_output_stream( name, mode ); | |
94 | + if( (fd == -1) && ((errno == EEXIST) || (errno == EACCES)) ) | |
95 | + { | |
96 | + /* Overwrite prevention was triggered; diagnose. | |
97 | + */ | |
98 | + dmh_notify_extraction_failed( name ); | |
99 | + dmh_notify( DMH_ERROR, "cannot replace existing file\n" ); | |
100 | + } | |
101 | + return fd; | |
102 | +} | |
103 | + | |
80 | 104 | inline int pkgArchiveProcessor::SetOutputStream( const char *name, int mode ) |
81 | 105 | { |
82 | 106 | /* Wrapper method to facilitate the set up of output streams |
83 | 107 | * for writing extracted content to disk, except in the special |
84 | 108 | * case where saving of files has been disabled. |
85 | 109 | */ |
86 | - return save_on_extract ? set_output_stream( name, mode ) : -2; | |
110 | + return save_on_extract ? create_output_stream( name, mode ) : -2; | |
87 | 111 | } |
88 | 112 | |
89 | 113 | int pkgArchiveProcessor::ExtractFile( int fd, const char *pathname, int status ) |
@@ -106,7 +130,7 @@ int pkgArchiveProcessor::ExtractFile( int fd, const char *pathname, int status ) | ||
106 | 130 | * written; discard it, and diagnose failure. |
107 | 131 | */ |
108 | 132 | unlink( pathname ); |
109 | - dmh_notify( DMH_ERROR, "%s: extraction failed\n", pathname ); | |
133 | + dmh_notify_extraction_failed( pathname ); | |
110 | 134 | switch( status ) |
111 | 135 | { |
112 | 136 | case TAR_ARCHIVE_DATA_READ_ERROR: |