Rev 2073 | Rev 2085 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed
/*============================================================================** Copyright (C) 1998-2012 Vix Technology, All rights reserved**============================================================================**** Project/Product :** Filename : JatsFileUtil.c** Author(s) : DDP**** Description :** The program mimics - but a lot faster a Jats Makefile fragment** The program will:**** Operate in two modes** CopyFile** DeleteFile** Remove Files**** CopyFile (5 args)** 1) Display the ----- Text dest** 2) Error if the source is not found** 3) Create target path if not alraedy existing** 4) Copy the source to the target - overwritting the target** 5) Set File mode** 6) Test for file existence**** DeleteFile (3 args)** 1) Display the ----- Text dest** 2) Delete the target file**** RemoveFiles ( >1 arg)** 1) Silenty delete a list of files. The files may** be readonly so the attributes will need to be fixed.**** Make paths use '/'****** Information :** Compiler : ANSI C++** Target :*****==========================================================================*/#include <stdio.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <unistd.h>#include <stdlib.h>#include <string.h>void ErrorExit (char * lpszMessage, char * lpszMessage2);void createPaths ( char *path );int CopyFile ( char *src, char *dst, mode_t st_mode );void deleteFileList( int argc, char* argv[] );/*** Global*/char verbose = 1; /* Debugging aid */char copyMode = 0; /* Mode *//*----------------------------------------------------------------------------** FUNCTION : main**** DESCRIPTION : Main entry points****** INPUTS : Arguments are fixed** Mode - ModeDebug** Text - Text to output** dest - Target Path** file - Source path [Copy Only]** fmode - File mode [Copy Only]**** RETURNS : 0 - All is good**----------------------------------------------------------------------------*/int main(int argc, char* argv[]){int rv;struct stat fstat;char *dst;char *src;mode_t src_mode;/*** Examine the first argument** Must be a character string of** [0] - Mode : c or d or r** [1] - Verbose : 0 .. 9*/if ( argc > 1 ){if ( argv[1][0] == 'c' ) {copyMode = 1;} else if ( argv[1][0] == 'd' ) {copyMode = 2;} else if ( argv[1][0] == 'r' ) {copyMode = 3;} else {ErrorExit("Unknown mode: ",argv[1]);}if ( argv[1][1] >= '0' && argv[1][1] <= '9' ) {verbose = argv[1][1] - '0';}}/*** If Verbose, then display arguments*/if ( verbose > 1 ){int ii;for ( ii = 0; ii < argc ; ii++ ){fprintf(stderr, "Arg%d: %s:\n", ii, argv[ii] );}fprintf(stderr, "Mode : %d:\n", copyMode );fprintf(stderr, "Verbose: %d:\n", verbose );fflush(stderr) ;}/*** Determine required operation*/if ( copyMode == 3 ){deleteFileList(argc - 2, argv + 2 );return 0;}/*** Determine mode of operation** Copy or Delete*/if ( copyMode == 1 && argc == 6 ) {src = argv[4];dst = argv[3];} else if ( copyMode == 2 && argc == 4) {dst = argv[3];} else {fprintf(stderr, "Mode: %d, Args: %d\n", copyMode, argc);ErrorExit("Incorrect argument count for mode","");}/*** Display user text*/fprintf(stderr, "---- %s %s\n", argv[2], argv[3]);fflush(stderr) ;/*** Check that the source is a file*/if ( copyMode == 1 ){if ( verbose )fprintf(stderr, "Validate Source File: %s\n", src);rv = stat( src, &fstat );if ( rv != 0 ){/* Need to be a better message */fprintf(stderr, "Source: %s\n", src);ErrorExit("Source File not found: ", argv[4]);}src_mode = fstat.st_mode;}/*** Remove the ReadOnly attribute on the dest file*/if ( verbose )fprintf(stderr, "Remove target file: %s\n", dst);rv = stat( dst, &fstat );if ( rv == 0 ){if ( verbose )fprintf(stderr, "FileExists with attr: 0%o\n", fstat.st_mode);if ( !(fstat.st_mode & S_IWRITE) ){fstat.st_mode |= S_IWRITE;rv = chmod( dst, fstat.st_mode );if ( rv != 0 ){ErrorExit("Attempt to allow write access: ", argv[3]);}}if ( unlink( dst ) ){ErrorExit("Deleting file: ", argv[3]);}}if ( copyMode == 1 ){/*** Create directories** Use the path to the target - not the provided directory** as the createPaths function will not create the last element*/createPaths( dst );/*** Copy the file*/if ( ! CopyFile( src, dst, src_mode ) ){ErrorExit("Copy Error: ", argv[4]);}/*** Test for files existence*/if ( verbose )fprintf(stderr, "Test target was copied: %s\n", dst);rv = stat( dst, &fstat );if ( rv != 0 ){/* Need to be a better message */ErrorExit("File not found after copy: ", argv[3]);}/*** Set the files attributes** Assume read-only*/if ( strstr( argv[5], "-w" ) ){if ( verbose > 1 )fprintf(stderr, "Set target read-only: %s\n", dst);fstat.st_mode &= ~(S_IWRITE | S_IWOTH | S_IWGRP );}if ( strstr( argv[5], "+w" ) ){if ( verbose > 1 )fprintf(stderr, "Set target writable: %s\n", dst);fstat.st_mode |= (S_IWRITE | S_IWOTH | S_IWGRP );}if ( strstr( argv[5], "+x" ) ){if ( verbose > 1 )fprintf(stderr, "Set target executable: %s\n", dst);fstat.st_mode |= ( S_IXUSR | S_IXOTH | S_IXGRP );}if ( strstr( argv[5], "-x" ) ){if ( verbose > 1)fprintf(stderr, "Set target executable: %s\n", dst);fstat.st_mode &= ~( S_IXUSR | S_IXOTH | S_IXGRP );}if ( verbose )fprintf(stderr, "Set target perms: %s, 0%o\n", dst, fstat.st_mode);rv = chmod( dst, fstat.st_mode );if ( rv != 0 ){ErrorExit("Setting ReadOnly: ", argv[3]);}}return 0;}/*----------------------------------------------------------------------------** FUNCTION : createPaths**** DESCRIPTION : Create the path to the target****** INPUTS : path**** RETURNS : Will not return in error**----------------------------------------------------------------------------*/void createPaths ( char *path ){struct stat fstat;int rv;char *ptr = path;while ( *ptr ){if ( *ptr == '/' ){*ptr = 0;rv = stat( path, &fstat );if ( rv ){if ( verbose > 1 ){fprintf(stderr, "createPaths: %s\n", path);fflush(stderr) ;}rv = mkdir( path, 0777 );if ( rv ){ErrorExit("Could not create directories:", path);}}*ptr = '/';}ptr++;}}/*----------------------------------------------------------------------------** FUNCTION : CopyFile**** DESCRIPTION : Just copy a file****** INPUTS : src - source path - already exists** dst - path. Dirs already exist** st_mode - Creation mode. Copied from source file**** RETURNS : false - Error**----------------------------------------------------------------------------*/#define COPYSIZE 1024int CopyFile ( char *src, char *dst, mode_t st_mode ){ssize_t rlen = 0 ;ssize_t wlen = 0 ;int in;int out;int ferror = 0;char buffer[COPYSIZE] = { '\0' } ;if ( verbose ){fprintf(stderr, "CopyFile: Output Mode: 0%o\n", st_mode);fflush(stderr) ;}in = open( src, O_RDONLY ) ;if ( in < 0 )ErrorExit("Could not open source:", src);out = open( dst, O_WRONLY | O_CREAT, st_mode | S_IWRITE );if ( out < 0 )ErrorExit("Could not open dst:", dst);while( (rlen = read( in, buffer, COPYSIZE )) > 0 ){wlen = write( out, buffer, rlen ) ;if ( wlen != rlen ){ferror = 1;break;}}close(in) ;close(out) ;/*** File error** Delete target*/if ( ferror || rlen < 0 ){unlink(dst) ;return 0;}return 1;}/*----------------------------------------------------------------------------** FUNCTION : deleteFileList**** DESCRIPTION : Delete a list of files** Ensure files are writable****** INPUTS : argc - count of args** argv - list of files to delete**** RETURNS : Wil not return on error**----------------------------------------------------------------------------*/void deleteFileList( int argc, char* argv[] ){int rv;struct stat fstat;for ( ; argc ; argc--, argv++ ){/*** Remove the ReadOnly attribute on the dest file*/if ( verbose > 1 )fprintf(stderr, "Remove target file: %s\n", *argv);rv = stat( *argv, &fstat );if ( rv == 0 ){if ( verbose )fprintf(stderr, "Delete file: %s : Attr: 0%o\n", *argv, fstat.st_mode);if ( !(fstat.st_mode & S_IWRITE) ){fstat.st_mode |= S_IWRITE;rv = chmod( *argv, fstat.st_mode );if ( rv != 0 ){fprintf(stderr, "Warning: Attempt to allow write access: %s\n", *argv);}}if ( unlink( *argv ) ){fprintf(stderr, "Warning: Did not remove file: %s\n", *argv);}}}}/*----------------------------------------------------------------------------** FUNCTION : ErrorExit**** DESCRIPTION : Error processing** Report an error and terminate process****** INPUTS : lpszMessage - Message to display**** RETURNS : Does't return** Will exit with bad code**----------------------------------------------------------------------------*/void ErrorExit (char * lpszMessage, char * lpszMessage2){fprintf(stderr, "JatsFileUtil:Error: %s%s\n", lpszMessage,lpszMessage2);fflush(stderr) ;exit(-1);}