mkdisk.c

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

C
1,483
字号
/****************************************************************************
*
*                            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:  Utility to create setup.inf files for Watcom installer.
*
****************************************************************************/


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <process.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "disksize.h"

#define RoundUp( size, limit )  ( ( ( size + limit - 1 ) / limit ) * limit )


enum {
        FALSE, TRUE
};


typedef struct path_info {
    char                *path;
    int                 target;
    int                 parent;
    struct path_info    *next;
} PATH_INFO;

typedef struct size_list size_list;

struct size_list {
    size_list   *next;
    long        size;
    long        stamp;
    char        redist;
    char        *dst_var;
    char        name[1];
};

typedef struct file_info {
    char                *file;
    char                *pack;
    char                *condition;
    int                 path;
    int                 old_path;
    int                 num_files;
    size_list           *sizes;
    long                cmp_size;
    struct file_info    *next;
} FILE_INFO;


typedef struct list {
    char                *item;
    struct list         *next;
    int                 type;
} LIST;

enum {
    DELETE_DIALOG,
    DELETE_FILE,
    DELETE_DIR
};

char                    *Product;
long                    DiskSize;
int                     BlockSize;
char                    *RelRoot;
char                    *PackDir;
char                    *Setup;
FILE_INFO               *FileList = NULL;
PATH_INFO               *PathList = NULL;
LIST                    *AppSection = NULL;
LIST                    *IconList = NULL;
LIST                    *SupplimentList = NULL;
LIST                    *IniList = NULL;
LIST                    *AutoList = NULL;
LIST                    *CfgList = NULL;
LIST                    *EnvList = NULL;
LIST                    *DialogList = NULL;
LIST                    *BootTextList = NULL;
LIST                    *ExeList = NULL;
LIST                    *TargetList = NULL;
LIST                    *LabelList = NULL;
LIST                    *UpgradeList = NULL;
LIST                    *AutoSetList = NULL;
LIST                    *AfterList = NULL;
LIST                    *BeforeList = NULL;
LIST                    *EndList = NULL;
LIST                    *DeleteList = NULL;
LIST                    *ForceDLLInstallList = NULL;
LIST                    *ErrMsgList = NULL;
LIST                    *SetupErrMsgList = NULL;
unsigned                DiskNum;
unsigned                MaxDiskFiles;
int                     FillFirst = 1;
int                     Lang = 1;
int                     Upgrade = FALSE;
char                    *Include;
const char              MkdiskInf[] = "mkdisk.inf";


static char *mygets( char *buf, unsigned len, FILE *fp )
{
    char        *p,*q,*start;
    int         lang;
    unsigned    got;

    /* syntax is //nstring//mstring//0 */

    p = buf;
    for( ;; ) {
        if( fgets( p, len, fp ) == NULL ) return( NULL );
        q = p;
        while( *q == ' ' || *q == '\t' ) ++q;
        if( p != q ) strcpy( p, q );
        got = strlen( p );
        if( got <= 1 ) break;
        got-=2;
        if( p[got] != '\\' || p[got+1] != '\n' ) break;
        p += got;
        len -= got;
    }
    p = buf;
    while( *p ) {
        if( p[0] == '/' && p[1] == '/' && isdigit( p[2] ) ) {
            start = p;
            lang = p[2] - '0';
            if( lang == 0 ) {
                strcpy( start, start+3 );
                continue;
            }
            p += 3;
            while( p[0] != '/' || p[1] != '/' ) {
                ++p;
            }
            if( lang == Lang ) {
                strcpy( start, start+3 );
                p -= 3;
            } else {
                strcpy( start, p );
                p = start;
            }
        } else {
            ++p;
        }
    }
    return( buf );
}

long FileSize( char *file )
//=========================

{
    struct stat         stat_buf;

    if( stat( file, &stat_buf ) != 0 ) {
        printf( "Can't find '%s'\n", file );
        return( 0 );
    } else {
        return( RoundUp( stat_buf.st_size, BlockSize ) );
    }
}


int main( int argc, char *argv[] )
//================================

{
    int                 ok;
    FILE                *fp;

    if( !CheckParms( &argc, &argv ) ) {
        return( 1 );
    }
    fp = fopen( argv[ 3 ], "r" );
    if( fp == NULL ) {
        printf( "Cannot open '%s'\n", argv[ 3 ] );
        return( 1 );
    }
    printf( "Reading Info File...\n" );
    ReadInfFile();
    ok = ReadList( fp );
    if( !ok ) return( 1 );
    printf( "Checking for duplicate files...\n" );
    ok = CheckForDuplicateFiles();
    if( !ok ) return( 1 );
    fclose( fp );
    printf( "Making script...\n" );
    MakeScript();
    CreateDisks();
    return( 0 );
}


int CheckParms( int *pargc, char **pargv[] )
//======================================

{
    char                *size;
    struct stat         stat_buf;
    char                **argv;
    int                 argc;
    LIST                *new;

    FillFirst = 1;
    if( *pargc > 1 ) {
        while( ((*pargv)[1] != NULL) && ((*pargv)[1][0] == '-') ) {
            if( (*pargv)[1][1] == '0' ) {
                FillFirst = 0;
            } else if( tolower( (*pargv)[1][1] ) == 'l' ) {
                Lang = (*pargv)[1][2] - '0';
            } else if( tolower( (*pargv)[1][1] ) == 'd' ) {
                new = malloc( sizeof( LIST ) );
                if( new == NULL ) {
                    printf( "\nOut of memory\n" );
                    exit( 1 );
                }
                new->next = NULL;
                new->item = strdup( &(*pargv)[1][2] );
                AddToList( new, &AppSection );
            } else if( tolower( (*pargv)[1][1] ) == 'i' ) {
                Include = (*pargv)[1]+2;
            } else if( tolower( (*pargv)[1][1] ) == 'u' ) {
                Upgrade = TRUE;
            } else {
                printf( "Unrecognized option %s\n", (*pargv)[1] );
            }
            ++*pargv;
            --*pargc;
        }
    }
    argc = *pargc;
    argv = *pargv;
    if( argc != 6 ) {
        printf( "Usage: mkdisk [-x] <product> <size> <file_list> <pack_dir> <rel_root>\n" );
        return( FALSE );
    }
    Product = argv[ 1 ];
    size = argv[ 2 ];
    if( strcmp( size, "360" ) == 0 ) {
        DiskSize = DISK_360;
        MaxDiskFiles = DISK_360_FN;
        BlockSize = 1024;
    } else if( strcmp( size, "720" ) == 0 ) {
        DiskSize = DISK_720;
        MaxDiskFiles = DISK_720_FN;
        BlockSize = 1024;
    } else if( strcmp( size, "1.2" ) == 0 ) {
        DiskSize = DISK_1p2;
        MaxDiskFiles = DISK_1p2_FN;
        BlockSize = 1024;
    } else if ( strcmp( size, "1.4" ) == 0 ) {
        DiskSize = DISK_1p4;
        MaxDiskFiles = DISK_1p4_FN;
        BlockSize = 512;
    } else {
        printf( "SIZE must be one of 360, 720, 1.2, 1.4\n" );
        return( FALSE );
    }
    PackDir  = argv[ 4 ];
    if( stat( PackDir, &stat_buf ) != 0 ) {  // exists
        printf( "\nDirectory '%s' does not exist\n", PackDir );
        return( FALSE );
    }
    RelRoot  = argv[ 5 ];
    if( stat( RelRoot, &stat_buf ) != 0 ) {  // exists
        printf( "\nDirectory '%s' does not exist\n", RelRoot );
        return( FALSE );
    }
    return( TRUE );
}


int ReadList( FILE *fp )
//======================

{
    char        *path;
    char        *old_path;
    char        *file;
    char        *rel_fil;
    char        *condition;
    char        *patch;
    char        *dst_var;
    char        buf[ 512 ];
    char        redist;
    int         no_error;

    printf( "Checking files...\n" );
    no_error = TRUE;
    while( fgets( buf, sizeof( buf ), fp ) != NULL ) {
        buf[ strlen( buf ) - 1 ] = '\0';
        redist = buf[0];
        path = strtok( buf + 1, " \t" );
        if( path == NULL ) {
            printf( "Invalid list file format - 'path' not found\n" );
            exit( 2 );
        }
        old_path = strtok( NULL, " \t" );
        if( old_path == NULL ) {
            printf( "Invalid list file format - 'old path' not found\n" );
            exit( 2 );
        }
        if( stricmp( path, old_path ) == 0 ) old_path = NULL;
        file = strtok( NULL, " \t" );
        if( file == NULL ) {
            printf( "Invalid list file format - 'file' not found\n" );
            exit( 2 );
        }
        rel_fil = strtok( NULL, " \t" );
        if( rel_fil == NULL ) {
            printf( "Invalid list file format - 'rel file' not found\n" );
            exit( 2 );
        }
        patch = strtok( NULL, " \t" );
        if( patch == NULL ) {
            printf( "Invalid list file format - 'patch' not found\n" );
            exit( 2 );
        }
        dst_var = strtok( NULL, " \t" );
        if( dst_var == NULL ) {
            printf( "Invalid list file format - 'destination' not found\n" );
            exit( 2 );
        }
        condition = strtok( NULL, "\0" ); // rest of line
        if( condition == NULL ) { // no packfile
            condition = dst_var;
            dst_var = ".";
        }
        while( *condition == ' ' ) ++condition;
        while( *dst_var == ' ' ) ++dst_var;
        if( strcmp( dst_var, "." ) == 0 ) {
            dst_var = NULL;
        } else {
            dst_var = strdup( dst_var );
        }
        if( !AddFile( path, old_path, redist, file, rel_fil, patch, dst_var, condition ) ) {
            no_error = FALSE;
        }
    }
    printf( ".\n" );
    return( no_error );
}


int AddPathTree( char *path, int target )
/***************************************/
{
    int         parent;
    char        *p;

    if( path == NULL ) return( -1 );
    parent = AddPath( ".", target, -1 );
    p = strchr( path, '\\' );
    while( p != NULL ) {
        *p = '\0';
        parent = AddPath( path, target, parent );
        if( parent == 0 ) return( FALSE );
        *p = '\\';
        p = strchr( p + 1, '\\' );
    }
    return( AddPath( path, target, parent ) );
}


int AddFile( char *path, char *old_path, char redist, char *file, char *rel_file, char *patch, char *dst_var, char *cond )
/*******************************************************************************************************************/
{
    int                 path_dir, old_path_dir, target;
    FILE_INFO           *new, *curr;
    long                act_size, cmp_size;
    long                time;
    struct stat         stat_buf;
    char                *p;
    char                *root_file;
    char                src[ _MAX_PATH ], dst[ _MAX_PATH ];
    size_list           *ns,*sl;

    if( stricmp( rel_file, "." ) != 0 ) {
        if( strchr( rel_file, ':' ) != NULL
        ||  *rel_file == '\\'
        ||  *rel_file == '/' ) {
            strcpy( src, rel_file );
        } else {
            strcpy( src, RelRoot );
            if( src[ strlen( src ) - 1 ] != '\\' ) {
                strcat( src, "\\" );
            }
            strcat( src, rel_file );
        }
    } else if( strchr( path, ':' ) != NULL ) {
        // path is absolute. don't use RelRoot
        strcpy( src, path );
        strcat( src, "\\" );
        strcat( src, file );
    } else {
        strcpy( src, RelRoot );
        if( src[ strlen( src ) - 1 ] != '\\' ) {
            strcat( src, "\\" );
        }
        if( path[ 0 ] != '.' ) {
            strcat( src, path );
            strcat( src, "\\" );
        }
        strcat( src, file );
    }
    if( stat( src, &stat_buf ) != 0 ) {
        printf( "\n'%s' does not exist\n", src );
        return( FALSE );
    } else {
        act_size = stat_buf.st_size;
        time = stat_buf.st_mtime;
    }
    strcpy( dst, PackDir );
    if( dst[ strlen( dst ) - 1 ] != '\\' ) {
        strcat( dst, "\\" );
    }
    strcat( dst, patch );
    if( stat( dst, &stat_buf ) != 0 ) {
        printf( "\n'%s' does not exist\n", dst );
        return( FALSE );
    } else {
        cmp_size = stat_buf.st_size;
    }
#if 0
    printf( "\r%s                              \r", file );
    fflush( stdout );
#endif
    act_size = RoundUp( act_size, 512 );
    cmp_size = RoundUp( cmp_size, BlockSize );

    // strip target off front of path
    if( *path == '%' ) {
        p = strchr( ++path, '%' );
        if( p == NULL ) {
            printf( "Invalid path(%s)\n", path );
            return( 0 );
        }
        *p = '\0';
        target = AddTarget( path );
        path = p + 1;
        if( *path == '\0' ) {
            path = ".";
        } else if( *path == '\\' ) {
            ++path;
        } else {
            printf( "Invalid path (%s)\n", path );
            return( 0 );
        }
    } else {
        target = AddTarget( "DstDir" );
    }
    if( target == 0 ) {
        return( 0 );
    }

    // handle sub-directories in path before full path
    path_dir = AddPathTree( path, target );
    old_path_dir = AddPathTree( old_path, target );
    if( path_dir == 0 ) {
        return( FALSE );
    }
    root_file = p = file;
    while( *p != '\0' ) {
        switch( *p ) {
        case '/':
        case ':':

⌨️ 快捷键说明

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