1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
| #include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<unistd.h>
#include<fcntl.h>
#include<dirent.h>
#define DIR_MAXSIZE 1024
void copie(char *src, char *dest){
int fd_src, fd_dest;
char buf[DIR_MAXSIZE];
struct stat s;
size_t b_read;
if((fd_src=open(src,O_RDONLY))==-1){
perror("open");
return;
}
if(stat(src,&s) !=0){
perror("stat");
return;
}
if((fd_dest=open(dest, O_WRONLY|O_CREAT|O_TRUNC,s.st_mode))==-1){
perror("open dest");
return;
}
while((b_read=read(fd_src,buf,DIR_MAXSIZE))>0)
write(fd_dest,buf,b_read);
if(b_read == -1){
perror("read");
}
}
void copylink(char *src, char *dest){
char buf[DIR_MAXSIZE];
size_t re;
re = readlink(src,buf,DIR_MAXSIZE);
buf[re] = '\0';
if(symlink(buf,dest) != 0){
perror("symlink");
return ;
}
}
/*
*on suppose que source est déjà un dossier
*Dans le main, on teste donc si c'est un dossier ; si ce n'est pas un ,
*on fait directement une "copie"
*/
void copie_rec(char *source, char *dest){
DIR *rep;
struct dirent *d;
struct stat s;
char current_dir [DIR_MAXSIZE];
char next_dir [DIR_MAXSIZE];
if(lstat(source, &s)){
perror("lstat");
return;
}
if((rep=opendir(source))==NULL){
perror("opendir");
return;
}
if ((s.st_mode & S_IXOTH) || ((s.st_mode & S_IXGRP) && (s.st_gid==getgid()))
|| ((s.st_mode & S_IXUSR) && (s.st_uid == getuid()))){
while((d = readdir(rep))){
if(strcmp(d->d_name, ".")==0 || strcmp(d->d_name,"..")==0)
continue;
sprintf(current_dir, "%s%s",source,d->d_name);
sprintf(next_dir,"%s%s",dest,d->d_name);
if(lstat(current_dir,&s)==-1){
perror("lstat");
return;
}
if(S_ISDIR(s.st_mode)){
if(mkdir(next_dir,s.st_mode)==-1){
perror("mkdir");
return;
}
copie_rec(current_dir,next_dir);
}
else if(S_ISLNK(s.st_mode)){
copylink(current_dir,next_dir);
}
else{
copie(current_dir,next_dir);
}
}
closedir(rep);
}
}
int main(int argc, char *argv[]){
if(argc != 3){
printf( "usage: %s source destination\n");
exit(1);
}
char *src = argv[1];
char *dest = argv[2];
if(src[0] != '/' && dest[0] != '/'){
copie(src, dest);
}
else if(src[0] != '/' && dest[0] == '/'){
int i;
for(i = 1; i<=strlen(dest); i++){
dest[(i - 1)] = dest[i];
}
strcat(dest, "/");
strcat(dest, src);
copie(src, dest);
}
else if(src[0] == '/' && dest[0] == '/'){
int i;
for(i = 1; i<=strlen(dest); i++){
dest[(i - 1)] = dest[i];
}
for(i = 1; i<=strlen(src); i++){
src[(i - 1)] = src[i];
copie_rec(src, dest);
}
else{
fprintf(stderr, "usage: cp1 source destination\n");
exit(1);
}
} |