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