📄 chg-scsi.c
字号:
char *argv[], command *rval){ int i; for (i=0; i < argc; i++) dbprintf(_("ARG [%d] : %s\n"), i, argv[i]); i = 0; if ((argc<2)||(argc>3)) usage(argv); while ((i<COMCOUNT)&&(strcmp(argdefs[i].str,argv[1]))) i++; if (i==COMCOUNT) usage(argv); rval->command_code = argdefs[i].command_code; if (argdefs[i].takesparam) { if (argc<3) usage(argv); rval->parameter=argv[2]; } else { if (argc>2) usage(argv); rval->parameter=0; }}/* used to find actual slot number from keywords next, prev, first, etc */intget_relative_target( int fd, int nslots, char *parameter, int param_index, int loaded, char *slot_file, int slot_offset, int maxslot){ int current_slot; (void)loaded; /* Quiet unused parameter warning */ current_slot = get_current_slot(slot_file); if (current_slot > maxslot) { current_slot = slot_offset; } if (current_slot < slot_offset) { current_slot = slot_offset; } switch(param_index) { case SLOT_CUR: return current_slot; case SLOT_NEXT: case SLOT_ADVANCE: if (++current_slot==nslots+slot_offset) return slot_offset; return current_slot; case SLOT_PREV: if (--current_slot<slot_offset) return maxslot; return current_slot; case SLOT_FIRST: return slot_offset; case SLOT_LAST: return maxslot; default: break; } g_printf(_("<none> no slot `%s'\n"),parameter); close(fd); exit(2); /*NOTREACHED*/}/* This function should ask the drive if it wants to be cleaned */intask_clean( char *tapedev){ int ret; ret = get_clean_state(tapedev); if (ret < 0) /* < 0 means query does not work ... */ { return(0); } return ret;}/* This function should move the cleaning cartridge into the drive */voidclean_tape( int fd, char *tapedev, char *cnt_file, int drivenum, int cleancart, int maxclean, char *usagetime){ int counter; if (cleancart == -1 ){ return; } /* Now we should increment the counter */ if (cnt_file != NULL){ counter = get_current_slot(cnt_file); counter++; if (counter>=maxclean){ /* Now we should inform the administrator */ char *mail_cmd = NULL; FILE *mailf = NULL; int mail_pipe_opened = 1;#ifdef MAILER if(getconf_seen(CNF_MAILTO) && strlen(getconf_str(CNF_MAILTO)) > 0 && validate_mailto(getconf_str(CNF_MAILTO))) { mail_cmd = vstralloc(MAILER, " -s", " \"", _("AMANDA PROBLEM: PLEASE FIX"), "\"", " ", getconf_str(CNF_MAILTO), NULL); if((mailf = popen(mail_cmd, "w")) == NULL){ g_printf(_("Mail failed\n")); error(_("could not open pipe to \"%s\": %s"), mail_cmd, strerror(errno)); /*NOTREACHED*/ } } else { mail_pipe_opened = 0; mailf = stderr; g_fprintf(mailf, _("\nNo mail recipient specified, output redirected to stderr")); } #else mail_pipe_opened = 0; mailf = stderr; g_fprintf(mailf, _("\nNo mailer specified; output redirected to stderr"));#endif g_fprintf(mailf,_("\nThe usage count of your cleaning tape in slot %d"), cleancart); g_fprintf(mailf,_("\nis more than %d. (cleanmax)"),maxclean); g_fprintf(mailf,_("\nTapedrive %s needs to be cleaned"),tapedev); g_fprintf(mailf,_("\nPlease insert a new cleaning tape and reset")); g_fprintf(mailf,_("\nthe countingfile %s"),cnt_file); if(mail_pipe_opened == 1 && pclose(mailf) != 0) { error(_("mail command failed: %s"), mail_cmd); /*NOTREACHED*/ } return; } put_current_slot(cnt_file, counter); } load(fd,drivenum,cleancart); /* * Hack, sleep for some time */ sleep(60); if (drive_loaded(fd, drivenum)) unload(fd, drivenum, cleancart); if (usagetime) unlink(usagetime);}/* ----------------------------------------------------------------------*/intmain( int argc, char ** argv){ int loaded; int target, oldtarget; command com; /* a little DOS joke */ int x; MBC_T *pbarcoderes; /* * drive_num really should be something from the config file, but.. * for now, it is set to zero, since most of the common changers * used by amanda only have one drive ( until someone wants to * use an EXB60/120, or a Breece Hill Q45.. ) */ unsigned char emubarcode; int drive_num; int need_eject; /* Does the drive need an eject command ? */ time_t need_sleep; /* How many seconds to wait for the drive to get ready */ int maxclean; char *clean_file; char *time_file; /* * For the emubarcode stuff */ int use_slots; int slot_offset; int confnum; int fd; int slotcnt; int drivecnt; int endstatus = 0; char *changer_dev; char *tape_device; char *chg_scsi_conf; /* The config file for us */ char *slot_file; /* Where we will place the info which * slot is loaded */ char *scsitapedevice; int param_index = 0; /* * Configure program for internationalization: * 1) Only set the message locale for now. * 2) Set textdomain for all amanda related programs to "amanda" * We don't want to be forced to support dozens of message catalogs. */ setlocale(LC_MESSAGES, "C"); textdomain("amanda"); changer = alloc(SIZEOF(changer_t)); pbarcoderes = alloc(SIZEOF(MBC_T)); memset(pbarcoderes, 0 , SIZEOF(MBC_T)); changer->number_of_configs = 0; changer->eject = 0; changer->sleep = 0; changer->cleanmax = 0; changer->device = NULL; changer->labelfile = NULL; changer->conf = NULL;#ifdef CHG_SCSI_STANDALONE g_printf(_("Ups standalone\n"));#else set_pname("chg-scsi"); /* Don't die when child closes pipe */ signal(SIGPIPE, SIG_IGN); dbopen(DBG_SUBDIR_SERVER); dbprintf("chg-scsi: %s\n", rcsid); ChangerDriverVersion(); if (debug_file == NULL) { debug_file = dbfp(); } parse_args(argc,argv,&com); pDev = (OpenFiles_T *)alloc(SIZEOF(OpenFiles_T) * CHG_MAXDEV); memset(pDev, 0, SIZEOF(OpenFiles_T) * CHG_MAXDEV ); switch(com.command_code) { case COM_SCAN: ScanBus(1); return(0); case COM_GEN_CONF: ScanBus(0); PrintConf(); return(0); default: break; } config_init(CONFIG_INIT_USE_CWD | CONFIG_INIT_FATAL, NULL); chg_scsi_conf = getconf_str(CNF_CHANGERFILE); tape_device = getconf_str(CNF_TAPEDEV); /* Get the configuration parameters */ /* Attention, this will not support more than 10 tape devices 0-9 */ /* */ if (strlen(tape_device)==1){ if (read_config(chg_scsi_conf, changer) == -1) { g_fprintf(stderr, _("%s open: of %s failed\n"), get_pname(), chg_scsi_conf); return (2); } confnum=atoi(tape_device); if (changer->number_of_configs == 0) { g_fprintf(stderr,_("%s: changer->conf[%d] == NULL\n"), get_pname(), confnum); return (2); } if (confnum >= changer->number_of_configs) { g_fprintf(stderr,_("%s: Configuration %s config # out of range (%d >= %d)\n"), get_pname(), chg_scsi_conf, confnum, changer->number_of_configs); return (2); } use_slots = changer->conf[confnum].end-changer->conf[confnum].start+1; slot_offset = changer->conf[confnum].start; drive_num = changer->conf[confnum].drivenum; need_eject = changer->eject; need_sleep = changer->sleep; if ( NULL != changer->conf[confnum].cleanfile) clean_file = stralloc(changer->conf[confnum].cleanfile); else clean_file = NULL; clean_slot = changer->conf[confnum].cleanslot; maxclean = changer->cleanmax; emubarcode = changer->emubarcode; if (NULL != changer->conf[confnum].timefile) time_file = stralloc(changer->conf[confnum].timefile); else time_file = NULL; if (NULL != changer->conf[confnum].slotfile) slot_file = stralloc(changer->conf[confnum].slotfile); else slot_file = NULL; if (NULL != changer->conf[confnum].device) tape_device = stralloc(changer->conf[confnum].device); else tape_device = NULL; if (NULL != changer->device) changer_dev = stralloc(changer->device); else changer_dev = NULL; if (NULL != changer->conf[confnum].scsitapedev) scsitapedevice = stralloc(changer->conf[confnum].scsitapedev); else scsitapedevice = NULL; if (NULL != changer->conf[confnum].tapestatfile) tapestatfile = stralloc(changer->conf[confnum].tapestatfile); else tapestatfile = NULL; dump_changer_struct(changer); /* * The changer device. * If we can't open it fail with a message */ if (OpenDevice(INDEX_CHANGER , changer_dev, "changer_dev", changer->conf[confnum].changerident) == 0) { int localerr = errno; g_fprintf(stderr, _("%s: open: %s: %s\n"), get_pname(), changer_dev, strerror(localerr)); g_printf(_("%s open: %s: %s\n"), _("<none>"), changer_dev, strerror(localerr)); dbprintf(_("open: %s: %s\n"), changer_dev, strerror(localerr)); return 2; } fd = INDEX_CHANGER; /* * The tape device. * We need it for: * eject if eject is set * inventory (reading of the labels) if emubarcode (not yet) */ if (tape_device != NULL) { if (OpenDevice(INDEX_TAPE, tape_device, "tape_device", changer->conf[confnum].tapeident) == 0) { dbprintf(_("warning open of %s: failed\n"), tape_device); } } /* * This is for the status pages of the SCSI tape, nice to have but no must.... */ if (scsitapedevice != NULL) { if (OpenDevice(INDEX_TAPECTL, scsitapedevice, "scsitapedevice", changer->conf[confnum].tapeident) == 0) { dbprintf(_("warning open of %s: failed\n"), scsitapedevice); } } /* * So if we need eject we need either an raw device to eject with an ioctl, * or an SCSI device to send the SCSI eject. */ if (need_eject != 0 ) { if (pDev[INDEX_TAPE].avail == 0 && pDev[INDEX_TAPECTL].avail == 0) { g_printf(_("No device found for tape eject")); return(2); } } if ((changer->conf[confnum].end == -1) || (changer->conf[confnum].start == -1)){ slotcnt = get_slot_count(fd); use_slots = slotcnt; slot_offset = 0; } /* * Now check if we have all what we need * If either emubarcode is set or the changer support barcode * we need an label file */ if ( changer->emubarcode == 1 || BarCode(INDEX_CHANGER) == 1) { if (changer->labelfile == NULL) { g_printf(_("labelfile param not set in your config\n")); return(2); } } if (slot_file == NULL) { g_printf(_("slotfile param. not set in your config\n")); return(2); } if (access(slot_file,R_OK|W_OK) != 0) { g_printf(_("slotfile %s does not exsist or is not read/write\n"), slot_file); return(2); } } else { /* if (strlen(tape_device)==1) */ g_printf(_("please check your config and use a config file for chg-scsi\n")); return(2); } drivecnt = get_drive_count(fd); if (drive_num > drivecnt) { g_printf(_("%s drive number error (%d > %d)\n"), _("<none>"), drive_num, drivecnt); g_fprintf(stderr, _("%s: requested drive number (%d) greater than " "number of supported drives (%d)\n"), get_pname(), drive_num, drivecnt); dbprintf(_("requested drive number (%d) is greater than " "number of supported drives (%d)\n"), drive_num, drivecnt); return 2; } loaded = (int)drive_loaded(fd, drive_num); target = -1; switch(com.command_code) {/* This is only for the experts ;-) */ case COM_TRACE: ChangerReplay(com.parameter); break;/**/ case COM_DUMPDB: pbarcoderes->action = BARCODE_DUMP; MapBarCode(changer->labelfile, pbarcoderes); break; case COM_STATUS: ChangerStatus(com.parameter, changer->labelfile, BarCode(fd), slot_file, changer_dev, tape_device); break; case COM_LABEL: /* Update BarCode/Label mapping file */ pbarcoderes->action = BARCODE_PUT;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -