📄 tmsea.c
字号:
/*
* +-------------------------------------------------------------------+
* | Copyright (c) 1995,2000 TriMedia Technologies Inc. |
* | |
* | This software is furnished under a license and may only be used |
* | and copied in accordance with the terms and conditions of such a |
* | license and with the inclusion of this copyright notice. This |
* | software or any other copies of this software may not be provided |
* | or otherwise made available to any other person. The ownership |
* | and title of this software is not transferred. |
* | |
* | The information in this software is subject to change without |
* | any prior notice and should not be construed as a commitment by |
* | TriMedia Technologies. |
* | |
* | This code and information is provided "as is" without any |
* | warranty of any kind, either expressed or implied, including but |
* | not limited to the implied warranties of merchantability and/or |
* | fitness for any particular purpose. |
* +-------------------------------------------------------------------+
*
* Module name : tmSEA.c 1.13
*
* Module type : IMPLEMENTATION
*
* Title : Self Extracting Archieve
*
* Last update : 16:00:19 - 00/06/16
*
* Description : Usase zlib compression and Command line parser
*
*/
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#ifndef _WIN32
#include <unistd.h>
#include <dirent.h>
#else
#include <windows.h>
#endif
#include <tmhost.h>
/* if using the hp build */
#ifdef hpux
/* undefine Long and uLongf for zlib.h*/
#undef uLong
#undef uLongf
#undef Byte
#endif
#include <tsaCmdOpt.h>
#include <zlib.h>
#include "tmSEA_options.h"
tsaCmdOptOption_t options[] = {
#define _Eg_opts_impl
#undef Def
#define Def(name,o1,o2,typ,flags,dflt,descr) \
o1,o2,typ,flags,(void *)(dflt),descr,Null,
#include "tmSEA_options.h"
};
#define Nelts(vec) (sizeof(vec) / sizeof((vec)[0]))
#ifdef _WIN32
#define SLASH "\\"
#else
#define SLASH "/"
#endif
#define UNIX_PATH_NAME_SEPARATOR '/'
#define WIN_PATH_NAME_SEPARATOR '\\'
#define TEMP_DIR ".tmSEA.temp"
#define TEMP_BASE TEMP_DIR SLASH "tmpackedarch"
static char *progname = NULL;
static char *out_name_temp = NULL;
static char *out_namet =NULL;
static char *out_nameh =NULL;
static int fo = 0;
static int ft = 0;
static int fh = 0;
#define MAX_FILENAME 1024
#define BLOCKSIZE 0x800
#ifndef O_BINARY
#define O_BINARY 0 /* not defined on Unix */
#endif
static char buf[BLOCKSIZE];
static char buffer[MAX_FILENAME];
static char tcspath_buffer[MAX_FILENAME];
static char nostandard_buf[MAX_FILENAME];
static unsigned int NumElements = 0;
/* options arguements intialised as per data
struct in tmSEA_options.h */
static char *outputdir;
static char *bigendian;
static char* host;
static Bool verbose;
static char *output;
static char *cflags;
static char *ldflags;
static Bool nostandard;
static Bool flashbsp;
static Bool NoCompression;
static char *tcspath;
static char *cpath;
static Bool Big_Endian;
static char *inputdir;
static int host_int;
/*--------------------------- helper functions -------------------------*/
static int
copy( char *old, char *new){
int src, dest ;
int lv_read,lv_write,lv_ret,file_size;
void *inmem;
struct stat statBuf;
src = open(old, O_RDONLY|O_BINARY,O_RDONLY|O_BINARY);
if (src == -1) {
printf("Failed to open %s with error code %d\n", old, errno);
return False;
}
/* get size of source file */
lv_ret = fstat(src,&statBuf);
if(lv_ret == -1) {
printf("Failed to stat %s with error code %d\n", old, errno);
close(src);
return False;
}
file_size = statBuf.st_size;
/* inmem is input memory */
inmem = (void *)malloc(file_size);
/* buffer will be output memory */
if (inmem == NULL)
{
printf("out of memory\n");
free(inmem);close(src);
return False;
}
/* read the source into buf */
lv_read= read (src, inmem, file_size);
if(lv_read != file_size)
{
printf("read failure\n");
free(inmem);close(src);
return False;
}
close(src);
errno = 0;
dest = open(new,O_CREAT|O_WRONLY|O_BINARY,0x1FF);
if (dest == -1) {
printf("Failed to create %s with error code %d\n", new, errno);
free(inmem);
return False;
}
lv_write = write(dest, inmem, file_size);
if(lv_write != file_size)
{
printf("write failure\n");
free(inmem); close(dest);
return False;
}
free(inmem);
close(dest);
/* ensure that the file is readable */
chmod(new,0x1FF);
return file_size;
}
void
rewrite_slashes( char *cmd )
{
#if defined(_WIN32)
int i, len = strlen(cmd);
for ( i = 0; i < len; i++ ) {
if ( cmd[i] == UNIX_PATH_NAME_SEPARATOR )
cmd[i] = WIN_PATH_NAME_SEPARATOR;
}
#endif
}
#if defined(_WIN32)
/* Windows implementation of Posix.1 directory handling calls:
* opendir(), readdir(), rewinddir(), closedir()
* and also the unrelated system calls
* fsync(), sync().
* These are implemented directly as system calls on SunOS and HP-UX
* but not on Windows,
* so this is Windows-specific code, required only for Windows.
*/
/* Directory entry. */
struct dirent
{
long d_ino;
long d_namlen;
char d_name[MAX_PATH];
};
/* Directory. */
typedef struct
{
struct dirent dirent;
int Win32EntryCount;
HANDLE Win32DirectoryHandle;
WIN32_FIND_DATA Win32FindData;
char Win32DirectoryName[1];
} DIR;
#define _IFMT 0170000 /* type of file */
#define _IFDIR 0040000 /* directory */
#define _IFCHR 0020000 /* character special */
#define _IFBLK 0060000 /* block special */
#define _IFREG 0100000 /* regular */
#define _IFLNK 0120000 /* symbolic link */
#define _IFSOCK 0140000 /* socket */
#define _IFIFO 0010000 /* fifo */
#define S_ISDIR(m) (((m)&_IFMT) == _IFDIR)
/* Open a directory. */
DIR *
opendir(char const *dirname)
{
DIR *dir;
dir = (DIR *)malloc(sizeof(*dir) + strlen(dirname) + 3);
if (dir == NULL) {
/* No memory for DIR structure. */
errno = ENOMEM;
return NULL;
}
dir->Win32EntryCount = 0;
sprintf(dir->Win32DirectoryName, "%s\\*", dirname);
dir->Win32DirectoryHandle = FindFirstFile(dir->Win32DirectoryName,
&dir->Win32FindData);
if (dir->Win32DirectoryHandle == INVALID_HANDLE_VALUE) {
/* Not found, free and return failure. */
free(dir);
errno = ENOENT;
return NULL;
}
return dir; /* success */
}
/* Read the next entry from a directory. */
struct dirent *
readdir(DIR * dir)
{
if (dir->Win32EntryCount == 0) {
FindClose(dir->Win32DirectoryHandle);
dir->Win32DirectoryHandle = FindFirstFile(dir->Win32DirectoryName,
&dir->Win32FindData);
if (dir->Win32DirectoryHandle == INVALID_HANDLE_VALUE) {
errno = EINVAL;
return NULL;
}
} else if ((FindNextFile(dir->Win32DirectoryHandle,
&dir->Win32FindData) == 0)
&& (GetLastError() == ERROR_NO_MORE_FILES)) {
return NULL;
}
dir->Win32EntryCount++;
dir->dirent.d_ino = dir->Win32EntryCount; /* this field is unneeded */
dir->dirent.d_namlen = strlen(dir->Win32FindData.cFileName);
strcpy(dir->dirent.d_name, dir->Win32FindData.cFileName);
return &dir->dirent;
}
/* Rewind a directory. */
void
rewinddir(DIR *dir)
{
dir->Win32EntryCount = 0;
}
/* Close a directory. */
int
closedir(DIR *dir)
{
if (dir->Win32DirectoryHandle != INVALID_HANDLE_VALUE)
FindClose(dir->Win32DirectoryHandle);
free(dir);
return 0;
}
/* File sync: a nop. */
int
fsync(int fildes)
{
return 0;
}
/* Sync: a nop. */
int
sync(void)
{
return 0;
}
#endif /* defined(_WIN32) */
/*------------------------ compression function ----------------------*/
static int compressSrc (int src, char *buffer, int blocksize)
{
int usize;
uLongf csize;
int lv_ret;
void *inmem = NULL;
/* inmem is input memory */
inmem = (void *)malloc(blocksize);
/* buffer will be output memory */
if (inmem == NULL)
{
printf("%s: out of memory\n", progname);
free(inmem);
exit(1);
}
/* read the source into buf */
usize= read (src, inmem, blocksize);
if(usize <= 0)
{
free(inmem);
return usize;
}
/* fill in output length */
csize = usize + (int)((usize*0.015)+1.0) +12;
lv_ret = compress((unsigned char *)buffer,&csize,inmem,usize);
if (lv_ret != Z_OK)
{
/* this should NEVER happen */
printf("internal error - compression failed: %d\n", lv_ret);
free(inmem);
exit(2);
}
free(inmem);
return (int)csize;
}
/*------------------------ Recursive directory printing ----------------------*/
static void copy_file(char *inpath,char *outpath)
{
int src = open(inpath, O_RDONLY | O_BINARY);
unsigned int size, count = 0;
unsigned int c_size =0,total_size =0;
int NotFirstElement = False;
int ret;
char *buffer;
struct stat statBuf;
if (src == -1) {
printf("* F %s SOURCE FAILED\n", inpath, errno);
} else {
printf(" F %s \n", outpath);
/* write extern for the datafile in the header */
sprintf(buf,"extern Byte DataFile%d[];\n",NumElements);
write(fh, buf, strlen(buf));
sprintf(buf,"{.global _DataFile%d}\n{_DataFile%d:}\n",NumElements,NumElements);
write(ft, buf, strlen(buf));
/* get size of file */
ret = fstat(src,&statBuf);
if(ret == -1) {
/* errno will be filled in by the archieve driver */
close(src);
return;
}
total_size = statBuf.st_size;
if(NoCompression == True){
/* allocate space for buffer */
buffer = (char *)malloc(total_size);
/* read data from original file */
size= read (src, buffer, total_size);
}
else{
/* compressed image can be bigger than uncompressed some times */
buffer = (char *)malloc(total_size+ (unsigned int)((total_size*0.015)+1) +12);
/* need to set value 'size', and have compressed data in 'buffer' */
size = c_size = compressSrc (src, buffer,total_size);
}
/* while data left in this block */
while (count < size){
/* if its one of the middle 64 */
if((count % 64 != 0 ) && (count % 64 != 63))
sprintf(buf,",0x%2.2x",(unsigned char)buffer[count]);
/* if this is the first byte of 64 */
else if((count % 64) == 0)
sprintf(buf,"{.byte 0x%2.2x",(unsigned char)buffer[count]);
/*else this is the last of 64 */
else
sprintf(buf,",0x%2.2x}\n",(unsigned char)buffer[count]);
/* write to tree file */
write(ft, buf, strlen(buf));
count++;
}
count = 0;
/* no need to do this - fill in last few bytes */
while(count % 4 != 0 ){
/* write 0 values */
sprintf(buf,",0x00");
write(ft, buf, strlen(buf));
count++;
}
/* if this is the not a 64th byte will need to add end curly brace */
if(size % 64 != 0){
/* write final bit for this file in output file */
sprintf(buf,"}\n");
write(ft, buf, strlen(buf));
}
/* fill in path names in header file */
sprintf(buf,"Char Path%d[] = \"%s\";\n", NumElements,outpath);
write(fh, buf, strlen(buf));
/* fill in data struct in temp output file 3 */
/* if this is not the first element don print a comma at start */
if(NumElements != 0)
sprintf(buf,",\n {\n File, Path%d, %d, %d, DataFile%d\n }",
NumElements, total_size, c_size, NumElements);
else
sprintf(buf,"\n {\n File, Path%d, %d, %d, DataFile%d\n }",
NumElements, total_size, c_size, NumElements);
write(fo, buf, strlen(buf));
}
free(buffer);
if (src != -1) { close(src ); }
}
/* outputs to temp output file #3 */
static void copy_dir(char *outpath)
{
printf(" D %s \n", outpath);
/* if this is the first element don't print a comma */
if(NumElements != 0)
sprintf(buf,",\n {\n Dir, Path%d, 0, 0, Null\n }",NumElements);
else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -