Chinaunix首页 | 论坛 | 博客
  • 博客访问: 299441
  • 博文数量: 83
  • 博客积分: 3193
  • 博客等级: 中校
  • 技术积分: 1679
  • 用 户 组: 普通用户
  • 注册时间: 2006-04-03 12:04
文章分类

全部博文(83)

文章存档

2013年(2)

2012年(6)

2011年(72)

2010年(2)

2009年(1)

分类: C/C++

2011-08-11 21:42:14

作业:编写一个程序,实现目录的拷贝(包括目录里的n级子目录)
利用上班空闲时间,花了3~4个小时写完了。(最近狂练C,状态不错)
提示:
1.需要用到递归遍历目标目录。
2.需要建立一个trie树来作为目录项存储各级目录的信息

代码:
#include
#include
#include
#include
#include
#include
#include
#include

#define MAX_PATH    255
#define NAMESIZE    32
#define    NUM        1024


typedef struct foder_st{
    int depth;
    int f_num;
    char name[NAMESIZE];
    mode_t    st_mode;
    struct foder_st *DIR[NUM];
}FOLDER_ST;

//static float st_blocks=0l;


void usage(char *arg)
{
    printf("Usage: %s SOURCE DEST\n",arg);
}

int check_dir(char *path, char *filename)
{
    struct stat buf;
    int count=0;
    char whole_path_name[MAX_PATH];

    strcpy(whole_path_name,path);
    strcat(whole_path_name,filename);
   
    if(filename == NULL)
    {
        if(lstat(path, &buf) < 0)
        {
            perror("first using lstat error");
            return errno;
        }
    }
    else
    {
    if(chdir(path)<0)
        {
        printf("%s:",path);
        perror("chdir error");
        return errno;
        }

    //printf("checking %s\n",whole_path_name);

    if(lstat(filename, &buf)<0)
        {
        fprintf(stderr,"%s%s ",path,filename);
        perror("lstat error");
        return errno;
        }
    }
    if((buf.st_mode & S_IFMT) == S_IFDIR)
        return 1;
    return 0;
}

void supply_path(char *path,char *filename)
{
    char localpath[MAX_PATH];
    if(path[0]!='/')
    {
        strcpy(filename,path);
        if(getcwd(localpath, MAX_PATH) == NULL)
            {  
             perror("pwd error");
             exit(1);
                }  
        strcat(localpath,"/");
        strcpy(path,localpath);
    }
}

void dirdata_clean(FOLDER_ST *root)
{
    FOLDER_ST *cur = root;
    void *p;
    int i;

    if(cur==NULL)
    {
        printf("wrong *p\n");
        return;
    }
       
    if(cur->f_num!=0)   
    {
        for(i=0;if_num;i++)
        {
            dirdata_clean(cur->DIR[i+1]);
        }
    }
    else
    {
//        printf("Free %s info\n", cur->name);
        p = cur;
        free(p);
        cur = NULL;
    }

}


int mydu(char *path, char *filename, int depth, FOLDER_ST **src_dir)
{
    DIR *p;
    FILE *fp;
    struct stat statres;
    struct dirent *dirp;
    char whole_path[MAX_PATH]={0};
    int ret=0;
       
    FOLDER_ST *new;

    supply_path(path,filename);

    strcat(whole_path,path);
    strcat(whole_path,"/");
    strcat(whole_path,filename);
   

    //save folder info into struct data
    if(*src_dir == NULL)
    {
    fp = fopen(whole_path, "rb");
    if (fp==NULL) {
                  perror("fopen()");
                  return errno;
                  }
    if(fstat(fileno(fp), &statres) <0)
                 {
                 perror("fstat()");
                 return errno;
                 }

    new = malloc(sizeof(*new));
    if(new == NULL)
        {
        perror("Fail to malloc src_dir");
        exit(1);
        }
    new->depth = depth;
    strcpy(new->name,filename);
    new->f_num=0;
    new->DIR[new->f_num+1] = new->DIR[new->f_num] = NULL;
    new->st_mode = statres.st_mode;
    (*src_dir) = new;
    fclose(fp);
    }


    p = opendir(whole_path);

    if(p == NULL)
    {
        perror("opendir error");
        return errno;
    }

    while((dirp=readdir(p))!=NULL)
        {
        if((strcmp(dirp->d_name,"..")==0) || (strcmp(dirp->d_name,".")==0))
            continue;
        else
            {
                if(check_dir(whole_path,dirp->d_name))
                {
                    (*src_dir)->DIR[++(*src_dir)->f_num]=NULL;
                    mydu(whole_path, dirp->d_name,depth+1,&(*src_dir)->DIR[(*src
_dir)->f_num]);
                }
            }
        }
    closedir(p);
    return ret;
}

void create_sub_dir(FOLDER_ST *root)
{
    FOLDER_ST *cur = root;
    int i;
    int ret;
    if(cur==NULL)
    {
        printf("Wrong root path\n");
        return;
    }
    if(mkdir(cur->name,cur->st_mode)==-1)
        fprintf(stderr,"Fail to create %s:  %s\n",cur->name,strerror(errno));

    if( chdir(cur->name)==-1)
        fprintf(stderr,"Fail to enter %s:  %s\n",cur->name,strerror(errno));

    if(cur->f_num!=0)   
    {
        for(i=0;if_num;i++)
        {
            create_sub_dir(cur->DIR[i+1]);
        }
    }

    if(chdir("..")==-1)
        fprintf(stderr,"Fail to quit %s:  %s\n",cur->name,strerror(errno));
}

int create_dir(char dest[], FOLDER_ST *src_dir)
{
    int ret;
    if(dest==NULL)
    {
        printf("%s--",dest);
        perror("Wrong path");
        return -1;
    }
    ret = chdir(dest);
    if(ret != 0)
    {
        perror("Enter dest error");
        return ret;
    }
    create_sub_dir(src_dir);
    return 0;

}

int main(int argc, char **argv)
{
    int ret;
    char filename[NAMESIZE]={0};
    int depth = 0;
    char dest[NAMESIZE];
    FOLDER_ST *src_dir = NULL;
   
    if(argc < 3)
    {
        usage(argv[0]);
        exit(0);
    }
    strcpy(dest,argv[2]);
    ret = mydu(argv[1], filename, depth, &src_dir);
    if(ret == 0)
    {
        create_dir(dest,src_dir);
        dirdata_clean(src_dir);
    }
    return ret;
}

阅读(794) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~