⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 archiver.cpp

📁 非常好用的五子棋游戏源码
💻 CPP
字号:
// Created:11-16-98
// By Jeff Connelly

// An archiver using ComprLib

#if 0
************************** Archive structure ******************************
This header is present only at the beginning:
OFFSET              Count TYPE   Description
0x0000                   4 char   ID="ARCH"
0x0004                   4 char   ID="IVE" followed by 1Ah
0x0008                   1 dword  Files in archive (up to over a million!)

For each file, there is:
OFFSET              Count TYPE   Description
0x0000                  1 byte   Misc flags, bitmapped:
                                 Bits numbered: 7654 3210
                                 0 - Compressed
                                 1 - CRC-32 stored
                                 2 - Comment
                                 3 - File is deleted
                                 4 to 7 - Compression method if compressed
                                 (see table 0x0000)
0x0000                  1 dword   Size of file in the archive (not orig size)
????                    1 dword   If compressed: original size
????                    1 dword   If CRC-32 stored: CRC-32
????                    1 word    If comment: comment length
????                    ? char    If comment: comment text
????                    ? char    Filename, ASCIIZ
????                    ? byte    File contents

TABLE 0x0000: Compression methods
0000 - Not used, set if not compressed
0001 - RLE method 1
0010 - RLE method 2
0011 - LZSS
0100 - LZW
0101 - Inverted (encryption sort of)
#endif

#include "comprlib.h"
#include <stdio.h>
#include <stdlib.h>
#include <io.h>

FILE* arc;                               // The archive
char* archive;                           // Filename of archive
bool flag_recover_deleted = false;       // Extract deleted files?
bool flag_verbose = true;                // Verbose output?

// Class representing a file in this archive
struct Member
{
public:
    Member():flags(0), size(0), origsize(0), crc32(0), commentlen(0),
             comment(NULL), data(NULL) { };
    void Destroy();
    ~Member() { Destroy(); };
    void Write();
    void Read();

    // 'flags' can be ANDed with these values to see if the bits are set:
    #define FLAG_COMPRESSED    0x01
    #define FLAG_CRC32         0x02
    #define FLAG_COMMENT       0x04
    #define FLAG_DELETED       0x08
    unsigned char flags;
    unsigned long size;
    unsigned long origsize;
    unsigned long crc32;
    unsigned short commentlen;
    char* comment;
    char* filename;
    char* data;
};

// Free memory allocated by this
void Member::Destroy()
{
    xfree(data);
    xfree(filename);
    xfree(comment);
}

// Write this member to the archive
void Member::Write()
{
    fwrite (&flags, 1, 1, arc);
    fwrite (&size, 1, 4, arc);
    if (flags & FLAG_COMPRESSED)
        fwrite (&origsize, 1, 4, arc);
    if (flags & FLAG_CRC32)
        fwrite (&crc32, 1, 4, arc);
    if (flags & FLAG_COMMENT)
    {
        fwrite (&commentlen, 1, 2, arc);
        fwrite (comment, 1, commentlen, arc);
    }
    fwrite (filename, 1, strlen(filename) + 1, arc);
    fwrite (data, 1, size, arc);
}

// Read the member from the archive
void Member::Read()
{
    register char c;
    int i;

    fread (&flags, 1, 1, arc);
    fread (&size, 1, 4, arc);
    if (flags & FLAG_COMPRESSED)
        fread (&origsize, 1, 4, arc);
    if (flags & FLAG_CRC32)
        fread (&crc32, 1, 4, arc);
    if (flags & FLAG_COMMENT)
    {
        fread (&commentlen, 1, 2, arc);
        fread (comment, 1, commentlen, arc);
    }

    // Read the null-terminated filename
    {
        int i = 0;
        register char c;
        filename = NULL;
        filename = (char*)xmalloc(1);
        do
        {
            c = getc(arc);
            filename[i] = c;
            filename = (char*)xrealloc(filename, (i++) + 1);
        } while (c);
        filename[i - 2] = 0;
    }
    fread (data, 1, size, arc);
}

// Deturmine size of file 'fp'
long file_size(FILE* fp)
{
    unsigned long pos, ret;
    pos = ftell(fp);
    fseek (fp, 0, SEEK_END);
    ret = ftell(fp);
    fseek (fp, pos, SEEK_SET);
    return ret;
}

// Does the option 'opt'
void CheckOption(char* opt)
{
    if (opt[0] != '-' && opt[0] != '/')
        return;
    switch (tolower(opt[1]))
    {
    case 'R': flag_recover_deleted = true; break;
    case 'V': flag_verbose = true; break;
    case 'Q': flag_verbose = false; break;
    }
}

void add_files(int count, char* files[])
{
    int i;
    FILE* fp;
    Member file;

    arc = fopen(archive, "ab");

    if (!file_size(arc))         // New archive
    {
        {
            char* sig = (char*)xmalloc(8);
            int count = 0;          // Initialized to zero
            strcpy (sig, "ARCHIVE\032");
            fwrite(sig, 1, 8, arc);
            fwrite(&count, 1, 4, arc);
        }
    }

    for (i = 0; i < count && files[i]; ++i)
    {
        if (files[i][0] == '-' || files[i][0] == '/')
        {
            CheckOption(files[i]);
            continue;
        }
        printf ("\nArchiving %s...\n", files[i]);
        fp = fopen(files[i], "rb");
        if (!fp)
        {
            printf ("Cannot open %s\n", files[i]);
            exit (2);
        }

        // Read the entire file
        file.size = file_size(fp);
        file.data = (char*)xmalloc(file.size);
        fread(file.data, 1, file.size, fp);
        fclose(fp);

        // Set the filename
        file.filename = (char*)xmalloc(strlen(files[i]));
        strcpy (file.filename, files[i]);

        file.Write();             // Archive the file
    }
    // We're not done yet.  We need to write the file count.
    fseek(arc, 9, SEEK_SET);
    fwrite(&count, 1, 4, arc);
}

// Extracts all the files
void extract_files()
{
    FILE* fp;
    unsigned long count;
    Member file;
    register int i;

    arc = fopen(archive, "rb");
    if (!arc)
    {
        printf ("Cannot open %s\n", archive);
        exit (2);
    }

    // Read the header
    {
        char* sig = (char*)xmalloc(9);
        fread (sig, 1, 8, arc);
        sig[8] = 0;
        if (strcmp(sig, "ARCHIVE\032"))
        {
            printf ("Invalid archive\n");
            exit (3);
        }
        fread (&count, 1, 4, arc);
    }

    // Read the files
    for (i = 0; i < count && !feof(arc); ++i)
    {
        file.Read();
        if (file.flags & FLAG_DELETED)
        {
            if (!flag_recover_deleted)
            {
                // Not to be extracted
                printf ("\nIgnoring %s\n", file.filename);
                continue;
            }
        }
        printf ("\nExtracting %s...", file.filename);
        fp = fopen(file.filename, "wb");
        if (!fp)
        {
            printf ("Cannot open %s\n", file.filename);
            exit (1);
        }
        fwrite (file.data, 1, file.size, fp);
        fclose(fp);
    }
}

// List all the files
void list_files()
{
    Member file;
    char* filename;
    unsigned long count;
    char deleted;
    char* comment;

    // Open and initialize archive
    {
        char* sig;

        arc = fopen(archive, "rb");
        if (!arc)
        {
            printf ("Cannot open %s\n", arc);
            exit (1);
        }
        sig = (char*)xmalloc(9);
        sig[8] = 0;         // Null-terminated string
        fread (sig, 1, 8, arc);
        if (strcmp(sig, "ARCHIVE\032"))
        {
            printf ("Invalid archive\n");
            exit (3);
        }
        xfree(sig);
        fread (&count, 1, 4, arc);
    }

    // Print the header
    printf ("    Filename    Size    Packed    Ratio    CRC32    Deleted    Comment");

    while(!feof(arc))
    {
        file.Read();

        // If the file is not compressed, 'origsize' will not be set, but
        // we need to know it to calculate the ratio
        if (!(file.flags & FLAG_COMPRESSED))
            file.origsize = file.size;
        if (file.flags & FLAG_COMMENT)
        {
            comment = (char*)xmalloc(file.commentlen + 1);
            strcpy (comment, file.comment);
            comment[file.commentlen + 1] = 0;   // Null-terminated
        }
        if (file.flags & FLAG_DELETED)
            deleted = '*';
        else
            deleted = ' ';
        printf ("    %s    %U    %U    %d    %x    %s    %c\n",
            file.filename,
            file.size,
            file.origsize,
            (double)file.size / (double)file.origsize,
            file.crc32,
            deleted,
            comment);
        xfree(comment);
    }
}

const char* help = "Archives files to archives\n"
                   "\tARCHIVE command archive [files]\n"
                   "Commands are: \n"
                   "a       Add files (no files specified -> create archive)\n"
                   "x       Extract files\n"
                   "l       List files\n"
                   "Options can be specified within the file list: \n"
                   "\n";

int main(int argc, char* argv[])
{
    register int i;

    if (argc == 1)
    {                 
        printf(help);
        exit(0);
    }

    char cmd;

    cmd = tolower(argv[1][0]);
    archive = (char*)xmalloc(strlen(argv[2]));
    strcpy (archive, argv[2]);

    // Parse the flags
    for (i = 3; i < argc; ++i)
    {
         CheckOption(argv[i]);
    }

    switch(cmd)
    {
    case 'a': add_files(argc - 2, &argv[3]); break;
    case 'x': extract_files(); break;
    case 'l': list_files(); break;
    default: printf ("Bad command '%c'\n", cmd); exit (3); break;
    }

    return 0;
}



    

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -