first commit
This commit is contained in:
		
						commit
						a6dac2e2dc
					
				| 
						 | 
				
			
			@ -0,0 +1,9 @@
 | 
			
		|||
all: ctar utar dump
 | 
			
		||||
 | 
			
		||||
ctar: ctar.c; gcc -o ctar ctar.c
 | 
			
		||||
 | 
			
		||||
utar: utar.c; gcc -o utar utar.c
 | 
			
		||||
 | 
			
		||||
dump: dumparchiveheader.c; gcc -o dump dumparchiveheader.c
 | 
			
		||||
 | 
			
		||||
clean:; rm -f ctar ; rm -f utar ; rm -f dump
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,3 @@
 | 
			
		|||
A simple `tar` and `untar` program
 | 
			
		||||
 | 
			
		||||
Also includes a `dump` program to check if the archive header is valid
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,549 @@
 | 
			
		|||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <sys/uio.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <fcntl.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
 | 
			
		||||
#include "tar.h"
 | 
			
		||||
 | 
			
		||||
int archiveexists(char *fname);
 | 
			
		||||
 | 
			
		||||
int last_header_pointer;
 | 
			
		||||
 | 
			
		||||
hdr head = {0x63746172,  // head header for rewriting eop pointer
 | 
			
		||||
			sizeof(head),
 | 
			
		||||
			0,
 | 
			
		||||
			{0, 0, 0, 0, 0, 0, 0, 0},
 | 
			
		||||
			{0, 0, 0, 0, 0, 0, 0, 0},
 | 
			
		||||
			{0, 0, 0, 0, 0, 0, 0, 0},
 | 
			
		||||
			-1};
 | 
			
		||||
 | 
			
		||||
hdr empty = {0x63746172, // empty header for copying
 | 
			
		||||
			 sizeof(empty),
 | 
			
		||||
			 0,
 | 
			
		||||
			 {0, 0, 0, 0, 0, 0, 0, 0},
 | 
			
		||||
			 {0, 0, 0, 0, 0, 0, 0, 0},
 | 
			
		||||
			 {0, 0, 0, 0, 0, 0, 0, 0},
 | 
			
		||||
			 -1}; 
 | 
			
		||||
 | 
			
		||||
int main(int argc, char *argv[])
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
	if (argc < 2)
 | 
			
		||||
	{ // check to see if inputs exist
 | 
			
		||||
		fprintf(stderr, "%s [No Input]:\n Usage: ctar (-a | -d) <archive file name> <file name> \n", strerror(5));
 | 
			
		||||
		exit(EXIT_FAILURE);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	char *f = argv[1];			  // read the flag
 | 
			
		||||
	char *archivename = argv[2];  // name of archive
 | 
			
		||||
	int numberoffiles = argc - 3; // number of files to process
 | 
			
		||||
	char buffer[300];			  // character buffer for sprintf
 | 
			
		||||
	int i, j, k, x;				  // loop counters
 | 
			
		||||
	int r;						  // read pointer
 | 
			
		||||
	int w;						  // write pointer
 | 
			
		||||
	int fp;						  // file pointer
 | 
			
		||||
	char *current_file;
 | 
			
		||||
	int Current_EOP;
 | 
			
		||||
 | 
			
		||||
	if (argc < 3 && strcmp(argv[1], "-a") == 0)
 | 
			
		||||
	{ // check to see if arguments are correct for flag -a
 | 
			
		||||
		fprintf(stderr, "%s:\n	Usage: ctar -a <archive file name> file1, file2, ... filen\n", strerror(5));
 | 
			
		||||
		exit(EXIT_FAILURE);
 | 
			
		||||
	}
 | 
			
		||||
	else if (argc != 4 && strcmp(argv[1], "-d") == 0)
 | 
			
		||||
	{ // check to see if arguments are correct for flag -d
 | 
			
		||||
		fprintf(stderr, "%s:\n	Usage: ctar -d <archive file name> <file name>\n", strerror(5));
 | 
			
		||||
		exit(EXIT_FAILURE);
 | 
			
		||||
	}
 | 
			
		||||
	else if (strcmp(argv[1], "-a") != 0 && strcmp(argv[1], "-d") != 0)
 | 
			
		||||
	{ // check to see if the user has a valid flag
 | 
			
		||||
		fprintf(stderr, "%s [Unknown Flag]:\n	Usage: ctar (-a | -d) <archive file name> <file name>\n", strerror(5));
 | 
			
		||||
		exit(EXIT_FAILURE);
 | 
			
		||||
	}
 | 
			
		||||
#ifdef DEBUG
 | 
			
		||||
	printf("numberoffiles = %d\n", numberoffiles);
 | 
			
		||||
#endif
 | 
			
		||||
	if (archiveexists(archivename) == 0)
 | 
			
		||||
	{													// if file does not exist
 | 
			
		||||
		fp = open(archivename, O_RDWR | O_CREAT, 0644); // opens file; creates it if it does not exist;
 | 
			
		||||
 | 
			
		||||
		if (strcmp(argv[1], "-a") == 0)
 | 
			
		||||
		{
 | 
			
		||||
#ifdef DEBUG
 | 
			
		||||
			sprintf(buffer, "case -a (file doesn't exist)\n");
 | 
			
		||||
			write(1, buffer, strlen(buffer));
 | 
			
		||||
#endif
 | 
			
		||||
			if (numberoffiles == 0)
 | 
			
		||||
			{ // create an empty archive file
 | 
			
		||||
				w = write(fp, (char *)&head, sizeof(head));
 | 
			
		||||
				if (w < 0)
 | 
			
		||||
				{
 | 
			
		||||
					fprintf(stderr, "%s\n", strerror(5));
 | 
			
		||||
					exit(EXIT_FAILURE);
 | 
			
		||||
				}
 | 
			
		||||
				close(fp);
 | 
			
		||||
				return EXIT_SUCCESS;
 | 
			
		||||
			}
 | 
			
		||||
			else
 | 
			
		||||
			{ // create an archive file with content
 | 
			
		||||
#ifdef DEBUG
 | 
			
		||||
				sprintf(buffer, "create an archive with content\n");
 | 
			
		||||
				write(1, buffer, strlen(buffer));
 | 
			
		||||
#endif
 | 
			
		||||
				int numberofheaders = (numberoffiles / 8) + 1; // calculate the number of headers
 | 
			
		||||
				hdr temp;
 | 
			
		||||
				int temp_sizeof_file;
 | 
			
		||||
				int temp_file_pointer;
 | 
			
		||||
				int temp_file_read;
 | 
			
		||||
				int temp_filename_pointer;
 | 
			
		||||
				int argv_pointer;
 | 
			
		||||
				int temp_header_pointer = 0;
 | 
			
		||||
				char byte;
 | 
			
		||||
				short int char_len_buf;
 | 
			
		||||
 | 
			
		||||
				// First write empty header to archive
 | 
			
		||||
				lseek(fp, 0, SEEK_SET);
 | 
			
		||||
				w = write(fp, (char *)&head, sizeof(head));
 | 
			
		||||
				Current_EOP = sizeof(empty);
 | 
			
		||||
 | 
			
		||||
				for (i = 0; i < numberofheaders; i++)
 | 
			
		||||
				{ // iterate through all headers
 | 
			
		||||
#ifdef DEBUG
 | 
			
		||||
					printf("ITERATION:%i\n", i);
 | 
			
		||||
#endif
 | 
			
		||||
					temp = empty;			// sets the temp header to an empty hdr
 | 
			
		||||
					head.eop = Current_EOP; // write the eop to the head node
 | 
			
		||||
					for (j = 1; j <= 8; j++)
 | 
			
		||||
					{ // reads 8 files at a time
 | 
			
		||||
						argv_pointer = (j + (i * 8)) + 2;
 | 
			
		||||
						if (argv_pointer - 2 > numberoffiles)
 | 
			
		||||
						{
 | 
			
		||||
#ifdef DEBUG
 | 
			
		||||
							sprintf(buffer, "makes sure that the parser ends when the last file is read [file:%d]\n", argv_pointer - 2);
 | 
			
		||||
							write(1, buffer, strlen(buffer));
 | 
			
		||||
#endif
 | 
			
		||||
							close(fp);
 | 
			
		||||
							return EXIT_SUCCESS; // makes sure that the parser ends when the last file is read
 | 
			
		||||
						}
 | 
			
		||||
 | 
			
		||||
						if (i > 0)
 | 
			
		||||
						{
 | 
			
		||||
#ifdef DEBUG
 | 
			
		||||
							printf("write new header : [header %i]\n", temp_header_pointer);
 | 
			
		||||
#endif
 | 
			
		||||
							lseek(fp, temp_header_pointer, SEEK_SET);
 | 
			
		||||
							w = write(fp, (char *)&temp, sizeof(temp));
 | 
			
		||||
						}
 | 
			
		||||
 | 
			
		||||
						current_file = argv[argv_pointer];
 | 
			
		||||
 | 
			
		||||
						temp_file_pointer = open(current_file, O_RDWR, 0644); // opens file;
 | 
			
		||||
 | 
			
		||||
						if (temp_file_pointer < 0)
 | 
			
		||||
						{
 | 
			
		||||
							fprintf(stderr, "%s\n", strerror(5));
 | 
			
		||||
							exit(EXIT_FAILURE);
 | 
			
		||||
						}
 | 
			
		||||
 | 
			
		||||
						temp_sizeof_file = 0; // reset file size counter
 | 
			
		||||
 | 
			
		||||
						// Create Filename, Write to archive
 | 
			
		||||
						Current_EOP = lseek(fp, 0, SEEK_END);
 | 
			
		||||
						temp_filename_pointer = Current_EOP;
 | 
			
		||||
						char_len_buf = strlen(argv[argv_pointer]);
 | 
			
		||||
						write(fp, (char *)&char_len_buf, sizeof(char_len_buf)); // write size
 | 
			
		||||
						Current_EOP = lseek(fp, 0, SEEK_END);
 | 
			
		||||
#ifdef DEBUG
 | 
			
		||||
						sprintf(buffer, "file_name_size written to archive [file:%d]\n", argv_pointer - 2);
 | 
			
		||||
						write(1, buffer, strlen(buffer));
 | 
			
		||||
#endif
 | 
			
		||||
						write(fp, argv[argv_pointer], char_len_buf * sizeof(char)); // write title
 | 
			
		||||
						Current_EOP = lseek(fp, 0, SEEK_END);
 | 
			
		||||
 | 
			
		||||
						// Write file to archive
 | 
			
		||||
						temp_file_read = read(temp_file_pointer, &byte, sizeof(byte)); // read first byte
 | 
			
		||||
						Current_EOP = lseek(fp, 0, SEEK_END);
 | 
			
		||||
						temp_sizeof_file += sizeof(byte); // increment the size of file
 | 
			
		||||
						write(fp, &byte, sizeof(byte));	  // write first byte
 | 
			
		||||
#ifdef DEBUG
 | 
			
		||||
						sprintf(buffer, "Read first byte [file:%d]\n", argv_pointer - 2);
 | 
			
		||||
						write(1, buffer, strlen(buffer));
 | 
			
		||||
#endif
 | 
			
		||||
						int k = 1;
 | 
			
		||||
 | 
			
		||||
						while (temp_file_read > 0)
 | 
			
		||||
						{																   // iterate until it reaches end of file
 | 
			
		||||
							temp_file_read = read(temp_file_pointer, &byte, sizeof(byte)); // read all next bytes
 | 
			
		||||
							if (temp_file_read < 1)
 | 
			
		||||
							{
 | 
			
		||||
								break; // breaks to make sure the last byte isnt written twice
 | 
			
		||||
							}
 | 
			
		||||
 | 
			
		||||
							Current_EOP = lseek(fp, 0, SEEK_END);
 | 
			
		||||
							temp_sizeof_file += sizeof(byte); // increment the size of file
 | 
			
		||||
#ifdef DEBUG
 | 
			
		||||
							sprintf(buffer, "Read %d-th byte [file:%d]\n", k, argv_pointer - 2);
 | 
			
		||||
							write(1, buffer, strlen(buffer));
 | 
			
		||||
#endif
 | 
			
		||||
							write(fp, &byte, sizeof(byte)); // write following byte(s)
 | 
			
		||||
#ifdef DEBUG
 | 
			
		||||
							sprintf(buffer, "wrote %d-th byte [file:%d]\n", k, argv_pointer - 2);
 | 
			
		||||
							write(1, buffer, strlen(buffer));
 | 
			
		||||
#endif
 | 
			
		||||
							k++;
 | 
			
		||||
						}
 | 
			
		||||
#ifdef DEBUG
 | 
			
		||||
						sprintf(buffer, "file written to archive [file:%d]\n", argv_pointer - 2);
 | 
			
		||||
						write(1, buffer, strlen(buffer));
 | 
			
		||||
#endif
 | 
			
		||||
						Current_EOP = lseek(fp, 0, SEEK_END);
 | 
			
		||||
						head.eop = Current_EOP;
 | 
			
		||||
 | 
			
		||||
						lseek(fp, 0, SEEK_SET);
 | 
			
		||||
						w = write(fp, (char *)&head, sizeof(head));
 | 
			
		||||
#ifdef DEBUG
 | 
			
		||||
						sprintf(buffer, "first header rewritten [file:%d]\n", argv_pointer - 2);
 | 
			
		||||
						write(1, buffer, strlen(buffer));
 | 
			
		||||
 | 
			
		||||
						sprintf(buffer, "filename is: %s, written to archive [file:%d]\n", argv[argv_pointer], argv_pointer - 2);
 | 
			
		||||
						write(1, buffer, strlen(buffer));
 | 
			
		||||
#endif
 | 
			
		||||
						if (i < 1)
 | 
			
		||||
						{
 | 
			
		||||
							head.block_count = (head.block_count + 1);
 | 
			
		||||
							head.file_size[j - 1] = temp_sizeof_file;
 | 
			
		||||
							head.file_name[j - 1] = temp_filename_pointer;
 | 
			
		||||
						}
 | 
			
		||||
						else
 | 
			
		||||
						{
 | 
			
		||||
							temp.block_count = (temp.block_count + 1);
 | 
			
		||||
							temp.file_size[j - 1] = temp_sizeof_file;
 | 
			
		||||
							temp.file_name[j - 1] = temp_filename_pointer;
 | 
			
		||||
						}
 | 
			
		||||
#ifdef DEBUG
 | 
			
		||||
						sprintf(buffer, "starting writing file to archive [file:%d]\n", argv_pointer - 2);
 | 
			
		||||
						write(1, buffer, strlen(buffer));
 | 
			
		||||
#endif
 | 
			
		||||
						if (w < 0)
 | 
			
		||||
						{
 | 
			
		||||
							fprintf(stderr, "%s\n", strerror(5));
 | 
			
		||||
							exit(EXIT_FAILURE);
 | 
			
		||||
						}
 | 
			
		||||
 | 
			
		||||
						if (i > 0)
 | 
			
		||||
						{
 | 
			
		||||
#ifdef DEBUG
 | 
			
		||||
							printf("write header %i data\n", i);
 | 
			
		||||
#endif
 | 
			
		||||
							lseek(fp, temp_header_pointer, SEEK_SET);
 | 
			
		||||
							w = write(fp, (char *)&temp, sizeof(temp));
 | 
			
		||||
 | 
			
		||||
							if (w < 0)
 | 
			
		||||
							{
 | 
			
		||||
								fprintf(stderr, "%s\n", strerror(5));
 | 
			
		||||
								exit(EXIT_FAILURE);
 | 
			
		||||
							}
 | 
			
		||||
						}
 | 
			
		||||
						else
 | 
			
		||||
						{
 | 
			
		||||
#ifdef DEBUG
 | 
			
		||||
							printf("write header %i data\n", i);
 | 
			
		||||
#endif
 | 
			
		||||
							lseek(fp, 0, SEEK_SET);
 | 
			
		||||
							w = write(fp, (char *)&head, sizeof(head));
 | 
			
		||||
 | 
			
		||||
							if (w < 0)
 | 
			
		||||
							{
 | 
			
		||||
								fprintf(stderr, "%s\n", strerror(5));
 | 
			
		||||
								exit(EXIT_FAILURE);
 | 
			
		||||
							}
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
					if (i < 1)
 | 
			
		||||
					{
 | 
			
		||||
						head.next = head.eop;
 | 
			
		||||
						temp_header_pointer = head.eop;
 | 
			
		||||
					}
 | 
			
		||||
					else
 | 
			
		||||
					{
 | 
			
		||||
						temp.next = head.eop;
 | 
			
		||||
						temp_header_pointer = head.eop;
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				close(fp);
 | 
			
		||||
				return EXIT_SUCCESS;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		close(fp);
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{										  // file already exist
 | 
			
		||||
		fp = open(archivename, O_RDWR, 0644); // opens file; creates it if it does not exist;
 | 
			
		||||
 | 
			
		||||
		if (strcmp(argv[1], "-a") == 0)
 | 
			
		||||
		{ // add file(s) to an archive that already exists
 | 
			
		||||
#ifdef DEBUG
 | 
			
		||||
			printf("case -a (file exists)\n");
 | 
			
		||||
#endif
 | 
			
		||||
			hdr header;
 | 
			
		||||
			int temp_sizeof_file;
 | 
			
		||||
			int temp_file_pointer;
 | 
			
		||||
			int temp_file_read;
 | 
			
		||||
			int temp_filename_pointer;
 | 
			
		||||
			char f_name[sizeof(short int)];
 | 
			
		||||
			short int l;
 | 
			
		||||
			int p = 0;
 | 
			
		||||
			int poi;
 | 
			
		||||
 | 
			
		||||
			lseek(fp, 0, SEEK_SET);
 | 
			
		||||
			r = read(fp, &header, sizeof(hdr)); // load first header
 | 
			
		||||
			if (r != sizeof(hdr))
 | 
			
		||||
			{
 | 
			
		||||
				fprintf(stderr, "%s: file is not the size of a header object", strerror(5));
 | 
			
		||||
				exit(EXIT_FAILURE);
 | 
			
		||||
			}
 | 
			
		||||
			else if (header.magic != 0x63746172)
 | 
			
		||||
			{
 | 
			
		||||
				fprintf(stderr, "%s: header does not include the magic number", strerror(5));
 | 
			
		||||
				exit(EXIT_FAILURE);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			char byte;
 | 
			
		||||
			int char_len_buf;
 | 
			
		||||
			int not_finished_reading;
 | 
			
		||||
			int temp_header_pointer = 0;
 | 
			
		||||
			int number_of_headers;
 | 
			
		||||
			k = 0;
 | 
			
		||||
 | 
			
		||||
			while (k < argc - 3)
 | 
			
		||||
			{
 | 
			
		||||
				not_finished_reading = true;
 | 
			
		||||
				number_of_headers = 1;
 | 
			
		||||
				while (not_finished_reading)
 | 
			
		||||
				{
 | 
			
		||||
					if (header.block_count < 8)
 | 
			
		||||
					{ // if it has 8 elements then the header is full and we must move to the next one
 | 
			
		||||
						for (j = 0; j < header.block_count; j++)
 | 
			
		||||
						{ // search through all blocks in the header
 | 
			
		||||
							lseek(fp, header.file_name[j], SEEK_SET);
 | 
			
		||||
							read(fp, (char *)&l, sizeof(short int));
 | 
			
		||||
							read(fp, f_name, l);
 | 
			
		||||
 | 
			
		||||
							if (header.deleted[j] == 1)
 | 
			
		||||
							{
 | 
			
		||||
								// do nothing because the file is already deleted
 | 
			
		||||
							}
 | 
			
		||||
							else
 | 
			
		||||
							{
 | 
			
		||||
								if (strcmp(argv[k + 3], f_name) == 0)
 | 
			
		||||
								{ // check if the filename is the same as the input
 | 
			
		||||
									fprintf(stderr, "%s: file already exists\n", strerror(5));
 | 
			
		||||
									exit(EXIT_FAILURE);
 | 
			
		||||
								}
 | 
			
		||||
							}
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					if (header.next > 0)
 | 
			
		||||
					{
 | 
			
		||||
						number_of_headers++;
 | 
			
		||||
						p = header.next;
 | 
			
		||||
						temp_header_pointer = lseek(fp, header.next, SEEK_SET);
 | 
			
		||||
						r = read(fp, (char *)&header, sizeof(hdr));
 | 
			
		||||
					}
 | 
			
		||||
					else
 | 
			
		||||
					{
 | 
			
		||||
						not_finished_reading = false; // first file has been iterated through
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
#ifdef DEBUG
 | 
			
		||||
				sprintf(buffer, "file \"%s\" is not in archive: writing file\n", argv[k + 3]);
 | 
			
		||||
				write(1, buffer, strlen(buffer));
 | 
			
		||||
#endif
 | 
			
		||||
				current_file = argv[k + 3];
 | 
			
		||||
 | 
			
		||||
				temp_sizeof_file = 0;								  // reset file size counter
 | 
			
		||||
				temp_file_pointer = open(current_file, O_RDWR, 0644); // opens file;
 | 
			
		||||
 | 
			
		||||
				// Create Filename, Write to archive
 | 
			
		||||
				Current_EOP = lseek(fp, 0, SEEK_END);
 | 
			
		||||
				temp_filename_pointer = Current_EOP;
 | 
			
		||||
				char_len_buf = strlen(argv[header.block_count]);
 | 
			
		||||
#ifdef DEBUG
 | 
			
		||||
				sprintf(buffer, "char_len_buf=%i\n", char_len_buf);
 | 
			
		||||
				write(1, buffer, strlen(buffer));
 | 
			
		||||
#endif
 | 
			
		||||
				write(fp, &char_len_buf, sizeof(char_len_buf)); // write size
 | 
			
		||||
				Current_EOP = lseek(fp, 0, SEEK_END);
 | 
			
		||||
#ifdef DEBUG
 | 
			
		||||
				sprintf(buffer, "file \"%s\" : writing filename\n", argv[header.block_count]);
 | 
			
		||||
				write(1, buffer, strlen(buffer));
 | 
			
		||||
#endif
 | 
			
		||||
				write(fp, argv[header.block_count], char_len_buf * sizeof(char)); // write title
 | 
			
		||||
				Current_EOP = lseek(fp, 0, SEEK_END);
 | 
			
		||||
#ifdef DEBUG
 | 
			
		||||
				sprintf(buffer, "file \"%s\" : Write file to archive\n", argv[header.block_count]);
 | 
			
		||||
				write(1, buffer, strlen(buffer));
 | 
			
		||||
#endif
 | 
			
		||||
				// Write file to archive
 | 
			
		||||
				temp_file_read = read(temp_file_pointer, &byte, sizeof(byte)); // read first byte
 | 
			
		||||
				Current_EOP = lseek(fp, 0, SEEK_END);
 | 
			
		||||
				temp_sizeof_file += sizeof(byte); // increment the size of file
 | 
			
		||||
				write(fp, &byte, sizeof(byte));	  // write first byte
 | 
			
		||||
 | 
			
		||||
				int x = 1;
 | 
			
		||||
 | 
			
		||||
				while (temp_file_read > 0)
 | 
			
		||||
				{																   // iterate until it reaches end of file
 | 
			
		||||
					temp_file_read = read(temp_file_pointer, &byte, sizeof(byte)); // read all next bytes
 | 
			
		||||
					if (temp_file_read < 1)
 | 
			
		||||
					{
 | 
			
		||||
						break; // breaks to make sure the last byte isnt written twice
 | 
			
		||||
					}
 | 
			
		||||
#ifdef DEBUG
 | 
			
		||||
					sprintf(buffer, "Read %d-th byte [file:%d]\n", x, header.block_count - 2);
 | 
			
		||||
					write(1, buffer, strlen(buffer));
 | 
			
		||||
#endif
 | 
			
		||||
					write(fp, &byte, sizeof(byte)); // write following byte(s)
 | 
			
		||||
					Current_EOP = lseek(fp, 0, SEEK_END);
 | 
			
		||||
					temp_sizeof_file += sizeof(byte); // increment the size of file
 | 
			
		||||
#ifdef DEBUG
 | 
			
		||||
					sprintf(buffer, "wrote %d-th byte [file:%d]\n", x, header.block_count - 2);
 | 
			
		||||
					write(1, buffer, strlen(buffer));
 | 
			
		||||
#endif
 | 
			
		||||
					x++;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				header.file_size[header.block_count] = temp_sizeof_file;
 | 
			
		||||
				header.file_name[header.block_count] = temp_filename_pointer;
 | 
			
		||||
				header.block_count = (header.block_count + 1);
 | 
			
		||||
#ifdef DEBUG
 | 
			
		||||
				printf("write header %i data\n", i);
 | 
			
		||||
#endif
 | 
			
		||||
				lseek(fp, temp_header_pointer, SEEK_SET);
 | 
			
		||||
				w = write(fp, (char *)&header, sizeof(header));
 | 
			
		||||
 | 
			
		||||
				if (w < 0)
 | 
			
		||||
				{
 | 
			
		||||
					fprintf(stderr, "%s\n", strerror(5));
 | 
			
		||||
					exit(EXIT_FAILURE);
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				if (header.block_count == 8)
 | 
			
		||||
				{
 | 
			
		||||
					Current_EOP = lseek(fp, 0, SEEK_END);
 | 
			
		||||
					header = empty;
 | 
			
		||||
#ifdef DEBUG
 | 
			
		||||
					printf("write header %i data\n", i);
 | 
			
		||||
#endif
 | 
			
		||||
					lseek(fp, Current_EOP, SEEK_SET);
 | 
			
		||||
					w = write(fp, (char *)&header, sizeof(header));
 | 
			
		||||
 | 
			
		||||
					if (w < 0)
 | 
			
		||||
					{
 | 
			
		||||
						fprintf(stderr, "%s\n", strerror(5));
 | 
			
		||||
						exit(EXIT_FAILURE);
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				k++; // get the next input
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
		{ // Delete the file
 | 
			
		||||
#ifdef DEBUG
 | 
			
		||||
			printf("case -d\n");
 | 
			
		||||
#endif
 | 
			
		||||
			hdr header;
 | 
			
		||||
			char f_name[sizeof(short int)];
 | 
			
		||||
			short int l;
 | 
			
		||||
			int p = 0;
 | 
			
		||||
			int poi;
 | 
			
		||||
			lseek(fp, 0, SEEK_SET);
 | 
			
		||||
 | 
			
		||||
			r = read(fp, (char *)&header, sizeof(hdr)); // load first header
 | 
			
		||||
 | 
			
		||||
			if (r != sizeof(hdr))
 | 
			
		||||
			{
 | 
			
		||||
				fprintf(stderr, "%s: file is not the size of a header object", strerror(5));
 | 
			
		||||
				exit(EXIT_FAILURE);
 | 
			
		||||
			}
 | 
			
		||||
			else if (header.magic != 0x63746172)
 | 
			
		||||
			{
 | 
			
		||||
				fprintf(stderr, "%s: header does not include the magic number", strerror(5));
 | 
			
		||||
				exit(EXIT_FAILURE);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if (header.block_count == 0)
 | 
			
		||||
			{
 | 
			
		||||
				fprintf(stderr, "%s: Archive is empty\n", strerror(2));
 | 
			
		||||
				exit(EXIT_FAILURE);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			while (true)
 | 
			
		||||
			{
 | 
			
		||||
				for (i = 0; i < header.block_count; i++)
 | 
			
		||||
				{
 | 
			
		||||
					lseek(fp, header.file_name[i], SEEK_SET);
 | 
			
		||||
					read(fp, (char *)&l, sizeof(short int));
 | 
			
		||||
					read(fp, f_name, l);
 | 
			
		||||
 | 
			
		||||
					if (strcmp(argv[3], f_name) == 0)
 | 
			
		||||
					{
 | 
			
		||||
 | 
			
		||||
						if (header.deleted[i] == 1)
 | 
			
		||||
						{
 | 
			
		||||
							// do nothing because the file is already deleted
 | 
			
		||||
						}
 | 
			
		||||
						else
 | 
			
		||||
						{
 | 
			
		||||
							header.deleted[i] = (char)1; // set found file to deleted
 | 
			
		||||
							poi = lseek(fp, p, SEEK_SET);
 | 
			
		||||
 | 
			
		||||
							w = write(fp, (char *)&header, sizeof(header));
 | 
			
		||||
 | 
			
		||||
							if (w < 0)
 | 
			
		||||
							{
 | 
			
		||||
								fprintf(stderr, "%s\n", strerror(5));
 | 
			
		||||
								exit(EXIT_FAILURE);
 | 
			
		||||
							}
 | 
			
		||||
							exit(EXIT_SUCCESS);
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				if (header.next < 0)
 | 
			
		||||
				{
 | 
			
		||||
					fprintf(stderr, "%s\n", strerror(2));
 | 
			
		||||
					exit(EXIT_FAILURE);
 | 
			
		||||
				}
 | 
			
		||||
				else
 | 
			
		||||
				{
 | 
			
		||||
					p = header.next;
 | 
			
		||||
					lseek(fp, header.next, SEEK_SET);
 | 
			
		||||
					r = read(fp, (char *)&header, sizeof(hdr));
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		close(r);
 | 
			
		||||
		close(fp);
 | 
			
		||||
	}
 | 
			
		||||
	return EXIT_SUCCESS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int archiveexists(char *fname)
 | 
			
		||||
{
 | 
			
		||||
	if (access(fname, F_OK) != -1)
 | 
			
		||||
	{
 | 
			
		||||
		return true; // file exists
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		return false; // file doesn't exist
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,80 @@
 | 
			
		|||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <sys/uio.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <fcntl.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include "tar.h"
 | 
			
		||||
 | 
			
		||||
int main(int argc, char *argv[])
 | 
			
		||||
{
 | 
			
		||||
	char *name = argv[1]; // name of archive
 | 
			
		||||
	int numberoffiles = argc - 3;
 | 
			
		||||
	char buffer[300]; // character buffer for write
 | 
			
		||||
	int fp, r, i, p;
 | 
			
		||||
 | 
			
		||||
	if (argc != 2)
 | 
			
		||||
	{
 | 
			
		||||
		fprintf(stderr, "%s: Usage: dah filename \n", strerror(5));
 | 
			
		||||
		exit(EXIT_FAILURE);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	fp = open(name, O_RDONLY, 0644); // opens file; creates it if it does not exist;
 | 
			
		||||
	if (fp < 0)
 | 
			
		||||
	{
 | 
			
		||||
		fprintf(stderr, "cannot open %s because of %s\n", name, strerror(5));
 | 
			
		||||
		exit(EXIT_FAILURE);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	write(1, "\n", 1);
 | 
			
		||||
 | 
			
		||||
	hdr header;
 | 
			
		||||
	while (true)
 | 
			
		||||
	{
 | 
			
		||||
		r = read(fp, &header, sizeof(hdr));
 | 
			
		||||
		if (r != sizeof(hdr))
 | 
			
		||||
		{
 | 
			
		||||
			fprintf(stderr, "%s: file is not the size of a header object\n", strerror(5));
 | 
			
		||||
			exit(EXIT_FAILURE);
 | 
			
		||||
		}
 | 
			
		||||
		else if (header.magic != 0x63746172)
 | 
			
		||||
		{
 | 
			
		||||
			fprintf(stderr, "%s: header does not include the magic number [magic number is: %x]\n", strerror(5), header.magic);
 | 
			
		||||
			exit(EXIT_FAILURE);
 | 
			
		||||
		}
 | 
			
		||||
		printf("magic number is: %x\n", header.magic);
 | 
			
		||||
		printf("The end of file pointer is at: %i\n", header.eop);
 | 
			
		||||
		printf("number of used blocks are: %i\n", header.block_count);
 | 
			
		||||
		for (i = 0; i < 8; i++)
 | 
			
		||||
		{
 | 
			
		||||
			printf("The filesize of block [%i] is %i\n", i, header.file_size[i]);
 | 
			
		||||
		}
 | 
			
		||||
		for (i = 0; i < 8; i++)
 | 
			
		||||
		{
 | 
			
		||||
			printf("Is block [%i] deleted? (1=true, 0=false): %i\n", i, header.deleted[i]);
 | 
			
		||||
		}
 | 
			
		||||
		for (i = 0; i < 8; i++)
 | 
			
		||||
		{
 | 
			
		||||
			printf("The filename in block [%i] is %i\n", i, header.file_name[i]);
 | 
			
		||||
		}
 | 
			
		||||
		printf("The next header is at: %i\n", header.next);
 | 
			
		||||
 | 
			
		||||
		if (header.next < 0)
 | 
			
		||||
		{
 | 
			
		||||
			printf("End of headers\n");
 | 
			
		||||
			exit(EXIT_SUCCESS);
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
			p = header.next;
 | 
			
		||||
			lseek(fp, header.next, SEEK_SET);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	close(r);
 | 
			
		||||
	close(fp);
 | 
			
		||||
 | 
			
		||||
	return EXIT_SUCCESS;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,17 @@
 | 
			
		|||
#ifndef TAR_
 | 
			
		||||
#define TAR_
 | 
			
		||||
 | 
			
		||||
#define true 1
 | 
			
		||||
#define false 0
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
	int  magic;        /* This value must be 0x63746172                               */
 | 
			
		||||
	int  eop;          /* End of file pointer                                         */
 | 
			
		||||
	int  block_count;  /* Number of entries in the block which are in use             */
 | 
			
		||||
	int  file_size[8]; /* File size in bytes for files 1..8                           */
 | 
			
		||||
	char deleted[8];   /* Contains binary one at position i if i-th entry was deleted */
 | 
			
		||||
	int  file_name[8]; /* pointer to the name of the file.                            */
 | 
			
		||||
	int  next;         /* pointer to the next header block                            */
 | 
			
		||||
} hdr;
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,122 @@
 | 
			
		|||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <sys/uio.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <fcntl.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include "tar.h"
 | 
			
		||||
 | 
			
		||||
int fileexists(char *fname);
 | 
			
		||||
 | 
			
		||||
int main(int argc, char *argv[])
 | 
			
		||||
{
 | 
			
		||||
	char *name = argv[1];  // name of archive
 | 
			
		||||
	char buffer[300];	   // character buffer for sprintf
 | 
			
		||||
	int fp, r, i, j, p, w; // counters and pointers
 | 
			
		||||
 | 
			
		||||
	if (argc != 2)
 | 
			
		||||
	{
 | 
			
		||||
		fprintf(stderr, "%s:\n	Usage: utar filename \n", strerror(5));
 | 
			
		||||
		exit(EXIT_FAILURE);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (fileexists(name) == 0)
 | 
			
		||||
	{
 | 
			
		||||
		fprintf(stderr, "archive doesnt exist%s\n", strerror(2));
 | 
			
		||||
		exit(EXIT_FAILURE);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	fp = open(name, O_RDONLY, 0644); // opens file; creates it if it does not exist;
 | 
			
		||||
	if (fp < 0)
 | 
			
		||||
	{
 | 
			
		||||
		fprintf(stderr, "cannot open %s because of %s\n", argv[2], strerror(5));
 | 
			
		||||
		exit(EXIT_FAILURE);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	hdr header;
 | 
			
		||||
	int tempfp;
 | 
			
		||||
	char byte;
 | 
			
		||||
	char f_name[sizeof(short int)];
 | 
			
		||||
	short int l;
 | 
			
		||||
 | 
			
		||||
	while (true)
 | 
			
		||||
	{
 | 
			
		||||
 | 
			
		||||
		r = read(fp, &header, sizeof(hdr));
 | 
			
		||||
		if (r != sizeof(hdr))
 | 
			
		||||
		{
 | 
			
		||||
			fprintf(stderr, "%s: file is not the size of a header object\n", strerror(5));
 | 
			
		||||
			exit(EXIT_FAILURE);
 | 
			
		||||
		}
 | 
			
		||||
		else if (header.magic != 0x63746172)
 | 
			
		||||
		{
 | 
			
		||||
			fprintf(stderr, "%s: header does not include the magic number [magic number is: %x]\n", strerror(5), header.magic);
 | 
			
		||||
			exit(EXIT_FAILURE);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		for (i = 0; i < header.block_count; i++)
 | 
			
		||||
		{
 | 
			
		||||
			if (header.deleted[i] == 1)
 | 
			
		||||
			{
 | 
			
		||||
				// skip it
 | 
			
		||||
			}
 | 
			
		||||
			else
 | 
			
		||||
			{
 | 
			
		||||
				lseek(fp, header.file_name[i], SEEK_SET);
 | 
			
		||||
				read(fp, (char *)&l, sizeof(short int));
 | 
			
		||||
				read(fp, f_name, l);
 | 
			
		||||
 | 
			
		||||
				if (fileexists(f_name))
 | 
			
		||||
				{
 | 
			
		||||
					fprintf(stderr, "%s\n", strerror(17));
 | 
			
		||||
					exit(EXIT_FAILURE);
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				tempfp = open(f_name, O_RDWR | O_CREAT, 0644); // creates the new file;
 | 
			
		||||
				for (j = 0; j < header.file_size[i]; j++)
 | 
			
		||||
				{
 | 
			
		||||
					r = read(fp, &byte, sizeof(byte));
 | 
			
		||||
					if (r < 0)
 | 
			
		||||
					{
 | 
			
		||||
						fprintf(stderr, "%s: file %s could not be read from archive\n", f_name, strerror(5));
 | 
			
		||||
						exit(EXIT_FAILURE);
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					w = write(tempfp, &byte, sizeof(byte));
 | 
			
		||||
					if (w < 0)
 | 
			
		||||
					{
 | 
			
		||||
						fprintf(stderr, "%s: file %s could not be written to file\n", f_name, strerror(5));
 | 
			
		||||
						exit(EXIT_FAILURE);
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (header.next < 0)
 | 
			
		||||
		{
 | 
			
		||||
			printf("Untared Successfully\n");
 | 
			
		||||
			exit(EXIT_SUCCESS);
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
			p = header.next;
 | 
			
		||||
			lseek(fp, header.next, SEEK_SET);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return EXIT_SUCCESS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int fileexists(char *fname)
 | 
			
		||||
{
 | 
			
		||||
	if (open(fname, O_RDONLY, 0644) < 0)
 | 
			
		||||
	{
 | 
			
		||||
		return false; // file doesn't exist
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		return true; // file exists
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
		Reference in New Issue