📄 backup.c
字号:
/*************************************************************************** file : backup.c begin : Sun Jan 30 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 <pthread.h>#include <stdlib.h>#include <unistd.h>#include <string.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <errno.h>#include <time.h>/*local headers*/#include "sitback.h"/*special includes*/#include <sys/errno.h>#include <time.h>#include <sys/ioctl.h>#include <signal.h>#include <sys/wait.h>/*local prototypes*/void __run_backup_script();void *__check_for_new_volume(void *word);void __daemon_killed(int signal);void __backup_cleanup();int __execute_backup();int __execute_tar_backup();int __execute_filecopy_backup();int __execute_iso_backup(char *archive);int __execute_verify();int __execute_tar_verify();int __execute_filecopy_verify();void __caught_sigpipe(int signal);int __run_with_tracker(char *command);int __execute_iso_backup_on_the_fly(char *archive);int __make_archive_cd();int __tracksize(char *archive);int __execute_zip_backup();/*local data*/extern int errno;/******************************************************************** int Backup() Prepare the backup arguments: none return: 0 on success -1 on error********************************************************************/int Backup(){ time_t start_time=0; time_t end_time; int retry; char *p; char timecomponent[5]; time_t currtime=time(NULL); struct tm *timeptr=localtime(&currtime); struct stat fi; FILE *file; char ch; /*single process or daemon*/ if(Daemonize()) return -1; /*install a signal handler to handle clenanup when killed*/ if(signal(SIGINT,__daemon_killed)==SIG_ERR) { log("Unable to install signal handler for SIGINT"); } if(signal(SIGTERM,__daemon_killed)==SIG_ERR) { log("Unable to install signal handler for SIGTERM"); } if(signal(SIGPIPE,__caught_sigpipe)==SIG_ERR) { log("Unable to install signal handler for SIGPIPE"); } /*Tell the log that we are ready*/ log("Backup operation initialized and ready"); /*go into a loop, break out at end of the loop if not a daemon*/ for(;;) { /* clear the errcode in case we a daemon wich had errors */ errcode=0; /*if a time is set, wait for that time-condition to occur*/ if(conf__timelist!=NULL) { debug("Time-info present. Waiting for time-condition\n"); UI__Message("Waiting until %s\n",Next_time_condition()); log("Waiting until %s",Next_time_condition()); Wait_for_time_condition(); } else if(conf__timelist==NULL && conf__mode==DAEMON) { /*Uh, this is not allowed*/ errcode=18; debug("Daemon mode requires at least 1 time string\n"); log("Request for sitback to run as daemon, but no time-info.. This is not allowed"); return -1; } /* Initialize the report */ if(Initialize_Report()) { errcode=99; log("Unable to open report file\n"); UI__Warning("Unable to open report file\n"); if( conf__mode!=SINGLE ) goto BACKUP_RESTART; else break; } /* any command or script to run before the backup ?? */ if(conf__before[0]!='\0') { UI__Message("Running 'before' command\n"); debug("Running command '%s'\n",conf__before); Report("'Before':\n"); Report("---------\n\n"); if(__run_with_tracker(conf__before)) { /* report it, then stop.. we might depend in this */ log("Error while executing 'before backup' command"); UI__Warning("Error while executing 'before backup' command\n"); Report("Error"); if( !stat("sitback.tmpout",&fi) && fi.st_size!=0 ) { if( (file = fopen("sitback.tmpout","r"))!=NULL ) { Report("\n\n"); ch = fgetc(file); while( !feof(file) ) { Report("%c",ch); ch = fgetc(file); } fclose(file); } } Report("\n\n\n\n"); Finalize_Report(); errcode=78; if( conf__mode!=SINGLE ) goto BACKUP_RESTART; else break; } Report("Success\n\n\n\n"); } /*allow a certain amount of retry's*/ for(retry=conf__retry;retry>0;retry--) { /*get the current timestamp*/ start_time=time(NULL); /* Any substitutions in the archive name ?? */ strcpy(conf__archive,conf__org_archive); if((p=strstr(conf__archive,"%Y"))!=NULL && strlen(conf__archive)<252) { /* Year */ memmove(p+4,p+2,strlen(p+2)+1); sprintf(timecomponent,"%04d",timeptr->tm_year+1900); memcpy(p,timecomponent,4); } if((p=strstr(conf__archive,"%M"))!=NULL) { /* Month */ sprintf(timecomponent,"%02d",timeptr->tm_mon+1); memcpy(p,timecomponent,2); } if((p=strstr(conf__archive,"%D"))!=NULL) { /* Day of month */ sprintf(timecomponent,"%02d",timeptr->tm_mday); memcpy(p,timecomponent,2); } if((p=strstr(conf__archive,"%h"))!=NULL) { /* Hour */ sprintf(timecomponent,"%02d",timeptr->tm_hour); memcpy(p,timecomponent,2); } if((p=strstr(conf__archive,"%m"))!=NULL) { /* Minute */ sprintf(timecomponent,"%02d",timeptr->tm_min); memcpy(p,timecomponent,2); } if((p=strstr(conf__archive,"%s"))!=NULL) { /* Sec. */ sprintf(timecomponent,"%02d",timeptr->tm_sec); memcpy(p,timecomponent,2); } if((p=strstr(conf__archive,"%w"))!=NULL) { /* Sec. */ memmove(p,p+1,strlen(p+1)+1); sprintf(timecomponent,"%01d",timeptr->tm_wday); memcpy(p,timecomponent,1); } /*Start backup*/ debug("Running backup script\n"); __run_backup_script(); /*Sets errcode if any error*/ debug("Backup script executed, errorcode=%d\n",errcode); remove(conf__start_mark); /* Make sure that all zombies is dead */ while(waitpid(-1,NULL,WNOHANG | WUNTRACED)>0) debug("Zombie put to rest...\n"); /*check for errors during backup*/ if(errcode) { debug("backup indicated error %d. Retry's left: %d\n",errcode,retry-1); if(retry>1) UI__Message("Retrying operation\n"); else { if( conf__mode!=SINGLE ) goto BACKUP_RESTART; else break; } errcode=0; } else { break; } } /* any command or script to run after the backup ?? */ if(conf__after[0]!='\0' && errcode==0) { UI__Message("Running 'after' command\n"); debug("Running command '%s'\n",conf__after); Report("'After':\n"); Report("--------\n\n"); if(ArchiveReady(3600)) { log("Error while waiting for device to become available"); Report("Device did not become available..\n\n\n\n"); } else if(__run_with_tracker(conf__after)) { /* report it, then stop... we might need it */ log("Error while executing 'after backup' command"); UI__Warning("Error while executing 'after backup' command\n"); Report("Error"); if( !stat("sitback.tmpout",&fi) && fi.st_size!=0 ) { if( (file = fopen("sitback.tmpout","r"))!=NULL ) { Report("\n\n"); ch = fgetc(file); while( !feof(file) ) { Report("%c",ch); ch = fgetc(file); } fclose(file); } } Report("\n\n\n\n"); Finalize_Report(); errcode=79; if( conf__mode!=SINGLE ) goto BACKUP_RESTART; else break; } Report("Success\n\n\n\n"); } /*general info at end of report*/ Finalize_Report(); /*cleanup after backup*/ __backup_cleanup(); /*if we are only supposed to run once, break out now*/ if(conf__mode==SINGLE) break; /*time-condition is checked on minutes, so we must be at least 1 minute after the time-condition was true, before continuing, elsewise we risk that the backup restarts*/ BACKUP_RESTART: while((end_time=time(NULL))-start_time<60) { debug("Waiting for the time to pass current minutes-count\n"); sleep(30); } } /*no problems*/ return errcode; /*0 if no errors, else error-code*/}/******************************************************************** void __run_backup_script() Run the backup as specified in the script arguments: none, uses conf__*** return: none, instead errcode is set********************************************************************/void __run_backup_script(){ int rc; FILE *err_in; char ch; char buffer[57]; unsigned int count=0; pthread_t vchecker=0; pthread_attr_t attr; char errbuffer[1026]; pthread_t tracker=0; int msg_on=0; int exec_pid; char backup_new_volume_msg[]="Backup\n- Creating archive\n"; char verify_new_volume_msg[]="Verify\n"; unsigned error_severity; char ch2strn[2]; /*say something to the log*/ log("Backup operation starting..."); UI__Message("Backup operation starting...\n"); /*sync the filesystem*/ Sync(); /*The backup device _must_ be available at this point in time.. No work has been done, so check for it.. Well. the user may have started a single backup operation before the tape has completed the initial alignment of the head, so allow for a little bit of time to go by before giving up*/ if(ArchiveReady(3600)) { errcode=50; log("Archive or device no longer available"); Report("Archive or device no longer available\nERROR\n"); return; } /* Rewind */ if(RewindDevice()) { Report("Unable to rewind the tape\n"); return; } /*make the archive-list file*/ UI__Message("Writing archive list\n"); Report("Archivelist: [%s]\n",conf__script_name); Report("---------------"); for(count=0;count<=strlen(conf__script_name);count++) Report("-"); Report("\n\n"); if(ArchiveList()==-1) { log("Unable to create archivelist file. Error %d",errcode); Report("Error while creating the archivelist file. Please check the logfile\n"); return; } Report("Success\n\n\n\n"); /*make the archive-name file*/ if(ArchiveName()==-1) { log("Unable to create archivename file. Error %d",errcode); Report("Error while creating the archivename file. Please check the logfile\n"); return; } /*check for an old archive id*/ if(conf__skip_old_archiveinfo==0 && (conf__type==TAR || conf__type==FILECOPY)) { UI__Message("Trying to obtain id from current archive\n"); if(OldArchiveId()==-1) { log("Error while trying to resolve current archive-id. Error %d",errcode); Report("Error while trying to resolve current archive-id. Please check the logfile\n"); return; } /*make sure the tape is rewound*/ if(RewindDevice()) { Report("Unable to rewind the tape\n"); return; } } /*make the archive-id file*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -