/**
cptest.cpp
A file copying program.
@author elliot@wpi.edu
*/
#include <iostream>
#include <fstream>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
using namespace std;
// function prototype
int copyfile1(char* infilename, char* outfilename);
int copyfile2(char* infilename, char* outfilename);
int copyfile3(char* infilename, char* outfilename, ssize_t size);
/**
Prints usage instructions.
@param program_name the name of this program
*/
void usage(char* program_name)
{
cout << "Usage: " << program_name << "\n "
<< program_name<< " infile outfile, \n "
<< program_name<< " infile outfile copytype,\n "
<< program_name<< " infile outfile copytype buffersize. \n";
exit(1);
}
/**
Prints file opening error message
@param filename the name of the file that could not be opened
*/
void open_file_error(char* filename)
{
cout << "Error opening file " << filename << "\n";
exit(1);
}
/** Main program: copies a file.
@param argc Number of command-line arguments (including program name).
@param argv Array of pointers to character arays holding arguments.
@return 0 if successful, 1 if fail.
*/
int main(int argc, char* argv[])
{
char* infilename; // Names of files.
char* outfilename;
if (argc < 3 || argc > 5) usage(argv[0]); // correct usage check
// For only 2 arguments
if(argc == 3) {
infilename = argv[1];
outfilename = argv[2];
// Perform the copying
int returnstatus = copyfile2(infilename, outfilename);
return returnstatus;
}
// For 3 arguments
if(argc == 4) {
infilename = argv[1];
outfilename = argv[2];
int copytype = static_cast<int>(*argv[3]);
// Pick the copy types
if(copytype == 1) {
int returnstatus = copyfile1(infilename, outfilename);
return returnstatus;
} else if(copytype == 2) {
int returnstatus = copyfile2(infilename, outfilename);
return returnstatus;
} else if(copytype == 3) { // 1024 is default buffer size
int returnstatus = copyfile3(infilename, outfilename, 1024);
return returnstatus;
}
// Perform the copying
int returnstatus = copyfile2(infilename, outfilename);
return returnstatus;
}
// For 4 arguments
if(argc == 5) {
infilename = argv[1];
outfilename = argv[2];
char* copytype = (argv[3]);
size_t buffersize = static_cast<size_t>(*argv[4]);
// Copytype check
if (*copytype != 51) {
fputs ("Copytype must be 3\n",stderr); exit (1);
} else {
int returnstatus = copyfile3(infilename, outfilename, buffersize);
return returnstatus;
}
}
}
/** Copies one file to another using formatted I/O, one character at a time.
@param infilename Name of input file
@param outfilename Name of output file
@return 0 if successful, 1 if error.
*/
int copyfile1(char* infilename, char* outfilename) {
FILE* infile; //File handles for source and destination.
FILE* outfile;
infile = fopen(infilename, "r"); // Open the input and output files.
if (infile == NULL) {
open_file_error(infilename);
return 1;
}
outfile = fopen(outfilename, "w");
if (outfile == NULL) {
open_file_error(outfilename);
return 1;
}
int intch; // Character read from input file. must be an int to catch EOF.
unsigned char ch; // Characted stripped down to a byte.
// Read each character from the file, checking for EOF.
while ((intch = fgetc(infile)) != EOF) {
ch = static_cast<unsigned char> (intch); // Convert to one-byte char.
fputc(ch, outfile); // Write out.
}
// All done--close the files and return success code.
fclose(infile);
fclose(outfile);
return 0; // Success!
}
int copyfile2(char* infilename, char* outfilename) {
int infile; //File handles for source and destination.
int outfile;
infile = open(infilename, O_RDONLY); // Open the input and output files.
if (infile == -1) {
open_file_error(infilename);
return 1;
}
outfile = open(outfilename, O_CREAT | O_WRONLY);
if (outfile == -1) {
open_file_error(outfilename);
return 1;
}
int intch; // Character read from input file. must be an int to catch EOF.
char buf[1];
// Read each character from the file, checking for EOF.
while ((intch = read(infile, buf, 1)) != 0) {
write(outfile, buf, intch); // Write out.
}
// All done--close the files and return success code.
close(infile);
close(outfile);
return 0; // Success!
}
int copyfile3(char* infilename, char* outfilename, ssize_t size) {
int infile; //File handles for source and destination.
int outfile;
infile = open(infilename, O_RDONLY); // Open the input and output files.
if (infile == -1) {
open_file_error(infilename);
return 1;
}
outfile = open(outfilename, O_CREAT | O_WRONLY);
if (outfile == -1) {
open_file_error(outfilename);
return 1;
}
int intch; // Character read from input file. must be an int to catch EOF.
char* buf = static_cast<char*>(malloc(size));
// Read each character from the file, checking for EOF.
while ((intch = read(infile, buf, size)) != 0) {
write(outfile, buf, intch); // Write out.
}
// All done--close the files and return success code.
close(infile);
close(outfile);
return 0; // Success!
}