Пример #1
0
/** Extract files stored in a tarball archive
 *
 * tarName: tarball's pathname
 *
 * On success, it returns EXIT_SUCCESS; upon error it returns EXIT_FAILURE. 
 * (macros defined in stdlib.h).
 *
 * HINTS: First load the tarball's header into memory.
 * After reading the header, the file position indicator will be located at the 
 * tarball's data section. By using information from the 
 * header --number of files and (file name, file size) pairs--, extract files 
 * stored in the data section of the tarball.
 *
 */
int
extractTar(char tarName[])
{
	FILE *tarFile, *outFile;
    int numFiles,i = 0;
    stHeaderEntry *header;

    if (!(tarFile = fopen(tarName, "r"))){
        //If we don't have read permission on the .tar file
        return (EXIT_FAILURE);
    }

    //Extracts the name, size and number of files from the .tar header.
    readHeader(tarFile, &header, &numFiles);

    for (; i<numFiles; i++){
        if (!(outFile = fopen(header[i].name, "w"))){
            //If we don't have write permission in the 'extracting' folder.
            return (EXIT_FAILURE);
        }
        copynFile(tarFile, outFile, header[i].size);
        fclose(outFile);

    }
    fclose(tarFile);
    free(header);
return (EXIT_SUCCESS);
}
Пример #2
0
int extractTarDirectory(char* tarName,char* directory) {
    
    char *filepath = malloc(strlen(directory) + 1 + strlen(tarName) + 2);
    filepath = strcpy(filepath, directory);
    filepath = strcat(filepath, "/");
    filepath = strcat(filepath, tarName);

    if(DEVELOPING == 1) printf("Filepath is %s \n", filepath);
 
    // First check if the directory exists.
    if (0 != access(directory, F_OK)) {
        if(DEVELOPING == 1) printf("Can't create file at %s\n", directory);
        return EXIT_FAILURE;
    }
    
    // At this point we know the directory exists.
    // So create a file

    if(DEVELOPING == 1) printf("Oh yes. The directory exists :-)\n");

    FILE *tarFile = NULL; // file manager
    stHeaderEntry *stHeader; // Array of structs for header
    int nr_files = 0, index = 0, copiedBytes = 0;

    if((tarFile = fopen(tarName, "r")) == NULL) {
        if(DEVELOPING == 1) printf("Yo! %s file doesn't exit \n", tarName);
        return (EXIT_FAILURE); // File doesn't exit or there was a problem
    }

    if (readHeader(tarFile, &stHeader, &nr_files) == -1) {
        if(DEVELOPING == 1) printf("We couldn't load the header \n");
        return (EXIT_FAILURE); 
    } // Returns in stHeader the array of struct (name/size) for each file and in nr_files the total num of files in the .mtar

    // Write the content to the outputFile

    for (index = 0; index < nr_files; index++) {
    
        char *destFilename = malloc(strlen(directory) + 1 + strlen(tarName) + 2);
        destFilename = strcpy(filepath, directory);
        destFilename = strcat(filepath, "/");
        destFilename = strcat(filepath, stHeader[index].name);
        
        FILE *destinationFile = NULL;

        if ((destinationFile = fopen(destFilename, "w")) == NULL) { return EXIT_FAILURE; } // Try to open the output file | return error if we couldn't create the file
        else {
            copiedBytes = copynFile(tarFile, destinationFile, stHeader[index].size); // Write nBytes to the output file (where nBytes is obtained when reading the .mtar header)        
            if (copiedBytes == -1) { return EXIT_FAILURE; }     
        }  // copied nBytes to output file
    
        if(fclose(destinationFile) != 0) { return EXIT_FAILURE; } // close the file
    }
    
    if (fclose(tarFile) == EOF) { return (EXIT_FAILURE); } // Try close file. Return an error if wasn't possible

    if (DEVELOPING == 1) printf("Yeah. Extract a directory\n");
    return 0;
}
Пример #3
0
/** Extract files stored in a tarball archive
 *
 * tarName: tarball's pathname
 *
 * On success, it returns EXIT_SUCCESS; upon error it returns EXIT_FAILURE. 
 * (macros defined in stdlib.h).
 *
 * HINTS: First load the tarball's header into memory.
 * After reading the header, the file position indicator will be located at the 
 * tarball's data section. By using information from the 
 * header --number of files and (file name, file size) pairs--, extract files 
 * stored in the data section of the tarball.
 *
 */
int
extractTar(char tarName[])
{ 
    FILE *tarFile = NULL; // file manager
    FILE *destinationFile = NULL;
    stHeaderEntry *stHeader; // Array of structs for header
    int nr_files = 0, index = 0, copiedBytes = 0;

    if((tarFile = fopen(tarName, "r") ) == NULL) {
        if(DEVELOPING == 1) printf("Yo! %s file doesn't exit \n", tarName);
        return (EXIT_FAILURE); // File doesn't exit or there was a problem
    }

    if (readHeader(tarFile, &stHeader, &nr_files) == -1) {
        if(DEVELOPING == 1) printf("We couldn't load the header \n");
        return (EXIT_FAILURE); 
    } // Returns in stHeader the array of struct (name/size) for each file and in nr_files the total num of files in the .mtar

    // Write the content to the outputFile

    for (index = 0; index < nr_files; index++) {

        if ((destinationFile = fopen(stHeader[index].name, "w")) == NULL) { return EXIT_FAILURE; } // Try to open the output file | return error if we couldn't create the file
        else {
            copiedBytes = copynFile(tarFile, destinationFile, stHeader[index].size); // Write nBytes to the output file (where nBytes is obtained when reading the .mtar header)        
        if (copiedBytes == -1) { return EXIT_FAILURE; }     
    }  // copied nBytes to output file
        
        if(fclose(destinationFile) != 0) { return EXIT_FAILURE; } // close the file
    }
    
    // DEBUG STUFF
    if(DEVELOPING == 1) {
        printf("Number of files is %d\n", nr_files);
        for (index = 0; index <nr_files;index++) {
            printf("File %s size is %d bytes\n", stHeader[index].name, stHeader[index].size);
        }
    }

    // FREE MEMORY

    for (index = 0; index <nr_files; index++) {
        free(stHeader[index].name);
    }

    free(stHeader); // Delete main struct
    if (fclose(tarFile) == EOF) { return (EXIT_FAILURE); } // Try close file. Return an error if wasn't possible

    return (EXIT_SUCCESS);
}
Пример #4
0
/** Extract files stored in a tarball archive
 *
 * tarName: tarball's pathname
 *
 * On success, it returns EXIT_SUCCESS; upon error it returns EXIT_FAILURE. 
 * (macros defined in stdlib.h).
 *
 * HINTS: First load the tarball's header into memory.
 * After reading the header, the file position indicator will be located at the 
 * tarball's data section. By using information from the 
 * header --number of files and (file name, file size) pairs--, extract files 
 * stored in the data section of the tarball.
 *
 */
int extractTar(char tarName[])
{
	if(!esTar(tarName)){ 
		printf("Incorrect file extension\n");
		return EXIT_FAILURE;
	}

	//COMPROBACION DE QUE EL ARCHIVO .mtar EXISTE

	FILE *tarFile, *f;
	if((tarFile = fopen(tarName,"r")) == NULL){ 
		printf("The file %s doesn't exist\n", tarName);	
		return EXIT_FAILURE;
	}

	int nFiles, i=0;
	stHeaderEntry *header;
	
	//OBTENCION DE LOS DATOS DE LA CABECERA

	readHeader(tarFile, &header, &nFiles); //Obtencion de la cabecera del archivo .mtar

	//CREACION Y COPIADO DEL CONTENIDO DEL ARCHIVO .mtar EN CADA UNO DE LOS ARCHIVOS CONTENIDOS

	for (i=0; i < nFiles; i++)
	{	
		f = fopen(header[i].name, "w");
		if((copynFile(tarFile, f, header[i].size)) != header[i].size){
			fclose(f);
			printf("The %s file has been copied incorrectly\n", header[i].name);	
			return EXIT_FAILURE;
		}

		fclose(f);
	}
	
	fclose(tarFile);
	return 0;
}
Пример #5
0
/** Creates a tarball archive 
 *
 * nfiles: number of files to be stored in the tarball
 * filenames: array with the path names of the files to be included in the tarball
 * tarname: name of the tarball archive
 * 
 * On success, it returns EXIT_SUCCESS; upon error it returns EXIT_FAILURE. 
 * (macros defined in stdlib.h).
 *
 * HINTS: First reserve room in the file to store the tarball header.
 * Move the file's position indicator to the data section (skip the header)
 * and dump the contents of the source files (one by one) in the tarball archive. 
 * At the same time, build the representation of the tarball header in memory.
 * Finally, rewind the file's position indicator, write the number of files as well as 
 * the (file name,file size) pairs in the tar archive.
 *
 * Important reminder: to calculate the room needed for the header, a simple sizeof 
 * of stHeaderEntry will not work. Bear in mind that, on disk, file names found in (name,size) 
 * pairs occupy strlen(name)+1 bytes.
 *
 */
int createTar(int nFiles, char *fileNames[], char tarName[])
{
	if(!esTar(tarName)){ 
		printf("Incorrect file extension\n");
		return EXIT_FAILURE;
	}

	FILE *tarFile = fopen(tarName,"w"), *f;
	stHeaderEntry *header = (stHeaderEntry*)malloc(nFiles * sizeof(stHeaderEntry));		// Reservamos espacio para las cabeceras
	int i;
	char caracter, *buffer;

	//COMPROBACION DE LA EXISTENCIA DE TODOS LOS ARCHIVOS

	for(i = 0; i < nFiles; i++){		//si alguno no se puede abrir ya no se ejecuta mas programa						
		if((f=fopen(fileNames[i], "r"))==NULL){							
			printf("The file %s doesn't exist\n", fileNames[i]); 
			return EXIT_FAILURE;
		}
		else
			fclose(f);
	}	
	
	//CREACION DEL HEADER

	for(i = 0; i < nFiles; i++){								//Rellenamos las cabeceras
		if((header[i].name = (char*)malloc(strlen(fileNames[i]))) == NULL)
			return EXIT_FAILURE; 	
		strcpy(header[i].name, fileNames[i]);					//Copiamos el valor de filenames a header[i]
	}




	//AVANZAR CURSOR HASTA DEJAR ESPACIO PARA EL HEADER

	fseek(tarFile, sizeof(int)+1, SEEK_SET); //Dejamos espacio para nFiles
	for(i = 0; i < nFiles; i++){ //Dejamos espacio para el nombre y el entero del tamaño
		fseek(tarFile, strlen(header[i].name)+1, SEEK_CUR); //+1 para el \0 del nombre
		fseek(tarFile, sizeof(int)+1, SEEK_CUR); //+1 para el \0 del tamanio
	}
	

	//EMPEZAMOS A ESCRIBIR LOS DATOS DE LOS FICHEROS
	
	for(i = 0; i < nFiles; i++){ 		
			
		FILE *fichero = fopen(header[i].name, "r"); 	
		
		fseek(fichero, 0, SEEK_END);		//Desplazamos el cursor hasta el final del fichero para obtener el numero de bytes del mismo
		header[i].size = ftell(fichero);	//Lo guardamos en la estructura de la cabecera y volvemos a poner el cursor al principio
		fseek(fichero, 0, SEEK_SET);
		
		if((copynFile(fichero, tarFile, header[i].size)) != header[i].size){ //Copiamos el contenido del archivo al mtar y si el tamaño 
			fclose(fichero);													//que devuelve no es igual al que tenia que haber copiado
			printf("The %s file has been copied incorrectly\n", header[i].name);//entonces devuelve error
			return EXIT_FAILURE;	
		}

		fclose(fichero);
	}
	//VOLVEMOS A PONER EL CURSOR AL COMIENZO

	rewind(tarFile);

	//ESCRIBIMOS EL HEADER

	fwrite(&nFiles, sizeof(int),1, tarFile);
	fputc('\0',tarFile);
	for(i = 0; i < nFiles; i++){ 
		fwrite(header[i].name, 1, strlen(header[i].name), tarFile);
		fputc('\0',tarFile);
		fwrite(&header[i].size, sizeof(int),1,  tarFile);
		fputc('\0',tarFile);
	}
	
	free(header);
	fclose(tarFile);

	return 0;
}
Пример #6
0
/** Creates a tarball archive 
 *
 * nfiles: number of files to be stored in the tarball
 * filenames: array with the path names of the files to be included in the tarball
 * tarname: name of the tarball archive
 * 
 * On success, it returns EXIT_SUCCESS; upon error it returns EXIT_FAILURE. 
 * (macros defined in stdlib.h).
 *
 * HINTS: First reserve room in the file to store the tarball header.
 * Move the file's position indicator to the data section (skip the header)
 * and dump the contents of the source files (one by one) in the tarball archive. 
 * At the same time, build the representation of the tarball header in memory.
 * Finally, rewind the file's position indicator, write the number of files as well as 
 * the (file name,file size) pairs in the tar archive.
 *
 * Important reminder: to calculate the room needed for the header, a simple sizeof 
 * of stHeaderEntry will not work. Bear in mind that, on disk, file names found in (name,size) 
 * pairs occupy strlen(name)+1 bytes.
 *
 */
int
createTar(int nFiles, char *fileNames[], char tarName[])
{
	FILE *tarFile, *inFile;
    int headerSize = sizeof(int);
    stHeaderEntry *header;

    if (nFiles <=0){
        //This shouldn't happen, but we never know.
	   return (EXIT_FAILURE);
    }

    if (!(tarFile = fopen(tarName, "w"))){
        //If we try to execute from a folder with read only permissions.
        return (EXIT_FAILURE);
    }

    if (!(header = malloc(sizeof(stHeaderEntry)*nFiles))){
        //If we can't allocate memory we fail.
        fclose(tarFile);
        remove(tarName);
        return(EXIT_FAILURE);
    }

    int i = 0;
    //We calculate how much memory we need for the header
    for(; i<nFiles; i++){
        headerSize += sizeof(unsigned int);
        headerSize += sizeof(char)*((strlen(fileNames[i]))+1);
    }

    fseek(tarFile, headerSize, SEEK_SET); //Open the tarFile after the header
    
    i=0;
    for (; i<nFiles; i++){
        /**
         * We dump every file's name, size (calculated with the
         * reading pointer) into our allocated header, and the 
         * content from the the original file into the .tar.
         */
        if ((inFile = fopen(fileNames[i], "r+"))==NULL){
        	fclose(tarFile);
            remove(tarName);
            return(EXIT_FAILURE);
        }
        header[i].name = fileNames[i];
        fseek(inFile, 0L, SEEK_END);
        header[i].size = ftell(inFile);
        fseek(inFile, 0L, SEEK_SET);
        copynFile(inFile,tarFile,header[i].size);
    }

    //The number of files is written at the start of the file
    fseek(tarFile, 0L, SEEK_SET);
    fwrite(&nFiles, sizeof(int), 1, tarFile);

    i=0;
    for(; i<nFiles; i++){
        /**
         * Lastly, the headear is copied into the file, following
         * the number of files, and before the actual files.
         */
        fwrite(header[i].name, strlen(fileNames[i])+1, 1, tarFile);
        fwrite(&header[i].size, sizeof(unsigned int), 1, tarFile);
    }
    fclose(tarFile);
    free(header);
    return(EXIT_SUCCESS);
}
Пример #7
0
int
createTar(int nFiles, char *fileNames[], char tarName[])
{
    FILE * inputFile; // Used for reading each .txt file
    FILE * outputFile; // Used for writing in the output file.

    int copiedBytes = 0, stHeaderBytes = 0, index = 0;
    stHeaderEntry *stHeader; // Pointer to the program header struct.

    // Create a stHeader in the heap with the correct size

    stHeader      =  malloc(sizeof(stHeaderEntry) * nFiles); // Allocate memory for an array of stHeader Structs
    stHeaderBytes += sizeof(int); // One integer for the number of files (written at the beginning of the file)
    stHeaderBytes += nFiles*sizeof(unsigned int); // other int for each struct to store the bytes (aka size) of the file

    for (index=0; index < nFiles; index++) {
        stHeaderBytes+=strlen(fileNames[index])+1; // Sum the bytes for each filename (+1 for the '\0' character)
    }

    outputFile =  fopen(tarName, "w"); // Open the name.mtar file for writing the header and data of the files.
    fseek(outputFile, stHeaderBytes, SEEK_SET); // Move Outputfile pointer to the "data" section (leaving space for the header we'll write at the end of this function)

    for (index=0; index < nFiles; index++) {

        if ((inputFile = fopen(fileNames[index], "r")) == NULL) {
            if(DEVELOPING == 1) printf("Yo! File: %s doesn't exist\n", fileNames[index]);
            return (EXIT_FAILURE);
        } // Try to open the file. EXIT_FAILURE will be returned if errors

        copiedBytes = copynFile(inputFile, outputFile, INT_MAX); // Copy N bytes to the output file (INT_MAX == huge number to ensure you copy all the character)
    
    if (copiedBytes == -1) {
        if (DEVELOPING == 1) printf("Copied bytes in the create tar is: %d\n", copiedBytes);        
        return EXIT_FAILURE;    
    }
    else {
            stHeader[index].size = copiedBytes; // Set the size from the copiedBytes for each struct.
            stHeader[index].name = malloc(sizeof(fileNames[index]) + 1); // Heap space for the name char + '\0' character
            strcpy(stHeader[index].name, fileNames[index]); // Copy one string to the struct entry
        if (DEVELOPING == 1) printf("File %s size is %d bytes\n", stHeader[index].name, stHeader[index].size);  
    }        
    
    if (fclose(inputFile) == EOF) return EXIT_FAILURE; // Wasn't possible to close the file. Return and error
    }
     
    // Now move the file pointer to the beggining of the file in order to write: number of files + the header for each file

    if (fseek(outputFile, 0, SEEK_SET) != 0)
        return (EXIT_FAILURE); // wasn't possible to move the pointer to the beginning of the file. Returns and error
    else
        fwrite(&nFiles, sizeof(int), 1, outputFile); // write Number of Files in the output .tar
    
    // Write header for each struct
    // Documentation: http://www.tutorialspoint.com/c_standard_library/c_function_fwrite.htm

    for (index = 0; index < nFiles; index++) {
        fwrite(stHeader[index].name, strlen(stHeader[index].name)+1, 1, outputFile); // Important add one when saving the length for the name (for the '\0' character)
        fwrite(&stHeader[index].size, sizeof(unsigned int), 1, outputFile); // Write one byte 
        // printf("%d\n", stHeader[index].size);
    }

    // FREE MEMORY. First, delete the char *names pointer.
    // Then erase all the structs.
    
    for (index=0; index < nFiles; index++) {
        free(stHeader[index].name); // Free the filenames array of characters
    }

    free(stHeader); // Free the struct created in heap

    if (fclose(outputFile) == EOF) { return (EXIT_FAILURE); } // Try close file. Return an error if wasn't possible

    printf("mtar file created successfully\n");

    return (EXIT_SUCCESS);
}