이것은 tar 파일을 푸는부분만 구현한것입니다.

코드:

/*
Copyright (c) 2002 Information Equipment co.,LTD.
All Right Reserved.

Code by JaeHyuk Cho <minzkn@infoeq.co.kr>
*/

#if !defined(DEF_tar_c)
#define DEF_tar_c "tar.c"

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <sys/stat.h>
#include <utime.h>
#include <time.h>
#include <errno.h>

#define DEF_TAR_MAGIC "ustar "
#define DEF_TAR_BLOCK (512)

typedef enum
{
E_TAR_ERROR_NONE                  = 0x00000000,
E_TAR_ERROR_FOUND                 = 0x00000001,
E_TAR_ERROR_CREATE                = 0x00000002,
E_TAR_ERROR_PERMISSION            = 0x00000004,
E_TAR_ERROR_INVALID_OPERATION     = 0x00000008,
E_TAR_ERROR_INVALID_DATA          = 0x00000010,
E_TAR_ERROR_MEMORY                = 0x00000020,
}e_TAR_ERROR;

typedef enum
{
E_TAR_FLAG_NONE                   = 0x00000000,   
E_TAR_FLAG_DEBUG                  = 0x00000001,
E_TAR_FLAG_VERBOSE                = 0x00000002,
E_TAR_FLAG_LIST                   = 0x00000004,
E_TAR_FLAG_EXTRACT                = 0x00000008,
E_TAR_FLAG_CREATE                 = 0x00000010,
E_TAR_FLAG_STREAM                 = 0x00000020,
}e_TAR_FLAG;

typedef enum
{
E_TAR_HEADER_SIZE_NAME            = 100,
E_TAR_HEADER_SIZE_MODE            =   8,
E_TAR_HEADER_SIZE_UID             =   8,
E_TAR_HEADER_SIZE_GID             =   8,
E_TAR_HEADER_SIZE_SIZE            =  12,
E_TAR_HEADER_SIZE_MAKETIME        =  12,
E_TAR_HEADER_SIZE_CHECKSUM        =   8,
E_TAR_HEADER_SIZE_TYPEFLAG        =   1,
E_TAR_HEADER_SIZE_LINKNAME        = 100,
E_TAR_HEADER_SIZE_MAGIC           =   6,
E_TAR_HEADER_SIZE_VERSION         =   2,
E_TAR_HEADER_SIZE_UNAME           =  32,
E_TAR_HEADER_SIZE_GNAME           =  32,
E_TAR_HEADER_SIZE_DEVMAJOR        =   8,
E_TAR_HEADER_SIZE_DEVMINOR        =   8,
E_TAR_HEADER_SIZE_PREFIX          = 155,
E_TAR_HEADER_SIZE_PADDING         =  12,
}e_TAR_HEADER;

typedef enum
{
E_TAR_TYPEFLAG_REGULAR            = '0',  /* Normal regular file */
E_TAR_TYPEFLAG_REGULAR_BUG        = '\0', /* For ancient bug complete */
E_TAR_TYPEFLAG_LINK               = '1',  /* Hard link */
E_TAR_TYPEFLAG_SYMLINK            = '2',  /* Symbolic link */
E_TAR_TYPEFLAG_CHARDEV            = '3',  /* Character device */
E_TAR_TYPEFLAG_BLOCKDEV           = '4',  /* Block device */
E_TAR_TYPEFLAG_DIRECTORY          = '5',  /* Directory */
E_TAR_TYPEFLAG_FIFO               = '6',  /* FIFO */
E_TAR_TYPEFLAG_RESERVED           = '7',  /* Reserved */
E_TAR_TYPEFLAG_LONGLINK           = 'K',  /* Long link name */
E_TAR_TYPEFLAG_LONGNAME           = 'L',  /* Long file name */
}e_TAR_TYPEFLAG;

typedef struct
{
char                       Name[E_TAR_HEADER_SIZE_NAME];
char                       Mode[E_TAR_HEADER_SIZE_MODE];
char                       UID[E_TAR_HEADER_SIZE_UID];
char                       GID[E_TAR_HEADER_SIZE_GID];
char                       Size[E_TAR_HEADER_SIZE_SIZE];
char                       MakeTime[E_TAR_HEADER_SIZE_MAKETIME];
char                       CheckSum[E_TAR_HEADER_SIZE_CHECKSUM];
char                       TypeFlag[E_TAR_HEADER_SIZE_TYPEFLAG];
char                       LinkName[E_TAR_HEADER_SIZE_LINKNAME];
char                       Magic[E_TAR_HEADER_SIZE_MAGIC];
char                       Version[E_TAR_HEADER_SIZE_VERSION];
char                       UName[E_TAR_HEADER_SIZE_UNAME];
char                       GName[E_TAR_HEADER_SIZE_GNAME];
char                       DevMajor[E_TAR_HEADER_SIZE_DEVMAJOR];
char                       DevMinor[E_TAR_HEADER_SIZE_DEVMINOR];
char                       Prefix[E_TAR_HEADER_SIZE_PREFIX];
char                       Padding[E_TAR_HEADER_SIZE_PADDING];
}t_TAR_HEADER; /* Total header size is 512 bytes */

typedef struct ts_TAR_List
{
struct ts_TAR_List        *Next;   
char                      *Name;
unsigned long              Mode;
uid_t                      UID;
gid_t                      GID;
unsigned long long         Size;
time_t                     MakeTime;
long                       CheckSum;
e_TAR_TYPEFLAG             TypeFlag;
char                      *LinkName;
char                      *UName;
char                      *GName;
unsigned long              DevMajor;
unsigned long              DevMinor;
unsigned long long         Position;
}t_TAR_List;

typedef struct
{
char                      *TarName;   
t_TAR_List                *List;
unsigned long              ErrorCode;
unsigned long              Flag;
int                        ReadHandle;
int                        WriteHandle;
}t_TAR;

static int _MZ_MakeDirectory(char *s_Path, unsigned long s_Mode, int s_Flag);
int MZ_MakeDirectory(char *s_Path, unsigned long s_Mode);
static void *MZ_VSPrintf(void *s_Format, va_list s_VaArg);
void *MZ_SPrintf(void *s_Format, ...);
static void *MZ_SDUP(void *s_String, int s_n);
static t_TAR *MZ_CreateTAR(void);
static unsigned long MZ_GetTAR_Value(void *s_Ptr, int s_Size);
t_TAR *MZ_OpenTAR(char *s_TarName, unsigned long s_Flag);
t_TAR *MZ_CloseTAR(t_TAR *s_HANDLE_TAR);
t_TAR *MZ_ListTAR(t_TAR *s_HANDLE_TAR);
unsigned long MZ_DoTAR(t_TAR *s_Tar, t_TAR_List *s_TarList, unsigned long s_Flag);
int main(int s_Argc, char *s_Argv[]);

static int _MZ_MakeDirectory(char *s_Path, unsigned long s_Mode, int s_Flag)
{
int s_Return = (-1);
if(s_Flag == 1)
{
  if(mkdir(s_Path, 0777) == 0)
  {
   if(chmod(s_Path, s_Mode) == 0)s_Return = 1;
   else fprintf(stderr, "%s: %s - [ERROR] Can not chmod \"%s\"\n", __FILE__, __FUNCTION__, s_Path);
  }
  else fprintf(stderr, "%s: %s - [ERROR] Can not mkdir \"%s\"\n", __FILE__, __FUNCTION__, s_Path);
}
else
{
  struct stat s_Stat;
  if(stat(s_Path, &s_Stat) != 0 && errno == ENOENT)
  {
   int s_Status;
   char *s_Buffer;
   mode_t s_Mask;
   s_Mask = umask(0);
   umask(s_Mask);
   s_Buffer = MZ_SDUP(s_Path, strlen(s_Path));
   if(s_Buffer)
   {
    int s_Index;
    s_Index = strlen(s_Path);
    if(s_Index > 0)
    {
     s_Index--;      
     while(s_Index > 0 && *(s_Buffer + s_Index) == '/')
     {
      *(s_Buffer + s_Index) = '\0';          
      s_Index--;
     }       
     while(s_Index > 0)
     {
      if(*(s_Buffer + s_Index) == '/')break;
      s_Index--;
     }
     if(s_Index > 0)
     {
      *(s_Buffer + s_Index) = '\0';
      s_Status = _MZ_MakeDirectory(s_Buffer, (0777 & (~s_Mask)) | 0300, 0);
      free(s_Buffer);
     }
     else s_Status = 1;
     if(s_Status <= 0 || _MZ_MakeDirectory(s_Path, s_Mode, 1) <= 0);
     else s_Return = 1;
    }
   }
  }
  else s_Return = 1; 
}
return(s_Return);
}

int MZ_MakeDirectory(char *s_Path, unsigned long s_Mode)
{
if(s_Path)return(_MZ_MakeDirectory(s_Path, s_Mode, 0));
else return(-1);
}

static void *MZ_SDUP(void *s_String, int s_n)
{
void *s_Return;
s_Return = (void *)malloc(s_n + 1);
if(s_Return)
{
  if(s_n > 0)memcpy(s_Return, s_String, s_n);   
  *(((char *)s_Return) + s_n) = '\0';
}
return(s_Return);
}

void *MZ_VSPrintf(void *s_Format, va_list s_VaArg)
{
void *s_Return;
int s_BufferSize = 256;
do
{
  s_Return = (void *)malloc(s_BufferSize);
  if(s_Return)
  {
   if(vsnprintf(s_Return, s_BufferSize - 1, s_Format, s_VaArg) < s_BufferSize)
   {
    void *s_TempPtr = s_Return;
    s_Return = (void *)MZ_SDUP(s_TempPtr, strlen(s_TempPtr));
    free(s_TempPtr);     
    break;
   }
   else free(s_Return);
  }
  else break;
  s_Return = (void *)0;
  s_BufferSize += 256;
}while(s_BufferSize < 8192);
return(s_Return);
}

void *MZ_SPrintf(void *s_Format, ...)
{
void *s_Return;   
va_list s_VaArg;
va_start(s_VaArg, s_Format);
s_Return = MZ_VSPrintf(s_Format, s_VaArg);
va_end(s_VaArg);
return(s_Return);
}

static t_TAR *MZ_CreateTAR(void)
{
t_TAR *s_Return;
s_Return = (t_TAR *)malloc(sizeof(t_TAR));
if(s_Return)
{
  memset((void *)s_Return, 0, sizeof(t_TAR));
  s_Return->ErrorCode = E_TAR_ERROR_NONE;
  s_Return->ReadHandle = (-1);
  s_Return->WriteHandle = (-1);
}
return(s_Return);
}

static unsigned long MZ_GetTAR_Value(void *s_Ptr, int s_Size)
{
char *s_TempBuffer;
unsigned long s_Return = 0lu;
if(s_Ptr)
{
  if(*((char *)s_Ptr))
  {    
   s_TempBuffer = MZ_SDUP(s_Ptr, s_Size);
   if(s_TempBuffer)
   {
    sscanf(s_TempBuffer, "%li", &s_Return);
    free(s_TempBuffer);
   }
   else sscanf(s_Ptr, "%li", &s_Return);
  }
}
return(s_Return);
}

t_TAR *MZ_OpenTAR(char *s_TarName, unsigned long s_Flag)
{
t_TAR *s_Return = (t_TAR *)0;
t_TAR *s_Tar = MZ_CreateTAR();
if(s_Tar)
{
  s_Tar->Flag    = s_Flag;
  if(s_TarName)s_Tar->TarName = MZ_SDUP(s_TarName, strlen(s_TarName));
  if(s_Tar->TarName)
  {
   if(s_Flag & E_TAR_FLAG_EXTRACT)s_Tar->ReadHandle = open(s_Tar->TarName, O_RDONLY);
   if(s_Flag & E_TAR_FLAG_CREATE )s_Tar->WriteHandle = open(s_Tar->TarName, O_WRONLY | O_CREAT, 0664);
  }
  s_Return = s_Tar;   
}
else fprintf(stderr, "tar.c: MZ_OpenTAR - [ERROR] s_Tar is null !!!\n");
if(s_Return == (t_TAR *)0)s_Tar = MZ_CloseTAR(s_Tar);
return(s_Return);
}

t_TAR *MZ_CloseTAR(t_TAR *s_HANDLE_TAR)
{
if(s_HANDLE_TAR)
{
  t_TAR_List *s_PrevList;
  while(s_HANDLE_TAR->List)
  {
   s_PrevList = s_HANDLE_TAR->List;
   s_HANDLE_TAR->List = s_HANDLE_TAR->List->Next;
   if(s_PrevList->Name        )free(s_PrevList->Name);
   if(s_PrevList->LinkName    )free(s_PrevList->LinkName);
   if(s_PrevList->UName       )free(s_PrevList->UName);
   if(s_PrevList->GName       )free(s_PrevList->GName);
   free(s_PrevList);
  }
  if(s_HANDLE_TAR->ReadHandle >= 0)close(s_HANDLE_TAR->ReadHandle);
  if(s_HANDLE_TAR->WriteHandle >= 0)close(s_HANDLE_TAR->WriteHandle);
  if(s_HANDLE_TAR->TarName)free(s_HANDLE_TAR->TarName);
  free(s_HANDLE_TAR);
  s_HANDLE_TAR = (t_TAR *)0;
}   
return(s_HANDLE_TAR);
}

t_TAR *MZ_ListTAR(t_TAR *s_HANDLE_TAR)
{
if(s_HANDLE_TAR)
{
  if(s_HANDLE_TAR->TarName)
  {
   int s_Handle;
   s_Handle = s_HANDLE_TAR->ReadHandle;
   if(s_Handle < 0)s_Handle = open(s_HANDLE_TAR->TarName, O_RDONLY);
   if(s_Handle >= 0)
   {
    t_TAR_HEADER s_TAR_HEADER;
    int s_ReadSize;
    unsigned long long s_Position = (unsigned long long)0;
    char *s_LongName = (char *)0;
    char *s_LongLink = (char *)0;
    do
    {
     s_ReadSize = read(s_Handle, &s_TAR_HEADER, sizeof(t_TAR_HEADER));
     if(s_ReadSize == sizeof(t_TAR_HEADER))
     {
      s_Position += (unsigned long long)s_ReadSize;
      if(memcmp(&s_TAR_HEADER.Magic[0], DEF_TAR_MAGIC, strlen(DEF_TAR_MAGIC)) == 0)
      {
       unsigned long long s_Size = (unsigned long long)0, s_AlignSize = (unsigned long long)0;
       long s_CheckSum = 0;
       int s_Count;
       unsigned char *s_Ptr;
       s_Ptr = (unsigned char *)(&s_TAR_HEADER);
       for(s_Count = 0;s_Count < sizeof(t_TAR_HEADER);s_Count++)s_CheckSum += *(s_Ptr++);
       s_Ptr = (unsigned char *)(&s_TAR_HEADER.CheckSum[0]);
       for(s_Count = 0;s_Count < E_TAR_HEADER_SIZE_CHECKSUM;s_Count++)s_CheckSum -= *(s_Ptr++);
       s_CheckSum += ' ' * E_TAR_HEADER_SIZE_CHECKSUM;
       if(s_TAR_HEADER.Size[0])
       {
   char *s_TempBuffer;
        s_TempBuffer = MZ_SDUP(&s_TAR_HEADER.Size[0], E_TAR_HEADER_SIZE_SIZE);
        if(s_TempBuffer)
   {
    sscanf(s_TempBuffer, "%lli", &s_Size);     
         free(s_TempBuffer);
   }
   else
   {
    s_HANDLE_TAR->ErrorCode |= E_TAR_ERROR_MEMORY;   
    sscanf(&s_TAR_HEADER.Size[0], "%lli", &s_Size);     
   }
       }
       if(s_Size > (unsigned long long)0)
       {
        s_AlignSize = (s_Size + (unsigned long long)(DEF_TAR_BLOCK - 1)) / (unsigned long long)DEF_TAR_BLOCK;
   s_AlignSize *= (unsigned long long)DEF_TAR_BLOCK;
       }
       if(s_TAR_HEADER.TypeFlag[0] == E_TAR_TYPEFLAG_LONGNAME ||
          s_TAR_HEADER.TypeFlag[0] == E_TAR_TYPEFLAG_LONGLINK)
       {
   char *s_TempBuffer;
        if(s_LongName){free(s_LongName); s_LongName = (char *)0;}
        if(s_LongLink){free(s_LongLink); s_LongLink = (char *)0;}
   s_TempBuffer = malloc(s_AlignSize);
        if(s_TempBuffer)
   {
    if(s_AlignSize > (unsigned long long)0)s_ReadSize = read(s_Handle, s_TempBuffer, s_AlignSize);
    else s_ReadSize = 0;
    if(s_ReadSize == s_AlignSize)
    {
     if(s_TAR_HEADER.TypeFlag[0] == E_TAR_TYPEFLAG_LONGNAME)s_LongName = MZ_SDUP(s_TempBuffer, s_Size);
     else /* if(s_TAR_HEADER.TypeFlag[0] == E_TAR_TYPEFLAG_LONGLINK) */s_LongName = MZ_SDUP(s_TempBuffer, s_Size);
    }
    if(s_ReadSize > 0)s_Position += (unsigned long long)s_ReadSize;
    free(s_TempBuffer);   
    if(s_LongName || s_LongLink)continue;
    else
    {
          s_HANDLE_TAR->ErrorCode |= E_TAR_ERROR_INVALID_DATA;
          fprintf(stderr, "tar.c: MZ_ListTAR - [ERROR] Can not found long name or long link name !!!\n");
     break;
    }
   }
   else
   {
         s_HANDLE_TAR->ErrorCode |= E_TAR_ERROR_MEMORY;
         fprintf(stderr, "tar.c: MZ_ListTAR - [ERROR] s_TempBuffer is null !!!\n");
    break;
   }
       }
       else
       {       
        t_TAR_List *s_TarList;
        s_TarList = (t_TAR_List *)malloc(sizeof(t_TAR_List));
        if(s_TarList)
        {
    t_TAR_List *s_TraceList = s_HANDLE_TAR->List;   
         memset((void *)s_TarList, 0, sizeof(t_TAR_List));
    if(s_LongName)
    {
          s_TarList->Name = s_LongName;
          s_LongName = (char *)0;    
    }
    else if(s_TAR_HEADER.Name[0])s_TarList->Name = MZ_SDUP(&s_TAR_HEADER.Name[0], E_TAR_HEADER_SIZE_NAME);   
         s_TarList->Mode = (unsigned long)MZ_GetTAR_Value(&s_TAR_HEADER.Mode[0], E_TAR_HEADER_SIZE_MODE);
         s_TarList->UID = (uid_t)MZ_GetTAR_Value(&s_TAR_HEADER.UID[0], E_TAR_HEADER_SIZE_UID);
         s_TarList->GID = (uid_t)MZ_GetTAR_Value(&s_TAR_HEADER.GID[0], E_TAR_HEADER_SIZE_GID);
         s_TarList->Size = s_Size;
    s_TarList->MakeTime = MZ_GetTAR_Value(&s_TAR_HEADER.MakeTime[0], E_TAR_HEADER_SIZE_MAKETIME);
    s_TarList->CheckSum = MZ_GetTAR_Value(&s_TAR_HEADER.CheckSum[0], E_TAR_HEADER_SIZE_CHECKSUM);
    s_TarList->TypeFlag = (e_TAR_TYPEFLAG)s_TAR_HEADER.TypeFlag[0];
    if(s_LongLink)
    {
          s_TarList->LinkName = s_LongLink;
     s_LongLink = (char *)0;
    }
    else if(s_TAR_HEADER.LinkName[0])s_TarList->LinkName = MZ_SDUP(&s_TAR_HEADER.LinkName[0], E_TAR_HEADER_SIZE_LINKNAME);
    if(s_TAR_HEADER.UName[0])s_TarList->UName = MZ_SDUP(&s_TAR_HEADER.UName[0], E_TAR_HEADER_SIZE_UNAME);
    if(s_TAR_HEADER.GName[0])s_TarList->GName = MZ_SDUP(&s_TAR_HEADER.GName[0], E_TAR_HEADER_SIZE_GNAME);
    s_TarList->DevMajor = MZ_GetTAR_Value(&s_TAR_HEADER.DevMajor[0], E_TAR_HEADER_SIZE_DEVMAJOR);
    s_TarList->DevMinor = MZ_GetTAR_Value(&s_TAR_HEADER.DevMinor[0], E_TAR_HEADER_SIZE_DEVMINOR);
    s_TarList->Position = s_Position;
    if(s_CheckSum != s_TarList->CheckSum)
    {
          s_HANDLE_TAR->ErrorCode |= E_TAR_ERROR_INVALID_DATA;
     fprintf(stderr, "tar.c: MZ_ListTAR - [ERROR] Invalid checksum (0x%08lx != Compute_0x%08lx) !!!\n",
             s_TarList->CheckSum, s_CheckSum
       );
    }
    if(s_TraceList)
    {
          while(s_TraceList->Next)s_TraceList = s_TraceList->Next;
     s_TraceList->Next = s_TarList;
    }
    else s_HANDLE_TAR->List = s_TarList;
    lseek(s_Handle, (off_t)s_AlignSize, SEEK_CUR);
    s_Position += s_AlignSize;
   }
        else
        {
         s_HANDLE_TAR->ErrorCode |= E_TAR_ERROR_MEMORY;
         fprintf(stderr, "tar.c: MZ_ListTAR - [ERROR] s_TarList is null !!!\n");
         break;
        }
        if(s_LongName){free(s_LongName); s_LongName = (char *)0;}
        if(s_LongLink){free(s_LongLink); s_LongLink = (char *)0;}
       }
      }
     }
    }while(s_ReadSize > 0); 
    if(s_LongName)free(s_LongName);
    if(s_LongLink)free(s_LongLink);
    if(s_HANDLE_TAR->ReadHandle < 0)close(s_Handle);
   }
   else
   {
    s_HANDLE_TAR->ErrorCode |= E_TAR_ERROR_FOUND;
    fprintf(stderr, "tar.c: MZ_ListTAR - [ERROR] Can not open tar file \"%s\" !!!\n", s_HANDLE_TAR->TarName);
   }   
  }
  else
  {
   s_HANDLE_TAR->ErrorCode |= E_TAR_ERROR_INVALID_OPERATION;
   fprintf(stderr, "tar.c: MZ_ListTAR - [ERROR] s_HANDLE_TAR->TarName is null !!!\n");
  }
}
else fprintf(stderr, "tar.c: MZ_ListTAR - [ERROR] s_HANDLE_TAR is null !!!\n");
return(s_HANDLE_TAR);
}

void MZ_PermissionTAR(t_TAR_List *s_TarList)
{
struct utimbuf s_UTimeBuf;   
chown(s_TarList->Name, s_TarList->UID, s_TarList->GID);
chmod(s_TarList->Name, s_TarList->Mode);
s_UTimeBuf.actime  = time((time_t *)0);
s_UTimeBuf.modtime = s_TarList->MakeTime;
utime(s_TarList->Name, &s_UTimeBuf);
}

unsigned long MZ_DoTAR(t_TAR *s_Tar, t_TAR_List *s_TarList, unsigned long s_Flag)
{
unsigned long s_Return = E_TAR_ERROR_NONE;
if(s_TarList)
{
  char *s_TypeString;
  switch(s_TarList->TypeFlag)
  {
   case E_TAR_TYPEFLAG_REGULAR:
   case E_TAR_TYPEFLAG_REGULAR_BUG:
        if(s_TarList->TypeFlag == E_TAR_TYPEFLAG_REGULAR_BUG)s_TypeString = "Regular (Ancient bug compat)";   
   else s_TypeString = "Regular";   
   if(s_Flag & E_TAR_FLAG_EXTRACT)
   {
    if(s_Tar->ReadHandle >= 0)
    {   
          if(lseek(s_Tar->ReadHandle, (off_t)s_TarList->Position, SEEK_SET) == (off_t)s_TarList->Position)
     {
           if(s_Tar->WriteHandle >= 0)close(s_Tar->WriteHandle);
      unlink(s_TarList->Name);   
      s_Tar->WriteHandle = open(s_TarList->Name, O_WRONLY | O_CREAT | O_TRUNC, s_TarList->Mode & (~S_IFMT));
           if(s_Tar->WriteHandle >= 0)
      {
            unsigned long long s_Size;
            int s_BlockSize, s_ReadSize, s_WriteSize;
       unsigned char s_Buffer[32 << 10];
       s_Size = s_TarList->Size;
            while(s_Size > 0)
       {
        if(s_Size >= (unsigned long long)sizeof(s_Buffer))s_BlockSize = sizeof(s_Buffer);      
        else s_BlockSize = (int)s_Size;
        s_ReadSize = read(s_Tar->ReadHandle, &s_Buffer[0], s_BlockSize);
        if(s_ReadSize > 0)
        {
              s_Size -= (unsigned long long)s_ReadSize;
              s_WriteSize = write(s_Tar->WriteHandle, &s_Buffer[0], s_ReadSize);
              if(s_WriteSize == s_ReadSize)continue;
         else
         {
               s_Return |= E_TAR_ERROR_CREATE;           
               break;
         }
        }
        else
        {
              s_Return |= E_TAR_ERROR_CREATE;           
              break;
        }
        if(s_BlockSize < sizeof(s_Buffer))break;
       }      
            close(s_Tar->WriteHandle);
       s_Tar->WriteHandle = (-1);
       MZ_PermissionTAR(s_TarList);
      }
           else s_Return |= E_TAR_ERROR_PERMISSION;   
     }      
          else s_Return |= E_TAR_ERROR_PERMISSION;   
    }
         else s_Return |= E_TAR_ERROR_PERMISSION;   
   }
   break;
   case E_TAR_TYPEFLAG_LINK:
        s_TypeString = "Hard link";   
   if(s_Flag & E_TAR_FLAG_EXTRACT)
   {
    unlink(s_TarList->Name);   
    if(link(s_TarList->LinkName, s_TarList->Name) != 0)s_Return |= E_TAR_ERROR_CREATE;
    else MZ_PermissionTAR(s_TarList);
   }
   break;
   case E_TAR_TYPEFLAG_SYMLINK:
        s_TypeString = "Symbolic link";   
   if(s_Flag & E_TAR_FLAG_EXTRACT)
   {
    unlink(s_TarList->Name);   
    if(symlink(s_TarList->LinkName, s_TarList->Name) != 0)s_Return |= E_TAR_ERROR_CREATE;
    else lchown(s_TarList->Name, s_TarList->UID, s_TarList->GID);
   }
   break;
   case E_TAR_TYPEFLAG_CHARDEV:
        s_TypeString = "Char device";
        goto L_SpeacialCreate;
   case E_TAR_TYPEFLAG_BLOCKDEV:
        s_TypeString = "Block device";   
        goto L_SpeacialCreate;
   case E_TAR_TYPEFLAG_FIFO:
        s_TypeString = "FIFO";   
        L_SpeacialCreate:;
   if(s_Flag & E_TAR_FLAG_EXTRACT)
   {
         if(S_ISCHR(s_TarList->Mode) || S_ISBLK(s_TarList->Mode) || S_ISSOCK(s_TarList->Mode))
    {
     unlink(s_TarList->Name);   
          if(mknod(s_TarList->Name, s_TarList->Mode, makedev(s_TarList->DevMajor, s_TarList->DevMinor)) != 0)
     {
      if(errno != EEXIST)s_Return |= E_TAR_ERROR_PERMISSION;
     }
     MZ_PermissionTAR(s_TarList);
    }
    else if(S_ISFIFO(s_TarList->Mode))
    {
     unlink(s_TarList->Name);   
     if(mkfifo(s_TarList->Name, s_TarList->Mode) != 0)s_Return |= E_TAR_ERROR_PERMISSION;
     else MZ_PermissionTAR(s_TarList);
    }
         else s_Return |= E_TAR_ERROR_CREATE;   
   }
   break;
   case E_TAR_TYPEFLAG_DIRECTORY:
        s_TypeString = "Directory";   
   if(s_Flag & E_TAR_FLAG_EXTRACT)
   {
    if(MZ_MakeDirectory(s_TarList->Name, s_TarList->Mode) <= 0)s_Return |= E_TAR_ERROR_CREATE;
    else MZ_PermissionTAR(s_TarList);
   }
   break;
   case E_TAR_TYPEFLAG_RESERVED:
        s_TypeString = "Reserved";   
   if(s_Flag & E_TAR_FLAG_EXTRACT)
   {
   }
   break;
   case E_TAR_TYPEFLAG_LONGNAME:
        s_TypeString = "Long name";   
   if(s_Flag & E_TAR_FLAG_EXTRACT)
   {
   }
   break;
   case E_TAR_TYPEFLAG_LONGLINK:
        s_TypeString = "Long link";   
   if(s_Flag & E_TAR_FLAG_EXTRACT)
   {
   }
   break;
   default:
        s_TypeString = "Unknown";   
   if(s_Flag & E_TAR_FLAG_EXTRACT)
   {
   }
   break;
  }
  if(s_Flag & E_TAR_FLAG_VERBOSE)
  {
   char *s_Verbose0 = (char *)0;
   if(s_TarList->TypeFlag == E_TAR_TYPEFLAG_DIRECTORY)s_Verbose0 = MZ_SPrintf("");
   else if(s_TarList->TypeFlag == E_TAR_TYPEFLAG_CHARDEV || s_TarList->TypeFlag == E_TAR_TYPEFLAG_BLOCKDEV)
   {
    s_Verbose0 = MZ_SPrintf("Major %d, Minor %d", s_TarList->DevMajor, s_TarList->DevMinor);
   }
   else if(s_TarList->TypeFlag == E_TAR_TYPEFLAG_LINK || s_TarList->TypeFlag == E_TAR_TYPEFLAG_SYMLINK)
   {
    s_Verbose0 = MZ_SPrintf("\"%s\" ->", s_TarList->LinkName);
   }
   else s_Verbose0 = MZ_SPrintf("%12llu", s_TarList->Size);
   fprintf(stdout, "[%-13s] %12s \"%s\"\n",
           s_TypeString,         
      s_Verbose0 ? s_Verbose0 : "-",
           s_TarList->Name ? s_TarList->Name : ""
          );
   if(s_Verbose0)free(s_Verbose0);
  }
  else if(s_Flag & E_TAR_FLAG_LIST)
  {
   fprintf(stdout, "%s\n",
           s_TarList->Name ? s_TarList->Name : ""
          );
  }
}
else
{
  s_Return |= E_TAR_ERROR_INVALID_OPERATION;
  fprintf(stderr, "tar.c: MZ_ExtractTAR - [ERROR] s_TarList is null !!!\n");
}
return(s_Return);
}

int main(int s_Argc, char *s_Argv[])
{
int s_Return = (-1);

if(s_Argc > 1)
{
  t_TAR *s_Tar;
  t_TAR_List *s_TarList;
 
  s_Tar = MZ_OpenTAR(s_Argv[1], E_TAR_FLAG_EXTRACT | E_TAR_FLAG_VERBOSE | E_TAR_FLAG_LIST);
  if(s_Tar)
  {
   s_Tar = MZ_ListTAR(s_Tar);    
   s_TarList = s_Tar->List;
   while(s_TarList)
   {
    s_Tar->ErrorCode |= MZ_DoTAR(s_Tar, s_TarList, s_Tar->Flag);
    s_TarList = s_TarList->Next;
   }
   s_Tar = MZ_CloseTAR(s_Tar);
  }
  else fprintf(stderr, "Can not open tar \"%s\"\n", s_Argv[1]);
 
}
else fprintf(stdout, "Usage: mztar <tar>\n");

return(s_Return);
}

#endif

/* End of source */
2007/05/08 17:32 2007/05/08 17:32
받은 트랙백이 없고, 댓글이 없습니다.

댓글+트랙백 RSS :: http://blog.minzkn.com/rss/response/74

댓글+트랙백 ATOM :: http://blog.minzkn.com/atom/response/74

트랙백 주소 :: http://blog.minzkn.com/trackback/74

트랙백 RSS :: http://blog.minzkn.com/rss/trackback/74

트랙백 ATOM :: http://blog.minzkn.com/atom/trackback/74

댓글을 달아 주세요

댓글 RSS 주소 : http://blog.minzkn.com/rss/comment/74
댓글 ATOM 주소 : http://blog.minzkn.com/atom/comment/74