main.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 491 行
C
491 行
/****************************************************************************
*
* 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: VI editor bind utility.
*
****************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <ctype.h>
#include <unistd.h>
#include <fcntl.h>
#include <malloc.h>
#include <sys/stat.h>
#include "banner.h"
char magic_cookie[]="CGEXXX";
#define MAX_LINE_LEN 1024
#define FALSE 0
#define TRUE 1
#define COPY_SIZE 0x8000-512
#define MAX_FILES 255
char *dats[MAX_FILES];
#define MAGIC_COOKIE_SIZE sizeof( magic_cookie )
short FileCount;
long *index;
short *entries;
short sflag = FALSE;
short qflag = FALSE;
char _bf[] = "edbind.dat";
char *bindfile=_bf;
void Banner( void )
{
if( qflag ) {
return;
}
printf( "%s\n", banner1w( "Editor Bind Utility",_EDBIND_VERSION_ ) );
printf( "%s\n", banner2a() );
printf( "%s\n", banner3 );
printf( "%s\n", banner3a );
}
/*
* Abort - made a boo-boo
*/
void Abort( char *str, ... )
{
va_list al;
va_start( al, str );
vprintf( str, al );
va_end( al );
printf("\n");
exit( 1 );
} /* Abort */
/*
* MyPrintf - do a printf
*/
void MyPrintf( char *str, ... )
{
va_list al;
if( !qflag ) {
va_start( al, str );
vprintf( str, al );
va_end( al );
}
} /* MyPrintf */
/*
* AddDataToEXE - tack data to end of an EXE
*/
void AddDataToEXE( char *exe, char *buffer, unsigned short len,
unsigned long tocopy )
{
int h,i,newh;
char buff[MAGIC_COOKIE_SIZE+3];
long shift;
short taillen;
char *copy;
char foo[128];
char drive[_MAX_DRIVE],dir[_MAX_DIR];
/*
* get files
*/
copy = malloc( COPY_SIZE );
if( copy == NULL ) {
Abort( "Out of Memory" );
}
h = open( exe, O_RDWR | O_BINARY );
if( h == -1 ) {
Abort("Fatal error opening \"%s\"",exe );
}
_splitpath( exe, drive, dir, NULL, NULL );
_makepath( foo, drive,dir,"__cge__",".exe" );
newh = open( foo, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, S_IRWXU | S_IRWXG | S_IRWXO );
if( newh == -1 ) {
Abort("Fatal error opening \"%s\"",foo );
}
/*
* get trailer
*/
i = lseek( h, -((long) MAGIC_COOKIE_SIZE+3L), SEEK_END );
if( i == -1 ) {
Abort( "Initial seek error on \"%s\"", exe );
}
i = read( h, buff, 3+MAGIC_COOKIE_SIZE );
if( i == -1) {
Abort( "Read error on \"%s\"", exe );
}
/*
* if trailer is one of ours, then set back to overwrite data;
* else just set to write at end of file
*/
if( strcmp( buff, magic_cookie ) ) {
if( sflag ) {
Abort("\"%s\" does not contain configuration data!", exe);
}
} else {
taillen = *( (unsigned short *) &(buff[MAGIC_COOKIE_SIZE+1]) );
shift = (long) -((long) taillen+(long) MAGIC_COOKIE_SIZE+3);
tocopy += shift;
}
i = lseek( h,0, SEEK_SET );
if( i ) {
Abort( "Seek error on \"%s\"",exe );
}
/*
* copy crap
*/
while( tocopy > 0 ) {
if( tocopy > (unsigned long) COPY_SIZE ) {
i = read( h, copy, COPY_SIZE );
if( i != COPY_SIZE ) {
Abort( "Read error on \"%s\"", exe );
}
i = write( newh, copy, COPY_SIZE );
if( i != COPY_SIZE ) {
Abort( "Write error on \"%s\"", foo );
}
tocopy -= (unsigned long) COPY_SIZE;
} else {
i = read( h, copy, (unsigned int) tocopy );
if( i != tocopy ) {
Abort( "Read error on \"%s\"", exe );
}
i = write( newh, copy, (unsigned int) tocopy );
if( i != (int) tocopy ) {
Abort( "Write error on \"%s\"", foo );
}
tocopy = 0;
}
}
close( h );
/*
* write out data and new trailer
*/
if( !sflag ) {
i = write( newh, buffer, len );
if( i != len ) {
Abort( "write 1 error on \"%s\"", exe );
}
i = write( newh, magic_cookie, MAGIC_COOKIE_SIZE+1 );
if( i != MAGIC_COOKIE_SIZE+1 ) {
Abort( "write 2 error on \"%s\"", exe );
}
i = write( newh, &len, sizeof( short ) );
if( i != sizeof( short ) ) {
Abort( "write 3 error on \"%s\"", exe );
}
}
close( newh );
remove( exe );
rename( foo, exe );
} /* AddDataToEXE */
/*
* GetFromEnv - get file name from environment
*/
static void GetFromEnv( char *what, char *path )
{
_searchenv(what,"EDPATH",path );
if( path[0] != 0 ) {
return;
}
_searchenv(what,"PATH",path );
} /* GetFromEnv */
/*
* GetFromEnvAndOpen - search env and fopen a file
*/
FILE *GetFromEnvAndOpen( char *inpath )
{
char tmppath[_MAX_PATH];
GetFromEnv( inpath, tmppath );
if( tmppath[0] != 0 ) {
MyPrintf(" %s...",tmppath );
return( fopen( tmppath, "r" ) );
}
return( NULL );
} /* GetFromEnvAndOpen */
/*
* Usage - dump the usage message
*/
#ifndef __ALPHA__
#pragma aux Usage aborts;
#endif
void Usage( char *msg )
{
if( msg != NULL ) {
printf( "%s\n", msg );
}
printf("Usage: edbind [-?sq] [-d<datfile>] <exename>\n");
if( msg == NULL ) {
printf("\t<exename>\t executable to add editor data to\n" );
printf("\tOptions -?:\t display this message\n");
printf("\t\t-s:\t strip info from executable\n");
printf("\t\t-q:\t run quietly\n");
printf("\t\t-d<datfile>: specify data file other than edbind.dat\n");
}
exit( 1 );
} /* Usage */
/*
* EliminateFirstN - eliminate first n chars from buff
*/
static void EliminateFirstN( char *buff, short n )
{
char *buff2;
buff2 = &buff[n];
while( *buff2 != 0 ) {
*buff++ = *buff2++;
}
*buff = 0;
} /* EliminateFirstN */
/*
* RemoveLeadingSpaces - remove leading spaces from a string
*/
void RemoveLeadingSpaces( char *buff )
{
short k=0;
if( buff[0] == 0 ) {
return;
}
while( isspace( buff[k] ) ) {
k++;
}
if( k==0 ) {
return;
}
EliminateFirstN( buff, k );
} /* RemoveLeadingSpaces */
/*
* MyAlloc - allocate memory, failing if cannot
*/
void *MyAlloc( unsigned size )
{
void *tmp;
tmp = malloc( size );
if( tmp == NULL ) {
Abort("Out of Memory!" );
}
return( tmp );
} /* MyAlloc */
int main( int argc, char *argv[] )
{
char *buff=NULL,*buff2,*buff3;
char *buffn,*buffs;
int i,cnt,bytes,lines,j,k,sl;
FILE *f;
struct stat fs;
char drive[_MAX_DRIVE],dir[_MAX_DIR];
char fname[_MAX_FNAME],ext[_MAX_EXT];
char path[_MAX_PATH];
char tmppath[_MAX_PATH];
char tmpfname[_MAX_FNAME],tmpext[_MAX_EXT];
j=argc-1;
while( j > 0 ) {
if( argv[j][0] == '/' || argv[j][0] == '-' ) {
sl = strlen( argv[j] );
for(i=1;i<sl;i++) {
switch( argv[j][i] ) {
case 's': sflag = TRUE; break;
case 'q': qflag = TRUE; break;
case 'd':
bindfile = &argv[j][i+1];
i = sl;
break;
case '?':
Banner();
Usage( NULL );
default:
Banner();
Usage( "Invalid option" );
}
}
for(i=j;i<(unsigned) argc;i++) {
argv[i]=argv[i+1];
}
argc--;
}
j--;
}
Banner();
/*
* now, check for null file name
*/
if( argc<2 ) {
Usage( "No executable to bind" );
}
_splitpath( argv[1], drive, dir, fname, ext );
if( ext[0] == 0 ) {
_makepath( path, drive, dir, fname, ".exe" );
} else {
strcpy( path, argv[1] );
}
if( stat( path, &fs ) == -1 ) {
Abort( "Could not find executable \"%s\"", path );
}
if( !sflag ) {
buff = MyAlloc( 65000 );
buff2 = MyAlloc( 32000 );
buff3 = MyAlloc( MAX_LINE_LEN );
/*
* read in all data files
*/
MyPrintf( "Getting data files from" );
f = GetFromEnvAndOpen( bindfile );
MyPrintf( "\n" );
if( f == NULL ) {
Abort( "Could not open %s",bindfile );
}
while( fgets( buff3,MAX_LINE_LEN-1,f ) != NULL ) {
if( buff[0] == '#' ) {
continue;
}
i = strlen( buff3 );
// Strip off trailing '\n' - and possible '\r' from DOS file.
while( i > 0 && isspace( buff3[--i] ) ) {
buff3[i] = 0;
}
if( i == 0 ) {
continue;
}
dats[ FileCount ] = MyAlloc( i+1 );
strcpy( dats[ FileCount], buff3 );
FileCount++;
if( FileCount >= MAX_FILES ) {
Abort( "Too many files to bind!" );
}
}
fclose( f );
index = MyAlloc( FileCount * sizeof( long ) );
entries = MyAlloc( FileCount * sizeof( short ) );
buffn = buff;
cnt = 0;
*(short *) buffn = FileCount;
buffn += sizeof( short );
cnt += sizeof( short );
buffs = buffn;
buffn += sizeof( short );
cnt += sizeof( short );
k = 0;
for( i=0;i<FileCount;i++ ) {
// j = strlen( dats[i] ) + 1;
// memcpy( buffn, dats[i], j );
_splitpath( dats[i], NULL, NULL, tmpfname, tmpext );
_makepath( tmppath, NULL, NULL, tmpfname, tmpext );
j = strlen( tmppath ) + 1;
memcpy( buffn, tmppath, j );
buffn += j;
cnt += j;
k += j;
}
*(short *) buffs = k+1; /* size of token list */
*buffn = 0; /* trailing zero */
buffn++;
cnt++;
buffs = buffn;
buffn += FileCount*(sizeof(short)+sizeof(long));
cnt += FileCount*(sizeof(short)+sizeof(long));
for( j=0;j<FileCount;j++ ) {
MyPrintf( "Loading" );
f = GetFromEnvAndOpen( dats[j] );
if( f == NULL ) {
Abort("\nLoad of %s failed!",dats[j] );
}
setvbuf( f, buff2, _IOFBF, 32000 );
bytes = lines = 0;
index[j] = (long) cnt;
while( fgets( buff3,MAX_LINE_LEN-1,f ) != NULL ) {
if( buff3[0] == '#' ) {
continue;
}
i = strlen( buff3 );
i--;
buff3[i] = 0;
RemoveLeadingSpaces( buff3 );
if( buff3[0] == 0 ) {
continue;
}
*buffn = (char) i;
buffn++;
memcpy( buffn, buff3, i );
buffn += i;
cnt += i+1;
lines ++;
bytes += i;
}
fclose( f );
entries[j] = lines;
MyPrintf( "Added %d lines (%d bytes)\n",lines,bytes );
}
i = FileCount;
memcpy( buffs, index, FileCount * sizeof( long ));
buffs += FileCount * sizeof( long );
memcpy( buffs, entries, FileCount * sizeof( short ));
}
AddDataToEXE( path, buff, cnt, fs.st_size );
if( !sflag ) {
MyPrintf( "Added %d bytes to \"%s\"\n",cnt, path );
} else {
MyPrintf( "\"%s\" has been stripped of configuration information\n", path );
}
return( 0 );
} /* main */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?