Subversion Repositories DevTools

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2073 dpurdie 1
/*============================================================================
2
** Copyright (C) 1998-2012 Vix Technology, All rights reserved
3
**============================================================================
4
**
5
**  Project/Product : 
2075 dpurdie 6
**  Filename        : JatsFileUtil.c
2073 dpurdie 7
**  Author(s)       : DDP
8
**
2311 dpurdie 9
**  Description     :   Jats Build System File utility
10
**                      Used by the generated makefiles to perform specific operations
2073 dpurdie 11
**
2311 dpurdie 12
**                      The program exists to solve problems:
13
**                          Windows: Shell is very very slow to start up
14
**                          Windows: Some commands have ~260 character path length issue
15
**                          Windows/Solaris/Linux: Compatibility issues with the 'rm' command
16
**                          All: Consistent use of '/' as a path separator
2073 dpurdie 17
**
2311 dpurdie 18
**                      Note: There are two flavors of this program that MUST be
19
**                            kept in sync.
2310 dpurdie 20
**
2311 dpurdie 21
**                      The program will perform the following operations:
22
**                          (c) CopyFile
23
**                          (d) DeleteFile
24
**                          (r) Remove Files (wildcard)
25
**                          (D) DeleteDir after deleting specified files (wildcard)
2313 dpurdie 26
**                          (T) Delete Directory Trees
2354 dpurdie 27
**                          (R) Remove Files and Empty Directories
2311 dpurdie 28
**
29
**                      Example Usage
30
**
31
**                          JatsFileUtil c9 'copyFile'    aaa/bbb/ccc/dddd/file build_test.pl +w
32
**                          JatsFileUtil d9 'unCopyFile'  aaa/bbb/ccc/dddd/file
33
**                          JatsFileUtil r9 'deleteFile'  a1 b2 c3
34
**                          JatsFileUtil D9 'DeleteFiles' src/WIN32P.OBJ *.err *.pch '*'
35
**                          JatsFileUtil T9 'DeleteTree'  interface
2354 dpurdie 36
**                          JatsFileUtil R9 'RmItem'       build
2311 dpurdie 37
**
2310 dpurdie 38
**                      First two arguments are common to all
39
**                          argv[1]     - Mode specifier, Debug specifier
40
**                          argv[2]     - Display Text
41
**
2073 dpurdie 42
**  Information     :
2311 dpurdie 43
**   Compiler       : ANSI C
44
**   Target         : Windows 2000+, Linux, Solaris8+
2073 dpurdie 45
**
46
***==========================================================================*/
47
 
48
#include <stdio.h>
49
#include <sys/types.h>
50
#include <sys/stat.h>
51
#include <fcntl.h>
52
#include <unistd.h>
53
#include <stdlib.h>
2085 dpurdie 54
#include <dirent.h>
2073 dpurdie 55
#include <string.h>
56
 
57
void ErrorExit (char * lpszMessage, char * lpszMessage2);
58
void createPaths ( char *path );
2085 dpurdie 59
void DeleteDir( int argc, char* argv[] );
2310 dpurdie 60
char * makePath( char *base, char *path);
61
void DeleteOneDirectoryTree( char* baseDir );
62
void copyOneFile( int argc, char* argv[] );
2311 dpurdie 63
int CopyFile ( char *src, char *dst, mode_t st_mode );
2354 dpurdie 64
void RmItem( int argc, char* argv[] );
2311 dpurdie 65
int wildcmp(char *string, char *wild );
2354 dpurdie 66
int DeleteOneFile (char * dst );
67
void DeleteOneDirectory (char *path );
68
void stdCheck( char *name, int argBad, char *txt );
2073 dpurdie 69
 
70
/*
71
**  Global
72
*/
73
char  verbose = 1;                          /* Debugging aid */
2354 dpurdie 74
char  *helpText =
75
         "Usage: JatsFileUtil Mode Text Arguments\n"
76
         "\n"
77
         "  Where 'Mode' is two characters:\n"
78
         "      1 - Operation Specifier\n"
79
         "      2 - Debug Mode. 0..9\n"
80
         "  Where 'Text' is a, possibly empty, display string\n"
81
         "\n"
82
         "  By Example:\n"
83
         "      c9 copyFile     dstPath srcPath chmod\n"
84
         "      d9 unCopyFile   dstPath\n"
85
         "      r9 RmFile       file+\n"
86
         "      D9 DeleteFiles  dstDir file+ - supports (?*)\n"
87
         "      T9 DeleteTree   dstDir+\n"
88
         "      R9 RmItem       (dir|file)+\n";
2073 dpurdie 89
 
90
/*----------------------------------------------------------------------------
91
** FUNCTION           : main
92
**
93
** DESCRIPTION        : Main entry points
94
**
95
**
2311 dpurdie 96
** INPUTS             : argc            - Argument Count
97
**                      argv            - Argument Vector
2073 dpurdie 98
**
99
** RETURNS            : 0 - All is good
100
**
101
----------------------------------------------------------------------------*/
102
 
103
int main(int argc, char* argv[])
104
{
2354 dpurdie 105
    int ii;
106
 
2073 dpurdie 107
    /*
2313 dpurdie 108
    **  User must provide some thing
109
    */
110
    if ( argc < 2 )
111
    {
2354 dpurdie 112
       fprintf(stderr, helpText );
113
       return 1;
2313 dpurdie 114
    }
115
 
116
    /*
2073 dpurdie 117
    **  Examine the first argument
118
    **  Must be a character string of
2311 dpurdie 119
    **      [0] - Mode : One character
2073 dpurdie 120
    **      [1] - Verbose : 0 .. 9
121
    */
2310 dpurdie 122
    if ( argc > 1 && ( argv[1][1] >= '0' && argv[1][1] <= '9' ) )
2073 dpurdie 123
    {
2311 dpurdie 124
        verbose = argv[1][1] - '0';
2073 dpurdie 125
 
2311 dpurdie 126
        /*
127
        **  If Verbose, then display arguments
128
        */
129
        if ( verbose > 2 )
2073 dpurdie 130
        {
2311 dpurdie 131
            for ( ii = 0; ii < argc ; ii++ )
132
            {
133
                fprintf(stderr, "Arg%d: %s:\n", ii, argv[ii] );
134
            }
135
            fflush(stderr) ;
2073 dpurdie 136
        }
137
    }
2311 dpurdie 138
 
2073 dpurdie 139
    /*
2310 dpurdie 140
    **  Switch to required operation
2075 dpurdie 141
    */
2311 dpurdie 142
    switch( argv[1][0] )
2075 dpurdie 143
    {
2311 dpurdie 144
        /*
145
        **  CopyFile
146
        **      argv[2] - Text
147
        **      argv[3] - target path
148
        **      argv[4] - Source path
149
        **      argv[5] - File attributes
150
        */
2310 dpurdie 151
        case 'c':
2354 dpurdie 152
            stdCheck( "CopyFile", argc != 6, NULL );
153
            fprintf(stderr, "---- %s %s\n", argv[2], argv[3]);
154
            fflush(stderr) ;
2310 dpurdie 155
            copyOneFile(argc, argv);
156
            break;
2075 dpurdie 157
 
2311 dpurdie 158
        /*
159
        **  UnCopy a file
160
        **      argv[2] - Text
161
        **      argv[3] - target path
162
        */
2310 dpurdie 163
        case 'd':
2354 dpurdie 164
            stdCheck( "UnCopy", argc != 4, NULL );
165
            fprintf(stderr, "---- %s %s\n", argv[2], argv[3]);
166
            fflush(stderr) ;
2085 dpurdie 167
 
2354 dpurdie 168
            DeleteOneFile(argv[3]);
2310 dpurdie 169
            break;
2073 dpurdie 170
 
2311 dpurdie 171
        /*
172
        **  Remove named files
173
        **      argv[2]     - Text
174
        **      argv[3]+    - target path
175
        */
2310 dpurdie 176
        case 'r':
2354 dpurdie 177
            stdCheck( "RmFile", argc <= 3, argv[2] );
178
            for ( ii = 3; ii < argc ; ii++ )
179
            {
180
                DeleteOneFile(argv[ii]);
181
            }
2310 dpurdie 182
            break;
2073 dpurdie 183
 
2311 dpurdie 184
        /*
185
        **  Delete files in directory - with wildcards
186
        **      argv[2]     - Text
187
        **      argv[3]     - Base directory
188
        **      argv[4]+    - Files in dir to delete.
189
        */
2310 dpurdie 190
        case 'D':
2354 dpurdie 191
            stdCheck( "DeleteDir", argc < 4, argv[2] );
192
            DeleteDir(argc, argv );
2310 dpurdie 193
            break;
2073 dpurdie 194
 
2311 dpurdie 195
        /*
196
        **  Delete files recursively
197
        **      argv[2] - Text
198
        **      argv[3]+  Base directory
199
        */
2310 dpurdie 200
        case 'T':
2354 dpurdie 201
            stdCheck( "DeleteDirTree", argc < 3, argv[2] );
202
            for ( ii = 3; ii < argc ; ii++)
203
            {
204
                DeleteOneDirectoryTree( argv[ii] );
205
            }
2310 dpurdie 206
            break;
2313 dpurdie 207
 
208
        /*
209
        **  Delete Empty Directories
210
        **      argv[2] - Text
211
        **      argv[3]+  Base directory
212
        */
213
        case 'R':
2354 dpurdie 214
            stdCheck( "RmItem", argc < 3, argv[2] );
215
            RmItem(argc, argv );
2313 dpurdie 216
            break;
2310 dpurdie 217
 
2313 dpurdie 218
 
2310 dpurdie 219
        default :
220
            ErrorExit("Unknown mode: ",argv[1]);
221
            break;
2073 dpurdie 222
    }
223
    return 0;
224
}
225
 
226
/*----------------------------------------------------------------------------
2354 dpurdie 227
** FUNCTION           : stdCheck
228
**
229
** DESCRIPTION        : Check arg count
230
**                      Print standard header
231
**
232
**
233
** INPUTS             : name        - Name of the operation
234
**                      argBad      - Arg count Not Ok
235
**                      text        - Text to print
236
**
237
** RETURNS            : Will not return on error
238
**
239
----------------------------------------------------------------------------*/
240
 
241
void stdCheck( char *name, int argBad, char *txt )
242
{
243
    if ( argBad  )
244
    {
245
       fprintf(stderr, "JatsFileUtil:Incorrect argument count for %s\n", name);
246
       ErrorExit(NULL, NULL);
247
    }
248
 
249
    /*
250
    **  Display user text
251
    **      Suppress display if the message is empty
252
    */
253
    if ( txt && *txt )
254
    {
255
        fprintf(stderr, "%s\n",txt);
256
        fflush(stderr) ;
257
    }
258
}
259
 
260
 
261
/*----------------------------------------------------------------------------
2073 dpurdie 262
** FUNCTION           : createPaths
263
**
264
** DESCRIPTION        : Create the path to the target
265
**
266
**
267
** INPUTS             : path
268
**
269
** RETURNS            : Will not return in error
270
**
271
----------------------------------------------------------------------------*/
272
 
273
void createPaths ( char *path )
274
{
275
    struct stat fstat;
276
    int  rv;
277
    char *ptr = path;
278
 
279
    while ( *ptr )
280
    {
281
        if ( *ptr == '/' )
282
        {
283
            *ptr = 0;
2310 dpurdie 284
/* fprintf(stderr, "createPaths: %s\n", path); */
2073 dpurdie 285
            rv = stat( path, &fstat );
286
            if ( rv )
287
            {
288
                if ( verbose > 1 )
289
                {
290
                    fprintf(stderr, "createPaths: %s\n", path);
291
                    fflush(stderr) ;
292
                }
293
                rv = mkdir( path, 0777 );
294
                if ( rv )
295
                {
2075 dpurdie 296
                    ErrorExit("Could not create directories:", path);
2073 dpurdie 297
                }
298
            }
299
            *ptr = '/';
300
        }
301
        ptr++;
302
    }
303
}
304
 
305
/*----------------------------------------------------------------------------
2310 dpurdie 306
** FUNCTION           : copyOneFile
307
**
308
** DESCRIPTION        : Copy one file to a target
309
**                      Used to package and install files
310
**
311
**
312
** INPUTS             : argc            - Argc count
313
**                      argv            - Argument list
314
**                          argv[2]     - Display text Prefix
315
**                          argv[3]     - Target path
316
**                          argv[4]     - Source Path
317
**                          argv[5]     - File attributes
318
**
319
** RETURNS            :
320
**
321
----------------------------------------------------------------------------*/
322
 
323
void copyOneFile( int argc, char* argv[] )
324
{
325
	int    rv;
326
    char * src;
327
    char * dst;
328
    struct stat fstat;
329
 
330
    dst = argv[3];
331
    src = argv[4];
332
 
333
    /*
334
    **   Check that the source is a file
335
    */
2354 dpurdie 336
    if ( verbose > 2)
2310 dpurdie 337
        fprintf(stderr, "Validate Source File: %s\n", src);
338
 
339
    rv = stat( src, &fstat );
340
    if ( rv != 0 )
341
    {
342
/* Need to be a better message */
343
        fprintf(stderr, "Source: %s\n", src);
344
        ErrorExit("Source File not found: ", argv[4]);
345
    }
346
 
347
    /*
2354 dpurdie 348
    **  Delete the destination file before the copy
349
    **  Will force it to be writable
2310 dpurdie 350
    */
351
    DeleteOneFile(dst);
352
 
353
    /*
354
    **  Create directories
355
    **  Use the path to the target - not the provided directory
356
    **  as the createPaths function will not create the last element
357
    */
358
    createPaths( dst );
359
 
360
    /*
361
    **   Copy the file
362
    */
363
    if ( ! CopyFile( src, dst, fstat.st_mode ) )
364
    {
365
        ErrorExit("Copy Error: ", argv[4]);
366
    }
367
 
368
    /*
369
    **  Test for files existence
370
    */
2354 dpurdie 371
    if ( verbose > 1 )
2310 dpurdie 372
        fprintf(stderr, "Test target was copied: %s\n", dst);
373
 
374
    rv = stat( dst, &fstat );
375
    if ( rv != 0 )
376
    {
377
/* Need to be a better message */
378
        ErrorExit("File not found after copy: ", argv[3]);
379
    }
380
 
381
    /*
382
    **  Set the files attributes
383
    **      Assume read-only
384
    */
385
    if ( strstr( argv[5], "-w" ) )
386
    {
387
        if ( verbose > 1 )
388
            fprintf(stderr, "Set target read-only: %s\n", dst);
389
        fstat.st_mode &= ~(S_IWRITE | S_IWOTH | S_IWGRP );
390
    }
391
 
392
    if ( strstr( argv[5], "+w" ) )
393
    {
394
        if ( verbose > 1 )
395
            fprintf(stderr, "Set target writable: %s\n", dst);
396
        fstat.st_mode |= (S_IWRITE | S_IWOTH | S_IWGRP );
397
    }
398
 
399
    if ( strstr( argv[5], "+x" ) )
400
    {
401
        if ( verbose > 1 )
402
            fprintf(stderr, "Set target executable: %s\n", dst);
403
        fstat.st_mode |= ( S_IXUSR | S_IXOTH | S_IXGRP );
404
    }
405
 
406
    if ( strstr( argv[5], "-x" ) )
407
    {
408
        if ( verbose > 1)
409
            fprintf(stderr, "Set target executable: %s\n", dst);
410
        fstat.st_mode &= ~( S_IXUSR | S_IXOTH | S_IXGRP );
411
    }
412
 
2354 dpurdie 413
    if ( verbose > 1 )
2310 dpurdie 414
        fprintf(stderr, "Set target perms: %s, 0%o\n", dst, fstat.st_mode);
415
    rv = chmod( dst, fstat.st_mode );
416
    if ( rv != 0 )
417
    {
418
        ErrorExit("Setting ReadOnly: ", argv[3]);
419
    }
420
}
421
 
422
/*----------------------------------------------------------------------------
2073 dpurdie 423
** FUNCTION           : CopyFile
424
**
425
** DESCRIPTION        : Just copy a file
426
**
427
**
428
** INPUTS             : src - source path - already exists
429
**                      dst - path. Dirs already exist
430
**                      st_mode - Creation  mode. Copied from source file
431
**
432
** RETURNS            : false - Error
433
**
434
----------------------------------------------------------------------------*/
435
 
436
#define COPYSIZE  1024
437
int CopyFile ( char *src, char *dst, mode_t st_mode )
438
{
439
 
440
     ssize_t rlen = 0 ;
441
     ssize_t wlen = 0 ;
442
     int in;
443
     int out;
444
     int ferror = 0;
445
    char buffer[COPYSIZE] = { '\0' } ;
446
 
2354 dpurdie 447
    if ( verbose > 2 )
2073 dpurdie 448
    {
449
        fprintf(stderr, "CopyFile: Output Mode: 0%o\n", st_mode);
450
        fflush(stderr) ;
451
    }
452
 
453
    in = open( src, O_RDONLY ) ;
454
    if ( in < 0 )
2075 dpurdie 455
        ErrorExit("Could not open source:", src);
2073 dpurdie 456
 
457
    out = open( dst, O_WRONLY | O_CREAT, st_mode | S_IWRITE );
458
    if ( out < 0 )
2075 dpurdie 459
        ErrorExit("Could not open dst:", dst);
2073 dpurdie 460
 
461
    while( (rlen = read( in, buffer, COPYSIZE )) > 0 )
462
    {
463
        wlen = write( out, buffer, rlen ) ;
464
        if ( wlen != rlen )
465
        {
466
            ferror = 1;
467
            break;
468
        }
469
    }
470
 
471
    close(in) ;
472
    close(out) ;
473
 
474
    /*
475
    **  File error
476
    **  Delete target
477
    */
478
    if ( ferror || rlen < 0 )
479
    {
480
        unlink(dst) ;
481
        return 0;
482
    }
483
    return 1;
484
}
485
 
2075 dpurdie 486
/*----------------------------------------------------------------------------
2085 dpurdie 487
** FUNCTION           : DeleteDir
488
**
489
** DESCRIPTION        : Delete a list of files in a specified directory
490
**                      Ensure files are writable
491
**                      Wilcarding is supported
492
**
493
**                      Then delete the directory - if its empty
494
**
495
**
496
** INPUTS             : argc    - count of args
497
**                      argv    - list of files to delete
2354 dpurdie 498
**                                [3]:  Base directory
499
**                                [4]+  Files in dir to delete
2085 dpurdie 500
**
2310 dpurdie 501
** RETURNS            : Will not return on error
2085 dpurdie 502
**
503
----------------------------------------------------------------------------*/
2075 dpurdie 504
 
2085 dpurdie 505
void DeleteDir( int argc, char* argv[] )
506
{
507
	int rv;
508
    struct stat fstat;
509
    char* baseDir;
510
    DIR *dir;
511
    struct dirent *dirent;
2310 dpurdie 512
    char *target;
2085 dpurdie 513
 
2310 dpurdie 514
 
2085 dpurdie 515
    /*
516
    **  Extract the base directory from the argument list
517
    **  This must be a directory
518
    */
2354 dpurdie 519
    baseDir = argv[3];
2085 dpurdie 520
 
521
    /*
522
    **  Ensure that the base directory exists
523
    */
524
    rv = stat( baseDir, &fstat );
525
    if ( rv != 0 )
526
    {
527
        /*
528
        **  Directory does not exists
2354 dpurdie 529
        **  Assume its already deleted
2085 dpurdie 530
        */
531
        if ( verbose > 1 )
532
            fprintf(stderr, "Base dir does not exist: %s\n", baseDir);
533
        return;
534
    }
535
 
536
    if ( !(fstat.st_mode & S_IFDIR))
537
    {
538
        /*
539
        **  Target is not a directory
540
        **  Don't do anything
541
        */
542
        if ( verbose > 1 )
543
            fprintf(stderr, "Base dir is not a directory: %s\n", baseDir);
544
        return;
545
    }
546
 
547
    /*
548
    **  Process all the suffixes
549
    **  They may contain a wild card
550
    */
551
    dir = opendir( baseDir );
552
    if ( dir == NULL )
553
    {
554
        /*
555
        **  Target is not a directory
556
        **  Don't do anything
557
        */
558
        if ( verbose > 1 )
559
            fprintf(stderr, "Base dir is not a directory: %s\n", baseDir);
560
        return;
561
    }
562
 
563
    /*
564
    **  Read next directory entry
565
    */
566
    while ( (dirent = readdir(dir)) != NULL )
567
    {
568
        int ii;
569
        if ( strcmp( ".", dirent->d_name ) == 0 )
570
            continue;
571
 
572
        if ( strcmp( "..", dirent->d_name ) == 0 )
573
            continue;
574
 
2313 dpurdie 575
        if ( verbose > 2 )
576
            fprintf(stderr, "Directory Entry:%s,%s\n", baseDir, dirent->d_name );
577
 
2085 dpurdie 578
        /*
579
        **  Compare against each item in the user list
580
        */
2354 dpurdie 581
        for ( ii = 4; ii < argc ; ii++)
2085 dpurdie 582
        {
583
 
584
            if ( wildcmp(dirent->d_name, argv[ii] )  )
585
            {
586
                if ( verbose > 1 )
587
                    fprintf(stderr, "Matching: %s, %s --- Found\n", dirent->d_name, argv[ii] );
2310 dpurdie 588
 
2085 dpurdie 589
                /*
590
                **  Matching file found
591
                */
2310 dpurdie 592
                target = makePath( baseDir, dirent->d_name);
593
                DeleteOneFile(target);
594
                free(target);
2085 dpurdie 595
            }
596
        }
597
    }
598
    closedir(dir);
599
 
600
    /*
601
    **  Finally delete the diretory
602
    **      Unless its '.'
603
    */
604
    if ( strcmp( ".", baseDir) != 0 )
605
    {
2354 dpurdie 606
        DeleteOneDirectory(baseDir);
2085 dpurdie 607
    }
608
}
609
 
2073 dpurdie 610
/*----------------------------------------------------------------------------
2310 dpurdie 611
** FUNCTION           : DeleteOneDirectoryTree
612
**
613
** DESCRIPTION        : Delete an entire directory tree(s)
2313 dpurdie 614
**                      Force it writable and searchable before deletion
615
**                      Don't follow symbolic links - just delete them
2310 dpurdie 616
**
617
** INPUTS             : path    - Dir to delete
618
**
619
** RETURNS            : Will not return on error
620
**
621
----------------------------------------------------------------------------*/
622
 
623
void DeleteOneDirectoryTree( char* baseDir )
624
{
625
    struct stat fstat;
626
    DIR *dir;
627
    struct dirent *dirent;
628
    char *target;
629
    int rv;
630
 
631
    /*
632
    **  A bit of a sanity test
633
    */
634
    if ( strcmp( ".", baseDir) == 0 || strcmp( "..", baseDir) == 0 )
635
    {
636
        fprintf(stderr, "DeleteOneDirectoryTree will not delete '.' or '..'\n");
637
        return;
638
    }
639
 
640
    /*
2313 dpurdie 641
    **  Ensure that the directory exists
642
    **  Force writable and searchable
643
    */
644
    rv = stat( baseDir, &fstat );
645
    if ( rv == 0 )
646
    {
647
        if ( fstat.st_mode & S_IFDIR )
648
        {
649
            mode_t newMode =  fstat.st_mode | S_IRUSR | S_IWUSR  | S_IXUSR;
650
            if ( fstat.st_mode != newMode )
651
            {
652
                if ( verbose > 1 )
653
                    fprintf(stderr, "Force u+rwx: %s\n", baseDir);
654
 
655
                rv = chmod( baseDir, newMode );
656
                if ( rv != 0 )
657
                {
658
                    fprintf(stderr, "Warning: Attempt to allow u+rwx access: %s\n", baseDir);
659
                }
660
            }
661
        }
662
    }
663
 
664
 
665
    /*
2310 dpurdie 666
    **  Process all entries
667
    */
668
    dir = opendir( baseDir );
669
    if ( dir == NULL )
670
    {
671
        /*
672
        **  Target is not a directory
673
        **  Don't do anything
674
        */
675
        if ( verbose > 1 )
676
            fprintf(stderr, "Base dir is not a directory: %s\n", baseDir);
677
        return;
678
    }
679
 
680
    /*
681
    **  Read next directory entry
682
    */
683
    while ( (dirent = readdir(dir)) != NULL )
684
    {
685
        if ( strcmp( ".", dirent->d_name ) == 0 )
686
            continue;
687
 
688
        if ( strcmp( "..", dirent->d_name ) == 0 )
689
            continue;
690
 
2313 dpurdie 691
        if ( verbose > 2 )
692
            fprintf(stderr, "Directory Entry:%s,%s\n", baseDir, dirent->d_name );
693
 
2310 dpurdie 694
        target = makePath( baseDir, dirent->d_name);
2313 dpurdie 695
        rv = lstat( target, &fstat );
2310 dpurdie 696
        if ( rv == 0 )
697
        {
698
            if ( fstat.st_mode & S_IFDIR )
699
            {
700
                DeleteOneDirectoryTree( target );
701
            }
702
            else
703
            {
704
                DeleteOneFile (target);
705
            }
706
        }
707
        free(target);
708
    }
709
    closedir(dir);
710
 
711
    /*
712
    **  Finally delete the directory
2354 dpurdie 713
    **  It should now be empty
2310 dpurdie 714
    */
2354 dpurdie 715
    DeleteOneDirectory(baseDir);
716
}
2310 dpurdie 717
 
2354 dpurdie 718
/*----------------------------------------------------------------------------
719
** FUNCTION           : RmItem
720
**
721
** DESCRIPTION        : Remove Empty directories and files
722
**
723
** INPUTS             : argc    - count of args
724
**                      argv    - list of files to delete
725
**                                [3]+  Base directory
726
**
727
** RETURNS            : Will not return on error
728
**
729
----------------------------------------------------------------------------*/
730
 
731
void RmItem( int argc, char* argv[] )
732
{
733
    int ii;
734
    struct stat fstat;
735
 
736
 
737
    for ( ii = 3; ii < argc ; ii++)
2310 dpurdie 738
    {
2354 dpurdie 739
        int rv;
740
 
741
        if ( verbose > 2)
742
            fprintf(stderr, "RmItem: %s\n", argv[ii]);
743
 
744
        rv = lstat( argv[ii], &fstat );
745
        if ( rv == 0 )
746
        {
747
            if (fstat.st_mode & S_IFDIR)
748
            {
749
                DeleteOneDirectory(argv[ii]);
750
            }
751
            else
752
            {
753
                DeleteOneFile(argv[ii]);
754
            }
755
        }
2310 dpurdie 756
    }
757
}
758
 
759
/*----------------------------------------------------------------------------
760
** FUNCTION           : DeleteOneFile
761
**
762
** DESCRIPTION        : Delete a file
2354 dpurdie 763
**                      Low level deletion operation to be used by other functions
2310 dpurdie 764
**                      Force it writable before deletion
2313 dpurdie 765
**                      Don't follow symbolic links - just delete them
2310 dpurdie 766
**
767
** INPUTS             : path        - path to the file
768
**
769
** RETURNS            : 0           - OK (file deleted or not present)
770
**
771
----------------------------------------------------------------------------*/
772
 
773
int DeleteOneFile (char * dst )
774
{
775
	int rv;
776
    struct stat fstat;
777
    int result = 0;
778
 
779
    if ( verbose > 1)
780
        fprintf(stderr, "Delete File: %s\n", dst);
781
 
2313 dpurdie 782
    rv = lstat( dst, &fstat );
2310 dpurdie 783
    if ( rv == 0 )
784
    {
785
        if ( verbose )
786
            fprintf(stderr, "Delete file: %s : Attr: 0%o\n", dst, fstat.st_mode);
787
        if ( !(fstat.st_mode & S_IWRITE) )
788
        {
789
            fstat.st_mode |= S_IWRITE;
790
            rv = chmod( dst, fstat.st_mode );
791
            if ( rv != 0 )
792
            {
793
                fprintf(stderr, "Warning: Attempt to allow write access: %s\n", dst);
794
            }
795
        }
796
 
797
        if ( unlink(dst) )
798
        {
799
            fprintf(stderr, "Warning: Did not remove file: %s\n", dst);
800
            result = 1;
801
        }
802
    }
2354 dpurdie 803
 
2310 dpurdie 804
    return result;
805
}
806
 
807
/*----------------------------------------------------------------------------
2354 dpurdie 808
** FUNCTION           : DeleteOneDirectory
2313 dpurdie 809
**
2354 dpurdie 810
** DESCRIPTION        : Low level function to delete a directory
811
**                      Assumes that checks have been performed
812
**                          It is a directory
813
**                          It does exist
2313 dpurdie 814
**
815
**
2354 dpurdie 816
** INPUTS             : path            - Target Path
2313 dpurdie 817
**
2354 dpurdie 818
** RETURNS            : Nothing
819
**
2313 dpurdie 820
----------------------------------------------------------------------------*/
821
 
2354 dpurdie 822
void DeleteOneDirectory (char *path )
2313 dpurdie 823
{
2354 dpurdie 824
    if ( verbose )
825
        fprintf(stderr, "Delete Directory: %s\n", path);
2313 dpurdie 826
 
2354 dpurdie 827
    if ( rmdir(path))
2313 dpurdie 828
    {
2354 dpurdie 829
        if ( verbose )
830
            fprintf(stderr, "Directory not deleted: %s\n", path);
2313 dpurdie 831
    }
832
}
833
 
834
/*----------------------------------------------------------------------------
2310 dpurdie 835
** FUNCTION           : makePath
836
**
837
** DESCRIPTION        : Create a path from two elements
2354 dpurdie 838
**                      Join 2 components together
2310 dpurdie 839
**                      Allocate memory
840
**
841
**
842
** INPUTS             : base        - Part 1
2354 dpurdie 843
**                      file        - Part 2 or NULL
2310 dpurdie 844
**
845
** RETURNS            :
846
**
847
----------------------------------------------------------------------------*/
848
 
849
char * makePath( char *base, char *path)
850
{
851
    int len1 = strlen(base);
852
    int len2 = strlen(path);
853
    char *data;
854
 
855
    data = (char *)malloc(len1 + len2 + 10);
856
    if ( data == NULL )
857
    {
858
        ErrorExit ("Malloc error:makePath","");
859
    }
860
 
861
    strcpy( data,base);
862
    strcpy( data + len1, "/");
863
    strcpy( data + len1 + 1, path);
864
 
865
    return data;
866
}
867
 
868
/*----------------------------------------------------------------------------
2085 dpurdie 869
** FUNCTION           : wildcmp
870
**
871
** DESCRIPTION        : Wildcard comparision
872
**
873
**
874
** INPUTS             : string          - String
875
**                      wild            - Wildcard template
876
**
877
** RETURNS            : TRUE - Match
878
**
879
----------------------------------------------------------------------------*/
880
 
881
int wildcmp(char *string, char *wild )
882
{
883
    char *cp, *mp;
884
    while ((*string) && (*wild != '*'))
885
    {
886
        if ((*wild != *string) && (*wild != '?'))
887
        {
888
            return 0;
889
        }
890
         wild++;
891
         string++;
892
    }
893
 
894
    while (*string)
895
    {
896
        if (*wild == '*')
897
        {
898
            if (!*++wild)
899
            {
900
                return 1;
901
            }
902
            mp = wild;
903
            cp = string+1;
904
        }
905
        else if ((*wild == *string) || (*wild == '?'))
906
        {
907
            wild++;
908
            string++;
909
        }
910
        else
911
        {
912
            wild = mp;
913
            string = cp++;
914
        }
915
    }
916
 
917
    while (*wild == '*')
918
    {
919
        wild++;
920
    }
921
 
922
    return !*wild;
923
}
924
 
925
 
926
 
927
 
928
/*----------------------------------------------------------------------------
2073 dpurdie 929
** FUNCTION           : ErrorExit
930
**
931
** DESCRIPTION        : Error processing
932
**                      Report an error and terminate process
933
**
934
**
935
** INPUTS             : lpszMessage     - Message to display
936
**
937
** RETURNS            : Does't return
938
**                      Will exit with bad code
939
**
940
----------------------------------------------------------------------------*/
941
 
942
void ErrorExit (char * lpszMessage, char * lpszMessage2)
943
{ 
2354 dpurdie 944
    if ( lpszMessage  )
945
    {
946
        fprintf(stderr, "JatsFileUtil:Error:%s%s\n", lpszMessage,lpszMessage2);
947
    }
2073 dpurdie 948
   fflush(stderr) ;
949
   exit(-1);
950
} 
951