#include "tarutil.h"
#include "defines.h"
#include <stdlib.h>
#include <stdio.h>
#include <zlib.h>
#include <math.h>
#include <tar.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <dirent.h>
#include <sys/stat.h>
#include <sys/types.h>
typedef struct stTarType {
char name[100];
char mode[8];
char uid[8];
char gid[8];
char size[12];
char mtime[12];
char chksum[8];
unsigned char typeflag;
char linkname[100];
char magic[6];
char version[2];
char uname[32];
char gname[32];
char devmajor[8];
char devminor[8];
char prefix[155];
} stTarUtil;
long decToOct(char *octValue)
{
int i;
long retValue=0;
char tempChar[2];
tempChar[1]='\0';
for (i=strlen(octValue)-1;i>=0;i--) {
tempChar[0]=octValue[i];
retValue+=(atoi(tempChar))*pow(8,strlen(octValue)-1-i);
}
return ((long)retValue);
}
TarFileList *getFileList(char *filename)
{
gzFile gfd;
int numread;
char hdrbuf[512];
long filesize;
stTarUtil *header;
TarFileList *first,*current,*tempname;
char tsize[13];
first=current=NULL;
gfd=gzopen(filename,"rb");
if (gfd==NULL) return NULL;
while ((numread=gzread(gfd,hdrbuf,sizeof(hdrbuf)))>0) {
header=(stTarUtil *)&hdrbuf;
memset(tsize,'\0',sizeof(tsize));
strncpy(tsize,header->size,11);
filesize=decToOct(tsize);
gzseek(gfd,filesize,SEEK_CUR);
if (filesize>0) gzseek(gfd,512 - (filesize % 512),SEEK_CUR);
if (header->name[0]=='\0') {
break;
} else {
tempname=(TarFileList *)malloc(sizeof(TarFileList));
if (tempname==NULL) {
printf("Error allocating memory\n");
exit (-1);
}
strncpy(tempname->filename,header->name,100);
tempname->next=NULL;
if (first==NULL) first=tempname;
else current->next=tempname;
current=tempname;
}
}
gzclose(gfd);
return(first);
}
/*********************************************************************
** checkDirectory() **
**------------------------------------------------------------------**
** This function handles checking the directory portion of a **
** filename to see if the directory exists or not. **
**------------------------------------------------------------------**
** Parameters: **
** The full filename of the file to check **
**------------------------------------------------------------------**
** Returns: **
** 0 on success **
** -1 on error **
*********************************************************************/
int checkDirectory(char *fullName)
{
char pathName[PATH_MAX];
char *lastSlash;
int error;
DIR *dir;
strncpy(pathName,fullName,PATH_MAX);
lastSlash=strrchr(pathName,'/');
if (lastSlash!=NULL) *lastSlash='\0';
dir=opendir(pathName);
if (dir==NULL) return -1;
closedir(dir);
return 0;
}
/*********************************************************************
** createDirectory() **
**------------------------------------------------------------------**
** This function handles creating a directory, by checking up the **
** list of directories and trying to create each one that doesn't **
** exist. **
**------------------------------------------------------------------**
** Parameters: **
** The full path of the directory to be created **
**------------------------------------------------------------------**
** Returns: **
** 0 on success **
** -1 on error **
*********************************************************************/
int createDirectory(char *fullPath)
{
int error;
char pathName[PATH_MAX];
char currPath[PATH_MAX];
int count;
/* First we'll just try creating the full directory */
error=mkdir(fullPath,0777);
/* If it works then we'll just return success */
if (error==0) return (0);
return -1;
/* strncpy(pathName,fullPath,PATH_MAX);
while ((pathName[count]!='\0')&&(count<PATH_MAX)) {
if (pathName[count]=='/') {
strncpy(currPath,pathName,count);
printf("%s\n",currPath);
}
count++;
}*/
return 0;
}
int untar(char *filename,char *destdir)
{
gzFile gfd;
int numread;
char hdrbuf[512];
long filesize;
stTarUtil *header;
char tsize[13];
char fullName[PATH_MAX];
char pathName[PATH_MAX];
char *pathPtr;
char *buffer=NULL;
FILE *fout;
int error;
gfd=gzopen(filename,"rb");
if (gfd==NULL) return;
while ((numread=gzread(gfd,hdrbuf,sizeof(hdrbuf)))!=0) {
header=(stTarUtil *)&hdrbuf;
memset(tsize,'\0',sizeof(tsize));
strncpy(tsize,header->size,11);
filesize=decToOct(tsize);
if (header->name[0]=='\0') break;
else {
if (header->typeflag==DIRTYPE) {
snprintf(fullName,PATH_MAX,"%s%s",destdir,header->name);
error=checkDirectory(fullName);
if (error==-1) {
error=createDirectory(fullName);
if (error==-1) {
snprintf(tarError,1024,"Unable to create directory\n%s",fullName);
gzclose(gfd);
return (-1);
}
}
} else {
if (buffer) free(buffer);
buffer=(char *)malloc(filesize);
if (buffer!=NULL) {
snprintf(fullName,PATH_MAX,"%s%s",destdir,header->name);
error=checkDirectory(fullName);
if (error) {
strncpy(pathName,fullName,PATH_MAX);
pathPtr=strrchr(pathName,'/');
if (pathPtr!=NULL) {
*pathPtr='\0';
}
error=createDirectory(pathName);
if (error) {
snprintf(tarError,1024,"Unable to create directory\n%s",pathName);
gzclose(gfd);
return -1;
}
}
fout=fopen(fullName,"w");
if (fout==NULL) {
snprintf(tarError,1024,"Unable to open output file\n%s",fullName);
gzclose(gfd);
return -1;
}
gzread(gfd,buffer,filesize);
fwrite(buffer,filesize,1,fout);
fclose(fout);
}
}
if (filesize>0) gzseek(gfd,512-filesize%512,SEEK_CUR);
}
}
if (buffer) free(buffer);
gzclose(gfd);
return 0;
}
syntax highlighted by Code2HTML, v. 0.9.1