📄 label_tape.c
字号:
/****************** Start of $RCSfile: label_tape.c,v $ ****************** $Source: /home/alb/afbackup/afbackup-3.3.8.1/RCS/label_tape.c,v $* $Id: label_tape.c,v 1.5 2004/07/08 20:34:44 alb Exp alb $* $Date: 2004/07/08 20:34:44 $* $Author: alb $********* description *********************************************************************************************************************/#include <conf.h>#include <version.h> static char * fileversion = "$RCSfile: label_tape.c,v $ $Source: /home/alb/afbackup/afbackup-3.3.8.1/RCS/label_tape.c,v $ $Id: label_tape.c,v 1.5 2004/07/08 20:34:44 alb Exp alb $ " PACKAGE " " VERSION_STRING;#include <stdio.h>#include <unistd.h>#include <stdarg.h>#include <fcntl.h>#include <sys/utsname.h>#ifdef HAVE_SYS_WAIT_H#include <sys/wait.h>#endif#ifdef HAVE_SYS_PARAM_H#include <sys/param.h>#endif#include <genutils.h>#include <x_regex.h>#include <fileutil.h>#include <packer.h>#include <mvals.h>#include <sysutils.h>#include "backup.h"#define CLEANUP { goto cleanup; }#define GETOUT { goto getout; }#define CLEANUPR(rval) { r = rval; goto cleanup; }Flag interactive;struct utsname unam;UChar *configfile = NULL;UChar *programfile = NULL;UChar *programdir = NULL;UChar *bindir = NULL;UChar *libdir = NULL;UChar *confdir = NULL;UChar *vardir = NULL;ReplSpec replacements[] = { { "%B", NULL, &bindir }, { "%L", NULL, &libdir }, { "%C", NULL, &confdir }, { "%V", NULL, &vardir }, };UChar *mail_program = NULL;UChar *user_to_inform = NULL;UChar *devicesstr = NULL;UChar *devicename = NULL;/* for cart_ctl */Int32 pos_in_changer = 0;UChar *changername = NULL;Int32 num_changer_slots = 0;Int32 num_changer_loadports = 0;UChar *changerconffile = NULL;StreamerDevice *streamers = NULL;Int32 num_streamers = 0;ChangerDevice *changers = NULL;Int32 num_changers = 0;Int32 curdevidx = 0;#define LOC_DRIVE 0#define LOC_SLOT 1#define LOC_LOADPORT 2#define LOC_EXTERNAL 99#define LOC_UNKNOWN 100#define NUM_LOC_CMD 3#define MOVE_UNSUPPORTED -99UChar *cartmove_cmds[NUM_LOC_CMD /* source */][NUM_LOC_CMD /* target */];UChar *freeslots_cmd = NULL;UChar *freeloadports_cmd = NULL;UChar *cartloc_file = NULL;Flag cctl_inventory = NO; /* operation flags from args */Flag cctl_move = NO;Flag cctl_label = NO;Flag cctl_list = NO;Flag cctl_eject = NO;Int32 have_loc_arg = 0;Int32 have_drive_arg = 0;Int32 have_loadp_arg = 0;Int32 have_slot_arg = 0;UChar *locstr = NULL; /* arg strings */UChar *cartstr = NULL; /* from command line */UChar *slotstr = NULL;UChar *loadportstr = NULL;UChar *drivestr = NULL;Uns32Range *cartridges = NULL; /* the really used ranges */Uns32Range *slots = NULL;Uns32Range *loadports = NULL;Uns32Range *drives = NULL;Int32 n_slots = 0; /* n_ means number of given */Int32 n_drives = 0;Int32 n_cartridges = 0;Int32 n_loadports = 0;UChar *given_changer = NULL;Int32 cartis_wcart = -1;Int32 cartis_wfile = -1;Int32 have_cartis_cart = 0;Int32 cartis_cart = -1;Int32 cartridge_set = 1;Uns32 cartins_gracetime = DEFAULT_CARTGRACETIME;Uns32 devunavail_send_mail = DEFAULT_DEVUNAVSENDMAIL;Uns32 devunavail_give_up = DEFAULT_DEVUNAVGIVEUP;UChar *bytesontape_file = NULL;UChar *precious_tapes_file = NULL;UChar *cartorder_file = NULL;UChar *ro_tapes_file = NULL;UChar *used_blocksizes_file = NULL;UChar *tapeposfile = NULL;UChar *client_message_file = NULL;Flag forced = NO;Flag query = NO;Flag dont_ask = NO;Flag delfromhd = NO;Flag only_read_label = NO;struct stat default_stat;struct stat devstatb;UChar *setfilecmd = NULL;Int32 tapeblocksize = DEFAULT_TAPEBLOCKSIZE;Int32 num_cartridges = 1;Int32 label = -1;Int32 scnd_label = -1;Int32 label_given = 0;Int32 scnd_label_arg = 0;UChar *comment = "<labeled manually>";Int32 actcart = 0;UChar *infobuffer;Int32 infobuffersize;UChar *loggingfile = NULL;UChar *syslog_ident = NULL;UChar *remoteuser = NULL;UChar *clientuname = NULL;#define TMPBUFSIZ 4096UChar tmpbuf[TMPBUFSIZ];Int32 mode = -1;#define MODE_LABEL_TAPE 0#define MODE_CART_CTL 1#define MODE_CART_IS 2UChar *cmd_res[] = { "[Ll][Aa][Bb][Ee][Ll]", "[Cc][Aa][Rr][Tt].*[Cc][Tt]\\([Rr]\\)?[Ll]", "[Cc][Aa][Rr][Tt].*[Ii][Ss]", };#define BU_NO_LOCK 0#define BU_LOCKED 1#define BU_GOT_LOCK 2#define BU_CANT_LOCK 99typedef struct __lockData { UChar *lockfile; int lockfd; UChar locked;} LockData;LockData devicelock = { NULL, -1, BU_NO_LOCK };LockData changerlock = { NULL, -1, BU_NO_LOCK };#define NUM_CHCF_ENTRIES 11#define NUM_PRESET_CHCF_ENTRIES 2static ParamFileEntry changerconf[NUM_CHCF_ENTRIES] = { { &freeslots_cmd, NULL, (UChar *) "^[ \t]*\\([Ll]ist[ \t]*\\)?\\([Ff]ree\\|[Ee]mpty\\)[-_ \t]*[Ss]lots?[-_ \t]*[Cc]o?mm?a?n?d:?[ \t]*", TypeUCharPTR }, { &freeloadports_cmd, NULL, (UChar *) "^[ \t]*\\([Ll]ist[ \t]*\\)?\\([Ff]ree\\|[Ee]mpty\\)[-_ \t]*[Ll]oad[-_ \t]*\\([Pp]ort\\|[Bb]ay\\)s?[-_ \t]*[Cc]o?mm?a?n?d:?[ \t]*", TypeUCharPTR },};/* the indexes of the following 2 must correspond to the macros LOC_XXX above */static UChar *loc_re_strings[] = { "[Dd][Rr][Ii][Vv][Ee]", "[Ss][Ll][Oo][Tt]", "[Ll][Oo][Aa][Dd][-_ \t]*\\([Pp][Oo][Rr][Tt]\\|[Bb][Aa][Yy]\\)",};static UChar *loc_strings[] = { TN_("drive"), TN_("slot"), TN_("loadport"),};UChar *default_configfilenames[] = { \ DEFAULT_SERVER_CONFIGFILES, NULL, NULL };ParamFileEntry entries[] = { { &devicesstr, NULL, (UChar *) "[Bb]ackup[-_ \t]*[Dd]evi?c?e?:?[ \t]*", TypeUCharPTR }, { &devicelock.lockfile, NULL, (UChar *) "^[ \t]*[Ll]ocki?n?g?[-_ \t]*[Ff]ile:?[ \t]*", TypeUCharPTR }, { &changerlock.lockfile, NULL, (UChar *) "^[ \t]*[Cc][Hh][Aa][Nn][Gg][Ee][Rr][-_ \t]*[Ll][Oo][Cc][Kk]\\([Ii][Nn][Gg]\\)?[-_ \t]*[Ff][Ii][Ll][Ee]:?[ \t]*", TypeUCharPTR }, { &tapeblocksize, NULL, (UChar *) "[Tt]ape[-_ \t]*[Bb]lock[-_ \t]*[Ss]ize:?", TypeInt32 }, { &setfilecmd, NULL, (UChar *) "[Ss]et[-_ \t]*[Ff]ile[-_ \t]*[Cc]o?mm?a?n?d:?[ \t]*", TypeUCharPTR }, { &num_cartridges, NULL, (UChar *) "[Nn]umb?e?r?[-_ \t]*[Oo]f[-_ \t]*[Cc]artr?i?d?g?e?s[-_ \t]*:?", TypeInt32 }, { &vardir, NULL, (UChar *) "^[ \t]*[Vv][Aa][Rr][-_ \t]*[Dd]ire?c?t?o?r?y?:?[ \t]*", TypeUCharPTR }, { &user_to_inform, NULL, (UChar *) "^[ \t]*[Uu]ser[-_ \t]*[Tt]o[-_ \t]*[Ii]nfor?m?:?[ \t]*", TypeUCharPTR }, { &mail_program, NULL, (UChar *) "^[ \t]*[Mm]ail[-_ \t]*[Pp]rogram:?[ \t]*", TypeUCharPTR }, { &changerconffile, NULL, (UChar *) "^[ \t]*[Cc][Hh][Aa][Nn][Gg][Ee][Rr][-_ \t]*[Cc][Oo][Nn][Ff][Ii][Gg]\\([Uu][Rr][Aa][Tt][Ii][Oo][Nn]\\)?[-_ \t]*\\([Ff][Ii][Ll][Ee][-_ \t]*\\)?:?[ \t]*", TypeUCharPTR }, { &tapeposfile, NULL, (UChar *) "^[ \t]*[Tt]ape[-_ \t]*[Pp]osi?t?i?o?n?[-_ \t]*[Ff]ile:?[ \t]*", TypeUCharPTR }, { &cartins_gracetime, NULL, (UChar *) "^[ \t]*[Cc]artr?i?d?g?e?[-_ \t]*[Ii]nse?r?t?[-_ \t]*[Gg]race[-_ \t]*[Tt]ime:?", TypeUns32 }, { &devunavail_send_mail, NULL, (UChar *) "^[ \t]*[Dd]evi?c?e?[-_ \t]*[Uu]n[Aa]vaila?b?l?e?[-_ \t]*[Ss]end[-_ \t]*[Mm]ail[-_ \t]*\\([Aa]fter[-_ \t]*\\)?[Mm]inu?t?e?s?:?", TypeUns32 }, { &devunavail_give_up, NULL, (UChar *) "^[ \t]*[Dd]evi?c?e?[-_ \t]*[Uu]n[Aa]vaila?b?l?e?[-_ \t]*[Gg]ive[-_ \t]*[Uu]p[-_ \t]*\\([Aa]fter[-_ \t]*\\)?[Mm]inu?t?e?s?:?", TypeUns32 }, { &loggingfile, NULL, (UChar *) "^[ \t]*[Ll]ogg?i?n?g?[-_ \t]*[Ff]ile:?[ \t]*", TypeUCharPTR }, };UChar *lockdirs[] = { "/var/locks", "/var/lock", "/var/spool/locks", "/var/spool/lock", "/var/tmp", "/tmp", NULL,};int waitlockfd = -1;#define EM__(nmem) { nomemfatal(nmem); }#define ER__(func, i) { if( (i = func) ) return(i); }#define EEM__(st) { if(st) nomemfatal(NULL); }#define repl_dirs(string) repl_substrings((string), replacements, \ sizeof(replacements) / sizeof(replacements[0]))static int cart_ctl(Int32, UChar **);static int label_tape(Int32, UChar **);static int cart_is(Int32, UChar **);static void report_problem(UChar *, ...);static Int32 move_cartridge_to(Int32, Int32, UChar *, Int32);voidlogmsg(int prio, UChar * fmt, ...){ va_list args; FILE *fp, *lfp = NULL; va_start(args, fmt); if(loggingfile) lfp = fopen(loggingfile, "a"); fp = (lfp ? lfp : stderr); fprintf(fp, "%s, ", actimestr()); vfprintf(fp, fmt, args); fflush(fp); if(lfp) fclose(lfp); if(syslog_ident) gvsyslog(syslog_ident, LOG_CONS | LOG_PID, LOG_DAEMON, prio, fmt, args); va_end(args);}voidrelease_lock(LockData * the_lock){ if(the_lock->locked == BU_GOT_LOCK){ close(the_lock->lockfd); unlink(the_lock->lockfile); the_lock->lockfd = -1; the_lock->locked = BU_NO_LOCK; }}voiddo_exit(int exitst){ release_lock(&devicelock); release_lock(&changerlock); exit(exitst);}voidfatal(UChar * msg){ fprintf(stderr, "%s", msg); do_exit(1);}voidnomemfatal(void * ptr){ if(!ptr) fatal(T_("Error: Cannot allocate memory.\n"));}Int32message_to_operator(FILE * mfp, Flag issue_clientmsg){ FILE *pp = NULL; UChar *mp, *cptr, *cptr2, msg_buf[1024]; Int32 r = 0, n; int fd; time_t starttime, time_now; struct stat statb; forever{ /* pseudo-loop for easily skipping code with break */ if(strlen(remoteuser) > 0){ mp = repl_substring(mail_program, "%U", remoteuser); if(!mp){ r |= 1; break; } } else{ mp = strdup(mail_program); if(!mp){ r |= 1; break; } while( (cptr = strstr(mp, "%U")) ){ /* remove entire word with %U */ cptr2 = first_space(cptr); cptr2 = first_nospace(cptr2); while(cptr > mp && !isspace(*(cptr - 1))) cptr--; memmove(cptr, cptr2, strlen(cptr2) + 1); } } if(strlen(clientuname) > 0){ cptr = repl_substring(mp, "%H", clientuname); free(mp); mp = cptr; if(!mp){ r |= 1; break; } } else{ while( (cptr = strstr(mp, "%H")) ){ /* remove entire word with %H */ cptr2 = first_space(cptr); cptr2 = first_nospace(cptr2); while(cptr > mp && !isspace(*(cptr - 1))) cptr--; memmove(cptr, cptr2, strlen(cptr2) + 1); } } pp = popen(mp, "w"); free(mp); break; /* always break */ } fd = -1; starttime = time(NULL); while(issue_clientmsg){ if(!stat(client_message_file, &statb)){ time_now = time(NULL); if(statb.st_mtime >= time_now){ ms_sleep((statb.st_mtime - time_now + 1) * 1000); continue; } } /* in fact we have a race here, but this is uncricital */ fd = set_wlock(client_message_file); if(fd >= 0){ ftruncate(fd, 0); break; } if(time(NULL) > starttime + 60){ r |= 2; break; } ms_sleep(200 + (Int32)(drandom() * 500.0)); } fseek(mfp, 0, SEEK_SET); while((n = fread(msg_buf, 1, 1024, mfp)) > 0){ if(fd >= 0) write_forced(fd, msg_buf, n); if(pp) fwrite(msg_buf, 1, n, pp); } fclose(mfp); if(fd >= 0) close(fd); if(pp) pclose(pp); return(r);}Int32set_lock(LockData * the_lock, Flag optional){ struct stat statb; int i; char buf[20]; struct flock lockb; if(the_lock->locked == BU_GOT_LOCK) return((Int32) the_lock->locked); i = lstat(the_lock->lockfile, &statb); if(!i && !IS_REGFILE(statb)){ if(unlink(the_lock->lockfile)){ fprintf(stderr, T_("Error: Cannot remove lock file entry `%s', that is not a file.\n"), the_lock->lockfile); return( (Int32) (the_lock->locked = BU_CANT_LOCK) ); } i = 1; } if(!i){ the_lock->lockfd = open(the_lock->lockfile, O_WRONLY | O_SYNC); if(the_lock->lockfd < 0){ fprintf(stderr, T_("Warning: Lock file `%s' exists, but can't open it.\n"), the_lock->lockfile); return( (Int32) (the_lock->locked = BU_CANT_LOCK) ); } } else{ the_lock->lockfd = open(the_lock->lockfile, O_WRONLY | O_CREAT | O_SYNC, 0644); if(the_lock->lockfd < 0){ fprintf(stderr, "%s: %s `%s'.\n", optional ? T_("Warning") : T_("Error"), T_("Cannot create lock file"), the_lock->lockfile); return( (Int32) (the_lock->locked = BU_CANT_LOCK) ); } } SETZERO(lockb); lockb.l_type = F_WRLCK; i = fcntl(the_lock->lockfd, F_SETLK, &lockb); if(i){ if(!optional || interactive) fprintf(stderr, "%s: %s `%s'.\n", optional ? T_("Warning") : T_("Error"), T_("Cannot lock file"), the_lock->lockfile); return( (Int32) (the_lock->locked = BU_LOCKED) ); } sprintf(buf, "%d\n", (int) getpid()); write(the_lock->lockfd, buf, strlen(buf)); return( (Int32) (the_lock->locked = BU_GOT_LOCK) );}static voidset_devices(Int32 idx){ devicename = streamers[idx].devicename; if(streamers[idx].changer){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -