📄 archive.c
字号:
/*************************************************************************** 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 + -