作业:编写一个程序,实现目录的拷贝(包括目录里的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;
}
阅读(957) | 评论(0) | 转发(0) |