/* Small help func takes ip-address-string, determines if a valid netmask is specified and inserts the netmask into mask. Cuts of the netmask of the string, if it founds a netmask !!! Returns 0 if no netmask found, -1 if netmask isn't valid, and 1 if successful. According to this function a mask is in form of 255.255.192.0 so an ip/mask looks like 10.0.0.0/255.255.192.0 we will extend it to 10.0.0.0/18 which will be also valid */ int parse_ip_netmask (char *c, char **ip, unsigned int *mask) { char *p, *q; unsigned int netmask; if (c == NULL) { return -10; } p = c; if ((q = strchr (p, '/')) == NULL) { *mask = 0xFFFFFFFF; return 0; /* no mask */ } else { *ip = (char *) malloc (q - p + 1); if ((*ip) == NULL) return -2; memcpy (*ip, p, q - p); (*ip)[q - p] = 0; // wrong (*q) = 0; /* cut of the netmask */ q++; /* * two possibilities /16 or /255.255.192.0 */ if (is_positive_number (q) == 1) { /* we have a /16 mask */ if ((netmask = make_mask (atoi (q))) == 0) { *mask = 0; /* error in value of /43 or something like */ return -1; } else { *mask = netmask; return 1; } } else /* we may have a 255.255.192.0 mask */ if (parse_ip_address (q, &netmask) == 1) /* and parse the netmask */ { *mask = netmask; return 1; } else { *mask = 0; return -1; } } }
int main( int argc, char ** argv) { int loaded; int target = -1; int oldtarget; command com; /* a little DOS joke */ /* * 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.. ) */ int drive_num = 0; int need_eject = 0; /* Does the drive need an eject command ? */ unsigned need_sleep = 0; /* How many seconds to wait for the drive to get ready */ int clean_slot = -1; int maxclean = 0; char *clean_file=NULL; char *time_file=NULL; int use_slots; int slot_offset; int confnum; int fd, slotcnt, drivecnt; int endstatus = 0; char *changer_dev = NULL; char *tape_device = NULL; char *changer_file = NULL; char *scsitapedevice = NULL; /* * 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"); set_pname("chg-scsi"); /* Don't die when child closes pipe */ signal(SIGPIPE, SIG_IGN); dbopen(DBG_SUBDIR_SERVER); parse_args(argc,argv,&com); changer = alloc(SIZEOF(changer_t)); config_init(CONFIG_INIT_USE_CWD, NULL); if (config_errors(NULL) >= CFGERR_WARNINGS) { config_print_errors(); if (config_errors(NULL) >= CFGERR_ERRORS) { g_critical(_("errors processing config file")); } } changer_dev = getconf_str(CNF_CHANGERDEV); changer_file = getconf_str(CNF_CHANGERFILE); tape_device = getconf_str(CNF_TAPEDEV); /* Get the configuration parameters */ if (strlen(tape_device)==1){ read_config(changer_file, changer); confnum=atoi(tape_device); 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; clean_file = stralloc(changer->conf[confnum].cleanfile); clean_slot = changer->conf[confnum].cleanslot; maxclean = changer->cleanmax; if (NULL != changer->conf[confnum].timefile) time_file = stralloc(changer->conf[confnum].timefile); if (NULL != changer->conf[confnum].slotfile) changer_file = stralloc(changer->conf[confnum].slotfile); else changer_file = NULL; if (NULL != changer->conf[confnum].device) tape_device = stralloc(changer->conf[confnum].device); if (NULL != changer->device) changer_dev = stralloc(changer->device); if (NULL != changer->conf[confnum].scsitapedev) scsitapedevice = stralloc(changer->conf[confnum].scsitapedev); if (NULL != changer->conf[confnum].tapestatfile) tapestatfile = stralloc(changer->conf[confnum].tapestatfile); dump_changer_struct(changer); /* get info about the changer */ fd = OpenDevice(INDEX_CHANGER , changer_dev, "changer_dev", changer->conf[confnum].changerident); if (fd == -1) { 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; } if (tape_device == NULL) { tape_device = stralloc(changer_dev); } if (scsitapedevice == NULL) { scsitapedevice = stralloc(tape_device); } if ((changer->conf[confnum].end == -1) || (changer->conf[confnum].start == -1)){ slotcnt = get_slot_count(fd); use_slots = slotcnt; slot_offset = 0; } free_changer_struct(&changer); } else { /* get info about the changer */ confnum = 0; fd = OpenDevice(INDEX_CHANGER , changer_dev, "changer_dev", changer->conf[confnum].changerident); if (fd == -1) { 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; } slotcnt = get_slot_count(fd); use_slots = slotcnt; slot_offset = 0; drive_num = 0; need_eject = 0; need_sleep = 0; } 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) greater than " "number of supported drives (%d)\n"), drive_num, drivecnt); CloseDevice("", fd); return 2; } loaded = drive_loaded(fd, drive_num); switch(com.command_code) { case COM_SLOT: /* slot changing command */ if (is_positive_number(com.parameter)) { if ((target = atoi(com.parameter))>=use_slots) { g_printf(_("<none> no slot `%d'\n"),target); close(fd); endstatus = 2; break; } else { target = target+slot_offset; } } else target=get_relative_target(fd, use_slots, com.parameter, loaded, changer_file,slot_offset,slot_offset+use_slots); if (loaded) { if (changer_file != NULL) { oldtarget=get_current_slot(changer_file); } else { oldtarget = GetCurrentSlot(fd, drive_num); } if ((oldtarget)!=target) { if (need_eject) eject_tape(scsitapedevice, need_eject); (void)unload(fd, drive_num, oldtarget); if (ask_clean(scsitapedevice)) clean_tape(fd,tape_device,clean_file,drive_num, clean_slot,maxclean,time_file); loaded=0; } } if (changer_file != NULL) { put_current_slot(changer_file, target); } if (!loaded && isempty(fd, target)) { g_printf(_("%d slot %d is empty\n"),target-slot_offset, target-slot_offset); close(fd); endstatus = 1; break; } if (!loaded) if (load(fd, drive_num, target) != 0) { g_printf(_("%d slot %d move failed\n"),target-slot_offset, target-slot_offset); close(fd); endstatus = 2; break; } if (need_sleep) Tape_Ready1(scsitapedevice, need_sleep); g_printf(_("%d %s\n"), target-slot_offset, tape_device); break; case COM_INFO: if (changer_file != NULL) { g_printf("%d ", get_current_slot(changer_file)-slot_offset); } else { g_printf("%d ", GetCurrentSlot(fd, drive_num)-slot_offset); } g_printf("%d 1\n", use_slots); break; case COM_RESET: if (changer_file != NULL) { target=get_current_slot(changer_file); } else { target = GetCurrentSlot(fd, drive_num); } if (loaded) { if (!isempty(fd, target)) target=find_empty(fd,0 ,0); if (need_eject) eject_tape(scsitapedevice, need_eject); (void)unload(fd, drive_num, target); if (ask_clean(scsitapedevice)) clean_tape(fd,tape_device,clean_file,drive_num,clean_slot, maxclean,time_file); } if (isempty(fd, slot_offset)) { g_printf(_("0 slot 0 is empty\n")); close(fd); endstatus = 1; break; } if (load(fd, drive_num, slot_offset) != 0) { g_printf(_("%d slot %d move failed\n"),slot_offset, slot_offset); close(fd); endstatus = 2; break; } if (changer_file != NULL) { put_current_slot(changer_file, slot_offset); } if (need_sleep) Tape_Ready1(scsitapedevice, need_sleep); if (changer_file != NULL) { g_printf("%d %s\n", get_current_slot(changer_file), tape_device); } else { g_printf("%d %s\n", GetCurrentSlot(fd, drive_num), tape_device); } break; case COM_EJECT: if (loaded) { if (changer_file != NULL) { target=get_current_slot(changer_file); } else { target = GetCurrentSlot(fd, drive_num); } if (need_eject) eject_tape(scsitapedevice, need_eject); (void)unload(fd, drive_num, target); if (ask_clean(scsitapedevice)) clean_tape(fd,tape_device,clean_file,drive_num,clean_slot, maxclean,time_file); g_printf("%d %s\n", target, tape_device); } else { g_printf(_("%d drive was not loaded\n"), target); endstatus = 1; } break; case COM_CLEAN: if (loaded) { if (changer_file != NULL) { target=get_current_slot(changer_file); } else { target = GetCurrentSlot(fd, drive_num); } if (need_eject) eject_tape(scsitapedevice, need_eject); (void)unload(fd, drive_num, target); } clean_tape(fd,tape_device,clean_file,drive_num,clean_slot, maxclean,time_file); g_printf(_("%s cleaned\n"), tape_device); break; }; CloseDevice("", 0); dbclose(); return endstatus; }