Thread: File archiving

    #1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jan 2011
    Posts
    4
    Rep Power
    0

    File archiving


    Hi, I hope someone can help me with a problem that I am currently stuck on, basically I am trying to create a file archive utility which can archive 1 or more file each specified in a command line into a file.

    My problem which I am currently stuck on is that, i have managed to create a file archive utility which can only archive 1 file.

    e.g: My program can copy the contents of 1 file and put the contents of that file into a new file so, it can copy a file and its contents called hello and put that in a new file which can be named hello1, whatever the user wants to name the file.

    I was also hoping if anyone can give me a clue on how to extract all of the files contained in the archive (specified on the command line) in to the current working
    directory.


    My code so far is:
    Code:
    #include <stdio.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <unistd.h>
    #include <fcntl.h>
    #include <stdlib.h>
    
    main (int argc, char **argv)
    {
    int bytes_read, bytes_written;
    struct stat inode;
    int input_fd, output_fd;
    char buffer[64];
    int eof = 0;
    int i;
    
    /* Check the command line arguments */
    if (argc != 3)
    {
    printf("syntax is: %s <fromfile> <tofile>\n", argv[0]);
    exit (1);
    }
    
    /* Check the input file exists and is a file */
    if ((stat(argv[1], &inode) == -1) || (!S_ISREG(inode.st_mode)))
    {
    printf("%s is not a file\n", argv[1]);
    exit(2);
    }
    
    /* Check that the output file doesnt exist */
    if (stat(argv[2], &inode) != -1)
    {
    printf("Warning: The file %s already exists. Not going to overwrite\n", argv[2]);
    exit(2);
    }
    
    /* Open the input file for reading */
    input_fd = open(argv[1], O_RDONLY, 0);
    if (input_fd == -1)
    {
    printf("%s cannot be opened\n", argv[1]);
    exit(3);
    }
    
    output_fd = open(argv[2], O_CREAT | O_WRONLY | O_EXCL , S_IRUSR|S_IWUSR);
    if (output_fd == -1)
    {
    printf("%s cannot be opened\n", argv[2]);
    exit(3);
    }
    
    /* Begin processing the input file here */
    while (!eof)
    {
    bytes_read = read(input_fd, buffer, sizeof(buffer));
    
    if (bytes_read == -1)
    {
    printf("%s cannot be read\n", argv[1]);
    exit(4);
    }
    
    if (bytes_read > 0)
    {
    bytes_written = write(output_fd, buffer, bytes_read);
    if (bytes_written == -1)
    {
    printf("There was an error writing to the file %s\n",argv[2]);
    exit(4);
    }
    
    if (bytes_written != bytes_read)
    {
    printf("Devistating failure! Bytes have either magically appeared and been written or dissapeard and been skipped. Data is inconsistant!\n");
    exit(101);
    }
    }
    else
    {
    eof = 1;
    }
    }
    close(input_fd);
    close(output_fd);
    
    }
    I'm hoping someone can help me with this.

    Thanks a lot.
  2. #2
  3. Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jan 2010
    Location
    Katy, Texas
    Posts
    495
    Rep Power
    199
    Please use code tags, proper indentation and please be specific where you are having issues.
    Do you agree? Disagree? And remember, it's all about the reputation power...
  4. #3
  5. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jan 2011
    Posts
    4
    Rep Power
    0
    Originally Posted by TheOtherDino
    Please use code tags, proper indentation and please be specific where you are having issues.
    Sorry about not using the code tags.

    My code has no errors at this moment but I'm in a situation where I do not know how to proceed further.

    Problem 1: I don't know how to archive more than 1 file specified at a command line.
    I think i need to use a loop but i'm not sure where to start and will it be a while or for loop, i was wondering if someone can give me a example or so.

    Problem 2: I am not sure how I would go on to extract all of the files contained in the archive (specified on the command line) into the current working directory.

    I hope someone can help, with some examples if possible thanks.
  6. #4
  7. Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jan 2010
    Location
    Katy, Texas
    Posts
    495
    Rep Power
    199
    Yes, you'll need a loop. You'll need to parse out all the passed file names, makes sure they exist, and determine the sizes of the files before you start writing them to the archive file.

    A simple and common approach is to write first write the size of the file (the data) in the archive file, and then write the file name and file data, separating the file name and file data however you choose. (newline, whatever).

    For example, if a file called test.txt contains the word "hello" (6 bytes), then the archive file might look like:
    Code:
    0x00000006    (an integer value of 6) 
    test.txt
    hello
    If you appended another file to the archive file, a second file called data.bin that contains 512 bytes of data, the archive file would look like this:

    Code:
    0x00000006    (an integer value of 6) 
    test.txt
    hello
    0x00000200    (an integer value of 512) 
    data.bin 
    ..........................................................
    where the .... represents 200 bytes of binary data.

    etc.
    Do you agree? Disagree? And remember, it's all about the reputation power...
  8. #5
  9. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jan 2011
    Posts
    4
    Rep Power
    0
    Originally Posted by TheOtherDino
    Yes, you'll need a loop. You'll need to parse out all the passed file names, makes sure they exist, and determine the sizes of the files before you start writing them to the archive file.

    A simple and common approach is to write first write the size of the file (the data) in the archive file, and then write the file name and file data, separating the file name and file data however you choose. (newline, whatever).

    For example, if a file called test.txt contains the word "hello" (6 bytes), then the archive file might look like:
    Code:
    0x00000006    (an integer value of 6) 
    test.txt
    hello
    If you appended another file to the archive file, a second file called data.bin that contains 512 bytes of data, the archive file would look like this:

    Code:
    0x00000006    (an integer value of 6) 
    test.txt
    hello
    0x00000200    (an integer value of 512) 
    data.bin 
    ..........................................................
    where the .... represents 200 bytes of binary data.

    etc.
    I had a go writing the loop so I can archive more than 1 file , but I have confused myself some what and I got few errors which I am not sure about:

    Code:
    	if ((archived_file = open("archive", "w")) == NULL ) 
    	{
    		printf("\nERROR: Sorry the file is open");
    
    	} 
    		else 
    			{
    
    				for (i = 1; i <= argc - 1; i++) 
    					{
    
    						if ((input_fd = open(argv[i]) == NULL)) 
    					}
    			
    					{
    
    						printf("\nError");
    
    					}
    							
    				
    			}
    The errors I get are:

    In function ‘main’:
    35: warning: passing argument 2 of ‘open’ makes integer from pointer without a cast
    35: warning: comparison between pointer and integer
    46: error: too few arguments to function ‘open’
    47: error: expected expression before ‘}’ token

    I have errors on these line and I'm not sure how to solve them I hope someone can help me out thanks.
  10. #6
  11. Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jan 2010
    Location
    Katy, Texas
    Posts
    495
    Rep Power
    199
    I would suggest you getting your code to the point where archiving and restoring one file works first. Is that where it is now?
    Do you agree? Disagree? And remember, it's all about the reputation power...
  12. #7
  13. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jan 2011
    Posts
    4
    Rep Power
    0
    Originally Posted by TheOtherDino
    I would suggest you getting your code to the point where archiving and restoring one file works first. Is that where it is now?
    I can archive 1 file. The code I posted right at the start allows me to archive 1 file.

    That code can for e.g. Copy the contents of a existing file named "Helloworld" and it's contents and can create a new file and put it in their.

    The syntax used is:
    Syntax is: %s <fromfile> <tofile> - where tofile will be the new file which will get created.

    Thanks
  14. #8
  15. Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jan 2010
    Location
    Katy, Texas
    Posts
    495
    Rep Power
    199
    I eyeballed your code - looks good so far.

    However, it does not implement any of the suggestions I offered to record the file name the data came from, nor how long the data (or file name) is. Also, there's no code there to restore the file.
    Do you agree? Disagree? And remember, it's all about the reputation power...
  16. #9
  17. Contributed User
    Devshed Specialist (4000 - 4499 posts)

    Join Date
    Jun 2005
    Posts
    4,363
    Rep Power
    1870
    Broadcast elsewhere - for the benefit of helpers.
    here and there
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper

IMN logo majestic logo threadwatch logo seochat tools logo