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

📄 unrar.c

📁 比zip压缩比率高的rar压缩方法的解压程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/******    *****   ******
 **   **  **   **  **   **      unRAR utility version 1.01
 ******   *******  ******       ~~~~~~~~~~~~~~~~~~~~~~~~~~~
 **   **  **   **  **   **         FREE portable version
 **   **  **   **  **   **         ~~~~~~~~~~~~~~~~~~~~~

         Main code

   YOU CAN CHANGE FOLLOWING CODE IN ORDER TO ACHIEVE
   COMPATIBILITY WITH YOUR OPERATING MEDIA.

   PLEASE SEND ALL NOTES, PATCHES TO andrey@vybor.chel.su
   OR TO Andrey Spasibozhko, 2:5010/23@fidonet.
   VOICE PHONE: +7-3512-130-231
*/

#include "unrar.h"          /* definitions */
#include "unpack.c"         /* unpacking procedures */

void   SplitCommandLine();  /* parses command string */
int    CmpName();           /* checks name for mask */
char*  PointToName();       /* returns pathname */
void   NextVolumeName();    /* gets next volume name */
void   SplitName();         /* splits pathname */
void   ExecuteCommand();    /* executes extr. command */
void   ListArchive();       /* lists archive contents */
int    ExtrFile();          /* extracts single file */
void   Help();              /* prints usage help */
void   ShutDown();          /* stops working */
void   ErrExit();           /* exits with error code */
void   CreatePath();        /* creates path */
int    tread();             /* reads with checking */
void   tclose();            /* closes with checking */
void   MergeArc();          /* to next volume */
void   UnstoreFile();       /* unpacks non-compressed file */
int    IsArchive();         /* checks for RAR archive signature */
void   CheckArc();          /* similar but with exit */
int    strnicomp();         /* compares strings */
char*  strtolwr();          /* convert string to lowercase
int    ToPercent();         /* calculates percentage */
int    ReadBlock();         /* reads archive block */
int    IsProcessFile();     /* should file be processed */
int    UnpRead();           /* reading while unpacking */
int    UnpWrite();          /* writing while unpacking */
void   InitCRC();           /* initializes CRC table */
UDWORD CRC();               /* calculates CRC */

struct MarkHeader MarkHead;
struct ArchiveHeader Mhd;
struct FileHeader Lhd;

UDWORD CRC32_Table[256],UnpFileCRC;
HPBYTE TmpMemory;

int ArgCount=0;
char ArgNames[16][80],MainCommand;
char CurExtrFile[80]={0},ArcName[80],ArcFileName[80],ExtrPath[80];
int SolidType,UnpVolume,TestMode,ExitCode=0;
FILE *ArcFPtr=NULL,*FileFPtr=NULL,*RdUnpFPtr,*WrUnpFPtr;
long NextBlockPos,UnpPackedSize;


main(Argc,Argv)
int Argc;
char *Argv[];
{
  printf("\n UNRAR 1.01 freeware portable version      (C) 1994-95 Eugene Roshal\n");
  if ((TmpMemory=(HPBYTE)MEMALLOC(UNP_MEMORY))==NULL)
    ErrExit(EMEMORY,MEMORY_ERROR);
  MakeTbl();
  SplitCommandLine(Argc,Argv);
  ExecuteCommand();
  ShutDown(SD_MEMORY);
  exit(ExitCode);
}


int CmpName(Mask,Name)
char *Mask;
char *Name;
{
  while (1)
  {
    if (*Mask=='*')
    {
      while (*Mask!='.' && *Mask!=0)
        Mask++;
      while (*Name!='.' && *Name!=0)
        Name++;
    }
    if (*Mask==0)
      return(*Name==0);
    if (*Name==0 && *Mask=='.')
    {
      Mask++;
      continue;
    }
    if (toupper(*Mask)==toupper(*Name) || *Mask=='?' && *Name!=0)
    {
      Mask++;
      Name++;
    }
    else
      return(0);
  }
}


void ErrExit(ErrCode,Code)
int ErrCode;
int Code;
{
  char ErrMsg[80];
  switch(ErrCode)
  {
    case EEMPTY:
      strcpy(ErrMsg,"");
      break;
    case EWRITE:
      strcpy(ErrMsg,"Write error. Disk full ?");
      break;
    case EREAD:
      strcpy(ErrMsg,"Read error");
      break;
    case EOPEN:
      strcpy(ErrMsg,"File open error");
      break;
    case ECLOSE:
      strcpy(ErrMsg,"File close error");
      break;
    case EMEMORY:
      strcpy(ErrMsg,"Not enough memory");
      break;
    case EARCH:
      strcpy(ErrMsg,"Broken archive");
      break;
  }
  if (ErrCode!=EEMPTY)
    printf("\n Program aborted\n %s",ErrMsg);
  ShutDown(SD_FILES | SD_MEMORY);
  exit(Code);
}


void CreatePath(fpath)
char *fpath;
{
  char *ChPtr;
  ChPtr=fpath;
  while(*ChPtr!=0 && (ChPtr=strchr(ChPtr,PATHDIV))!=NULL)
  {
    *ChPtr=0;
    if (MAKEDIR(fpath)==0)
      printf("\n Creating    %-55s",fpath);
    *ChPtr=PATHDIV;
    ChPtr++;
  }
}


void NextVolumeName()
{
  char *ChPtr;
  ChPtr=strrchr(ArcName,'.');
  if (!isdigit(*(ChPtr+2)) || !isdigit(*(ChPtr+3)))
    strcpy(ChPtr+2,"00");
  else
  {
    ChPtr+=3;
    while ((++(*ChPtr))=='9'+1)
    {
      if (*(ChPtr-1)=='.')
      {
        *ChPtr='A';
        break;
      }
      else
      {
        *ChPtr='0';
        ChPtr--;
      }
    }
  }
}


void MergeArc(ShowFileName)
int ShowFileName;
{
  int Ch;
  tclose(ArcFPtr);
  NextVolumeName();
  while ((ArcFPtr=fopen(ArcName,FOPENREADMODE))==NULL)
  {
    printf("\n Disk with %s required. Continue ? ",ArcName);
    Ch=getchar();
    if (toupper(Ch)=='N')
      ErrExit(EEMPTY,USER_BREAK);
  }
  if (MainCommand=='T')
    printf("\n\n Testing archive %s",ArcName);
  else
    if (MainCommand!='P')
      printf("\n\n Extracting from %s",ArcName);
  CheckArc();
  ReadBlock(FILE_HEAD);
  if (ShowFileName)
    printf("\n     ...     %-55s",ArcFileName);
  UnpVolume=(Lhd.Flags & LHD_SPLIT_AFTER);
  fseek(ArcFPtr,NextBlockPos-Lhd.PackSize,SEEK_SET);
  UnpPackedSize=Lhd.PackSize;
  RdUnpFPtr=ArcFPtr;
}


void UnstoreFile()
{
  int Code;
  while ( 1 )
  {
    if ((Code=UnpRead((UBYTE *)TmpMemory,0x7f00))==-1)
      ErrExit(EWRITE,WRITE_ERROR);
    if (Code==0)
      break;
    if (UnpWrite((UBYTE *)TmpMemory,(UWORD)Code)==-1)
      ErrExit(EWRITE,WRITE_ERROR);
  }
}


int IsArchive()
{
  UBYTE Mark[7],Header[13];
  SolidType=0;
  if (tread(ArcFPtr,Mark,7)!=7)
    return(0);
  if (Mark[0]!=0x52 || Mark[1]!=0x61 || Mark[2]!=0x72 || Mark[3]!=0x21 ||
      Mark[4]!=0x1a || Mark[5]!=0x07 || Mark[6]!=0x00)
    return(0);
  if (tread(ArcFPtr,Header,13) != 13)
    return(0);
  Mhd.HeadCRC  = Header[0]+(UWORD)Header[1]*0x100;
  Mhd.HeadType = Header[2];
  Mhd.Flags    = Header[3]+(UWORD)Header[4]*0x100;
  Mhd.HeadSize = Header[5]+(UWORD)Header[6]*0x100;
  if (!(Mhd.HeadCRC==(UWORD)~CRC(0xFFFFFFFFL,&Header[2],11)))
    printf("\n Archive header broken");
  SolidType=(Mhd.Flags & MHD_SOLID);
  fseek(ArcFPtr,Mhd.HeadSize-13,SEEK_CUR);
  return(1);
}


void CheckArc()
{
  if (!IsArchive())
  {
    printf("\nBad archive %s",ArcName);
    ErrExit(EEMPTY,FATAL_ERROR);
  }
}


int tread(FPtr,buf,len)
FILE *FPtr;
void *buf;
unsigned len;
{
  int Code;
  Code=fread(buf,1,len,FPtr);
  if (Code==-1)
    ErrExit(EREAD,FATAL_ERROR);
  return(Code);
}


void tclose(FPtr)
FILE *FPtr;
{
  if (fclose(FPtr)==EOF)
    ErrExit(ECLOSE,FATAL_ERROR);
}


char* PointToName(Path)
char *Path;
{
  char *ChPtr;
  if ((ChPtr=strrchr(Path,PATHDIV))!=NULL)
    return(ChPtr+1);
  else
    if ((ChPtr=strrchr(Path,':'))!=NULL)
      return(ChPtr+1);
    else
      return(Path);
}


int strnicomp(Str1,Str2,MaxLen)
char *Str1;
char *Str2;
int MaxLen;
{
  if (MaxLen==0)
    return(0);
  while (MaxLen-- > 0)
  {
    if (toupper(*Str1)!=toupper(*Str2))
      return(1);
    if (*Str1==0)
      return(0);
    Str1++;
    Str2++;
  }
  return(0);
}


char* strtolwr(Str)
char *Str;
{
  char *ChPtr;
  for (ChPtr=Str;*ChPtr!=0;ChPtr++)
    *ChPtr=tolower(*ChPtr);
  return(Str);
}


void SplitName(Path,Dir,Name)
char *Path;
char *Dir;
char *Name;
{
  char *ChPtr,*ChPtr1;
  if ((ChPtr=strrchr(Path,':'))!=NULL)
    ChPtr++;
  else
    ChPtr=Path;
  if ((ChPtr1=strrchr(ChPtr,PATHDIV))!=NULL)
  {
    *ChPtr1=0;
    strcpy(Dir,ChPtr);
    *ChPtr1=PATHDIV;
    ChPtr=ChPtr1+1;
  }
  else
    *Dir=0;
  strcpy(Name,ChPtr);
}


int ToPercent(N1,N2)
long N1;
long N2;
{
  if (N1 > 10000)
  {
    N1/=100;
    N2/=100;
  }
  if (N2==0)
    return(0);
  if (N2<N1)
    return(100);
  return((int)(N1*100/N2));
}


void SplitCommandLine(Argc,Argv)
int Argc;
char *Argv[];
{
  int I,Len;

  ArgCount = MainCommand = *ArcName = *ExtrPath = 0;

  if (Argc==2)
  {
    MainCommand='X';
    strcpy(ArcName,Argv[1]);
  }
  else
    for (I=1;I<Argc;I++)
    {
      if (MainCommand==0)
        MainCommand=toupper(Argv[I][0]);
      else
      {
        if (*ArcName==0)
          strncpy(ArcName,Argv[I],80);
        else
        {
          Len=strlen(Argv[I]);
          if (Len>0 && (Argv[I][Len-1]==':' || (Argv[I][Len-1]=='\\' || Argv[I][Len-1]=='/')))
          {
            strcpy(ExtrPath,Argv[I]);
            ExtrPath[Len-1]=PATHDIV;
          }
          else
            strncpy(ArgNames[(ArgCount++) & 0x0f],Argv[I],80);
        }
      }
    }

  if (ArgCount==0 && *ArcName!=0)
    strcpy(ArgNames[(ArgCount++) & 0x0f],"*.*");
  if (strrchr(PointToName(ArcName),'.')==NULL)
    strcat(ArcName,isupper(*ArcName) ? ".RAR":".rar");
  ArgCount &= 0xF;
}


void ExecuteCommand()
{
  switch(MainCommand)
  {
    case 'E':
    case 'X':
    case 'T':
      ExtrFile();
      break;
    case 'V':
    case 'L':
      ListArchive();
      break;

⌨️ 快捷键说明

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