Subversion Repositories DevTools

Rev

Rev 2085 | Rev 2311 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 2085 Rev 2310
Line 8... Line 8...
8
**
8
**
9
**  Description     :
9
**  Description     :
10
**                      The program mimics - but a lot faster a Jats Makefile fragment
10
**                      The program mimics - but a lot faster a Jats Makefile fragment
11
**                      The program will:
11
**                      The program will:
12
**
12
**
13
**                      Operate in two modes
13
**                      Operate in 5 modes
14
**                          CopyFile
14
**                          CopyFile
15
**                          DeleteFile
15
**                          DeleteFile
16
**                          Remove Files
16
**                          Remove Files (wildcard)
17
**                          DeleteDir after deleting specified files
17
**                          DeleteDir after deleting specified files (wildcard)
-
 
18
**                          Delete Directory Tree
-
 
19
**
-
 
20
**                          JatsFileUtil.exe c9 'copyFile'    aaa/bbb/ccc/dddd/file build_test.pl +w
-
 
21
**                          JatsFileUtil.exe d9 'unCopyFile'  aaa/bbb/ccc/dddd/file
-
 
22
**                          JatsFileUtil.exe r9 'deleteFile'  a1 b2 c3
-
 
23
**                          JatsFileUtil.exe D9 'DeleteFiles' src/WIN32P.OBJ *.err *.pch '*'
-
 
24
**                          JatsFileUtil.exe T9 'DeleteTree'  interface
-
 
25
**
-
 
26
**                      First two arguments are common to all
-
 
27
**                          argv[1]     - Mode specifier, Debug specifier
-
 
28
**                          argv[2]     - Display Text
18
**
29
**
19
**                      CopyFile (5 args)
30
**                      CopyFile (5 args)
20
**                          1) Display the ----- Text dest
31
**                          1) Display the ----- Text dest
21
**                          2) Error if the source is not found
32
**                          2) Error if the source is not found
22
**                          3) Create target path if not alraedy existing
33
**                          3) Create target path if not alraedy existing
Line 37... Line 48...
37
**                       DeleteDir (> 2 args)
48
**                       DeleteDir (> 2 args)
38
**                          1) Silenty delete a list of files. The files may
49
**                          1) Silenty delete a list of files. The files may
39
**                             be readonly so the attributes will need to be fixed.
50
**                             be readonly so the attributes will need to be fixed.
40
**                          2) Delete the directory if its empty
51
**                          2) Delete the directory if its empty
41
**
52
**
-
 
53
**                        Delete directory tree
-
 
54
**                          1) Silently delete an entire directory tree
-
 
55
**                             including files and subdiretories
-
 
56
**
42
**                      Make paths use '/'
57
**                      Make paths use '/'
43
**
58
**
44
**
59
**
45
**  Information     :
60
**  Information     :
46
**   Compiler       : ANSI C++
61
**   Compiler       : ANSI C++
Line 50... Line 65...
50
 
65
 
51
#include <tchar.h>
66
#include <tchar.h>
52
#include <stdio.h>
67
#include <stdio.h>
53
#include <windows.h>
68
#include <windows.h>
54
 
69
 
55
#define MAX_FILE 2000
-
 
56
#define INVALID_FILE_ATTIBUTES ((DWORD) -1)
70
#define INVALID_FILE_ATTIBUTES ((DWORD) -1)
57
 
71
 
58
void fullPath ( _TCHAR * src, _TCHAR *dst );
-
 
59
VOID ErrorExit (char *lpszMessage, LPTSTR lpszMessage2);
72
VOID ErrorExit (char *lpszMessage, LPTSTR lpszMessage2);
60
void createPaths ( _TCHAR *path );
73
void createPaths ( _TCHAR *path );
61
void deleteFileList( int argc, _TCHAR* argv[] );
-
 
62
void DeleteDir( int argc, _TCHAR* argv[] );
74
void DeleteDir( int argc, _TCHAR* argv[] );
-
 
75
void DeleteDirTree( int argc, _TCHAR* argv[] );
-
 
76
_TCHAR * makePath( _TCHAR *base, _TCHAR *path);
-
 
77
int DeleteOneFile (_TCHAR * dst );
-
 
78
void DeleteOneDirectoryTree( _TCHAR* baseDir );
-
 
79
void copyOneFile( int argc, _TCHAR* argv[] );
63
 
80
 
64
/*
81
/*
65
**  Global
82
**  Global
66
*/
83
*/
67
_TCHAR currentDir[MAX_FILE + 1];            /* Current working directory */
-
 
68
char  verbose = 1;                          /* Debugging aid */
84
char  verbose = 1;                          /* Debugging aid */
69
char  copyMode = 0;                         /* Mode */
-
 
70
 
-
 
71
_TCHAR src [MAX_FILE + 1];
-
 
72
_TCHAR dst [MAX_FILE + 1];
-
 
73
 
85
 
74
/*----------------------------------------------------------------------------
86
/*----------------------------------------------------------------------------
75
** FUNCTION           : main
87
** FUNCTION           : main
76
**
88
**
77
** DESCRIPTION        : Main entry points
89
** DESCRIPTION        : Main entry points
Line 88... Line 100...
88
**
100
**
89
----------------------------------------------------------------------------*/
101
----------------------------------------------------------------------------*/
90
 
102
 
91
int _tmain(int argc, _TCHAR* argv[])
103
int _tmain(int argc, _TCHAR* argv[])
92
{
104
{
93
	DWORD rv;
-
 
94
 
-
 
95
    /*
105
    /*
96
    **  Examine the first argument
106
    **  Examine the first argument
97
    **  Must be a character string of
107
    **  Must be a character string of
98
    **      [0] - Mode : c or d or r or l
108
    **      [0] - Mode : c or d or r or l
99
    **      [1] - Verbose : 0 .. 9
109
    **      [1] - Verbose : 0 .. 9
100
    */
110
    */
101
    if ( argc > 1 )
111
    if ( argc > 1 && ( argv[1][1] >= '0' && argv[1][1] <= '9' ) )
102
    {
112
    {
103
        if ( argv[1][0] == 'c' ) {
-
 
104
            copyMode = 1;
-
 
105
        } else if ( argv[1][0] == 'd' ) {
-
 
106
            copyMode = 2;
-
 
107
        } else if ( argv[1][0] == 'r' ) {
-
 
108
            copyMode = 3;
-
 
109
        } else if ( argv[1][0] == 'D' ) {
-
 
110
            copyMode = 4;
-
 
111
        } else {
-
 
112
            ErrorExit("Unknown mode: ",argv[1]);
-
 
113
        }
-
 
114
 
-
 
115
        if ( argv[1][1] >= '0' && argv[1][1] <= '9' ) {
-
 
116
            verbose = argv[1][1] - '0';
113
            verbose = argv[1][1] - '0';
117
        }
-
 
118
    }
114
    }
119
 
115
 
120
    /*
116
    /*
121
    **  If Verbose, then display arguments
117
    **  If Verbose, then display arguments
122
    */
118
    */
123
    if ( verbose > 1 )
119
    if ( verbose > 2 )
124
    {
120
    {
125
        int ii;
121
        int ii;
126
        for ( ii = 0; ii < argc ; ii++ )
122
        for ( ii = 0; ii < argc ; ii++ )
127
        {
123
        {
128
            fprintf(stderr, "Arg%d: %ls:\n", ii, argv[ii] );
124
            fprintf(stderr, "Arg%d: %ls:\n", ii, argv[ii] );
129
        }
125
        }
130
        fprintf(stderr, "Mode   : %d:\n", copyMode );
-
 
131
        fprintf(stderr, "Verbose: %d:\n", verbose );
-
 
132
        fflush(stderr) ;
126
        fflush(stderr) ;
133
    }
127
    }
134
 
128
 
135
    /*
129
    /*
136
    **  Determine cwd
-
 
137
    **  Used for ab path conversion
130
    **  Switch to required operation
138
    */
131
    */
139
    GetCurrentDirectory( MAX_FILE, currentDir );
-
 
140
    if ( verbose > 1 )
132
    switch ( argv[1][0]  )
141
        fprintf(stderr, "CWD: %ls\n", currentDir );
-
 
142
 
-
 
143
    /*
-
 
144
    **  Determine required operation
-
 
145
    */
-
 
146
    if ( copyMode == 3 )
-
 
147
    {
133
    {
-
 
134
        case 'c':
148
        deleteFileList(argc - 2, argv + 2 );
135
            copyOneFile(argc, argv);
149
        return 0;
136
            break;
150
    }
-
 
151
 
137
 
152
    if ( copyMode == 4 )
-
 
153
    {
-
 
154
        DeleteDir(argc - 2, argv + 2 );
-
 
155
        return 0;
138
        case 'd':
156
    }
-
 
157
 
-
 
158
    /*
-
 
159
    **  Determine mode of operation
-
 
160
    **      Copy or Delete
-
 
161
    */
-
 
162
    if ( copyMode == 1 && argc == 6 ) {
-
 
163
        fullPath( argv[4], src);
-
 
164
        fullPath( argv[3], dst);
-
 
165
 
-
 
166
    } else if ( copyMode == 2 && argc == 4) {
-
 
167
        fullPath( argv[3], dst);
-
 
168
 
-
 
169
    } else {
139
            {
170
        fprintf(stderr, "Mode: %d, Args: %d\n", copyMode, argc);
-
 
171
        ErrorExit("Incorrect argument count for mode",L"");
-
 
172
    }
-
 
173
 
-
 
174
    /*
-
 
175
    **  Display user text
-
 
176
    */
-
 
177
    fprintf(stderr, "---- %ls %ls\n", argv[2], argv[3]);
-
 
178
    fflush(stderr) ;
-
 
179
 
-
 
180
    /*
-
 
181
    **   Check that the source is a file
-
 
182
    */
-
 
183
    if ( copyMode == 1 )
-
 
184
    {
-
 
185
        if ( verbose )
140
                _TCHAR * dst;
186
            fprintf(stderr, "Validate Source File: %ls\n", src);
-
 
187
        
141
        
188
        rv = GetFileAttributesW( src );
142
                if ( argc != 4 )
189
        if ( rv == INVALID_FILE_ATTIBUTES )
-
 
190
        {
-
 
191
    /* Need to be a better message */
-
 
192
            fprintf(stderr, "Source: %ls\n", src);
-
 
193
            ErrorExit("Source File not found: ", argv[4]);
143
                    ErrorExit("Incorrect argument count for mode",L"");
194
        }
-
 
195
    }
-
 
196
 
144
 
197
    /*
-
 
198
    **  Remove the ReadOnly attribute on the dest file
-
 
199
    */
-
 
200
    if ( verbose )
145
                /*
201
        fprintf(stderr, "Remove target file: %ls\n", dst);
-
 
202
    rv = GetFileAttributesW( dst );
-
 
203
    if ( rv != INVALID_FILE_ATTIBUTES )
146
                **  Display user text
204
    {
-
 
205
        if ( verbose )
147
                */
206
            fprintf(stderr, "FileExists with attr: %ld\n", rv);
148
                fprintf(stderr, "---- %ls %ls\n", argv[2], argv[3]);
207
        if ( rv & FILE_ATTRIBUTE_READONLY )
149
                fflush(stderr) ;
208
        {
150
 
209
            rv &= ~FILE_ATTRIBUTE_READONLY;
151
                dst = makePath(argv[3], NULL);
210
            rv = SetFileAttributesW( dst, rv );
152
                DeleteOneFile(dst);
211
            if ( rv == 0 )
153
                free (dst);
212
            {
-
 
213
                ErrorExit("Attempt to allow write access: ", argv[3]);
-
 
214
            }
154
            }
215
        }
155
            break;
216
 
156
 
217
        if (! DeleteFile( dst ) )
-
 
218
        {
-
 
219
                ErrorExit("Deleting file: ", argv[3]);
-
 
220
        }
157
        case 'r':
221
    }
-
 
222
    
-
 
223
    if ( copyMode == 1 )
-
 
224
    {
-
 
225
        /*
158
                {
226
        **  Create directories
159
                    int ii;
227
        **  Use the path to the target - not the provided directory
-
 
228
        **  as the createPaths function will not create the last element
-
 
229
        */
-
 
230
        createPaths( dst );
-
 
231
 
160
 
232
        /*
-
 
233
        **   Copy the file
-
 
234
        */
-
 
235
        if ( ! CopyFile( src, dst, FALSE ) )
-
 
236
        {
-
 
237
            rv = GetLastError();
161
                    if ( argc < 4 )
238
            fprintf(stderr, "CopyFile Last Error: %ld\n", rv);
-
 
239
            ErrorExit("Copy Error: ", argv[4]);
162
                        ErrorExit("Incorrect argument count for mode",L"");
240
        }
-
 
241
 
163
 
242
        /*
164
                    /*
243
        **  Test for files existence
165
                    **  Display user text
244
        */
166
                    */
-
 
167
                    if ( argv[2][0] )
245
        if ( verbose )
168
                    {
246
            fprintf(stderr, "Test target was copied: %ls\n", dst);
169
                        fprintf(stderr, "%s\n", argv[2]);
247
        rv = GetFileAttributesW( dst );
170
                        fflush(stderr) ;
-
 
171
                    }
-
 
172
 
248
        if ( rv == INVALID_FILE_ATTIBUTES )
173
                    for ( ii = 3; ii < argc ; ii++ )
249
        {
174
                    {
-
 
175
                        _TCHAR * dst = makePath(argv[ii], NULL);
250
    /* Need to be a better message */
176
                        DeleteOneFile(dst);
251
            ErrorExit("File not found after copy: ", argv[3]);
177
                        free (dst);
-
 
178
                    }
252
        }
179
                }
-
 
180
            break;
253
 
181
 
254
        /*
182
        case 'D':
255
        **  Set the files attributes
183
            DeleteDir(argc - 2, argv + 2 );
256
        **      Assume read-only
184
            break;
-
 
185
 
257
        */
186
        case 'T':
258
        if ( _tcsstr( argv[5], L"-w" ) )
187
            DeleteDirTree(argc - 2, argv + 2 );
259
        {
-
 
260
            if ( verbose )
188
            break;
261
                fprintf(stderr, "Set target read-only: %ls\n", dst);
-
 
262
            
189
            
263
            rv |= FILE_ATTRIBUTE_READONLY;
-
 
264
            rv &= ~FILE_ATTRIBUTE_NORMAL;
-
 
265
            rv = SetFileAttributesW( dst, rv );
-
 
266
            if ( rv == 0 )
-
 
267
            {
190
        default :
268
                ErrorExit("Setting ReadOnly: ", argv[3]);
191
            ErrorExit("Unknown mode: ",argv[1]);
269
            }
192
            break;
270
        }
-
 
271
    }
193
    }
272
 
-
 
273
    return 0;
194
    return 0;
274
}
195
}
275
 
196
 
276
/*----------------------------------------------------------------------------
197
/*----------------------------------------------------------------------------
277
** FUNCTION           : createPaths
198
** FUNCTION           : createPaths
Line 306... Line 227...
306
        }
227
        }
307
        ptr++;
228
        ptr++;
308
    }
229
    }
309
}
230
}
310
 
231
 
311
 
-
 
312
/*----------------------------------------------------------------------------
232
/*----------------------------------------------------------------------------
313
** FUNCTION           : fullPath
233
** FUNCTION           : copyOneFile
314
**
234
**
315
** DESCRIPTION        : Creates a full file path for user
235
** DESCRIPTION        : Copy one file to a target
316
**                      Convert relative path to ABS path with \\?\ from
-
 
317
**                      Convert / into \ for windows
-
 
318
**
-
 
319
**                      Handle path elements
236
**                      Used to package and install files
320
**                          ./                  - Remove
-
 
321
**                          /bbb/../            - Remove
-
 
322
**                          /aaa/bbb/../../     - Remove
-
 
323
**
237
**
324
**
238
**
325
** INPUTS             : src         - Partial file path
239
** INPUTS             : argc            - Argc count
326
**                      dst         - Area to create full name
240
**                      argv            - Argument list
-
 
241
**                          argv[2]     - Display text Prefix
-
 
242
**                          argv[3]     - Target path
-
 
243
**                          argv[4]     - Source Path
327
**                                    Assumed to address a MAX_FILE space
244
**                          argv[5]     - File attributes
328
**
245
**
329
** RETURNS            : Nothing
246
** RETURNS            :
330
**
247
**
331
----------------------------------------------------------------------------*/
248
----------------------------------------------------------------------------*/
332
 
249
 
333
void fullPath ( _TCHAR * src, _TCHAR *dst )
250
void copyOneFile( int argc, _TCHAR* argv[] )
334
{
251
{
-
 
252
	DWORD rv;
335
    _TCHAR *udst = dst;
253
    _TCHAR * src;
336
    _TCHAR *usrc = src;
254
    _TCHAR * dst;
337
	_tcscpy(dst, TEXT("\\\\?\\"));
-
 
338
    if ( ( src[0] && (src[1] != ':') ) || src[0] == 0 )
-
 
339
    {
255
    
340
	    _tcscat(dst, currentDir );
256
    if ( argc != 6 )
341
	    _tcscat(dst, TEXT("\\") );
257
        ErrorExit("Incorrect argument count for file copy",L"");
342
    }
258
    
343
    udst += _tcslen(udst);
259
    /*
344
    while ( *usrc )
260
    **  Display user text
345
    {
261
    */
346
        if ( *usrc == '/' ) {
262
    fprintf(stderr, "---- %ls %ls\n", argv[2], argv[3]);
347
            *udst++ = '\\';
-
 
348
        } else {
263
    fflush(stderr) ;
-
 
264
 
349
            *udst++ = *usrc;
265
    dst = makePath(argv[3], NULL);
350
        }
-
 
351
        usrc++;
266
    src = makePath(argv[4], NULL);
352
    }
-
 
353
    *udst = 0;
-
 
354
 
267
 
355
    /*
268
    /*
356
    **  Now remove silly relative path bits
269
    **   Check that the source is a file
357
    */
270
    */
358
    udst = dst;
271
    if ( verbose )
-
 
272
        fprintf(stderr, "Validate Source File: %ls\n", src);
359
    while ( *udst )
273
        
-
 
274
    rv = GetFileAttributesW( src );
-
 
275
    if ( rv == INVALID_FILE_ATTIBUTES )
360
    {
276
    {
361
        if ( udst[0] == '\\' && udst[1] == '.' && (udst[2] == '\\' || udst[2] == 0) )
-
 
362
        {
-
 
363
            TCHAR* ptr1 = udst;
-
 
364
            TCHAR* ptr2 = udst + 2;
-
 
365
            while ( *ptr1++ = *ptr2++ ) {}
-
 
366
        }
-
 
367
        else if ( udst[0] == '\\' && udst[1] == '.' && udst[2] == '.' && udst[3] == '\\'  )
-
 
368
        {
-
 
369
            TCHAR* ptr = udst - 1;
-
 
370
            TCHAR* ptr2 = udst + 3;
-
 
371
 
-
 
372
            while ( *ptr-- != '\\' )
-
 
373
            {
-
 
374
                if ( ptr - dst < 6)
277
/* Need to be a better message */
375
                {
-
 
376
                    *ptr = 0;
-
 
377
                    fprintf(stderr, "Path: %ls\n", dst);
278
        fprintf(stderr, "Source: %ls\n", src);
378
                    ErrorExit("Bad relative path: ", src);
279
        ErrorExit("Source File not found: ", argv[4]);
379
                }
-
 
380
            }
-
 
381
            ptr++;
-
 
382
            udst = ptr;
-
 
383
            while ( *ptr++ = *ptr2++ ) {}
-
 
384
        }
-
 
385
        else
-
 
386
        {
-
 
387
            *udst++;
-
 
388
        }
-
 
389
    }
280
    }
390
 
281
 
391
if ( verbose > 1)
-
 
392
    fprintf(stderr, "AbsPath: %ls\n", dst);
-
 
393
}
-
 
394
 
-
 
395
/*----------------------------------------------------------------------------
-
 
396
** FUNCTION           : deleteFileList
-
 
397
**
282
    /*
398
** DESCRIPTION        : Delete a list of files
-
 
399
**                      Ensure files are writable
-
 
400
**
-
 
401
**
-
 
402
** INPUTS             : argc    - count of args
-
 
403
**                      argv    - list of files to delete
283
    **  Remove the ReadOnly attribute on the dest file
404
**
284
    */
405
** RETURNS            : Wil not return on error
285
    DeleteOneFile(dst);
406
**
-
 
407
----------------------------------------------------------------------------*/
-
 
408
 
286
 
-
 
287
    /*
-
 
288
    **  Create directories
409
void deleteFileList( int argc, _TCHAR* argv[] )
289
    **  Use the path to the target - not the provided directory
-
 
290
    **  as the createPaths function will not create the last element
410
{
291
    */
411
	DWORD rv;
292
    createPaths( dst );
412
 
293
 
-
 
294
    /*
-
 
295
    **   Copy the file
-
 
296
    */
413
    for ( ; argc ; argc--, argv++ )
297
    if ( ! CopyFile( src, dst, FALSE ) )
414
    {
298
    {
415
        fullPath( *argv, dst);
299
        rv = GetLastError();
-
 
300
        fprintf(stderr, "CopyFile Last Error: %ld\n", rv);
-
 
301
        ErrorExit("Copy Error: ", argv[4]);
-
 
302
    }
416
 
303
 
417
        /*
304
    /*
418
        **  Remove the ReadOnly attribute on the dest file
305
    **  Test for files existence
419
        */
306
    */
420
        if ( verbose > 1 )
307
    if ( verbose )
421
            fprintf(stderr, "Remove target file: %ls\n", dst);
308
        fprintf(stderr, "Test target was copied: %ls\n", dst);
422
 
309
 
423
        rv = GetFileAttributesW( dst );
310
    rv = GetFileAttributesW( dst );
424
        if ( rv != INVALID_FILE_ATTIBUTES )
311
    if ( rv == INVALID_FILE_ATTIBUTES )
425
        {
312
    {
426
            if ( verbose )
313
/* Need to be a better message */
427
                fprintf(stderr, "Delete file: %ls : Attr: 0x%lx\n", *argv, rv);
-
 
428
            if ( rv & FILE_ATTRIBUTE_READONLY )
-
 
429
            {
-
 
430
                rv &= ~FILE_ATTRIBUTE_READONLY;
-
 
431
                rv = SetFileAttributesW( dst, rv );
314
        ErrorExit("File not found after copy: ", argv[3]);
432
                if ( rv == 0 )
-
 
433
                {
-
 
434
                    fprintf(stderr, "Warning: Attempt to allow write access: %ls\n", *argv);
-
 
435
                }
-
 
436
            }
315
    }
437
 
316
 
-
 
317
    /*
-
 
318
    **  Set the files attributes
-
 
319
    **      Assume read-only
-
 
320
    */
438
            if (! DeleteFile( dst ) )
321
    if ( _tcsstr( argv[5], L"-w" ) )
-
 
322
    {
439
            {
323
        if ( verbose )
440
                fprintf(stderr, "Warning: Did not remove file: %ls\n", *argv);
324
            fprintf(stderr, "Set target read-only: %ls\n", dst);
441
            }
325
            
-
 
326
        rv |= FILE_ATTRIBUTE_READONLY;
-
 
327
        rv &= ~FILE_ATTRIBUTE_NORMAL;
-
 
328
        rv = SetFileAttributesW( dst, rv );
-
 
329
        if ( rv == 0 )
-
 
330
        {
-
 
331
            ErrorExit("Setting ReadOnly: ", argv[3]);
442
        }
332
        }
443
    }
333
    }
444
}
334
}
445
 
335
 
446
/*----------------------------------------------------------------------------
336
/*----------------------------------------------------------------------------
Line 453... Line 343...
453
**                      Then delete the directory - if its empty
343
**                      Then delete the directory - if its empty
454
**
344
**
455
**
345
**
456
** INPUTS             : argc    - count of args
346
** INPUTS             : argc    - count of args
457
**                      argv    - list of files to delete
347
**                      argv    - list of files to delete
-
 
348
**                                [0]:  Text to display
458
**                                First entry is a directory
349
**                                [1]:  Base directory
-
 
350
**                                [2]+  Files in dir to delete
459
**
351
**
460
** RETURNS            : Wil not return on error
352
** RETURNS            : Will not return on error
461
**
353
**
462
----------------------------------------------------------------------------*/
354
----------------------------------------------------------------------------*/
463
 
355
 
464
void DeleteDir( int argc, _TCHAR* argv[] )
356
void DeleteDir( int argc, _TCHAR* argv[] )
465
{
357
{
466
	DWORD rv;
358
	DWORD rv;
467
    _TCHAR* baseDir;
359
    _TCHAR* baseDir;
468
    WIN32_FIND_DATA FindFileData;
360
    WIN32_FIND_DATA FindFileData;
469
    HANDLE hFind;
361
    HANDLE hFind;
-
 
362
    _TCHAR *target;
-
 
363
    _TCHAR *dirPath;
470
 
364
 
471
    if ( argc < 3 )
365
    if ( argc < 3 )
472
        ErrorExit("Insuffiecient arguments for DeleteDir",L"");
366
        ErrorExit("Insuffiecient arguments for DeleteDir",L"");
473
        
367
        
474
    /*
368
    /*
Line 490... Line 384...
490
    argv+=2;
384
    argv+=2;
491
 
385
 
492
    /*
386
    /*
493
    **  Ensure that the base directory exists
387
    **  Ensure that the base directory exists
494
    */
388
    */
495
    fullPath( baseDir, dst);
389
    dirPath = makePath(baseDir, NULL);
496
    rv = GetFileAttributesW( dst );
390
    rv = GetFileAttributesW( dirPath );
497
    if ( rv == INVALID_FILE_ATTIBUTES )
391
    if ( rv == INVALID_FILE_ATTIBUTES )
498
    {
392
    {
499
        /*
393
        /*
500
        **  Directory does not exists
394
        **  Directory does not exists
501
        **  Assume its aleady deleted
395
        **  Assume its aleady deleted
502
        */
396
        */
503
        if ( verbose > 1 )
397
        if ( verbose > 1 )
504
            fprintf(stderr, "Base dir does not exist: %ls\n", baseDir);
398
            fprintf(stderr, "Base dir does not exist: %ls\n", baseDir);
-
 
399
        free(dirPath);
505
        return;
400
        return;
506
    }
401
    }
507
 
402
 
508
    if ( !(rv & FILE_ATTRIBUTE_DIRECTORY) )
403
    if ( !(rv & FILE_ATTRIBUTE_DIRECTORY) )
509
    {
404
    {
Line 511... Line 406...
511
        **  Target is not a directory
406
        **  Target is not a directory
512
        **  Don't do anything
407
        **  Don't do anything
513
        */
408
        */
514
        if ( verbose > 1 )
409
        if ( verbose > 1 )
515
            fprintf(stderr, "Base dir is not a directory: %ls\n", baseDir);
410
            fprintf(stderr, "Base dir is not a directory: %ls\n", baseDir);
-
 
411
        free(dirPath);
516
        return;
412
        return;
517
    }
413
    }
518
 
414
 
519
    /*
415
    /*
520
    **  Process all the suffixes
416
    **  Process all the suffixes
521
    **  They may contain a wild card
417
    **  They may contain a wild card
522
    */
418
    */
523
    for ( ; argc ; argc--, argv++ )
419
    for ( ; argc ; argc--, argv++ )
524
    {
420
    {
525
    	_tcscpy(src, baseDir);
421
        _TCHAR * thisDir = makePath( baseDir, *argv);
526
    	_tcscat(src, TEXT("\\"));
422
        hFind = FindFirstFile(thisDir, &FindFileData);
527
    	_tcscat(src, *argv);
423
        free(thisDir);
528
        fullPath( src, dst);
424
        
529
 
-
 
530
        hFind = FindFirstFile(dst, &FindFileData);
-
 
531
        if (hFind == INVALID_HANDLE_VALUE)
425
        if (hFind == INVALID_HANDLE_VALUE)
532
        {
426
        {
533
            /*
427
            /*
534
            **  No match
428
            **  No match
535
            */
429
            */
536
            if ( verbose > 1 )
430
            if ( verbose > 1 )
537
                fprintf(stderr, "No Match: %ls\n", dst);
431
                fprintf(stderr, "No Match: %ls, %ls\n", baseDir, *argv);
538
            continue;
432
            continue;
539
        }
433
        }
540
 
434
 
541
        /*
435
        /*
542
        **  Iterate over all the files
436
        **  Iterate over all the files
Line 546... Line 440...
546
                continue;
440
                continue;
547
 
441
 
548
            if ( _tcscmp( TEXT(".."), FindFileData.cFileName ) == 0 )
442
            if ( _tcscmp( TEXT(".."), FindFileData.cFileName ) == 0 )
549
                continue;
443
                continue;
550
 
444
 
551
            /*
-
 
552
            **  Create a full path to the file
-
 
553
            */
-
 
554
    	    _tcscpy(src, baseDir);
-
 
555
    	    _tcscat(src, TEXT("\\"));
-
 
556
    	    _tcscat(src, FindFileData.cFileName);
-
 
557
 
-
 
558
            if ( verbose )
445
            if ( verbose )
559
                fprintf(stderr, "Match: %ls\n", FindFileData.cFileName);
446
                fprintf(stderr, "Match: %ls\n", FindFileData.cFileName);
560
 
447
 
561
            /*
448
            /*
562
            **  Force file to be writable
449
            **  Matching file found
563
            */
450
            */
564
            if ( FindFileData.dwFileAttributes  & FILE_ATTRIBUTE_READONLY)
-
 
565
            {
-
 
566
                rv = SetFileAttributesW( src, FindFileData.dwFileAttributes & ~FILE_ATTRIBUTE_READONLY );
-
 
567
                if ( rv == 0 )
-
 
568
                {
-
 
569
                    fprintf(stderr, "Warning: Attempt to allow write access: %ls\n", FindFileData.cFileName);
451
            target = makePath( baseDir, FindFileData.cFileName);
570
                }
-
 
571
            }
-
 
572
 
-
 
573
            /*
-
 
574
            **  Delete the file
-
 
575
            */
-
 
576
            if (! DeleteFile( src ) )
452
            DeleteOneFile(target);
577
            {
-
 
578
                fprintf(stderr, "Warning: Did not remove file: %ls\n", FindFileData.cFileName);
-
 
579
            }
453
            free (target);
580
 
454
 
581
        } while  (FindNextFile(hFind, &FindFileData) != 0);
455
        } while  (FindNextFile(hFind, &FindFileData) != 0);
582
        FindClose(hFind);
456
        FindClose(hFind);
583
    }
457
    }
584
 
458
 
Line 586... Line 460...
586
    **  Finally delete the diretory
460
    **  Finally delete the diretory
587
    **      Unless its '.'
461
    **      Unless its '.'
588
    */
462
    */
589
    if ( _tcscmp( TEXT("."),baseDir) != 0 )
463
    if ( _tcscmp( TEXT("."),baseDir) != 0 )
590
    {
464
    {
591
        fullPath( baseDir, dst);
-
 
592
        if ( verbose > 1 )
465
        if ( verbose > 1 )
593
            fprintf(stderr, "Delete Directory: %ls\n", baseDir);
466
            fprintf(stderr, "Delete Directory: %ls\n", baseDir);
-
 
467
 
594
        if ( ! RemoveDirectory( dst ) )
468
        if ( ! RemoveDirectory( dirPath ) )
595
        {
469
        {
596
            if ( verbose )
470
            if ( verbose )
597
                fprintf(stderr, "Directory not deleted: %ls\n", baseDir);
471
                fprintf(stderr, "Directory not deleted: %ls\n", baseDir);
598
        }
472
        }
599
    }
473
    }
-
 
474
    free(dirPath);
-
 
475
}
-
 
476
 
-
 
477
/*----------------------------------------------------------------------------
-
 
478
** FUNCTION           : DeleteDirTree
-
 
479
**
-
 
480
** DESCRIPTION        : Delete an entire directory tree(s)
-
 
481
**
-
 
482
** INPUTS             : argc    - count of args
-
 
483
**                      argv    - list of files to delete
-
 
484
**                                [0]:  Text to display
-
 
485
**                                [1]+  Base directory
-
 
486
**
-
 
487
** RETURNS            : Will not return on error
-
 
488
**
-
 
489
----------------------------------------------------------------------------*/
-
 
490
 
-
 
491
void DeleteDirTree( int argc, _TCHAR* argv[] )
-
 
492
{
-
 
493
    int ii;
-
 
494
 
-
 
495
    if ( argc < 2 )
-
 
496
        ErrorExit("Insuffiecient arguments for DeleteDir",L"");
-
 
497
        
-
 
498
    /*
-
 
499
    **  Display the user message
-
 
500
    **      Supress display if the message is empty
-
 
501
    */
-
 
502
    if ( argv[0][0] )
-
 
503
    {
-
 
504
        fprintf(stderr, "%ls\n", argv[0]);
-
 
505
        fflush(stderr) ;
-
 
506
    }
-
 
507
 
-
 
508
    for ( ii = 1; ii < argc ; ii++)
-
 
509
    {
-
 
510
        DeleteOneDirectoryTree( argv[ii] );
-
 
511
    }
-
 
512
}
-
 
513
 
-
 
514
/*----------------------------------------------------------------------------
-
 
515
** FUNCTION           : DeleteOneDirectoryTree
-
 
516
**
-
 
517
** DESCRIPTION        : Delete an entire directory tree(s)
-
 
518
**
-
 
519
** INPUTS             : path    - Dir to delete
-
 
520
**
-
 
521
** RETURNS            : Will not return on error
-
 
522
**
-
 
523
----------------------------------------------------------------------------*/
-
 
524
 
-
 
525
void DeleteOneDirectoryTree( _TCHAR* baseDir )
-
 
526
{
-
 
527
	DWORD rv;
-
 
528
    WIN32_FIND_DATA FindFileData;
-
 
529
    HANDLE hFind;
-
 
530
    _TCHAR *target;
-
 
531
    _TCHAR *dirPath;
-
 
532
    _TCHAR *thisDir;
-
 
533
 
-
 
534
    /*
-
 
535
    **  A bit of a sanity test
-
 
536
    */
-
 
537
    if ( _tcscmp( L".", baseDir) == 0 || _tcscmp( L"..", baseDir) == 0 )
-
 
538
    {
-
 
539
        fprintf(stderr, "DeleteOneDirectoryTree will not delete '.' or '..'\n");
-
 
540
        return;
-
 
541
    }
-
 
542
 
-
 
543
    /*
-
 
544
    **  Ensure that the base directory exists
-
 
545
    */
-
 
546
    dirPath = makePath(baseDir, NULL);
-
 
547
    rv = GetFileAttributesW( dirPath );
-
 
548
    if ( rv == INVALID_FILE_ATTIBUTES )
-
 
549
    {
-
 
550
        /*
-
 
551
        **  Directory does not exists
-
 
552
        **  Assume its aleady deleted
-
 
553
        */
-
 
554
        if ( verbose > 1 )
-
 
555
            fprintf(stderr, "Base dir does not exist: %ls\n", baseDir);
-
 
556
        free(dirPath);
-
 
557
        return;
-
 
558
    }
-
 
559
 
-
 
560
    if ( !(rv & FILE_ATTRIBUTE_DIRECTORY) )
-
 
561
    {
-
 
562
        /*
-
 
563
        **  Target is not a directory
-
 
564
        **  Don't do anything
-
 
565
        */
-
 
566
        if ( verbose > 1 )
-
 
567
            fprintf(stderr, "Base dir is not a directory: %ls\n", baseDir);
-
 
568
        free(dirPath);
-
 
569
        return;
-
 
570
    }
-
 
571
 
-
 
572
    /*
-
 
573
    **  Read next directory entry
-
 
574
    */
-
 
575
    thisDir = makePath( baseDir, TEXT("*"));
-
 
576
    hFind = FindFirstFile(thisDir, &FindFileData);
-
 
577
    free(thisDir);
-
 
578
 
-
 
579
    if (hFind != INVALID_HANDLE_VALUE)
-
 
580
    {
-
 
581
 
-
 
582
        /*
-
 
583
        **  Iterate over all the files
-
 
584
        */
-
 
585
        do {
-
 
586
            if ( verbose > 2 )
-
 
587
                fprintf(stderr, "Directory Entry:%ls,%ls\n", baseDir, FindFileData.cFileName );
-
 
588
 
-
 
589
            if ( _tcscmp( TEXT("."), FindFileData.cFileName ) == 0 )
-
 
590
                continue;
-
 
591
 
-
 
592
            if ( _tcscmp( TEXT(".."), FindFileData.cFileName ) == 0 )
-
 
593
                continue;
-
 
594
 
-
 
595
            /*
-
 
596
            **  Create a full path to the file
-
 
597
            */
-
 
598
            target = makePath( baseDir, FindFileData.cFileName);
-
 
599
            if ( FindFileData.dwFileAttributes  & FILE_ATTRIBUTE_DIRECTORY)
-
 
600
            {
-
 
601
                DeleteOneDirectoryTree( target );
-
 
602
            }
-
 
603
            else
-
 
604
            {
-
 
605
                DeleteOneFile (target);
-
 
606
            }
-
 
607
            free (target);
-
 
608
 
-
 
609
        } while  (FindNextFile(hFind, &FindFileData) != 0);
-
 
610
        FindClose(hFind);
-
 
611
    }
-
 
612
 
-
 
613
    /*
-
 
614
    **  Finally delete the diretory
-
 
615
    */
-
 
616
    if ( verbose > 1 )
-
 
617
        fprintf(stderr, "Delete Directory: %ls\n", baseDir);
-
 
618
 
-
 
619
    if ( ! RemoveDirectory( dirPath ) )
-
 
620
    {
-
 
621
        if ( verbose )
-
 
622
            fprintf(stderr, "Directory not deleted: %ls\n", baseDir);
-
 
623
    }
-
 
624
    free(dirPath);
-
 
625
}
-
 
626
 
-
 
627
/*----------------------------------------------------------------------------
-
 
628
** FUNCTION           : DeleteOneFile
-
 
629
**
-
 
630
** DESCRIPTION        : Delete a file
-
 
631
**                      Force it writable before deletion
-
 
632
**
-
 
633
** INPUTS             : path        - path to the file
-
 
634
**
-
 
635
** RETURNS            : 0           - OK (file deleted or not present)
-
 
636
**
-
 
637
----------------------------------------------------------------------------*/
-
 
638
 
-
 
639
int DeleteOneFile (_TCHAR * dst )
-
 
640
{
-
 
641
	DWORD rv;
-
 
642
    int result = 0;
-
 
643
 
-
 
644
    if ( verbose > 1)
-
 
645
        fprintf(stderr, "Delete File: %ls\n", dst);
-
 
646
 
-
 
647
    rv = GetFileAttributesW( dst );
-
 
648
    if ( rv != INVALID_FILE_ATTIBUTES )
-
 
649
    {
-
 
650
        if ( verbose )
-
 
651
            fprintf(stderr, "Delete file: %ls : Attr: 0x%lx\n", dst, rv);
-
 
652
        if ( rv & FILE_ATTRIBUTE_READONLY )
-
 
653
        {
-
 
654
            rv &= ~FILE_ATTRIBUTE_READONLY;
-
 
655
            rv = SetFileAttributesW( dst, rv );
-
 
656
            if ( rv == 0 )
-
 
657
            {
-
 
658
                fprintf(stderr, "Warning: Attempt to allow write access: %ls\n", dst);
-
 
659
            }
-
 
660
        }
-
 
661
 
-
 
662
        if (! DeleteFile( dst ) )
-
 
663
        {
-
 
664
            fprintf(stderr, "Warning: Did not remove file: %ls\n", dst);
-
 
665
            result = 1;
-
 
666
        }
-
 
667
    }
-
 
668
 
-
 
669
    return result;
600
}
670
}
601
 
671
 
-
 
672
/*----------------------------------------------------------------------------
-
 
673
** FUNCTION           : makePath
-
 
674
**
-
 
675
** DESCRIPTION        : Creates a full file path for user
-
 
676
**                      Join 2 components together
-
 
677
**                      Convert relative path to ABS path with \\?\ from
-
 
678
**                      Convert / into \ for windows
-
 
679
**
-
 
680
**                      Handle path elements
-
 
681
**                          ./                  - Remove
-
 
682
**                          /bbb/../            - Remove
-
 
683
**                          /aaa/bbb/../../     - Remove
-
 
684
**
-
 
685
**
-
 
686
** INPUTS             : base        - Part 1
-
 
687
**                                    May already contain \\?\
-
 
688
**                      file        - Part 2 or NULL
-
 
689
**
-
 
690
** RETURNS            : fullPath - User must free memory
-
 
691
**
-
 
692
----------------------------------------------------------------------------*/
-
 
693
 
-
 
694
_TCHAR * makePath ( _TCHAR * base, _TCHAR *file )
-
 
695
{
-
 
696
    int lenp = 0;
-
 
697
    int lencwd = 0;
-
 
698
    int len1 = _tcslen(base);
-
 
699
    int len2 = 0;
-
 
700
    _TCHAR *data;
-
 
701
    _TCHAR *cdata;
-
 
702
    _TCHAR *udst;
-
 
703
 
-
 
704
    /*
-
 
705
    **  If the base contains a \\?\ then we don't need to add it
-
 
706
    */
-
 
707
    if ( !( len1 > 3 && base[2] == '?' ) )
-
 
708
    {
-
 
709
        lenp = _tcslen(TEXT("\\\\?\\"));
-
 
710
    }
-
 
711
 
-
 
712
    /*
-
 
713
    **  Unless an absolute path we need to insert CWD too
-
 
714
    **  Just determine the length of the entry for now
-
 
715
    */
-
 
716
    if ( lenp && ( ( base[0] && (base[1] != ':') ) || base[0] == 0 ) )
-
 
717
    {
-
 
718
        lencwd = GetCurrentDirectory(0,0) - 1; // determine size needed
-
 
719
    }
-
 
720
 
-
 
721
    /*
-
 
722
    **  2nd file argument may be a NULL
-
 
723
    */
-
 
724
    if ( file )
-
 
725
    {
-
 
726
        len2 = _tcslen(file);
-
 
727
    }
-
 
728
 
-
 
729
    data = (_TCHAR *)malloc((lenp + lencwd+ len1 + len2 + 10) * sizeof(_TCHAR));
-
 
730
    cdata = data;
-
 
731
    if ( data == NULL )
-
 
732
    {
-
 
733
        ErrorExit ("Malloc error:makePath",L"");
-
 
734
    }
-
 
735
 
-
 
736
    /*
-
 
737
    **  Join all the strings together
-
 
738
    */
-
 
739
    if ( lenp )
-
 
740
    {
-
 
741
        _tcscpy( cdata,TEXT("\\\\?\\"));
-
 
742
        cdata += lenp;
-
 
743
    }
-
 
744
 
-
 
745
    if ( lencwd )
-
 
746
    {
-
 
747
        GetCurrentDirectory(lencwd+1, cdata);
-
 
748
        cdata += lencwd;
-
 
749
        _tcscpy( cdata, TEXT("\\"));
-
 
750
        cdata += 1;
-
 
751
    }
-
 
752
 
-
 
753
    _tcscpy( cdata, base);
-
 
754
    cdata += len1;
-
 
755
 
-
 
756
    if ( len2 )
-
 
757
    {
-
 
758
        _tcscpy( cdata, TEXT("\\"));
-
 
759
        _tcscpy( cdata+1, file);
-
 
760
        cdata += len2 + 1;
-
 
761
    }
-
 
762
 
-
 
763
    /*
-
 
764
    **  Convert / into \
-
 
765
    */
-
 
766
    for ( udst = data; *udst ; udst++)
-
 
767
    {
-
 
768
        if ( *udst == '/' )
-
 
769
            *udst = '\\';
-
 
770
    }
-
 
771
 
-
 
772
    /*
-
 
773
    **  Now remove silly relative path bits
-
 
774
    */
-
 
775
    udst = data;
-
 
776
    while ( *udst )
-
 
777
    {
-
 
778
        if ( udst[0] == '\\' && udst[1] == '.' && (udst[2] == '\\' || udst[2] == 0) )
-
 
779
        {
-
 
780
            TCHAR* ptr1 = udst;
-
 
781
            TCHAR* ptr2 = udst + 2;
-
 
782
            while ( *ptr1++ = *ptr2++ ) {}
-
 
783
        }
-
 
784
        else if ( udst[0] == '\\' && udst[1] == '.' && udst[2] == '.' && udst[3] == '\\'  )
-
 
785
        {
-
 
786
            TCHAR* ptr = udst - 1;
-
 
787
            TCHAR* ptr2 = udst + 3;
-
 
788
 
-
 
789
            while ( *ptr-- != '\\' )
-
 
790
            {
-
 
791
                if ( ptr - data < 6)
-
 
792
                {
-
 
793
                    *ptr = 0;
-
 
794
                    fprintf(stderr, "Path: %ls\n", data);
-
 
795
                    ErrorExit("Bad relative path: ", data);
-
 
796
                }
-
 
797
            }
-
 
798
            ptr++;
-
 
799
            udst = ptr;
-
 
800
            while ( *ptr++ = *ptr2++ ) {}
-
 
801
        }
-
 
802
        else
-
 
803
        {
-
 
804
            *udst++;
-
 
805
        }
-
 
806
    }
-
 
807
 
-
 
808
    if ( verbose > 2)
-
 
809
        fprintf(stderr, "makePath: %ls\n", data);
-
 
810
 
-
 
811
    return data;
-
 
812
}
602
 
813
 
603
/*----------------------------------------------------------------------------
814
/*----------------------------------------------------------------------------
604
** FUNCTION           : ErrorExit
815
** FUNCTION           : ErrorExit
605
**
816
**
606
** DESCRIPTION        : Error processing
817
** DESCRIPTION        : Error processing