一个C程序,它复制包含文件和文件夹的目录中的所有内容

时间:2016-12-07 14:59:58

标签: c

我刚发布的最后一个代码现在有效。也就是说,它能够将所有文件从一个目录复制到另一个目录。但是现在,我想以这样一种方式更新它,它也复制了包含它内容的目录,无论是文件还是文件夹。 这是我到目前为止所做的,但这无法实现我的梦想。 我真的不知道代码有什么问题。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <fcntl.h>
#include <unistd.h>

#define Max 8192

int copy_files(char *src, char *dest);
int copy_dir(char *srcpath, char *destpath);

int copy_dir(char *srcpath, char *destpath)
{
  DIR *sdp = NULL;
  DIR *ddp = NULL;
  struct dirent *entry;
  struct stat sb;

  char tempsrc[strlen(srcpath)+1];
  char tempdest[strlen(destpath)+1];

  strcat(srcpath, "/");
  strcat(destpath, "/");
  strcpy(tempdest, destpath);
  strcpy(tempsrc, srcpath);

  if( (sdp = opendir(srcpath)) == NULL )
  {
    printf ("%s is not an existing directory\n", srcpath);
    return 0;
  }
  else
  {
    while( (entry = readdir(sdp)) )
    {
        stat(entry->d_name, &sb);

        //  printf("Cannot open directory\n");
        //  exit(EXIT_FAILURE);


        switch (sb.st_mode & S_IFMT) 
        {
            case S_IFREG:
            {
                strcat(tempdest, entry->d_name);
                strcat(tempsrc, entry->d_name);

                copy_files(tempsrc, tempdest);

                strcpy(tempdest, destpath);
                strcpy(tempsrc, srcpath);

                break;
            }
            case S_IFDIR:
            {
                strcat(tempsrc, entry->d_name);         
                strcat(tempdest, entry->d_name);
                mkdir(tempdest, 0777);

                ddp = opendir(tempdest);

                copy_dir(tempsrc, tempdest);
                strcpy(tempdest, destpath);
                strcpy(tempsrc, srcpath);  

                break;
            }
        }
      }

      closedir(sdp);
      closedir(ddp);
      return 1;
  }
}

int copy_files(char *src, char *dest)
{
  int sfd, dfd, ret_in, ret_out;
  char buff[Max];

  if ( (sfd = open(src, O_RDONLY)) == -1 )
  {
    printf("Error while reading %s\n", src);
    perror(src);
    exit(1);
  }

  if ( (dfd = creat(dest, 0644)) == -1 )
  {
    printf("Error while creating %s\n", dest);
    perror(dest);
    exit(1);
  }

  while( (ret_in = read(sfd, &buff, Max)) > 0 )
  {
    ret_out = write (dfd, &buff, ret_in);

    if (ret_out != ret_in)
    {
        printf("write error to %s", dest);
        perror(dest);
        exit(1);
    }

    if (ret_in == -1)
    {
        printf("read error from %s", src);
        perror(src);
        exit(1);
    }
  }

  close(sfd);
  close(dfd);

  return 1;
}

int main(int argc, char *argv[])
{
  int i; 

  if (argc != 3)
  {
    printf ("Usage: Programme_name src dest\n e.g. ./cp src dest\n");
    exit(1);
  }

  char *srcp = argv[1];
  char *destp = argv[2];

  if (srcp[0] == '/' && destp[0] == '/')
  {

    for (i = 1; i <= strlen(destp); i++)
        destp[(i-1)] = destp[i];

    for (i = 1; i <= strlen(srcp); i++)
        srcp[(i-1)] = srcp[i];

    copy_dir(srcp, destp);
  }
  else if (srcp[0] != '/' && destp[0] == '/') //./ass1 test /t2
  {
    for (i = 1; i <= strlen(destp); i++)
        destp[i-1] = destp[i];

    strcat(destp, "/");
    strcat(destp, srcp);

    copy_files(srcp, destp);
  }
  else 
  {
    printf ("Usage: Programme_name src dest\n e.g. ./cp src dest\n");
    exit(1);
  }
}

1 个答案:

答案 0 :(得分:1)

当读取目录条目/.时,您将无限期地将.添加到临时源路径和目标路径,该目录条目存在于所有目录中。相反,您应该跳过...条目。

另一个错误是临时路径的尺寸标注:

  char tempsrc[strlen(srcpath)+1];
  char tempdest[strlen(destpath)+1];

数组的长度足以容纳原始路径,但随后附加了子目录名,溢出了数组。更好:

  char tempsrc[PATH_MAX];
  char tempdest[PATH_MAX];