LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 907|回复: 3

一个简单却又让人头痛的备份程序

[复制链接]
发表于 2006-7-6 09:17:01 | 显示全部楼层 |阅读模式
我新买了刻录机,用它来备份。自然要编一个程序来找出指定日期以后在硬盘上出现或新被修改的文件。如下:
//This programme is writed by Vesuvius.
//It can be copy and motify under GNU General Public license.
#include <stdio.h>
#include <dirent.h>
#include <sys/stat.h>
#include <time.h>
#include <fcntl.h>
//The result file for test output.
FILE *out;
typedef struct dirent Di;
//The time which to be compared.
time_t com;
//The tmp root dirent for each find function.
char *rot;
extern char *mkstring(char *a,char*b,char *c);
//We need function which can create dir and cp file properly.
void makedir(char *a)
{
        int n,j;
        char *b;
        b=(char *)malloc(sizeof(char)*strlen(a));
        for(n=0;n<=strlen(a);n++)
          if(a[n]=='/'){
                strncpy(b,a,n);b[n]='\0';mkdir(b,666);
                //printf("The dir to be created is %s.\n",b);
                }
        mkdir(a,666);
        //printf("The dir to be created is %s.\n",a);
        free(b);
}
void copy(char *from,char *to)
{
        char buffer[4096];
        int in,out,n,m;
        in=open(from,O_RDONLY,666);
        if(in==-1) perror("open");
        out=open(to,O_WRONLY|O_CREAT,666);
        if(out==-1) perror("open");
        while(1){
         n=read(in,buffer,2048);
         if(n==-1) {perror("read");break;}
         if(n==0) break;
         m=write(out,buffer,n);
         if(m==-1) {perror("write");break;}
         if(m<n) {printf("little:%s\n",from);break;}
        }
        n=close(in);m=close(out);
        if(n==-1 || m==-1) printf("end\n");
        printf("The file to be copyed is %s and %s .\n",from,to);
}
//The two functions below is for scandir()
//scandir() find dir and file which after com.
//then qsort them with dir first file below.
int select1(const Di *a)
{
        struct stat buf;
        char *fname;
       
        if(strcmp(a->d_name,"..")!=0 && strcmp(a->d_name,".")!=0
                && strcmp(a->d_name,"System Volume Information")!=0) {
         if (a->d_type==DT_DIR) return 1;
         else{
          fname=mkstring(rot,"/",a->d_name);
          if(stat(fname,&buf)!=0) perror("stat");
          free(fname);
          if(buf.st_ctime>com) return 1;else return 0;          
         }
        }
        else return 0;
}
int compare(const Di **a,const Di **b)
{
        if((*a)->d_type!=DT_DIR) return 1;
        else return 0;
}
//This function link strings.
char *mkstring(char *a,char*b,char *c)
{
        char *r;
        r=(char *)malloc(sizeof(char)*(strlen(a)+strlen(b)+strlen(c)+1));
        sprintf(r,"%s%s%s",a,b,c);
        return r;
}
//The kernel function.
//find the file needed and write in result(like ls -R) or copy them.
void find(char *root,char *des)
{
        Di **list;
        int n;
        char *name,*name2,*name3;
        struct stat buf;

        rot=root;
        n=scandir(root,&list,select1,0);
        if(n>0 && list[n-1]->d_type!=DT_DIR) {
                fprintf(out,"%s\n",root);
                name2=mkstring(des,"/",root+1);
                makedir(name2);
                free(name2);
        }
        if(n<=0) {printf("%s is %d.\n",root,n);perror("scandir");}
        n--;
        while(n>=0){
           name=mkstring(root,"/",list[n]->d_name);
           stat(name,&buf);
           if(list[n]->d_type==DT_DIR) {
                find(name,des);
                free(name);
           }else{
                fprintf(out," %s\n",name);
                name3=mkstring(des,"/",name+1);
                copy(name,name3);
                free(name);
                free(name3);
           }
           free(list[n]);
           n--;
        }
}
//change the string refer to time.
//xxxxxxxx is 20040102
//to time_t
time_t gettime(char *a)
{
        struct tm t;
        int i;
        for(i=0;i<=7;i++) a-=48;
        t.tm_year=a[0]*1000+a[1]*100+a[2]*10+a[3]-1900;
        t.tm_mon=a[4]*10+a[5]-1;
        t.tm_mday=a[6]*10+a[7];
        t.tm_sec=t.tm_hour=t.tm_min=t.tm_isdst=0;
        return mktime(&t);
}
//第一个参数是要备份的源文件地址,第二个参数是日期如20060101,第三个是将找到的文件要复制到的位置
int main(int a,char **li)
{
        out=fopen("result","w");
        com=gettime(li[2]);
        find(li[1],li[3]);
        fclose(out);
        return 0;
}
--------------------------------------------
现在好了,我的e盘转成了ntfs且进行了磁盘清理,多数旧文件日期变成了最近的,这个程序也就失效了。
请问大家有无办法改进这一程序,或者提供利用刻录机备份的其他方法?
Thank you!
发表于 2006-7-6 09:49:39 | 显示全部楼层
这个用shell脚本做应该更简单吧。

1. find出一定条件的所有文件,拷到另一个地方
2. 用mkisofs把这些文件打成iso
3. 再把iso刻录到光盘
回复 支持 反对

使用道具 举报

 楼主| 发表于 2006-7-6 13:05:48 | 显示全部楼层
无论那种方式,我要解决的是应使用那种日期的问题。
回复 支持 反对

使用道具 举报

发表于 2006-7-11 23:26:52 | 显示全部楼层
判断创建时间应该可以,修改时间也许会随文件系统转换而改变

不过转换文件系统这种情况不会经常发生吧,所以我觉得程序没必要考虑文件系统转换的情况

就像2楼说的,写个脚本大概10行以内就解决问题了
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表