⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 arjsfxjr.c

📁 arj source code
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * $Id: arjsfxjr.c,v 1.6 2003/06/22 11:12:28 andrew_belov Exp $ * --------------------------------------------------------------------------- * This is the source for ARJSFXJR, the smallest SFX module. * */#include "arj.h"#include <fcntl.h>#if TARGET!=UNIX #include <io.h> #include <share.h>#endif#include <stdlib.h>#include <string.h>#include <sys/types.h>#include <sys/stat.h>#if COMPILER!=BCC #include <signal.h> #include <time.h>#endif#if TARGET==DOS #include <dos.h>                       /* Weird, eh? */#endif#if TARGET==UNIX #include <utime.h>#endifDEBUGHDR(__FILE__)                      /* Debug information block *//* Local variables */static int file_type;static int aistream;                    /* ARJSFXJR does not use FILE * */static unsigned short bitbuf;static int bitcount;static unsigned char subbitbuf;static long compsize;static long origsize;static char in_cache[CACHE_SIZE_SFXJR]; /* Cache for incoming data */static char *in_cache_ptr;              /* Pointer to fetch incoming data */static int fill_level;                  /* Cache fill level */static unsigned short reg_id;           /* ARJSFX registration ID */static unsigned int basic_hdr_size;static char header[HEADERSIZE_MAX];static unsigned long header_crc;static unsigned char first_hdr_size;static unsigned char arj_flags;static unsigned int method;static unsigned long ftime_stamp;static unsigned long file_crc;static unsigned short entry_pos;static unsigned int file_mode;static char *hdr_filename;static char *hdr_comment;static char filename[FILENAME_MAX];static char comment[COMMENT_MAX];static char archive_name[FILENAME_MAX];static unsigned char dec_text[DICSIZ];static unsigned short left[2*NC-1];static unsigned short right[2*NC-1];static unsigned char pt_len[NPT];static unsigned short c_table[CTABLESIZE];static unsigned short pt_table[PTABLESIZE];static unsigned char c_len[NC];static int blocksize;static char cmd_args[SFX_COMMAND_SIZE+1];static int st_argc;static char nullstr[]="";static char test_mode=0;                /* 1 if test mode (-t) is enabled */static int atstream=0;                  /* Output file handle */static int overwrite_existing=0;        /* -o enables this mode */static int allow_skipping=0;            /* (-n) no errors on skipped files */static unsigned int errors=0;           /* Number of errors */static unsigned int warnings=0;         /* Number of non-fatal errors */static unsigned int total_files=0;      /* Total number of files in archive */static int unpack_in_progress=0;        /* Unpack procedure indicator */static char *dest_dir=nullstr;          /* Destination directory */static char pathsep_sfxjr[]="\\:";      /* A simplified path separator list *//* Local forward-referenced functions */static void decode();/* Converts a numerical variable to string */static void numtostr(unsigned int n, char *str){ char *sptr; int i, j; char t; i=0; sptr=str; *sptr='\0'; do {  sptr[++i]=(char)(n%10)+'0';  n/=10U; } while(n!=0); for(j=0; j<=i; j++) {  t=str[i];  str[i]=str[j];  str[j]=t;  i--; }}/* The only screen output routine */static void sfxjr_puts(FMSG *str){ static char s_cr='\r'; #ifdef FMSG_ST  char c; #endif #if TARGET==DOS&&COMPILER==BORLAND  kbhit();                              /* Don't know/care why it's here */ #endif while(*str!='\0') {  if(*str=='\n')   _write(1, &s_cr, 1);  #ifdef FMSG_ST   c=*str;   _write(1, &c, 1);  #else   _write(1, str, 1);  #endif  str++; }}/* Writes a LF */static void nputlf(){ static char s_crlf[]={'\r', '\n'}; _write(1, &s_crlf, 2);}/* Error output routine. Very simplified, like all others. */static void error(FMSG *errmsg){ nputlf(); sfxjr_puts(errmsg); nputlf(); exit(ARJSFXJR_ERL_ERROR);}/* Converts a filename to the format used in current OS (simply substitutes   the UNIX separators with DOS ones) */static void name_to_hdr(char *name){ int i; for(i=0; name[i]!='\0'; i++) {  if(name[i]==PATHSEP_UNIX)   name[i]=PATHSEP_DEFAULT; }}/* Looks for a path separator in the given filename/pathnamee */static char *find_pathsep(char *name){ if(*name=='\0')  return(NULL); while(*name!='\0') {  if(*name==PATHSEP_DEFAULT)   return(name);  name++; } return((file_type==ARJT_DIR)?name:NULL);}/* Creates the necessary subdirectories before extracting a file */static void create_subdir_tree(char *name){ char tmp_name[FILENAME_MAX]; int rc; char *nptr; nptr=name; /* Skip over preceding drive specifications */ if(nptr[0]!='\0'&&nptr[1]==':')  nptr+=2; if(nptr[0]=='.') {  if(nptr[1]=='.'&&nptr[2]==PATHSEP_DEFAULT)   nptr++;  if(nptr[1]==PATHSEP_DEFAULT)   nptr++; } if(nptr[0]!=PATHSEP_DEFAULT)  nptr++; while((nptr=find_pathsep(nptr))!=NULL) {  strcpy(tmp_name, name);  tmp_name[nptr-name]='\0';  #if TARGET==UNIX   rc=chmod(tmp_name, 0755);  #else   rc=_chmod(tmp_name, 0);  #endif  if(rc==-1)  {   #if TARGET!=UNIX&&!defined(__EMX__)    if(mkdir(tmp_name))     return;   #else    if(mkdir(tmp_name, 666))     return;   #endif  }  else   if(!(rc&FATTR_DIREC))    return;  nptr++; }}#ifdef WORDS_BIGENDIAN#define mget_byte(p) (*(unsigned char FAR *)(p)&0xFF)/* Reads two bytes from the input archive */unsigned int mget_word(char *p){ unsigned int b0, b1; b0=mget_byte(p); b1=mget_byte(p+1); return (b1<<8)|b0;}#else#define mget_word(p) (*(unsigned short *)(p)&0xFFFF)#endif/* Reads four bytes from the input archive */#ifdef WORDS_BIGENDIANunsigned long mget_dword(char *p){ unsigned long w0, w1; w0=mget_word(p); w1=mget_word(p+2); return (w1<<16)|w0;}#else#define mget_dword(p) (*(unsigned long *)(p))#endifunsigned int fget_word(){ char b[2]; if(_read(aistream, b, 2)!=2)  error(M_CANTREAD);#ifdef WORDS_BIGENDIAN return (mget_byte(b+1)<<8)|mget_byte(b);#else return mget_word(b);#endif}/* Reads four bytes from the input archive */unsigned long fget_dword(){ char b[4]; if(_read(aistream, b, 4)!=4)  error(M_CANTREAD);#ifdef WORDS_BIGENDIAN return (mget_word(b+2)<<16)|mget_word(b); #else return mget_dword(b);#endif}/* Reads N bits from the input file into the buffer */static void fillbuf(int n){ unsigned int nbytes; bitbuf=(bitbuf<<n)&0xFFFF;             /* lose the first n bits */ while(n>bitcount) {  bitbuf|=subbitbuf<<(n-=bitcount);  if(compsize!=0L)  {   if(fill_level<=0)   {    nbytes=(unsigned int)min(compsize, (long)CACHE_SIZE_SFXJR);    fill_level=_read(aistream, in_cache, nbytes);    if(fill_level<0)     error(M_CANTREAD);    in_cache_ptr=in_cache;   }   subbitbuf=(unsigned char)*in_cache_ptr++;   fill_level--;   compsize--;  }  else   subbitbuf=0;  bitcount=CHAR_BIT; } bitbuf|=subbitbuf>>(bitcount-=n);}/* Reads and returns N bits */static unsigned short getbits(int n){ unsigned short x; x=bitbuf>>(CHAR_BIT*2-n); fillbuf(n); return(x);}/* Initializes bitwise reading mode */static void init_getbits(){ fill_level=0; bitbuf=0; subbitbuf=0; bitcount=0; fillbuf(CHAR_BIT*2);}/* Reads a block from the file, updating CRC */static int fread_crc(char *buffer, int count){ int n; n=_read(aistream, buffer, count); if(n>0) {  origsize+=(unsigned long)n;  crc32_for_block(buffer, n); } return(n);}/* Writes the output buffer to a file, updating the CRC */static void fwrite_crc(char *buffer, int count){ crc32_for_block(buffer, count); if(!test_mode) {  if(_write(atstream, buffer, count)<count)   error(M_DISK_FULL); }}/* Reads the registration ID from the archive */static void get_reg_id(){ _lseek(aistream, -2L, SEEK_CUR); reg_id=fget_word();}/* Looks for an archive header within the SFX */static void find_sfx_header(){ #ifndef ELF_EXECUTABLES  unsigned int remainder, blocks; #endif unsigned long exe_pos; /* Hack for MZ executables */ #ifndef ELF_EXECUTABLES  _lseek(aistream, 2L, SEEK_SET);  remainder=fget_word();  blocks=fget_word();  exe_pos=(blocks-1)*512L+remainder; #else  exe_pos=0L; #endif do {  while(exe_pos<HSLIMIT_ARJSFXJR)  {   _lseek(aistream, (long)exe_pos, SEEK_SET);   if(fget_word()==HEADER_ID)    break;   exe_pos++;  }  if((basic_hdr_size=fget_word())<=HEADERSIZE_MAX)  {   crc32term=CRC_MASK;   fread_crc(header, basic_hdr_size);   if((crc32term^CRC_MASK)==fget_dword())   {    _lseek(aistream, (long)exe_pos, SEEK_SET);    return;   }  }  exe_pos++; } while(exe_pos<HSLIMIT_ARJSFXJR);}/* Reads a compressed file header. Skips through any extended headers. */static int read_header(){ unsigned short header_id;  /* Strictly check the header ID */ if(fget_word()!=HEADER_ID)  error(M_BAD_HEADER); if((basic_hdr_size=fget_word())==0)  return(0); if(basic_hdr_size>HEADERSIZE_MAX)  error(M_BAD_HEADER); crc32term=CRC_MASK; fread_crc(header, basic_hdr_size); if((header_crc=fget_dword())!=(crc32term^CRC_MASK))  error(M_HEADER_CRC_ERROR); /* Selectively fetch header values */ first_hdr_size=header[0]; arj_flags=header[4]; method=(unsigned int)header[5]; file_type=(unsigned int)header[6]; ftime_stamp=mget_dword(header+8); compsize=mget_dword(header+12); origsize=mget_dword(header+16); file_crc=mget_dword(header+20); entry_pos=mget_word(header+24); file_mode=mget_dword(header+26); hdr_filename=header+first_hdr_size; strncpy(filename, hdr_filename, FILENAME_MAX); filename[FILENAME_MAX-1]='\0'; if(arj_flags&PATHSYM_FLAG)  name_to_hdr(filename); if((long)origsize<0||(long)compsize<0)  error(M_BAD_HEADER); hdr_comment=header+strlen(hdr_filename)+first_hdr_size+1; strncpy(comment, hdr_comment, COMMENT_MAX); comment[COMMENT_MAX-1]='\0'; /* Skip over extended headers, if any */ while((header_id=fget_word())!=0)  _lseek(aistream, (long)header_id+4L, SEEK_CUR); return(1);}/* Unarchives a stored file */static void unstore(){ int fetch_size; while(compsize!=0L) {  fetch_size=(int)min(compsize, (unsigned long)DICSIZ);  compsize-=(unsigned long)fetch_size;  if(_read(aistream, dec_text, fetch_size)!=fetch_size)   error(M_CANTREAD);  fwrite_crc(dec_text, fetch_size);  sfxjr_puts(M_SFXJR_TICKER); }}/* Skips an archived file */static void skip_file(FMSG *reason){ sfxjr_puts(reason); sfxjr_puts(M_SKIPPED); sfxjr_puts((FMSG *)filename); nputlf(); _lseek(aistream, compsize, SEEK_CUR);}/* Unpacks a single file, making all necessary checks */static int unpack_file(){ int c; char tmp_name[FILENAME_MAX]; if(!test_mode) {  strcpy(tmp_name, dest_dir);  strcat(tmp_name, filename);  strcpy(filename, tmp_name);  atstream=_open(filename, O_BINARY|O_RDONLY);  if(atstream>=0)  {   _close(atstream);   if(!overwrite_existing)   {    skip_file(M_FILE_EXISTS);    if(!allow_skipping)     warnings++;    return(0);   }  }  create_subdir_tree(filename);  if(file_type!=ARJT_DIR&&(atstream=open(filename, O_CREAT|O_TRUNC|O_BINARY|O_RDWR, S_IREAD|S_IWRITE))<0)  {   skip_file(M_CANTOPEN_F);   errors++;   return(0);  }  unpack_in_progress=1; } sfxjr_puts(M_EXTRACTING); sfxjr_puts(filename); c=strlen(filename); while(c++<12)  sfxjr_puts(M_VD_SPACE);

⌨️ 快捷键说明

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