分类: LINUX
2010-02-02 19:43:33
/*******************************************************/
fastcopy.c
基于文件系统的分区复制
/*******************************************************/
#include "beinclude.h"
int pathlen;
char buf[BUFSIZE];
struct aa finfo;
int main(int ac, char *av[]){
char cmd[50];
char *srcdev,*decdev;
struct stat st;
//DIR *sdir=NULL, *ddir=NULL;
//struct dirent diret, *diret_ptr;
if (ac < 2){
printf("the operate to less \n");
return -1;
}
memset(cmd, 0x00, sizeof(cmd));
srcdev = av[1];
decdev = av[2];
sprintf(cmd, "mount %s /data/sdev",av[1]);
system(cmd);
memset(cmd, 0x00, sizeof(cmd));
sprintf(cmd, "mount %s /data/ddev",av[2]);
system(cmd);
lstat(DEVS, &st);
if (!S_ISDIR(st.st_mode)){
printf("%s errpo@@@\n",DEVS);
return -1;
}
//if (ddir = opendir())
pathlen = strlen(srcdev);
if (scan_dir(DEVS, DEVD, &st) >= 0){
system("umount /data/sdev");
system("umount /data/ddev");
}
return 0;
}
int scan_dir(char *s, char *d, struct stat *fstat){
int retval = 0;
int rest;
struct dirent diret, *diret_ptr;
char filename[PATH_MAX],dfilename[PATH_MAX];
DIR *sdir=NULL, *ddir=NULL ,*sdirbak=NULL, *ddirbak=NULL;
if (!S_ISDIR(fstat->st_mode)){
printf("***%s is not a directy",s);
return -1;
}
//ddir = opendir(d);
//printf("######### s:%s ############# d:%s ##############\n",s,d);
if ((sdir = opendir(s)) == NULL){
printf("opendir %s error: %s\n",s, strerror(errno));
return (-1);
}
if ((ddir = opendir(d)) == NULL){
fprintf(stderr,"opendir %s error:%s\n",d,strerror(errno));
return (-1);
}
sdirbak = sdir;
ddirbak = ddir;
while(!(retval = readdir_r(sdir, &diret, &diret_ptr)) ){
struct stat dirinfo;
int filelen;
if (diret_ptr == NULL){
printf("readdir_r:%s error \n",diret.d_name);
break;
}
if ( (strncmp(diret.d_name, ".", PATH_MAX) == 0) ||
(strncmp(diret.d_name, "..", PATH_MAX) == 0)){
//retval = readdir_r(sdir, &diret, &diret_ptr);
continue;
}
filelen = strlen(diret.d_name);
if (filelen+pathlen > PATH_MAX){
printf("file name too long\n");
}
printf("@@@@ current dire:%s @@@@ \n",diret.d_name);
if (strcmp(s, "/")){
sprintf(filename,"%s/%s",s,diret.d_name);
sprintf(dfilename,"%s/%s",d,diret.d_name);
}else {
sprintf(filename,"/%s",diret.d_name);
sprintf(dfilename,"/%s",diret.d_name);
}
lstat(filename, &dirinfo);
memset(&finfo, 0x00, sizeof(&finfo));
memset(dfilename, 0x00, sizeof(dfilename));
sprintf(finfo.name, "%s",diret.d_name);
sprintf(dfilename,"%s/%s",d,diret.d_name);
printf("w:%s\n\n",dfilename);
//memcpy(&finfo->fstat, &dirinfo, sizeof(dirinfo) );
if (S_ISDIR(dirinfo.st_mode)){
printf("################It is a direct: %s \n", filename);
if (readops(filename, &dirinfo, dfilename) < 0){
printf("read directory %s error \n",filename);
}
rest = scan_dir(filename, dfilename, &dirinfo);
if (rest < 0){
printf("scan %s failed \n",filename);
}
continue;
}
else {
printf("%s not a directory \n",filename);
if (readops(filename, &dirinfo, dfilename) < 0){
printf("read reg file:%s error \n",filename);
}
}
}
while (closedir(sdirbak) != 0);
while (closedir(ddirbak) != 0);
return 0;
}
int readops(char *fname, struct stat *info, char *dname){
int red;
int rfd,wfd;
if(!S_ISREG(info->st_mode)){
if (S_ISDIR(info->st_mode)){
//mkdir(dname, 0644);
mkdir(dname, info->st_mode);
}else if (S_ISFIFO(info->st_mode)){
//mkfifo(dname, 0644);
mkdir(dname, info->st_mode);
}else if (S_ISSOCK(info->st_mode)){
mknod(dname, info->st_mode, info->st_rdev);
}else if ((S_ISBLK(info->st_mode))||(S_ISCHR(info->st_mode))){
mknod(dname, info->st_mode, info->st_rdev);
}else if (S_ISLNK(info->st_mode)){
readlink(fname, buf, BUFSIZE);
symlink(buf, fname);
}
rebak_mod(dname, info);
return 0;
}
if ((rfd = open(fname, O_RDONLY|O_NONBLOCK)) == -1){
printf("open %s error:%s",fname,strerror(errno) );
return -1;
}
if ((wfd = open(dname, O_WRONLY|O_CREAT|O_TRUNC)) == -1){
printf("open write file %s error:%s \n",dname,strerror(errno));
return -1;
}
do{
red = read(rfd, buf, BUFSIZE);
printf("readed :%d \n",red);
if(red < 0){
perror("read error: ");
break;
}else if(red == 0){
printf("read over \n");
break;
}
write(wfd, buf, red);
}while(1);
//if (red < 0)
// return -1;
close(rfd);
close(wfd);
rebak_mod(dname, info);
sync();
return 0;
}
int rebak_mod(char *fname, struct stat *bakmod){
struct utimbuf timebak;
int ret;
if (S_ISLNK(bakmod->st_mode)){
ret = lchown(fname, bakmod->st_uid, bakmod->st_gid);
}
else
ret = chown(fname, bakmod->st_uid, bakmod->st_gid);
if (ret < 0){
printf("can not change file:%s's owner\n",fname);
}
if (!S_ISLNK(bakmod->st_mode)){
ret = chmod(fname, bakmod->st_mode);
}
if (ret < 0 ){
printf("can not change file:%s mode\n",fname);
}
timebak.actime = bakmod->st_atime;
timebak.modtime = bakmod->st_mtime;
if (utime(fname, &timebak) < 0){
printf("can not change file:%s time\n",fname);
}
return 0;
}
/*********************************************************************
*binclude.h
*********************************************************************/
#include
#include
#include
//#include
#include
#include
#include
#include
#define DEVS "/data/sdev"
#define DEVD "/data/ddev"
#ifndef PATH_MAX
#define PATH_MAX 256
#endif
#define BUFSIZE 1024*1024
typedef struct aa{
struct stat statbak;
char name[NAME_MAX];
int flags;
}g_file_inf;