Code:
#define MIN_ARGS 4
#define BUFFER_SIZE 4096
FILE *OpenVolumeFile(char *volumeName, int volume) {
char volumeName[256];
FILE *fArchive;
if (volume > 0)
sprintf(volumeName, "%s-%d", archiveName, volume);
else
sprintf(volumeName, "%s", archiveName);
if (!(fArchive = fopen(volumeName, "wb", fArchive))
Error("No file handle\n");
return fArchive;
}
size_t ReadBuffer(FILE *fin, char *buffer, size_t bytesToRead) {
size_t bytesRead;
bytesRead = fread(buffer, 1, bytesToRead, fData);
if(bytesRead < bytesToRead) Error("fread failure");
return bytesRead;
}
size_t WriteArchiveHeader(FILE *fArchive, size_t volSize, int numFiles,
char *fileNames, size_t *fileSizes);
{
size_t headerSize = sizeof numFiles + sizeof volSize +
numFiles * (sizeof *fileSizes + sizeof (size_t));
if( fwrite(&numFiles, sizeof(numFiles), 1, fArchive) != 1)
Error("Error writing number of files to bin\n");
if( fwrite(&volSize, sizeof(volSize), 1, fArchive) != 1)
Error("Error writing volume size to bin\n");
for(i = 0; i < numFiles; i++)
{
size_t fileNameLen = strlen(fileNames[i]);
WriteArchiveHeaderRecord(fArchive, fileNames[i], fileNameLen, fileSizes[i]);
headerSize += fileNameLen;
}
printf("Wrote file header -> Size: %d\n\n", headerSize);
return headerSize;
}
void CreateArchive(
char *archiveName,
size_t volSize,
int numFiles,
char *fileNames)
{
FILE *fArchive;
size_t volBytesLeft;
size_t headerSize;
size_t fileSizes[numFiles]; // I got rid of the "file" struct
int i;
int volume = 0;
for(i = 0; i < numFiles; i++)
fileSizes[i] = GetFileSize(fileNames[i]);
fArchive = OpenVolumeFile(archiveName, volSize>0 ? ++volume : 0);
headerSize = WriteArchiveHeader(fArchive, volSize, numFiles, fileNames, fileSizes);
if (volSize > 0)
volBytesLeft = volSize - headerSize;
else
volBytesLeft = BUFFER_SIZE + 1; // ensure that it's greater than buffer size
for(i = 0; i < numFiles; i++)
{
size_t fileBytesLeft = fileSizes[i];
FILE *fData = fopen(fileNames[i], "rb");
if(fData == NULL) Error("Error opening file\n");
printf("File %i: %.2f MB\n", i + 1, (double)fileSizes[i] / 1024 / 1024);
do
{
char buffer[BUFFER_SIZE];
size_t bytesToRead, bytesRead;
if(volBytesLeft == 0)
{
fclose(fArchive);
fArchive = OpenVolumeFile(archiveName, ++volume);
volBytesLeft = volSize;
}
bytesRead = ReadBuffer(fData, buffer,
min3(sizeof buffer, fileBytesLeft, volBytesLeft));
WriteBuffer(fArchive, buffer, bytesRead);
fileBytesLeft -= bytesRead;
if (volSize > 0)
volBytesLeft -= bytesRead;
}
while(fileBytesLeft > 0);
fclose(fData);
printf("Wrote file %i: %s\n\n", i + 1, argv[i + MIN_ARGS - 1]);
}
fclose(fArchive);
printf("Success!");
}
// Call from main:
CreateArchive(
&argv[2],
(size_t)atoi(argv[1])*1024*1024,
argc - MIN_ARGS + 1,
&argv[3]);