| 코드: |
|
/* 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 */ |
이것은 tar 파일을 푸는부분만 구현한것입니다.
받은 트랙백이 없고,
댓글이 없습니다.

글
댓글을 달아 주세요
댓글 RSS 주소 : http://blog.minzkn.com/rss/comment/74댓글 ATOM 주소 : http://blog.minzkn.com/atom/comment/74