#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
#include <string.h>
#include <sys/stat.h>
#include <time.h>
#include <pwd.h>
#include <grp.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <dirent.h>
#include <linux/types.h>
#include <errno.h>
#include <pthread.h>
#define NAME_SIZE 256
struct fnode
{
struct fnode *next;
char name[NAME_SIZE];
};
struct fnode *insert_list(struct fnode *temp,struct fnode *head)
{
if(head==NULL) //if linklist is empty,for temp is the first one
{
head=temp;
return head;
}
if(strcmp(temp->name,head->name)<0) //temp will be insert before first one
{
temp->next=head;
head=temp;
return head;
}
struct fnode *next=head->next;
struct fnode *prev=head;
while(next!=NULL&& strcmp(temp->name,next->name)>0)
{
next=next->next;
prev=prev->next;
}
temp->next=next;
prev->next=temp;
return head;
}
output_type_perm(mode_t mode)
{
char type[7]={'p','c','d','b','-','l','s'};
int index=((mode>>12) & 0xF)/2;
printf("%c",type[index]);
char *perm[8]={"---","--x","-w-","-wx","r--","r-x","rw-","rwx"};//rwx
printf("%s",perm[mode>>6 &07]);
printf("%s",perm[mode>>3 &07]);
printf("%s",perm[mode>>0 &07]);
}
void output_user_group(uid_t uid,gid_t gid)
{
struct passwd *user;
user=getpwuid(uid);
printf(" %s",user->pw_name);
struct group *group;
group=getgrgid(gid);
printf(" %s",group->gr_name);
}
output_mtime(time_t mytime)
{
char buf[256];
memset(buf,'\0',256);
ctime_r(&mytime,buf);
buf[strlen(buf)-1]='\0';
//memcpy(buf,ctime(mytime),strlen(ctime(mytime))-1);
printf(" %s",buf);
}
void output_info(struct fnode *head)
{
struct fnode *temp=head;
while(temp!=NULL)
{
struct stat mystat;
if(-1==stat(temp->name,&mystat))
{
perror("stat");exit(EXIT_FAILURE);
}
output_type_perm(mystat.st_mode);
printf(" %4d",mystat.st_nlink);
output_user_group(mystat.st_uid,mystat.st_gid);
printf(" %8ld",mystat.st_size);
output_mtime(mystat.st_mtime);
printf(" %s\n",temp->name);
temp=temp->next;
}
}
void free_list(struct fnode *ptr)
{
struct fnode *temp=ptr;
struct fnode *link=ptr;
while(ptr)
{
temp=ptr;
ptr=ptr->next;
free(temp);
}
}
int cp_file(const char *src, const char *dst,mode_t mode)
{
int fd_src,fd_dst;
if(-1 == (fd_src =open(src,O_RDONLY)))
{
perror("open src");exit(EXIT_FAILURE);
}
if(-1 == (fd_dst =open(dst,O_WRONLY|O_TRUNC|O_CREAT,mode)))
{
perror("open dst");exit(EXIT_FAILURE);
}
int len=0;
do
{
char buf[1024];
len=read(fd_src,buf,1024);
write(fd_dst,buf,len);
}while(len>0);
close(fd_src);
close(fd_dst);
}
int cp_dir(const char *src,const char *dst)
{
DIR *dirp = NULL;
if(NULL== (dirp=opendir(src)))
{
perror("opendir");exit(EXIT_FAILURE);
}
struct dirent *entp = NULL;
while ( NULL != (entp =readdir(dirp)))
{
if (strcmp(entp->d_name, "..")==0 || strcmp(entp->d_name, ".")==0) //ignore ./ ../
{
continue;
}
char *name_src =(char *) malloc( strlen(src) + 1 + strlen(entp->d_name) + 1 );
sprintf(name_src,"%s/%s\0",src,entp->d_name);
char *name_dst =(char *) malloc( strlen(dst) + 1 + strlen(entp->d_name) + 1 );
sprintf(name_dst,"%s/%s\0",dst,entp->d_name);
struct stat stat_src;
if (stat(name_src, &stat_src) == -1)
{
fprintf(stderr, "%s(%d): stat error(%s)!\n", __FILE__, __LINE__, strerror(errno));
exit(EXIT_FAILURE);
}
if (S_ISREG(stat_src.st_mode)) //regular file
{
cp_file(name_src,name_dst,stat_src.st_mode);
free(name_src);
free(name_dst);
}
else if ( S_ISDIR( stat_src.st_mode ))
{
if( -1 ==mkdir(name_dst,stat_src.st_mode))
{
perror("mkdir1");exit(EXIT_FAILURE);
}
cp_dir( name_src, name_dst);
free(name_src);
free(name_dst);
}
}
}
void* cp_r(char *argv[])
{
/* if (argc < 3)
{
fprintf(stderr,"usage %s src_dir dst_src\n",argv[0]);exit(EXIT_FAILURE);
}
*/
struct stat stat_src;
if (stat(argv[1], &stat_src) != 0)
{
fprintf(stderr, "%s(%d): stat error(%s)!\n", __FILE__, __LINE__, strerror(errno));
exit(EXIT_FAILURE);
}
umask(0000);
if (S_ISREG(stat_src.st_mode)) //regular file
{
struct stat stat_dst;
if (stat(argv[2], &stat_dst) == -1)
{
if(errno != ENOENT) //if errno not cause by file/dir not exist
{
fprintf(stderr, "%s(%d): stat error(%s)!\n", __FILE__, __LINE__, strerror(errno));
exit(EXIT_FAILURE);
}
else //if dst_flie not exist.
{
cp_file(argv[1],argv[2],stat_src.st_mode);
}
}
else //dst file exist.
{
if(S_ISDIR(stat_dst.st_mode)) //cp a file to a exist dir
{
char *ptr=(char *)malloc(strlen(argv[2])+1+strlen(argv[1])+1);
sprintf(ptr,"%s/%s\0",argv[2],argv[1]);
cp_file(argv[1],ptr,stat_src.st_mode);
}
else //cp file to a exist file
{
printf("file %s exist, do you want overwrite it[y/n]:",argv[2]);
char ch;
while(!scanf("%c",&ch))
{
getchar();
}
if(ch =='Y' || ch == 'y' )
{
unlink(argv[2]);
cp_file(argv[1],argv[2],stat_src.st_mode);
}
else
return 1;
}
}
}
else if (S_ISDIR(stat_src.st_mode)) // dir
{
struct stat stat_dst;
if (stat(argv[2], &stat_dst) == -1)
{ printf("TEST1 %s\n",argv[1]);
if(errno != ENOENT) //if errno not cause by file/dir not exist
{
fprintf(stderr, "%s(%d): stat error(%s)!\n", __FILE__, __LINE__, strerror(errno));
exit(EXIT_FAILURE);
}
else //file/dir not exist
{
errno=0;
if(-1 == mkdir(argv[2],stat_src.st_mode))
{
perror("mkdir2");exit(EXIT_FAILURE);
}
char *le = argv[1];
int c = 0;
for (int i = 0;i < strlen(argv[1]);i++)
{
char l = *(argv[1]+i);
if (l == '/')
{
c=i;
break;
}
}
le = le + c + 1;
printf("DIR:%s\n",le);
char *ptr=(char *)malloc(strlen(argv[1])+1+strlen(le)+1);
sprintf(ptr,"%s/%s\0",argv[2],le);
if(-1 == mkdir(ptr,stat_src.st_mode))
{
printf("mk:%s\n",ptr);perror("mkdir3");exit(EXIT_FAILURE);
}
cp_dir(argv[1],ptr);
free(ptr);
}
}
else if(S_ISREG(stat_dst.st_mode)) //can't copy a dir to a file
{
fprintf(stderr,"can't copy a dir to a file\n");exit(EXIT_FAILURE);
}
else //copy a dir to a exsit dir ,
{
char *le = argv[1];
int c = 0;
for (int i = 0;i < strlen(argv[1]);i++)
{
char l = *(argv[1]+i);
if (l == '/')
{
c=i;
break;
}
}
le = le + c + 1;
printf("DIR:%s\n",le);
char *ptr=(char *)malloc(strlen(argv[1])+1+strlen(le)+1);
sprintf(ptr,"%s/%s\0",argv[2],le);
if(-1 == mkdir(ptr,stat_src.st_mode))
{
printf("mk:%s\n",ptr);perror("mkdir3");exit(EXIT_FAILURE);
}
cp_dir(argv[1],ptr);
free(ptr);
}
}
}
void* ls_l(char *argv[])
{
int argc = 2;
int i;
for(i=1;i<argc;i++)
{
struct fnode *linklist=NULL;
struct stat stat_info;
if(stat(argv[i],&stat_info)==-1)
{
perror("stat");exit(EXIT_FAILURE);
}
if (S_ISREG(stat_info.st_mode)) //regular file
{
struct fnode *temp=(struct fnode *)malloc(sizeof(struct fnode));
if(NULL==temp)
{
perror("malloc");exit(EXIT_FAILURE);
}
temp->next=NULL;
memset(temp->name,'\0',NAME_SIZE);
memcpy(temp->name,argv[i],strlen(argv[i]));
linklist=insert_list(temp,linklist);
output_info(linklist); // output information of the file
}
else if(S_ISDIR(stat_info.st_mode))
{
char buf[NAME_SIZE];
getcwd(buf,128);
DIR *dirp=NULL;
dirp=opendir(argv[i]);
if(NULL==dirp)
{
perror("opendir");exit(EXIT_FAILURE);
}
struct dirent *entp=NULL;
while(entp=readdir(dirp))
{
struct fnode *temp=(struct fnode *)malloc(sizeof(struct fnode));
char absolute_way[126];
sprintf(absolute_way,"%s%s\0",argv[1],entp->d_name);
struct stat stat_inside;
if(!((strcmp(entp->d_name,".")) && (strcmp(entp->d_name,"..")))) continue;
if(stat(absolute_way,&stat_inside)==-1)
{
perror("stat");printf("\nd_name:%s\n",entp->d_name);exit(EXIT_FAILURE);
}
if(NULL==temp)
{
perror("malloc");exit(EXIT_FAILURE);
}
/**************************************************************************************/
if(S_ISDIR(stat_inside.st_mode))
{
int res_1;
pthread_t cp_thread;
void *thread_result1;
char *cp_name = (char*)malloc(156);
sprintf(cp_name,"%s%s\0",argv[1],entp->d_name);
printf("TEST %s\n",entp->d_name);
char* point[] = {"cp_r",cp_name,"zhangxu",NULL};
res_1 = pthread_create(&cp_thread,NULL,cp_r,point);
if (res_1 != 0)
{
perror ("Thread creation failed");
exit (EXIT_FAILURE);
}
res_1 = pthread_join(cp_thread, &thread_result1);
printf("Waiting for cp_thread to finish...\n");
if (res_1 != 0)
{
perror("Thread join failed");
exit (EXIT_FAILURE);
}
else
{
temp->next=NULL;
memset(temp->name,'\0',NAME_SIZE);
memcpy(temp->name,entp->d_name,strlen(entp->d_name));
linklist=insert_list(temp,linklist);
free(cp_name);
}
/* pid_t pid;
int status;
char* pass_argv = argv;
if ((pid = fork()) == -1)
{
perror("fork");
exit(EXIT_FAILURE);
}
else if (pid == 0)
{
char *cp_name = (char*)malloc(256);
sprintf(cp_name,"%s%s\0",argv[1],entp->d_name);
char* point[] = {"cp_r",cp_name,"yourname",NULL};
// printf("命令:%s\n",ls_name);
// system(ls_name);
// int ret = execv("/home/vic/Desktop/cp_r",point);
int ret = execl("/home/vic/Desktop/cp_r","./cp_r",cp_name,"yourname",NULL);
if(ret == -1)
{
perror("execl error");
}
free(cp_name);
free(point);
exit(0);
}
else
{
printf("child_pid:%d\n",(waitpid(pid,&status,0)));
printf("CP RIGHT\n");
temp->next=NULL;
memset(temp->name,'\0',NAME_SIZE);
memcpy(temp->name,entp->d_name,strlen(entp->d_name));
linklist=insert_list(temp,linklist);
}
*/
}
/*********************************************************************************************/
else
{
temp->next=NULL;
memset(temp->name,'\0',NAME_SIZE);
memcpy(temp->name,entp->d_name,strlen(entp->d_name));
linklist=insert_list(temp,linklist);
}
}
chdir(argv[i]);//change the current dirctory
close(dirp);
output_info(linklist);
chdir(buf);
}
free_list(linklist);
}
return 1;
}
int main (int argc,char* argv[])
{
if(argc < 2)
{
printf("usage :%s dir_name\n",argv[0]);exit(EXIT_FAILURE);
}
int res;
pthread_t ls_thread;
void *thread_result;
res = pthread_create(&ls_thread, NULL, ls_l, argv);
if (res != 0)
{
perror ("Thread creation failed");
exit (EXIT_FAILURE);
}
res = pthread_join(ls_thread, &thread_result);
printf("Waiting for ls_thread to finish...\n");
if (res != 0)
{
perror("Thread join failed");
exit (EXIT_FAILURE);
}
return 1;
}
线程实现cp-r与ls-l
最新推荐文章于 2024-03-26 21:36:47 发布