0

i am looking through a copy program in c, i am trying to understand how the below code works. i have research about the functions but for some reason can't get my head around it. e.g. "./main a temp/" this command copies a into the folder temp, the code below assigns second argument as a directory if it ends with a "/" that is temp/. if the user enters "./main a b " then the program copies a and creates b with the same file permissions as b. I know everything else. Except the code below. Can someone please explain the code below and how it works. Thanks

if(S_ISDIR(ost.st_mode)){       //if output filename is a directory

    //concatenate directory name and input name
    int ilen = strlen(iname);
    int olen = strlen(oname);

    int len = ilen + olen + 2;
    char *copy_name = (char*) malloc(len);  //dynamically allocate a memory buffer
    if(copy_name == NULL)
        oops("Cannot malloc memory", ":");

    memcpy(copy_name, oname, olen);         //copy directory name
    copy_name[olen] = '/';                  //separate directory and file name with a slash
    memcpy(&copy_name[olen+1], iname, ilen);    //copy output file name
    return copy_name;
}else{
    return strdup(oname);   //if output filename is not a directory, just copy it
}
Mehdi Rahimi
  • 1
  • 1
  • 3
  • 1
    The code does not ensure that the string created is null terminated; it should copy `ilen + 1` bytes with the second `memcpy()` to ensure that the null byte at the end of `iname` is copied. – Jonathan Leffler May 09 '17 at 04:50
  • 1) the code *doesn't* check if the path ends with a / and 2) what exactly do you want to know about it? – user253751 May 09 '17 at 04:59
  • i want to know how the code works, you are right, it does not check but if the command is ./main a temp/, it assumes the second argument as directory since it includes a slash – Mehdi Rahimi May 09 '17 at 05:18
  • 1
    @MehdiRahimi - No, it does **not** check for a directory by looking for a `/`. It uses `S_ISDIR` - see https://www.gnu.org/software/libc/manual/html_node/Testing-File-Type.html or http://stackoverflow.com/questions/4989431/how-to-use-s-isreg-and-s-isdir-posix-macros You have posted too little of the code - important parts are missing. – Support Ukraine May 09 '17 at 05:21
  • i understand that now thanks, however, what is the use of memcpy and malloc in the code, since S_ISDIR(ost.st_mode already checks if the second argument is a directory. – Mehdi Rahimi May 09 '17 at 05:29
  • @MehdiRahimi - `malloc` and `memcpy` are for constructing a string to hold the name of the output file, i.e. directory name + `/` + filename. `malloc` reserves memory. `memcpy` copies the input values to the new string – Support Ukraine May 09 '17 at 05:36

1 Answers1

0

The purpose of this function is to return a file path. The destination file path.

You've identified that there are two modes for this program. 1) where both parameters are filenames, and 2) where the second parameters is a folder.

Mode 1) Both parameters are filenames.

./main old.txt new.txt

destinationFilePath = thisFunc("old.txt", "new.txt");
//new.txt

Mode 2) The second parameter is a folder.

./main old.txt my_archive/

destinationFilePath = thisFunc("old.txt", "my_archive/");
//my_archive/old.txt

P.S. In both modes, this code returns the filename in new memory, which should be managed; It doesn't rely in the allocated memory of either of the parameters.

P.P.S Like @Jonathan pointed out, the code quality around the memory and null termination isn't great.

Jeremy Lawson
  • 483
  • 3
  • 12
  • With your input: `my_archive/old.txt` -> `my_archive//old.txt` – Support Ukraine May 09 '17 at 05:14
  • i understand that, however i want to know how it knows if the second argument has a slash as in filename/, then it is a directory, – Mehdi Rahimi May 09 '17 at 05:19
  • @MehdiRahimi: that's a job of the `stat()` system call and the `if (IS_DIR(ost.st_mode))` test. See also POSIX on [Pathname resolution](http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_13): _A pathname that contains at least one non- `` character and that ends with one or more trailing `` characters shall not be resolved successfully unless the last pathname component before the trailing `` characters names an existing directory or a directory entry that is to be created for a directory immediately after the pathname is resolved._ – Jonathan Leffler May 09 '17 at 05:26
  • thanks, what is the purpose of malloc and memcpy in the code? since if (IS_DIR(ost.st_mode)) already checks if 2nd argument is a directory – Mehdi Rahimi May 09 '17 at 05:27