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

📄 unrar.c

📁 比zip压缩比率高的rar压缩方法的解压程序
💻 C
📖 第 1 页 / 共 2 页
字号:
    case 0:
      Help();
      exit(0);
    default:
      Help();
      exit(USER_ERROR);
  }
}

void ShutDown(Mode)
int Mode;
{
  if (Mode & SD_FILES)
  {
    if (ArcFPtr!=NULL)
      fclose(ArcFPtr);
    if (FileFPtr!=NULL)
      fclose(FileFPtr);
  }
  if (Mode & SD_MEMORY)
  {
    if (TmpMemory!=NULL)
      MEMFREE(TmpMemory);
    printf("\n");
  }
}


void Help()
{
  printf("\n Usage:     UNRAR <command> <archive> <files...>\n");
  printf("\n <Commands>\n");
  printf("\n x       Extract files with full path");
  printf("\n e       Extract files to current directory");
  printf("\n t       Test archive files");
  printf("\n v       Verbosely list contents of archive");
  printf("\n l       List contents of archive");
  printf("\n");
}


int ExtrFile()
{
  char DestFileName[80];
  long FileCount=0,TotalFileCount=0,DirCount=0,ErrCount=0;
  int ExtrFile=0,Size,SkipSolid=0,UnpSolid;

  if ((ArcFPtr=fopen(ArcName,FOPENREADMODE))==NULL)
    ErrExit(EOPEN,FATAL_ERROR);

  CheckArc();
  CreateEncTbl(TmpMemory);
  UnpVolume=UnpSolid=0;
  if (MainCommand=='T')
    printf("\n Testing archive %s\n",ArcName);
  else
    printf("\n Extracting from %s\n",ArcName);

  while (1)
  {
    Size=ReadBlock(FILE_HEAD);

    if (Size<=0 && UnpVolume==0)
      break;
    if ((Lhd.Flags & LHD_SPLIT_BEFORE) && SolidType)
    {
      printf("\nSolid archive: first volume required");
      ErrExit(EEMPTY,FATAL_ERROR);
    }
    if (UnpVolume && Size==0)
      MergeArc(0);
    UnpVolume=(Lhd.Flags & LHD_SPLIT_AFTER);
    fseek(ArcFPtr,NextBlockPos-Lhd.PackSize,SEEK_SET);

    TestMode=0;
    ExtrFile=0;
    SkipSolid=0;

    if (IsProcessFile(COMPARE_PATH) && (Lhd.Flags & LHD_SPLIT_BEFORE)==0
        || (SkipSolid=SolidType)!=0)
    {

      strcpy(DestFileName,ExtrPath);
      strcat(DestFileName,(MainCommand!='E') ? ArcFileName : PointToName(ArcFileName));

      ExtrFile=!SkipSolid;

      if (Lhd.UnpVer<15 || Lhd.UnpVer>UNP_VER)
      {
        printf("\n %s: unknown method",ArcFileName);
        ExtrFile=0;
        ErrCount++;
        ExitCode=WARNING;
      }

      if (Lhd.Flags & LHD_PASSWORD)
      {
        printf("\n %s: cannot process encrypted file",ArcFileName);
        if (SolidType)
          ErrExit(EEMPTY,FATAL_ERROR);
        ExtrFile=0;
        ErrCount++;
        ExitCode=WARNING;
      }

      if (Lhd.HostOS==MS_DOS && (Lhd.FileAttr & DOSFA_DIREC))
      {
        if (MainCommand=='E')
          continue;
        if (SkipSolid)
        {
          printf("\n Skipping    %-55s Ok",ArcFileName);
          continue;
        }
        if (MainCommand=='T')
        {
          printf("\n Testing     %-55s Ok",ArcFileName);
          continue;
        }
        CreatePath(DestFileName);
        if (MAKEDIR(DestFileName)==0)
          printf("\n Creating    %-55s",ArcFileName);
        continue;
      }
      else
      {
        if (MainCommand=='T' && ExtrFile)
          TestMode=1;
        if ((MainCommand=='E' || MainCommand=='X') && ExtrFile)
        {
          CreatePath(DestFileName);
          if ((FileFPtr=fopen(DestFileName,FOPENWRITEMODE))==NULL)
          {
            printf("\n Cannot create %s",DestFileName);
            ExitCode=WARNING;
            ExtrFile=0;
          }
        }
      }

      if (!ExtrFile && SolidType)
        SkipSolid=TestMode=ExtrFile=1;
      if (ExtrFile)
      {
        TotalFileCount++;
        if (SkipSolid)
          printf("\n Skipping    %-55s",ArcFileName);
        else
        {
          FileCount++;
          switch(MainCommand)
          {
            case 'T':
              printf("\n Testing     %-55s",ArcFileName);
              break;
            case 'X':
            case 'E':
              printf("\n Extracting  %-55s",DestFileName);
              break;
          }
        }
        strcpy(CurExtrFile,DestFileName);
        UnpFileCRC=0xFFFFFFFFL;
        UnpPackedSize=Lhd.PackSize;
        DestUnpSize=Lhd.UnpSize;
        RdUnpFPtr=ArcFPtr;
        WrUnpFPtr=FileFPtr;
        if (Lhd.Method==0x30)
          UnstoreFile();
        else
          if (unpack(TmpMemory,UnpRead,UnpWrite,UnpSolid)==-1)
            ErrExit(EWRITE,WRITE_ERROR);
        if (TotalFileCount>0 && SolidType)
          UnpSolid=1;
        if (UnpFileCRC==~Lhd.FileCRC)
        {
          if (MainCommand!='P')
            printf(" Ok");
        }
        else
        {
          fseek(ArcFPtr,NextBlockPos,SEEK_SET);
          printf("\n %-15s : CRC failed",ArcFileName);
          ExitCode=CRC_ERROR;
          ErrCount++;
        }
        if (!TestMode)
        {
          SETFILETIME(FileFPtr,(void *)&Lhd.FileTime);
          tclose(FileFPtr);
        }
        TestMode=0;
        *CurExtrFile=0;
      }
    }
    if (!ExtrFile && !SolidType)
      fseek(ArcFPtr,NextBlockPos,SEEK_SET);
  }
  tclose(ArcFPtr);
  if ((FileCount+DirCount)==0)
  {
    printf("\n No files");
    ExitCode=WARNING;
  }
  else
    if (ErrCount==0)
      printf("\n  All OK");
    else
      printf("\n  Total errors: %ld",ErrCount);
  return(0);
}


void ListArchive()
{
  unsigned long TotalPackSize,TotalUnpSize,FileCount;
  int I;
  TotalPackSize=TotalUnpSize=FileCount=0;
  if ((ArcFPtr=fopen(ArcName,FOPENREADMODE))==NULL)
    ErrExit(EOPEN,FATAL_ERROR);
  CheckArc();
  printf("\n ");
  if (SolidType)
    printf("Solid ");
  if (Mhd.Flags & MHD_MULT_VOL)
    printf("%colume ",(SolidType) ? 'v':'V');
  else
    printf("%crchive ",(SolidType) ? 'a':'A');
  printf("%s\n",ArcName);
  if (MainCommand=='V')
    printf("\n Pathname/Comment\n%12.12s","");
  else
    printf("\n Name       ");
  printf("      Size   Packed  Ratio   Date   Time  Attr   CRC-32  Meth Ver\n");
  for (I=0;I<77;I++)
    printf("-");
  while(ReadBlock(FILE_HEAD) > 0)
  {
    if (IsProcessFile(NOT_COMPARE_PATH))
    {
      printf("\n%c",(Lhd.Flags & LHD_PASSWORD) ? '*' : ' ');
      if (MainCommand=='V')
      {
        printf("%-s",ArcFileName);
        printf("\n%12s ","");
      }
      else
        printf("%-12s",PointToName(ArcFileName));

      printf(" %8ld %8ld ",Lhd.UnpSize,Lhd.PackSize);
      if (Lhd.Flags & (LHD_SPLIT_AFTER | LHD_SPLIT_BEFORE))
        printf(" Split");
      else
        printf(" %3d%% ",ToPercent(Lhd.PackSize,Lhd.UnpSize));

      printf(" %02d-%02d-%02d %02d:%02d ",(int)(Lhd.FileTime>>16) & 0x1f,
        (int)(Lhd.FileTime>>21) & 0xf,(int)((Lhd.FileTime>>25)+1980)%100,
        (int)(Lhd.FileTime>>11) & 0x1f,(int)(Lhd.FileTime>>5) & 0x3f);

      if (Lhd.HostOS==MS_DOS)
        printf("%c%c%c%c%c",
          (Lhd.FileAttr & DOSFA_DIREC ) ? 'D' : '.',
          (Lhd.FileAttr & DOSFA_RDONLY) ? 'R' : '.',
          (Lhd.FileAttr & DOSFA_HIDDEN) ? 'H' : '.',
          (Lhd.FileAttr & DOSFA_SYSTEM) ? 'S' : '.',
          (Lhd.FileAttr & DOSFA_ARCH  ) ? 'A' : '.');
      else
        printf("     ");
      printf(" %8.8lX  m%d  %d.%d",Lhd.FileCRC,Lhd.Method-0x30,Lhd.UnpVer/10,Lhd.UnpVer%10);
      if (!(Lhd.Flags & LHD_SPLIT_BEFORE))
      {
        TotalUnpSize+=Lhd.UnpSize;
        FileCount++;
      }
      TotalPackSize+=Lhd.PackSize;
    }
    fseek(ArcFPtr,NextBlockPos,SEEK_SET);
  }
  printf("\n");
  for (I=0;I<77;I++)
    printf("-");
  printf("\n%5ld %16ld %8ld %4d%%\n",FileCount,TotalUnpSize,TotalPackSize,ToPercent(TotalPackSize,TotalUnpSize));
  tclose(ArcFPtr);
}


int IsProcessFile(ComparePath)
int ComparePath;
{
  int NumName,WildCards;
  char ArgName[80],dir1[80],name1[15],dir2[80],name2[15];
  for (NumName=0;NumName<ArgCount;NumName++)
  {
    memcpy((void *)ArgName,(void *)ArgNames[NumName],sizeof(ArgName));
    WildCards=(strchr(ArgName,'?')!=NULL || strchr(ArgName,'*')!=NULL);
    SplitName(ArgName,dir1,name1);
    SplitName(ArcFileName,dir2,name2);
    if (CmpName(name1,name2) && ((ComparePath==NOT_COMPARE_PATH && *dir1==0) ||
          WildCards && strnicomp(dir1,dir2,strlen(dir1))==0 ||
          strnicomp(dir1,dir2,1000)==0))
      return(1);
  }
  return(0);
}

int ReadBlock(BlockType)
int BlockType;
{
  UDWORD HeadCRC;
  UBYTE Header[32];
  int Size,I;
  memset(&Lhd,0,sizeof(Lhd));
  memset(Header,0,sizeof(Header));
  while (1)
  {
    Size=tread(ArcFPtr,Header,32);
    Lhd.HeadCRC  = Header[0] +(UWORD)Header[1]*0x100;
    Lhd.HeadType = Header[2];
    Lhd.Flags    = Header[3] +(UWORD)Header[4]*0x100;
    Lhd.HeadSize = Header[5] +(UWORD)Header[6]*0x100;;
    Lhd.PackSize = Header[7] +(UWORD)Header[8]*0x100+(UDWORD)Header[9]*0x10000L+(UDWORD)Header[10]*0x1000000L;
    Lhd.UnpSize  = Header[11]+(UWORD)Header[12]*0x100+(UDWORD)Header[13]*0x10000L+(UDWORD)Header[14]*0x1000000L;
    Lhd.HostOS   = Header[15];
    Lhd.FileCRC  = Header[16]+(UWORD)Header[17]*0x100+(UDWORD)Header[18]*0x10000L+(UDWORD)Header[19]*0x1000000L;
    Lhd.FileTime = Header[20]+(UWORD)Header[21]*0x100+(UDWORD)Header[22]*0x10000L+(UDWORD)Header[23]*0x1000000L;
    Lhd.UnpVer   = Header[24];
    Lhd.Method   = Header[25];
    Lhd.NameSize = Header[26]+(UWORD)Header[27]*0x100;
    Lhd.FileAttr = Header[28]+(UWORD)Header[29]*0x100+(UDWORD)Header[30]*0x10000L+(UDWORD)Header[31]*0x1000000L;
    if (Size != 0 && (Size<7 || Lhd.HeadSize<7))
      ErrExit(EARCH,FATAL_ERROR);
    NextBlockPos=ftell(ArcFPtr)-Size+Lhd.HeadSize;
    if (Lhd.Flags & LONG_BLOCK)
      NextBlockPos+=Lhd.PackSize;
    if (Size==0 || BlockType==ALL_HEAD || Lhd.HeadType==BlockType)
      break;
    fseek(ArcFPtr,NextBlockPos,SEEK_SET);
  }
  if (Size>0 && BlockType==FILE_HEAD)
  {
    tread(ArcFPtr,ArcFileName,Lhd.NameSize);
    ArcFileName[Lhd.NameSize]=0;
    Size+=Lhd.NameSize;
    HeadCRC=CRC(0xFFFFFFFFL,&Header[2],30);
    if (!(Lhd.HeadCRC==(UWORD)~CRC(HeadCRC,&ArcFileName[0],Lhd.NameSize)))
      printf("\n %s: file header broken\n",ArcFileName);
    for (I=0;ArcFileName[I];I++)
      if (ArcFileName[I]=='\\' || ArcFileName[I]=='/')
        ArcFileName[I]=PATHDIV;
    if (Lhd.HostOS==MS_DOS)
      strtolwr(ArcFileName);
  }
  return(Size);
}


int UnpRead(Addr,Count)
UBYTE *Addr;
UWORD Count;
{
  int RetCode;
  unsigned int ReadSize,TotalRead=0;
  UBYTE *ReadAddr;
  ReadAddr=Addr;
  while (Count > 0)
  {
    ReadSize=(unsigned int)((Count>UnpPackedSize) ? UnpPackedSize : Count);
    if ((RetCode=fread(ReadAddr,1,ReadSize,RdUnpFPtr))!=ReadSize)
      break;
    TotalRead+=RetCode;
    ReadAddr+=RetCode;
    Count-=RetCode;
    UnpPackedSize-=RetCode;
    if (UnpPackedSize == 0 && UnpVolume)
      MergeArc(1);
    else
      break;
  }
  if (RetCode!=-1)
    RetCode=(int)TotalRead;
  return(RetCode);
}


int UnpWrite(Addr,Count)
UBYTE *Addr;
UWORD Count;
{
  int RetCode;
  if (TestMode)
    RetCode=(int)Count;
  else
    if ((RetCode=fwrite(Addr,1,Count,WrUnpFPtr))!=Count)
      RetCode = -1;
  if (RetCode!=-1)
    UnpFileCRC=CRC(UnpFileCRC,Addr,(UWORD)RetCode);
  return(RetCode);
}


UDWORD CRC(StartCRC,Addr,Size)
UDWORD StartCRC;
UBYTE *Addr;
UWORD Size;
{
  UWORD I;
  if (!CRC32_Table[1])
    InitCRC();
  for (I=0;I<Size;I++)
    StartCRC = CRC32_Table[(UBYTE)StartCRC ^ Addr[I]] ^ (StartCRC >> 8);
  return(StartCRC);
}

void InitCRC()
{
  int I, J;
  UDWORD C;
  for (I=0;I<256;I++)
  {
    for (C=I,J=0;J<8;J++)
      C=(C & 1) ? (C>>1)^0xEDB88320L : (C>>1);
    CRC32_Table[I]=C;
  }
}

⌨️ 快捷键说明

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