⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 archive.c

📁 Linux系统备份源代码 可基于用户自定义策略实现系统、应用数据备份
💻 C
📖 第 1 页 / 共 3 页
字号:
/***************************************************************************    file                 : archive.c    begin                : Sat Jan 29 2000    copyright            : (C) 2000 by Henrik Witt-Hansen    email                : bean@daisy.net ***************************************************************************//*************************************************************************** *                                                                         * *   This program is free software; you can redistribute it and/or modify  * *   it under the terms of the GNU General Public License as published by  * *   the Free Software Foundation; either version 2 of the License, or     * *   (at your option) any later version.                                   * *                                                                         * ***************************************************************************//*base configuration*/#ifdef HAVE_CONFIG_H#include <config.h>#endif/*standard includes*/#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <string.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>/*local headers*/#include "sitback.h"/*special includes*/#include <sys/stat.h>#include <unistd.h>#include <dirent.h>#include <time.h>#include <pthread.h>#include <signal.h>#include <sys/wait.h>#include <errno.h>/*used by the __stat_location function*/extern int errno;/*local prototypes*/int __stat_location(char *filename,FILE *archivelist,FILE *excludelist,int descend,ino_t stop_ino,dev_t stop_dev);int __write_archiveid();/********************************************************************	  int ArchiveList()  Make a total list of what will be in the archive.  This makes searching and partial restore more  quick and easy.  arguments:    none  return:    -1 on error    0 on success********************************************************************/int ArchiveList(){  FILE *archivelist,*excludelist;  char strn[1024];  pthread_t tracker=0;  /*reset the size counter so that daemon's will not add to the total    sum each time the run, and reset the bad symlinks flag */  conf__archive_size=0;  conf__bad_symlinks=0;  /*Sometime we dont have any files to backup, f.ex. when setting new    archive id on an empty tape. Just create an empty archivelist*/  if(conf__filelist==NULL)  {    if((archivelist=fopen("sitback.archivelist","w"))==NULL)    {      errcode=15;      sprintf(strn,"Unable to open sitback.archivelist. Check permissions\n");      UI__Warning(strn);      return -1;    }    fprintf(archivelist,"\n");    fclose(archivelist);    return 0;  }  /*make sure we are at the beginning of the filelist*/  while(conf__filelist->prev!=NULL)    conf__filelist=conf__filelist->prev;  /*open the archive-list file*/  if((archivelist=fopen("sitback.archivelist","w"))==NULL)  {    errcode=15;    sprintf(strn,"Unable to open sitback.archivelist. Check permissions\n");    UI__Warning(strn);    return -1;  }  /* Open and initialize exclude list */  if((excludelist=fopen("sitback.excludelist","w"))==NULL)  {    errcode=60;    UI__Warning("Unable to open sitback.excludelist. Check permissions\n");    fclose(archivelist);    return -1;  }  fprintf(excludelist,"%s/sitback.debug\n",conf__homedir);  fprintf(excludelist,"%s/sitback.config-debug\n",conf__homedir);  fprintf(excludelist,"%s/sitback.report\n",conf__homedir);  fprintf(excludelist,"%s/sitback.archivelist\n",conf__homedir);  fprintf(excludelist,"%s/*.chk\n",conf__homedir);  fprintf(excludelist,"%s/sitback.excludelist\n",conf__homedir);  fprintf(excludelist,"%s/sitback.tmpout\n",conf__homedir);  fprintf(excludelist,"%s/sitback.archivename\n",conf__homedir);  fprintf(excludelist,"%s/sitback.archiveid\n",conf__homedir);  fprintf(excludelist,"%s/sitback.log\n",conf__homedir);  fprintf(excludelist,"%s/sitback.tmpin\n",conf__homedir);  fprintf(excludelist,"%s/sitback.tmperr\n",conf__homedir);  fprintf(excludelist,"%sarchive.tar\n",conf__temp);  fprintf(excludelist,"%sarchive.tar.gz\n",conf__temp);  fprintf(excludelist,"%sarchive.tar.bz2\n",conf__temp);  fprintf(excludelist,"%sarchive.tar.Z\n",conf__temp);  fprintf(excludelist,"%sarchive.tar.zip\n",conf__temp);  fprintf(excludelist,"%sarchive.zip\n",conf__temp);  fprintf(excludelist,"%ssitback.iso\n",conf__temp);  /*now generate the archive-list*/  unlink("sitback.tmpout");  pthread_create(&tracker,NULL,UI__TrackStdout,NULL); /* track verbose output */  UI__SetProgressText("                                                            ");  while(conf__filelist!=NULL)  {    /*recursively check this location*/    debug("Checking location \"%s\"\n",conf__filelist->target);    if(__stat_location(conf__filelist->target,archivelist,excludelist,1,0,0)==-1)    {      errcode=13;      debug("location '%s' failed\n",conf__filelist->target);      fclose(archivelist);      fclose(excludelist);      if(!pthread_kill(tracker,0))  /* stop tracking output */      {        pthread_cancel(tracker);        pthread_join(tracker,NULL);      }      UI__SetProgressText("                                                            ");      return -1;    }    debug("Done, checking that location\n");    /*next location*/    if(conf__filelist->next!=NULL)      conf__filelist=conf__filelist->next;    else      break;    debug("One more location\n");  }  debug("No more locations to check\n");  /* Stop tracking output */  debug("tracker=%d\n",tracker);  if(!pthread_kill(tracker,0))  {    debug("Killing tracker\n");    pthread_cancel(tracker);    pthread_join(tracker,NULL);  }  UI__SetProgressText("                                                            ");  /* add exclude files from the command line */  debug("Adding excludefiles from command line\n");  if(conf__exclude_files!=NULL)    fprintf(excludelist,"%s\n",conf__exclude_files);  /*close the list-files*/  fclose(archivelist);  fclose(excludelist);  /* Report bad symlinks, if any */  debug("Any bad symlinks ??\n");  if(conf__bad_symlinks)  {    debug("Yep...\n");    UI__Warning("Bad symlinks found. Check the report\n");  }  /*no problems*/  debug("ArchiveList() done\n");  return 0;}/********************************************************************  int __stat_location(char *filename)  recursively check location  arguments:    filename:    starting location    archivelist: filepointer to open archive-list file. Can be                 NULL if the directory or file is just to be                 tested..    excludelist; filepointer to open exclude-list file. Can be                 NULL if the directory or file is just to be                 tested    descend:     if set to 0, dont descend into subdirs.    stop_ino;    stop and return error if this inode is reached.                 (for looping symlink detection)    stop_dev;    stop_ino belongs to this device  return:    -1 on error    0 on success********************************************************************/int __stat_location(char *filename,FILE *archivelist,FILE *excludelist,int descend,ino_t stop_ino,dev_t stop_dev){  char *location;  unsigned int location_length=1024;  struct stat info,linfo;  DIR *dir;  struct dirent *entry;  char strn[1024];  int know_this_is_symlink=0;  char *start,*end;  FILE *file;  char linkpath[4096];  char tmp_linkpath[4096];  char *p;  /* entering __stat_location() */  debug("__stat_location called on \"%s\"\n",filename);  /* Do not check the locations stated in the exclude list */  if(conf__exclude_files!=NULL)  {    debug("Checking location against exclude list\n");    start=conf__exclude_files;    do    {      /* find end of string */      end=start;      while(*end!='\n' && *end!='\0')        end++;      /* check location */      if(strlen(filename)==end-start)  /* only if lenghts is equal */      {        if(!memcmp(filename,start,strlen(filename)))        {          debug("location is included in the exclude list..  skipping\n");          return 0;        }      }      /* next entry */      start=end;      while(*start=='\n')        start++;    }    while(*start!='\0');  }  /* special cases... */  if(!strcmp(filename,"/dev/fd"))  {    debug("Returning since /dev/fd is an infinite loop\n");    fprintf(excludelist,"%s\n",filename);  /*filesize of -1 indicates an error*/    return 0;  }  /* if we are generating the archivelist, dump the filenames     to sitback.tmpout to allow tracking */  if(archivelist!=NULL)  {    if((file=fopen("sitback.tmpout","a"))!=NULL)    {      fprintf(file,"%s\n",filename);      fclose(file);    }  }  /*get info on the initial filename*/  #ifdef HAVE_STAT64  if((stat64(filename,&info))==-1)  #else  if((stat(filename,&info))==-1)  #endif  {    if( errno==EOVERFLOW )    {      debug("OVERFLOW %u %u\n",info.st_blksize,info.st_blocks);    }    debug("unable to stat \"%s\". \"%s\"\n",filename,strerror(errno));    debug("__stat_location return from \"%s\"\n",filename);    /*This error might be due to a bad symlink (link without source). We have to      check for this, since this would make it a sanity problem, not a hard-problem      with the file-system..  Tar just skips by these bad links, so no reason      to make problems about this...*/    #ifdef HAVE_LSTAT64    if((lstat64(filename,&info))==-1)    #else    if((lstat(filename,&info))==-1)    #endif    {      /* weird case..  looping symlinks. */      if(errno==ENAMETOOLONG)      {        UI__Warning("Filename too long.. possibly a looping symlink..\n");        if(strlen(filename)>128)        {          strcpy(&filename[128],"...");          UI__Warning("File is (truncated) '%s'\n",filename);        }        else          UI__Warning("File is '%s'\n",filename);        return -1;      }      /* Access problem ?? */      if(access(filename,R_OK))      {        UI__Warning("Bad permissions or dead link. '%s'\n",filename);        return -1;      }      /* Nope. this is really a problem.         write this bad entry into the archive-list and        include it in the exclude list */      UI__Warning("Bad location '%s'\n",filename);      log("Unable to stat location '%s'. Error '%s'",filename,strerror(errno));      return -1;    }    else    {      /* If we are checking a looping symlink, skip the output noise,         we might encounter a bad symlink error when a loop gets         too long, but this still has to be reported only as a         looping symlink, so the user do not get confused */      if(stop_ino==0 && stop_dev==0)      {        log("Bad symlink '%s'",filename);        Report("Bad symlink '%s'\n",filename);      }      if(archivelist!=NULL)        fprintf(archivelist,"%s,%ld\n",filename,info.st_size);      if(excludelist!=NULL)        fprintf(excludelist,"%s\n",filename);      if(conf__ignore_bad_symlinks==0)      {        UI__Warning("Bad symlink found '%s'\n",filename);        return -1;      }      else        conf__bad_symlinks=1;      /* Symlink is ignored */      return 0;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -