mksetup.c

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

C
1,351
字号
/****************************************************************************
*
*                            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 <ctype.h>
#include <sys/stat.h>
#include "diskos.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;
    struct file_info    *next;
} FILE_INFO;


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

enum {
    DELETE_DIALOG,
    DELETE_FILE,
    DELETE_DIR
};

static char                 *Product;
static long                 DiskSize;
static int                  BlockSize;
static char                 *RelRoot;
static char                 *Setup;
static FILE_INFO            *FileList = NULL;
static PATH_INFO            *PathList = NULL;
static LIST                 *AppSection = NULL;
static LIST                 *IconList = NULL;
static LIST                 *SupplimentList = NULL;
static LIST                 *IniList = NULL;
static LIST                 *AutoList = NULL;
static LIST                 *CfgList = NULL;
static LIST                 *EnvList = NULL;
static LIST                 *DialogList = NULL;
static LIST                 *BootTextList = NULL;
static LIST                 *ExeList = NULL;
static LIST                 *TargetList = NULL;
static LIST                 *LabelList = NULL;
static LIST                 *UpgradeList = NULL;
static LIST                 *AutoSetList = NULL;
static LIST                 *AfterList = NULL;
static LIST                 *BeforeList = NULL;
static LIST                 *EndList = NULL;
static LIST                 *DeleteList = NULL;
static LIST                 *ForceDLLInstallList = NULL;
static LIST                 *ErrMsgList = NULL;
static LIST                 *SetupErrMsgList = NULL;
static unsigned             MaxDiskFiles;
static int                  FillFirst = 1;
static int                  Lang = 1;
static int                  Upgrade = FALSE;
static int                  Verbose = FALSE;
static int                  IgnoreMissingFiles = FALSE;
static char                 *Include;
static const char           MksetupInf[] = "mksetup.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 );
}


static void AddToList( LIST *new, LIST **list )
/*********************************************/
{
    while( *list != NULL ) {
        list = &((*list)->next);
    }
    *list = new;
}


static long FileSize( char *file )
/********************************/
{
    struct stat         stat_buf;

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


int CheckParms( int *pargc, char **pargv[] )
/******************************************/
{
    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 if( tolower( (*pargv)[1][1] ) == 'v' ) {
                Verbose = TRUE;
            } else if( tolower( (*pargv)[1][1] ) == 'f' ) {
                IgnoreMissingFiles = TRUE;
            } else {
                printf( "Unrecognized option %s\n", (*pargv)[1] );
            }
            ++*pargv;
            --*pargc;
        }
    }
    argc = *pargc;
    argv = *pargv;
    if( argc != 4 ) {
        printf( "Usage: mksetup [-options] <product> <file_list> <rel_root>\n\n" );
        printf( "Supported options (case insensitive):\n" );
        printf( "-v         verbose operation\n" );
        printf( "-i<path>   include path for setup scripts\n" );
        printf( "-u         create upgrade setup script\n" );
        printf( "-d<string> specify string to add to Application section\n" );
        printf( "-f         force script creation if files missing (testing only)\n" );
        return( FALSE );
    }
    Product = argv[ 1 ];
    DiskSize = (1457664L-4096);
    MaxDiskFiles = 215;
    BlockSize = 512;

    RelRoot  = argv[ 3 ];
    if( stat( RelRoot, &stat_buf ) != 0 ) {  // exists
        printf( "\nDirectory '%s' does not exist\n", RelRoot );
        return( FALSE );
    }
    return( TRUE );
}


int AddTarget( char *target )
/***************************/
{
    int                 count;
    LIST                *new, *curr;

    count = 1;
    for( curr = TargetList; curr != NULL; curr = curr->next ) {
        if( stricmp( target, curr->item ) == 0 ) {
            return( count );
        }
        ++count;
    }

    new = malloc( sizeof( LIST ) );
    if( new == NULL ) {
        printf( "Out of memory\n" );
        return( 0 );
    } else {
        new->item = strdup( target );
        if( new->item == NULL ) {
            printf( "Out of memory\n" );
            return( 0 );
        }
        new->next = NULL;
        count = 1;
        if( TargetList == NULL ) {
            TargetList = new;
        } else {
            curr = TargetList;
            while( curr->next != NULL ) {
                curr = curr->next;
                ++count;
            }
            curr->next = new;
            ++count;
        }
        return( count );
    }
}


static char *GetBracketedString( const char *src, char **end )
/************************************************************/
{
    const char      *s = src;
    char            *ret;
    int             len;

    if( *s++ != '<' ) {
        return( NULL );
    }
    ret = strchr( s, '>' );
    if( ret == NULL ) {
        return( NULL );
    }
    len = ret - s;
    *end = (char *)src + len + 2;
    if( (ret = malloc( len + 1 )) == NULL ) {
        return( NULL );
    }
    strncpy( ret, s, len );
    ret[len] = '\0';
    return( ret );
}


int AddPath( char *path, int target, int parent )
/***********************************************/
{
    int                 count;
    PATH_INFO           *new, *curr;

    count = 1;
    for( curr = PathList; curr != NULL; curr = curr->next ) {
        if( stricmp( path, curr->path ) == 0 && target == curr->target ) {
            return( count );
        }
        ++count;
    }

    new = malloc( sizeof( PATH_INFO ) );
    if( new == NULL ) {
        printf( "Out of memory\n" );
        return( 0 );
    } else {
        new->path = strdup( path );
        if( new->path == NULL ) {
            printf( "Out of memory\n" );
            return( 0 );
        }
        new->target = target;
        new->parent = parent;
        new->next = NULL;
        count = 1;
        if( PathList == NULL ) {
            PathList = new;
        } else {
            curr = PathList;
            while( curr->next != NULL ) {
                curr = curr->next;
                ++count;
            }
            curr->next = new;
            ++count;
        }
        return( count );
    }
}


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 *dst_var, char *cond )
/***********************************************************************************************************/
{
    int                 path_dir, old_path_dir, target;
    FILE_INFO           *new, *curr;
    long                act_size;
    long                time;
    struct stat         stat_buf;
    char                *p;
    char                *root_file;
    char                *archive;
    char                src[ _MAX_PATH ];
    size_list           *ns,*sl;
    static char         archive_name[16] = "pck00000";
    static int          pack_num = 1;

    archive = archive_name;

    if( strcmp( rel_file, "." ) != 0 ) {
        if( strchr( rel_file, ':' ) != NULL
        ||  *rel_file == '\\'
        ||  *rel_file == '/' ) {
            strcpy( src, rel_file );
        } else {
            char        c;

            strcpy( src, RelRoot );
            c = src[ strlen( src ) - 1 ];
            if( (c != '/') && (c != '\\') ) {
                strcat( src, SYS_DIR_SEP_STR );
            }
            strcat( src, rel_file );
        }
    } else if( strchr( path, ':' ) != NULL ) {
        // path is absolute. don't use RelRoot
        strcpy( src, path );
        strcat( src, SYS_DIR_SEP_STR );
        strcat( src, file );
    } else {
        char    c;

        strcpy( src, RelRoot );
        c = src[ strlen( src ) - 1 ];
        if( (c != '\\') && (c != '/') ) {
            strcat( src, SYS_DIR_SEP_STR );
        }
        if( path[ 0 ] != '.' ) {
            strcat( src, path );
            strcat( src, SYS_DIR_SEP_STR );
        }
        strcat( src, file );
    }
    if( stat( src, &stat_buf ) != 0 ) {
        printf( "'%s' does not exist\n", src );
        if( IgnoreMissingFiles ) {

⌨️ 快捷键说明

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