wpack.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 588 行 · 第 1/2 页

C
588
字号
/****************************************************************************
*
*                            Open Watcom Project
*
*    Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
*  ========================================================================
*
*    This file contains Original Code and/or Modifications of Original
*    Code as defined in and that are subject to the Sybase Open Watcom
*    Public License version 1.0 (the 'License'). You may not use this file
*    except in compliance with the License. BY USING THIS FILE YOU AGREE TO
*    ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
*    provided with the Original Code and Modifications, and is also
*    available at www.sybase.com/developer/opensource.
*
*    The Original Code and all software distributed under the License are
*    distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
*    EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
*    ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
*    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
*    NON-INFRINGEMENT. Please see the License for the specific language
*    governing rights and limitations under the License.
*
*  ========================================================================
*
* Description:  Open Watcom file compression utility.
*
****************************************************************************/


/*
 * Based on Japanese version 29-NOV-1988
 * LZSS coded by Haruhiko OKUMURA
 * Adaptive Huffman Coding coded by Haruyasu YOSHIZAKI
 * Edited and translated to English by Kenji RIKITAKE
 *
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <malloc.h>
//#include "formglob.h"
#include "wpack.h"
//#include "rsr.h"
#include "txttable.h"
#ifdef UNIX
#include <clibext.h>
#endif

// external declarations
extern void             IndentLine( unsigned );
extern void             WriteMsg( char * );
extern void             WriteLen( char *, int );
extern int              InitIO( void );
extern void             Encode( void );
extern file_info **     ReadHeader( arccmd *, arc_header * );
extern void             QClose( int );
extern int              QWrite( int, void *, int );
extern void             CopyInfo( int, int, unsigned long );
extern void             QSeek( int, signed long, int );
extern int              QOpenW( char * );
extern void             WhereAmI( void );
extern void             DoTOption( char * );
extern void             DoDOption( char * );

typedef struct {
    uint_16     year;           /* full year (e.g., 1990) */
    uint_8      month;          /* 1-12 */
    uint_8      day;            /* 1-31 */
} datestruct;

typedef struct {
    uint_8      hours;          /* 0-23 */
    uint_8      minutes;        /* 0-59 */
    uint_8      seconds;        /* 0-59 */
} timestruct;

extern int  infile, outfile;
extern datestruct DateAdjust;
extern timestruct TimeAdjust;

static bool BannerPrinted = FALSE;

extern void PackExit( void )
/**************************/
{
    exit( EXIT_FAILED );
}

extern void Error(int code,char *message)
/******************************/
{
    code=code;
    WriteMsg( "\nError: " );
    WriteMsg( message );
    WriteMsg( "\n" );
    PackExit();
}

extern void * WPMemAlloc( size_t amount )
/***************************************/
{
    void *  ret;

    ret = malloc( amount );
    if( ret == NULL ) {
        Error( -1, "dynamic memory exhausted!" );
    }
    return( ret );
}

extern void WPMemFree( void *mem )
/******************************/
{
    free( mem );
}

enum {
    ERROR = 0,
    DO_ENCODE,
    DO_DECODE,
    DO_LIST,
    DO_DELETE
};

static void Usage( bool verbose )
/*******************************/
{
    WriteMsg( "Usage: wpack [-?acdklpqr] [-mNNNN] [-tDATE TIME] arcfile @filename files...\n" );
    if( verbose ) {
        WriteMsg( "-? = print this list\n"
                  "-a = add files to archive\n"
                  "-c = preserve the file name case in the archive\n"
                  "-d = delete files from archive\n"
                  "-k = keep pathnames on files when archiving\n"
                  "-mNNNN = make multiple archives with maximum size NNNN k\n"
                  "-l = generate a listing of the files in the archive\n"
                  "-p = prepend a pathname when unpacking files (e.g. -pc:\\lang)\n"
                  "-q = be quiet\n"
                  "-r = replace pathname when unpacking files (e.g. -rc:\\lang)\n"
                  "-tDATE TIME = use the specified date & time for the files\n"
                  "              ex. -tmm-dd-yy hh:mm:ss\n"
                  "@filename = list of files to process, one per line\n"
                  "files may contain wildcards\n"
                  "the default action is to extract files from the archive\n"
                  "if no files are specified when unpacking, all files will be unpacked\n" );
    }
    PackExit();
}

static void ProcPath( char **argv, arccmd *cmd )
/**********************************************/
{
    size_t len;

    (*argv)++;
    len = strlen( *argv ) + 1;
    cmd->u.path = WPMemAlloc( len );
    memcpy( cmd->u.path, *argv, len );
}

static void SetCmdTime( arccmd *cmd )
/***********************************/
/* set the time field in the cmd structure */
{
    struct tm   timeval;

    timeval.tm_sec = TimeAdjust.seconds;
    timeval.tm_min = TimeAdjust.minutes;
    timeval.tm_hour = TimeAdjust.hours;
    timeval.tm_mday = DateAdjust.day;
    timeval.tm_mon = DateAdjust.month - 1;
    timeval.tm_year = DateAdjust.year - 1900;
    timeval.tm_isdst = -1;
    cmd->time = mktime( &timeval );
}

static wpackfile *AddFileName( wpackfile *list, char *fname, size_t *listlen )
/******************************************************************************/
{
    char            *packname;

    *listlen += 1;
    list = realloc( list, (*listlen)*sizeof( *list ) );
    if( fname == NULL ) {
        list[(*listlen)-1].filename = NULL;
        list[(*listlen)-1].packname = NULL;
    } else {
        packname = NULL;
        packname = strchr( fname, ';' );
        if( packname == NULL ) {
            list[(*listlen)-1].packname = NULL;
        } else {
            *packname = '\0';
            ++packname;
            list[(*listlen)-1].packname = strdup( packname );
        }
        list[(*listlen)-1].filename = strdup( fname );
    }
    return( list );
}

static wpackfile *ProcFileName( char **argv )
/***************************************/
{
    unsigned    newlistlen;
    wpackfile   *newlist;
    char        buff[256];
    char        *curr;
    FILE        *io;

    newlist = NULL;
    newlistlen = 0;
    for( ; *argv != NULL ; ++argv ) {
        if( **argv == '@' ) {
            io = fopen( ++(*argv), "r" );
            fgets( buff, 256, io );
            while( !feof( io ) ) {
                curr = strrchr( buff, '\n' );
                if( curr ) {
                    *curr = '\0';
                    if( strlen( buff ) > 0 ) {
                        newlist = AddFileName( newlist, buff, &newlistlen );
                    }
                } else {
                    Error( -1, "invalid line in directive file\n" );
                }
                fgets( buff, 256, io );
            }
            fclose( io );
        } else {
            newlist = AddFileName( newlist, *argv, &newlistlen );
        }
    }
    newlist = AddFileName( newlist, NULL, &newlistlen );
    return( newlist );
}

static void PrintBanner( void )
/*****************************/
{
    if( !BannerPrinted ) {
        WriteMsg( "WATCOM Install Archiver Version 1.3\n" );
        WriteMsg( "Copyright by WATCOM Systems Inc. 1992.  All rights reserved.\n" );
        BannerPrinted = TRUE;
    }
}

extern int ProcessArgs( char **argv, arccmd *cmd )
/************************************************/
{
    int     status;
    char    c;

    cmd->files    = NULL;
    cmd->flags    = 0;
    cmd->u.path   = NULL;
    cmd->internal = 0;
    status = DO_DECODE;
    for( ++argv; *argv != NULL; ++argv ) {
        if( **argv == '-' || **argv == '/' ) {
            (*argv)++;
            c = toupper( **argv );
            switch( c ) {
            case '?':
                Usage( TRUE );
                break;
            case 'A':
                status = DO_ENCODE;
                break;
            case 'C':
                cmd->flags |= PRESERVE_FNAME_CASE;
                break;
            case 'D':
                status = DO_DELETE;
                break;
            case 'I':
                (*argv)++;
                if( *argv != '\0' ) {
                    cmd->internal = strtoul( *argv, NULL, 0 );
                    cmd->flags |= SECURE_PACK;
                }
                break;
            case 'K':
                cmd->flags |= KEEP_PATHNAME;
                break;
            case 'L':
                status = DO_LIST;
                break;
            case 'M':
                cmd->flags |= PACK_LIMIT;

⌨️ 快捷键说明

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