views:

144

answers:

4

How do I transfer files from one folder to another, where both folders are present in oracle home directory?

int main(int argc, char *argv[]){
    char *home, *tmp2;
    home = getenv("ORACLE_HOME");
    temp2 = getenv("ORACLE_HOME");
    strcat (home,"A");
    strcat (tmp2,"B");

//transfer files from home to tmp2

}

strcat doesn't seem to work. Here, I see tmp2 pointer doesn't get updated correctly.

Edit: OS is a UNIX based machine. Code edited. I require a binary file which does this copying, with the intention that the real code cannot be viewed. Hence I didn't consider using shell script as an option. The files in A are encrypted and then copied to B, decrypted in B and run. As the files are in perl, I intend to use system command to run them in the same C code.

A: 

Not realted to what you are asking, but a comment on your code:

You probably won't be able to strcat to the results of a getenv, because getenv might (in some environments) return a pointer to read-only memory. Instead, make a new buffer and strcpy the results of the getenv into it, and then strcat the rest of the file name.

Paul Tomblin
Regardless of whether it's read-only, it's writing into someone else's memory, and possibly a buffer overflow.
Matthew Flaschen
A: 

The quick-n-dirty way to do the transferring is to use the cp shell command to do the copying, but invoke it using the system command instead of using a shell script.

Or, have your C program create a shell script to do the copying, run the shell script, and then delete it.

bta
+1  A: 

First of all as pointed out before, this "security" of yours is completely useless. It is trivial to intercept the files being copied (there are plenty of tools to monitor file system changes and such), but that is another story.

This is how you could do it, for the first part. To do the actual copying, you'd have to either use system() or read the whole file and then write it again, which is kind of long for this kind of quick copy.

int main(int argc, char *argv[]){
  char *home, *tmp2;
  home = strdup(getenv("ORACLE_HOME"));
  tmp2 = strdup(getenv("ORACLE_HOME"));
  home = realloc(home, strlen(home)+strlen("A")+1);
  tmp2 = realloc(tmp2, strlen(tmp2)+strlen("B")+1);
  strcat (home,"A");
  strcat (tmp2,"B");
}

By the way, if you could stand just moving the file, it would be much easier, you could just do:

rename(home,tmp2);
houbysoft
+1  A: 

Using the system(3) command is probably a good idea since you get the convenience of a shell interpreter to expand filenames (via *) but avoids the hassle of computing the exact length of buffer needed to print the command by using a fixed length buffer and ensuring it cannot overflow:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define BUFSZ 0xFFF
int main(void)
{
    char * ohome = getenv("ORACLE_HOME"), cmd[BUFSZ];
    char * fmt="/bin/mv %s/%s/* %s/%s";
    int written = snprintf(cmd, BUFSZ, fmt, ohome, "A", ohome, "B"), ret;
    if ((written < 0) || (written >= (BUFSZ-1))) {
      /* ERROR: print error or ORACLE_HOME env var too long for BUFSZ. */
    }
    if ((ret = system(cmd)) == 0) {
      /* OK, move succeeded. */
    }
    return 0;
}

As commenter Paul Kuliniewicz points out, unexpected results may ensue if your ORACLE_HOME contains spaces or other special characters which may be interpreted by the subshell in the "system" command. Using one of the execl or execv family will let you build the arguments without worrying about the shell interpreter doing it's own interpretation but at the expense of using wildcards.

maerics
That code will do surprising things if $ORACLE_HOME contains spaces or any special characters. It's safer to use fork and execlp to skip the shell entirely and make sure the argument list gets parsed the way you want.
Paul Kuliniewicz
@Paul: true, I considered that option first but the convenience of using wildcards in the subshell to glob all filenames in the source directory seems like a big win to me; also building the argument values separately and then the argument is more tedious and not as demonstrative for the OP.
maerics