Subversion Repositories DevTools

Rev

Rev 2073 | Rev 2085 | Go to most recent revision | Details | Compare with Previous | 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
**
9
**  Description     :
10
**                      The program mimics - but a lot faster a Jats Makefile fragment
11
**                      The program will:
12
**
13
**                      Operate in two modes
14
**                          CopyFile
15
**                          DeleteFile
2075 dpurdie 16
**                          Remove Files
2073 dpurdie 17
**
18
**                      CopyFile (5 args)
19
**                          1) Display the ----- Text dest
20
**                          2) Error if the source is not found
21
**                          3) Create target path if not alraedy existing
22
**                          4) Copy the source to the target - overwritting the target
23
**                          5) Set File mode
24
**                          6) Test for file existence
25
**
26
**                      DeleteFile (3 args)
27
**                          1) Display the ----- Text dest
28
**                          2) Delete the target file
29
**
2075 dpurdie 30
**                      RemoveFiles ( >1 arg)
31
**                          1) Silenty delete a list of files. The files may
32
**                             be readonly so the attributes will need to be fixed.
33
**
2073 dpurdie 34
**                      Make paths use '/'
35
**
36
**
37
**  Information     :
38
**   Compiler       : ANSI C++
39
**   Target         : 
40
**
41
***==========================================================================*/
42
 
43
#include <stdio.h>
44
#include <sys/types.h>
45
#include <sys/stat.h>
46
#include <fcntl.h>
47
#include <unistd.h>
48
#include <stdlib.h>
49
#include <string.h>
50
 
51
void ErrorExit (char * lpszMessage, char * lpszMessage2);
52
void createPaths ( char *path );
2075 dpurdie 53
int CopyFile ( char *src, char *dst, mode_t st_mode );
54
void deleteFileList( int argc, char* argv[] );
2073 dpurdie 55
 
56
/*
57
**  Global
58
*/
59
char  verbose = 1;                          /* Debugging aid */
60
char  copyMode = 0;                         /* Mode */
61
 
62
/*----------------------------------------------------------------------------
63
** FUNCTION           : main
64
**
65
** DESCRIPTION        : Main entry points
66
**
67
**
68
** INPUTS             : Arguments are fixed
69
**                          Mode    - ModeDebug
70
**                          Text    - Text to output
71
**                          dest    - Target Path
72
**                          file    - Source path   [Copy Only]
73
**                          fmode   - File mode     [Copy Only]
74
**
75
** RETURNS            : 0 - All is good
76
**
77
----------------------------------------------------------------------------*/
78
 
79
int main(int argc, char* argv[])
80
{
81
 
82
	int rv;
83
    struct stat fstat;
84
    char *dst;
85
    char *src;
86
    mode_t src_mode;
87
 
88
    /*
89
    **  Examine the first argument
90
    **  Must be a character string of
2075 dpurdie 91
    **      [0] - Mode : c or d or r
2073 dpurdie 92
    **      [1] - Verbose : 0 .. 9
93
    */
94
    if ( argc > 1 )
95
    {
96
        if ( argv[1][0] == 'c' ) {
97
            copyMode = 1;
98
        } else if ( argv[1][0] == 'd' ) {
99
            copyMode = 2;
2075 dpurdie 100
        } else if ( argv[1][0] == 'r' ) {
101
            copyMode = 3;
2073 dpurdie 102
        } else {
2075 dpurdie 103
            ErrorExit("Unknown mode: ",argv[1]);
2073 dpurdie 104
        }
105
 
106
        if ( argv[1][1] >= '0' && argv[1][1] <= '9' ) {
107
            verbose = argv[1][1] - '0';
108
        }
109
    }
110
 
111
    /*
112
    **  If Verbose, then display arguments
113
    */
2075 dpurdie 114
    if ( verbose > 1 )
2073 dpurdie 115
    {
116
        int ii;
117
        for ( ii = 0; ii < argc ; ii++ )
118
        {
119
            fprintf(stderr, "Arg%d: %s:\n", ii, argv[ii] );
120
        }
121
        fprintf(stderr, "Mode   : %d:\n", copyMode );
122
        fprintf(stderr, "Verbose: %d:\n", verbose );
123
        fflush(stderr) ;
124
    }
125
 
126
    /*
2075 dpurdie 127
    **  Determine required operation
128
    */
129
    if ( copyMode == 3 )
130
    {
131
        deleteFileList(argc - 2, argv + 2 );
132
        return 0;
133
    }
134
 
135
    /*
2073 dpurdie 136
    **  Determine mode of operation
137
    **      Copy or Delete
138
    */
139
    if ( copyMode == 1 && argc == 6 ) {
140
        src = argv[4];
141
        dst = argv[3];
142
 
143
    } else if ( copyMode == 2 && argc == 4) {
144
        dst = argv[3];
145
 
146
    } else {
147
        fprintf(stderr, "Mode: %d, Args: %d\n", copyMode, argc);
148
        ErrorExit("Incorrect argument count for mode","");
149
    }
150
 
151
    /*
152
    **  Display user text
153
    */
154
    fprintf(stderr, "---- %s %s\n", argv[2], argv[3]);
155
    fflush(stderr) ;
156
 
157
    /*
158
    **   Check that the source is a file
159
    */
160
    if ( copyMode == 1 )
161
    {
162
        if ( verbose )
163
            fprintf(stderr, "Validate Source File: %s\n", src);
164
 
165
        rv = stat( src, &fstat );
166
        if ( rv != 0 )
167
        {
168
    /* Need to be a better message */
169
            fprintf(stderr, "Source: %s\n", src);
2075 dpurdie 170
            ErrorExit("Source File not found: ", argv[4]);
2073 dpurdie 171
        }
172
        src_mode = fstat.st_mode;
173
    }
174
 
175
    /*
176
    **  Remove the ReadOnly attribute on the dest file
177
    */
178
    if ( verbose )
179
        fprintf(stderr, "Remove target file: %s\n", dst);
180
    rv = stat( dst, &fstat );
181
    if ( rv == 0 )
182
    {
183
        if ( verbose )
184
            fprintf(stderr, "FileExists with attr: 0%o\n", fstat.st_mode);
185
        if ( !(fstat.st_mode & S_IWRITE) )
186
        {
187
            fstat.st_mode |= S_IWRITE;
188
            rv = chmod( dst, fstat.st_mode );
189
            if ( rv != 0 )
190
            {
2075 dpurdie 191
                ErrorExit("Attempt to allow write access: ", argv[3]);
2073 dpurdie 192
            }
193
        }
194
 
195
        if ( unlink( dst ) )
196
        {
2075 dpurdie 197
                ErrorExit("Deleting file: ", argv[3]);
2073 dpurdie 198
        }
199
    }
200
 
201
    if ( copyMode == 1 )
202
    {
203
        /*
204
        **  Create directories
205
        **  Use the path to the target - not the provided directory
206
        **  as the createPaths function will not create the last element
207
        */
208
        createPaths( dst );
209
 
210
        /*
211
        **   Copy the file
212
        */
213
        if ( ! CopyFile( src, dst, src_mode ) )
214
        {
2075 dpurdie 215
            ErrorExit("Copy Error: ", argv[4]);
2073 dpurdie 216
        }
217
 
218
        /*
219
        **  Test for files existence
220
        */
221
        if ( verbose )
222
            fprintf(stderr, "Test target was copied: %s\n", dst);
223
        rv = stat( dst, &fstat );
224
        if ( rv != 0 )
225
        {
226
    /* Need to be a better message */
2075 dpurdie 227
            ErrorExit("File not found after copy: ", argv[3]);
2073 dpurdie 228
        }
229
 
230
        /*
231
        **  Set the files attributes
232
        **      Assume read-only
233
        */
234
        if ( strstr( argv[5], "-w" ) )
235
        {
236
            if ( verbose > 1 )
237
                fprintf(stderr, "Set target read-only: %s\n", dst);
238
            fstat.st_mode &= ~(S_IWRITE | S_IWOTH | S_IWGRP );
239
        }
240
 
241
        if ( strstr( argv[5], "+w" ) )
242
        {
243
            if ( verbose > 1 )
244
                fprintf(stderr, "Set target writable: %s\n", dst);
245
            fstat.st_mode |= (S_IWRITE | S_IWOTH | S_IWGRP );
246
        }
247
 
248
        if ( strstr( argv[5], "+x" ) )
249
        {
250
            if ( verbose > 1 )
251
                fprintf(stderr, "Set target executable: %s\n", dst);
252
            fstat.st_mode |= ( S_IXUSR | S_IXOTH | S_IXGRP );
253
        }
254
 
255
        if ( strstr( argv[5], "-x" ) )
256
        {
257
            if ( verbose > 1)
258
                fprintf(stderr, "Set target executable: %s\n", dst);
259
            fstat.st_mode &= ~( S_IXUSR | S_IXOTH | S_IXGRP );
260
        }
261
 
262
        if ( verbose )
263
            fprintf(stderr, "Set target perms: %s, 0%o\n", dst, fstat.st_mode);
264
        rv = chmod( dst, fstat.st_mode );
265
        if ( rv != 0 )
266
        {
2075 dpurdie 267
            ErrorExit("Setting ReadOnly: ", argv[3]);
2073 dpurdie 268
            }
269
        }
270
 
271
    return 0;
272
}
273
 
274
/*----------------------------------------------------------------------------
275
** FUNCTION           : createPaths
276
**
277
** DESCRIPTION        : Create the path to the target
278
**
279
**
280
** INPUTS             : path
281
**
282
** RETURNS            : Will not return in error
283
**
284
----------------------------------------------------------------------------*/
285
 
286
void createPaths ( char *path )
287
{
288
    struct stat fstat;
289
    int  rv;
290
    char *ptr = path;
291
 
292
    while ( *ptr )
293
    {
294
        if ( *ptr == '/' )
295
        {
296
            *ptr = 0;
297
 
298
            rv = stat( path, &fstat );
299
            if ( rv )
300
            {
301
                if ( verbose > 1 )
302
                {
303
                    fprintf(stderr, "createPaths: %s\n", path);
304
                    fflush(stderr) ;
305
                }
306
                rv = mkdir( path, 0777 );
307
                if ( rv )
308
                {
2075 dpurdie 309
                    ErrorExit("Could not create directories:", path);
2073 dpurdie 310
                }
311
            }
312
            *ptr = '/';
313
        }
314
        ptr++;
315
    }
316
}
317
 
318
/*----------------------------------------------------------------------------
319
** FUNCTION           : CopyFile
320
**
321
** DESCRIPTION        : Just copy a file
322
**
323
**
324
** INPUTS             : src - source path - already exists
325
**                      dst - path. Dirs already exist
326
**                      st_mode - Creation  mode. Copied from source file
327
**
328
** RETURNS            : false - Error
329
**
330
----------------------------------------------------------------------------*/
331
 
332
#define COPYSIZE  1024
333
int CopyFile ( char *src, char *dst, mode_t st_mode )
334
{
335
 
336
     ssize_t rlen = 0 ;
337
     ssize_t wlen = 0 ;
338
     int in;
339
     int out;
340
     int ferror = 0;
341
    char buffer[COPYSIZE] = { '\0' } ;
342
 
343
    if ( verbose )
344
    {
345
        fprintf(stderr, "CopyFile: Output Mode: 0%o\n", st_mode);
346
        fflush(stderr) ;
347
    }
348
 
349
    in = open( src, O_RDONLY ) ;
350
    if ( in < 0 )
2075 dpurdie 351
        ErrorExit("Could not open source:", src);
2073 dpurdie 352
 
353
    out = open( dst, O_WRONLY | O_CREAT, st_mode | S_IWRITE );
354
    if ( out < 0 )
2075 dpurdie 355
        ErrorExit("Could not open dst:", dst);
2073 dpurdie 356
 
357
    while( (rlen = read( in, buffer, COPYSIZE )) > 0 )
358
    {
359
        wlen = write( out, buffer, rlen ) ;
360
        if ( wlen != rlen )
361
        {
362
            ferror = 1;
363
            break;
364
        }
365
    }
366
 
367
    close(in) ;
368
    close(out) ;
369
 
370
    /*
371
    **  File error
372
    **  Delete target
373
    */
374
    if ( ferror || rlen < 0 )
375
    {
376
        unlink(dst) ;
377
        return 0;
378
    }
379
    return 1;
380
}
381
 
2075 dpurdie 382
/*----------------------------------------------------------------------------
383
** FUNCTION           : deleteFileList
384
**
385
** DESCRIPTION        : Delete a list of files
386
**                      Ensure files are writable
387
**
388
**
389
** INPUTS             : argc    - count of args
390
**                      argv    - list of files to delete
391
**
392
** RETURNS            : Wil not return on error
393
**
394
----------------------------------------------------------------------------*/
2073 dpurdie 395
 
2075 dpurdie 396
void deleteFileList( int argc, char* argv[] )
397
{
398
	int rv;
399
    struct stat fstat;
2073 dpurdie 400
 
2075 dpurdie 401
    for ( ; argc ; argc--, argv++ )
402
    {
403
        /*
404
        **  Remove the ReadOnly attribute on the dest file
405
        */
406
        if ( verbose > 1 )
407
            fprintf(stderr, "Remove target file: %s\n", *argv);
408
 
409
 
410
        rv = stat( *argv, &fstat );
411
        if ( rv == 0 )
412
        {
413
            if ( verbose )
414
                fprintf(stderr, "Delete file: %s : Attr: 0%o\n", *argv, fstat.st_mode);
415
            if ( !(fstat.st_mode & S_IWRITE) )
416
            {
417
                fstat.st_mode |= S_IWRITE;
418
                rv = chmod( *argv, fstat.st_mode );
419
                if ( rv != 0 )
420
                {
421
                    fprintf(stderr, "Warning: Attempt to allow write access: %s\n", *argv);
422
                }
423
            }
424
 
425
            if ( unlink( *argv ) )
426
            {
427
                fprintf(stderr, "Warning: Did not remove file: %s\n", *argv);
428
            }
429
        }
430
    }
431
}
432
 
433
 
2073 dpurdie 434
/*----------------------------------------------------------------------------
435
** FUNCTION           : ErrorExit
436
**
437
** DESCRIPTION        : Error processing
438
**                      Report an error and terminate process
439
**
440
**
441
** INPUTS             : lpszMessage     - Message to display
442
**
443
** RETURNS            : Does't return
444
**                      Will exit with bad code
445
**
446
----------------------------------------------------------------------------*/
447
 
448
void ErrorExit (char * lpszMessage, char * lpszMessage2)
449
{ 
2075 dpurdie 450
   fprintf(stderr, "JatsFileUtil:Error: %s%s\n", lpszMessage,lpszMessage2);
2073 dpurdie 451
   fflush(stderr) ;
452
   exit(-1);
453
} 
454