0

I'm trying to move a directory with all its contents inside another directory, and I'm stuck. I'm trying to copy every single file from the source directory to the destination one and then delete it. I'm stuck at this too. But can I do somehow with the rename() function. If yes, how?

CODE UPDATE

void move_file(const char *name, const char *new_name) {
    size_t len = 0;
    char *buffer;
    long lSize;

    FILE *source = fopen(name, "r");
    FILE *target = fopen(new_name, "w");    

    if (source == NULL || target == NULL) {
        fprintf(stderr, "Error occurred when opening files\n");
        exit(1);
    }

    fseek(source, 0, SEEK_END);
    lSize = ftell(source);
    rewind(source);

    buffer = (char*)malloc(sizeof(char) * lSize);

    result = fread(buffer, 1, lSize, source);

    if (result != lSize) {
        fprintf(stderr, "Reading error\n");
        exit(2);
    }

    fwrite(buffer, 1, sizeof(buffer), target);

    fclose(source);
    fclose(target);

    if (!remove(source)) {
        fprintf(stderr, "Error deleting file\n");
    }
}

And my second function.

void move_directory(const char *target, const char *destination) {
    DIR *dir = opendir(target);

    if (dir) {
        char Path[256];
        char *EndPtr = Path;
        struct dirent *e;
        strcpy(Path, target);
        EndPtr += strlen(target);

        while ((e = readdir(dir)) != NULL) {
            struct stat info;
            strcpy(EndPtr, e->d_name);

            if (!strcmp(e->d_name, ".") || !strcmp(e->d_name, "..")) {
                continue;
            }

            if (!stat(Path, &info)) {
                if (S_ISDIR(info.st_mode)) {
                    move_directory(Path);
                } else
                if (S_ISREG(info.st_mode)) {
                    move_file(e->d_name, e->d_name);
                }
            }
        }
    }
}

I'm stuck, I don't have any ideas how I should proceed. That is what I have so far.

UPDATE: How can I now focus on my destination folder and create a folder exactly like the one I'm currently in, where my copied files should be moved into?

chqrlie
  • 131,814
  • 10
  • 121
  • 189
Andrei Olar
  • 2,270
  • 1
  • 15
  • 34
  • 1
    Please elaborate on "I'm stuck": how far have you gotten, and what aspect are you having trouble with? – Scott Hunter Jan 19 '16 at 20:50
  • This all all what I have. I pretty don't know hot to make the connection between what and where I want to move. I yet again, I'm was trying to copy every file. Can rename() be used in situations like this ? – Andrei Olar Jan 19 '16 at 20:51
  • rename() requires that both files be on the same file system. You could not use it to move a directory from one disk to another. http://www.gnu.org/software/libc/manual/html_node/Renaming-Files.html – Eric J. Jan 19 '16 at 20:57
  • So then, the only solution would be to copy every file and delete it afterwards ? But still I don't know how to make the connection between what I want to copy and where I want to copy... – Andrei Olar Jan 19 '16 at 20:59

1 Answers1

3

I'm not very up on the C IO library but I can point out a few issues

  • You are not creating the destination (sub)directory. Unless it happens to exist already, your copy will fail.
  • You are using hard-coded lengths for your paths that may well be too short. char Path[256], source_file[20], target_file[20].
  • source_file and target_file should be parameters to copy_file and are treated as such in move_directory() but are declared as stack variables in copy_file(). If this even compiles, there will be no meaningful value set for either variable.
  • You are copying files, not moving them. If you wish to move the structure, you will need to do something to delete the files and directories after a successful move.
  • You are copying one character at a time with fgetc() and fputc(). Use a buffered operation instead (fread() / fwrite()).
Eric J.
  • 147,927
  • 63
  • 340
  • 553
  • I didn't compile this, because it wasn't ready, didn't have any reasons to compile. That's works for me too, I'm not pretty good in C, that's why I ask, because I do know the logic of this. The idea is to move the structure, and I know there is a function `rename()` which moves a file in the current directory. I was trying to copy actually, in order to simulate the move, by deleting the file afterwards. – Andrei Olar Jan 19 '16 at 20:57
  • rename() only works on the same file system, so you could not use it to move a file from one disk to another or to a network drive. – Eric J. Jan 19 '16 at 20:58
  • 1
    And the code doesn't check for the `"."` and `".."` entries, which will result in infinite recursion. And the code doesn't call `mkdir` anywhere, which means that it can't possibly work. – user3386109 Jan 19 '16 at 21:08
  • @user3386109: I mentioned that the directories are not being created, but good catch on ignoring `.` and `..`. – Eric J. Jan 19 '16 at 21:20
  • Hello, I've modified a bit of my code and updated it, can you guys take a look at it ? And I still don't know, how do I focus on the destination and create a folder there, where I should copy my files then. ? – Andrei Olar Jan 19 '16 at 21:31
  • Please leave your original question intact (that is, don't edit it so as to make original answers meaningless). You can add modifications to the end of the question. – Eric J. Jan 19 '16 at 21:40
  • The modification looks essentially OK as long as the files are small enough so that you can allocate enough memory to read them in at once, except that you forgot to `free(buffer)`. However, the usual pattern is to use a buffer about the size of a block on disk (perhaps 4096 bytes) and use fread() in a loop, checking the return value to see how many bytes were actually read. See http://stackoverflow.com/a/15697826/141172 except that the buffer size of 4 is far too small. – Eric J. Jan 19 '16 at 21:43
  • Ok. But ok. I know that in my `move_directory()` function I have to open the destination directory. But how do I mix the logic where that file needs to be copied in that folder ? – Andrei Olar Jan 19 '16 at 21:47
  • You do the fread and the fwrite in the same loop. You'll read the result of fread() into a variable, fwrite() the number of bytes in that variable, and continue the loop if the number of bytes in that variable is equal to the buffer size. – Eric J. Jan 19 '16 at 22:14