-2

I'm trying to extract a directory recursively using the function below. When I run the program it is able to create a root directory and the files inside of it but it is not able to completely write the files inside of the sub directories.

My code is able to compile but I keep getting a segmentation fault error. I have tried looking for rogue pointers in my function or memory that should not be other wised accessed but I am getting nowhere. Any help or guidance in the right direction would be greatly appreciated!

Here is my Extraction function:

int DExtract(FILE* fp, char* outputName, char* inputName, DIR* d, bool root)
{
      DIR* dsub;
    struct dirent* p;
    FILE* outF;
    int i=0;
    char fileName[BUFFER_SIZE];
    char SfileName[BUFFER_SIZE];
    bool SC;
    int dz;
    int nameLength;
    int fileSize;
    int fileType;

////// ROOT CREATION /////////////
if(root)
{
       fscanf(fp,"%d %d %s %d\n", &fileType, &nameLength, inputName, &fileSize);
   if(fileType==0)
   {
   mkdir(outputName, 0755); // create root directory
   }

}
//////////////////////////////////

root = false;  // MOVING INTO ROOT
d = opendir(outputName);   // open directory with input name

while( (p = readdir(d)) || (dz  != EOF))
   { fscanf(fp,"%d %d %s %s %d ",&fileType, &nameLength, p->d_name, fileName, &fileSize);

//////////////////////////////////////////////////

     strcpy(SfileName,outputName);

     for(int h=0; h < strlen(fileName); h++ )
     {
        if( fileName[h] == '/')
        { SC = true;}

        if(SC == true)
        { strcat(SfileName, &fileName[h]);

           h=strlen(fileName);
        }
     }
      SC = false;
     cout << "STRING LENGTH FILENAME: " << strlen(fileName) << endl;
     cout << "SFILENAME in WHILE: " << SfileName << endl;






 /////////////////////////////////////  /////////////////

    if(strcmp(p->d_name, ".") != 0) // if they are not the same as current working directory
    { if(strcmp(p->d_name, "..") != 0) // if they are not the same as parent directory

       { if(p->d_name[nameLength - 1] != '~')  // If not the same as home directory
            {

///////////////////////////
    if(fileType == 1)
    {

  // This is a regular file

     outF = fopen(SfileName, "w+");  // create file
     i=0;


     do
     {
       int ch;
       ch = fgetc(fp);
       dz = ch;
       if(i != (fileSize-1))
        {
          fputc(ch,outF);
          i++;

        }

     }while( i != (fileSize-1) );
     fclose(outF);

 }
 else if( fileType == 0)
 {

    // This is a directory

cout << "SFILENAME in DIRECTORY: " << SfileName << endl;

     mkdir(SfileName, 0755);   // create directory

     if((strcmp(SfileName, ".") != 0) )
     {
       dsub = opendir(SfileName);
       DExtract(fp, outputName, inputName, dsub, root);

         }
     }
    }
   }
  }
 }


  return 0;
}
codeconscious
  • 396
  • 3
  • 15
JonSnow
  • 67
  • 3
  • 14
  • Why are you using `fscanf()` to overwrite `p->d_name` that you just read with `readdir()`? – Barmar May 02 '17 at 00:10
  • `if(p->d_name[nameLength - 1] != '~')` This will not work. The home directory isn't really named `~`, that's just a convention used by the shell and some other programs. They replace it with the value of the `$HOME` environment variable. – Barmar May 02 '17 at 00:13
  • What does "extract a directory" mean? Are you having a problem with listing files recursively or writing files recursively? – Nguai al May 02 '17 at 00:13
  • Why are you reading a line from `fp` after every time you read from the directory? What if the input file doesn't have the same number of rows as the number of files and directories in the directory you're trying to copy? – Barmar May 02 '17 at 00:14

1 Answers1

0

At a glance, this is a possible culprit:

strcpy(SfileName,outputName);

You may be trying to copy into a destination string when the source string exceeds the buffer size, leading to undefined behavior.

diametralpitch
  • 675
  • 3
  • 5