Beispiel #1
0
void check_collisions() {
	unsigned nx = snake->x, ny = snake->y;
	if(ground[nx][ny] == WALL)
		die_and_score();
	
	else if(ground[nx][ny] == BONUS) {
		no_pop++;
		score += BONUS_PTS;
		ground[nx][ny] = GROUND;
		timeout[nx][ny] = 0;
		
		find_empty(&nx, &ny);
		ground[nx][ny] = BONUS;
		timeout[nx][ny] = rnd_max(45) + 5;
		
	} else if(ground[nx][ny] == MALUS) {
		no_pop += 4;
		score -= MALUS_PTS;
		ground[nx][ny] = GROUND;
		timeout[nx][ny] = 0;
		
		find_empty(&nx, &ny);
		ground[nx][ny] = MALUS;
		timeout[nx][ny] = rnd_max(45) + 5;
	}
	
}
Beispiel #2
0
//==================================================================================
vAddr allocateNewInt(){
	vAddr virtual_addr;
	vAddr ram_empty;

	sem_wait(&ram_lock);
	ram_empty=find_empty(RAM);
	//printf("ram_empty index %d\n",ram_empty);

	
	if(ram_empty==-1){//if no empty slot in ram
		ram_empty=find_evict(RAM); //find a slot to swap out
		sem_post(&ram_lock);
		//printf("after sem_post &ram_lock\n");
		sem_wait(&ssd_lock);
		//printf("begin searching ssd\n");
		vAddr ssd_empty=find_empty(SSD);//find an empty slot to take in the swapped out RAM 
		if (ssd_empty==-1){//if no empty slot in ssd to take in
			ssd_empty=find_evict(SSD);//find a slot to evict
			sem_post(&ssd_lock);
			sem_wait(&disk_lock);
			vAddr disk_empty=find_empty(DISK);//find a slot in disk to take in
			if(disk_empty==-1){//if no place in disk
				virtual_addr=-1; //return false value
				printf("no space avaible\n");
			}
			else{//if find a slot in disk
				sem_post(&disk_lock);
				swap(SSD,ssd_empty,DISK,disk_empty);
				disk_info[disk_empty].lock=0;
				swap(RAM,ram_empty,SSD,ssd_empty);
				ssd_info[ssd_empty].lock=0;

			}
		}
		else{//if there is empty slot in ssd
			sem_post(&ssd_lock);
			swap(RAM,ram_empty,SSD,ssd_empty);
			ssd_info[ssd_empty].lock=0;
		}
	}
	else{
		sem_post(&ram_lock);
	}
	
	virtual_addr=find_in_pt(0,-9999);
	if(virtual_addr!=-1){
		pageTable[virtual_addr].address=ram_empty;
		pageTable[virtual_addr].array=RAM;
		ram_info[ram_empty].lock=0;
	}else{
		virtual_addr=-1;
		printf("page table is full\n");
	}
	//mark as selected
	//store in pageTable

	printf("recorded in pagetable: %d \n",virtual_addr);
	return virtual_addr;
}
Beispiel #3
0
void load_level(int lvl_nb)
{
	char fname[100];
	FILE *lev;
	unsigned iLin, iCol, x, y;
	char c;

	sprintf(fname, PATH"lvls/level-%d.lvl", lvl_nb);
	lev = fopen(fname, "r");
	if(lev == NULL) {
		printf("Cannot open %s\n", fname); fflush(stdout);
		quit_stuff();
	}

	for(iCol = 0; iCol < MAX_HEI; iCol++) {
		for(iLin = 0; iLin < MAX_LEN; iLin++) {
			c = getc(lev);
			if(c == '#') ground[iCol][iLin] = WALL;
			else ground[iCol][iLin] = GROUND;
		}
		getc(lev); /* This should be a \n */
	}

	find_empty(&x, &y);
	ground[x][y] = BONUS;
	timeout[x][y] = rnd_max(45) + 5;


	find_empty(&x, &y);
	ground[x][y] = MALUS;
	timeout[x][y] = rnd_max(45) + 5;

	find_empty(&x, &y);
	ground[x][y] = MALUS;
	timeout[x][y] = rnd_max(45) + 5;

	find_empty(&x, &y);
	ground[x][y] = MALUS;
	timeout[x][y] = rnd_max(45) + 5;

	fclose(lev);

	free_snake();
	/* Then the snake */
	snake = malloc(sizeof(Snake));
	snake->x = 9; snake->y = 13;
	snake->next = NULL;

	add_head(10, 13); add_head(11, 13); add_head(12, 13); add_head(13, 13);
}
Beispiel #4
0
/**
 * Allocates a single random object in the dungeon.
 * \param c the current chunk
 * \param set where the entity is placed (corridor, room or either)
 * \param typ what is placed (rubble, trap, gold, item)
 * \param depth generation depth
 * \param origin item origin (if appropriate)
 *
 * 'set' controls where the object is placed (corridor, room, either).
 * 'typ' conrols the kind of object (rubble, trap, gold, item).
 */
bool alloc_object(struct chunk *c, int set, int typ, int depth, byte origin)
{
    int x = 0, y = 0;
    int tries = 0;

    /* Pick a "legal" spot */
    while (tries < 2000) {
		tries++;

		find_empty(c, &y, &x);

		/* If we are ok with a corridor and we're in one, we're done */
		if (set & SET_CORR && !square_isroom(c, y, x)) break;

		/* If we are ok with a room and we're in one, we're done */
		if (set & SET_ROOM && square_isroom(c, y, x)) break;
    }

    if (tries == 2000) return false;

    /* Place something */
    switch (typ) {
    case TYP_RUBBLE: place_rubble(c, y, x); break;
    case TYP_TRAP: place_trap(c, y, x, -1, depth); break;
    case TYP_GOLD: place_gold(c, y, x, depth, origin); break;
    case TYP_OBJECT: place_object(c, y, x, depth, false, false, origin, 0); break;
    case TYP_GOOD: place_object(c, y, x, depth, true, false, origin, 0); break;
    case TYP_GREAT: place_object(c, y, x, depth, true, true, origin, 0); break;
    }
    return true;
}
Beispiel #5
0
void
insert(tw_event ** hash_t, tw_event * event, int hash_size)
{
	int             key = 0;

	key = find_empty(hash_t, event, hash_size);
	hash_t[key] = event;
}
int CondorFileTable::install_special( int real_fd, char *kind )
{
	int fd = find_empty();
	if(fd<0) return -1;

	CondorFileInfo *i= make_info(kind);
	i->already_warned = 1;
	i->open_count++;

	CondorFileSpecial *s = new CondorFileSpecial();
	s->attach( real_fd );

	pointers[fd] = new CondorFilePointer( s, i, O_RDWR, kind );

	return fd;
}
Beispiel #7
0
static int
register_thread(void)
{
	struct sigaction actions;
	int i;

	if ((i=find_empty(pthread_self())) >= 0) {
		threads[i].state = PTHREAD_CANCEL_ENABLE;
		threads[i].exit = 0;
	}

	memset(&actions, 0, sizeof(actions));

	sigemptyset(&actions.sa_mask);
	actions.sa_flags = 0;
	actions.sa_handler = sigusr1_handler;
	sigaction(SIGUSR1, &actions, NULL);

	return i;
}
Beispiel #8
0
void check_timeouts()
{
	Tile type;
	int i, j;
	unsigned x, y;

	for(i = 0; i < MAX_LEN; i++)
		for(j = 0; j < MAX_HEI; j++) {
			if(ground[i][j] == WALL || ground[i][j] == GROUND)
				break;
			timeout[i][j]--;
			if(!timeout[i][j]) {
				type = ground[i][j];
				ground[i][j] = GROUND;

				find_empty(&x, &y);
				ground[x][y] = type;
				timeout[x][y] = rnd_max(45) + 5;
			}
		}
}
int CondorFileTable::open( const char *logical_name, int flags, int mode )
{
	char *full_logical_name = NULL;

	CondorFile *file=0;
	CondorFileInfo *info=0;

	// Convert a relative path into a complete path

	complete_path( logical_name, &full_logical_name );

	// Find a fresh file descriptor

	int fd = find_empty();
	if(fd<0) {
		errno = EMFILE;
		free( full_logical_name );
		return -1;
	}

	file = open_file_unique( full_logical_name, flags, mode );
	if(!file) {
		free( full_logical_name );
		return -1;
	}

	info = make_info( full_logical_name );
	info->open_count++;

	// Flags that should be applied once only are now removed

	flags &= ~(O_TRUNC);
	flags &= ~(O_CREAT);
	
	// Install the pointer and return!

	pointers[fd] = new CondorFilePointer(file,info,flags,full_logical_name);
	free( full_logical_name );
	return fd;
}
Beispiel #10
0
/**
 * Place some staircases near walls.
 * \param c the current chunk
 * \param feat the stair terrain type
 * \param num number of staircases to place
 * \param walls number of walls to surround the stairs (negotiable)
 */
void alloc_stairs(struct chunk *c, int feat, int num, int walls)
{
    int y, x, i, j, done;

    /* Place "num" stairs */
    for (i = 0; i < num; i++) {
		/* Place some stairs */
		for (done = FALSE; !done; ) {
			/* Try several times, then decrease "walls" */
			for (j = 0; !done && j <= 1000; j++) {
				find_empty(c, &y, &x);

				if (next_to_walls(c, y, x) < walls) continue;

				place_stairs(c, y, x, feat);
				done = TRUE;
			}

			/* Require fewer walls */
			if (walls) walls--;
		}
    }
}
Beispiel #11
0
/*
 * map_ioctl:
 *   process the supported ioctls
 */
static int map_ioctl(RP rp)
{
    PARAM far *p = (PARAM far*)IOPARAM(rp);
    DATA far *d;
    int idx;
    ULONG addr, lock, temp;
    ULONG far *ud;

    /* only accept class XFREE86_PMAP */
    if (IOCAT(rp) != XFREE86_PMAP)
        return RP_EBAD;

    switch (IOFUNC(rp)) {
    case PMAP_MAP:
        /* test: Parameter packet is readable and has correct size
         *       get a free slot
         */
        if (Verify(p,sizeof(PARAM),0)==0 &&
                (idx = find_empty()) != -1) {

            /* map the requested region */
            addr = Pmap(p->u.physaddr,p->size);

            /* was okay? */
            if (addr) {

                /* get the return packet of ioctl */
                d = (DATA far*)IODATA(rp);

                /* writable ? */
                if (Verify(d,sizeof(DATA),1)==0) {

                    /* set the mapping address in
                     * process address space
                     */
                    d->addr = addr;
                    d->sel = 0;

                    /* registrate stuff in mapping table */
                    maps[idx].phys = p->u.physaddr;
                    maps[idx].vmaddr = addr;
                    maps[idx].sfnum = IOSFN(rp);
                    maps[idx].lockhan = 0;
                    return RPDONE;
                }
            }
        }
        /* come here for error condition */
        break;
    case PMAP_UNMAP:
        /* test: parameter packet readable and correct size
         *       entry found in table
         *       unmapping okay?
         */
        if (Verify(p,sizeof(PARAM),0)==0 &&
                (idx = find_map(IOSFN(rp),p->u.vmaddr)) != -1 &&
                Punmap(p->u.vmaddr)==0) {

            /* get the return packet of ioctl */
            ud = (ULONG far*)IODATA(rp);

            /* writable ? */
            if (Verify(d,sizeof(ULONG),1)==0) {

                /* set the vmaddress just invalidated
                 * into data packet
                 */
                *ud = maps[idx].vmaddr;

                /* remove entry from table */
                maps[idx].phys = 0;
                maps[idx].vmaddr = 0;
                maps[idx].sfnum = -1;
                maps[idx].lockhan = 0;
                return RPDONE;
            }
        }
        /* arrive here for error condition */
        break;
    case PMAP_UNMAP2:
        /* test: parameter packet readable and correct size
         *       entry found in table
         *       unmapping okay?
         */
        if (Verify(p,sizeof(PARAM),0)==0 &&
                (idx = find_mapphys(IOSFN(rp),p->u.physaddr,p->size)) != -1 &&
                Punmap(maps[idx].vmaddr)==0) {

            /* remove entry from table */
            maps[idx].phys = 0;
            maps[idx].vmaddr = 0;
            maps[idx].sfnum = -1;
            maps[idx].lockhan = 0;
            return RPDONE;
        }
        /* arrive here for error condition */
        break;
    case PMAP_NAME:
        if (Verify(d,14,1) == 0) {
            bmove((char far*)d,"\\dev\\pmap$\0",11);
            return RPDONE;
        }
        break;
    case PMAP_DRVID:
        return drvid(d,IODLEN(rp),PMAPDRV_ID);
    case PMAP_READROM:	/* testcfg.sys replacement function */
        if (Verify(p,sizeof(ROMPARAM),0) == 0) {
            ROMPARAM far *p1 = (ROMPARAM*)p;
            USHORT n = p1->numbytes;
            ULONG ad = p1->physaddr + n;
            if (p1->command == 0 &&
                    p1->physaddr >= 0xc0000 &&
                    p1->physaddr <= 0xfffff &&
                    ad >= 0xc0000 &&
                    ad <= 0xfffff) {
                char far *d1 = (char far*)IODATA(rp);
                if (Verify(d1,n,1) == 0) {
                    char far *addr;
                    if (P2V(p1->physaddr,n,&addr)==0) {
                        bmove(d1,addr,n);
                        /*UnPhysToVirt == NOOP in OS/2 2.x */
                        return RPDONE;
                    }
                }
            }
        }
        break;
    case PMAP_LOCKBUF:
        /* test: Parameter packet is readable and has correct size
         *
         */
        lock = 0;
        if (Verify(p,sizeof(PARAM),0)==0 &&
                (idx = find_empty()) != -1) {

            /* lock the requested region */
            lock = Vlock(p->u.vmaddr,p->size);
            temp = (p->u.vmaddr << 3) | 0x070000; /* Make sel */

            /* was okay? */
            if ((lock) &&
                    (Verify((FPVOID)temp, (USHORT)p->size, 0) ==0)) {

                /* get the return packet of ioctl */
                d = (DATA far*)IODATA(rp);

                /* writable ? */
                if (Verify(d,sizeof(DATA),1)==0) {

                    /* set the mapping address in
                     * process address space
                     */
                    /* This is where things crash: VtoP does not like our addr */
                    d->addr = VtoP(p->u.vmaddr);
                    d->sel = 0;
                    maps[idx].phys = addr;
                    maps[idx].vmaddr = p->u.vmaddr;
                    maps[idx].sfnum = IOSFN(rp);
                    maps[idx].lockhan = lock;
                    return RPDONE;

                }
            }
            if(lock) Vunlock(lock); /* In case Verify failed */
        }
        /* come here for error condition */
        break;
    default:
        return RP_EBAD;
    }

    /* break from case */
    return RP_EINVAL;
}
Beispiel #12
0
/**
 * Generate a random level.
 *
 * Confusingly, this function also generate the town level (level 0).
 * \param c is the level we're going to end up with, in practice the global cave
 * \param p is the current player struct, in practice the global player
 */
void cave_generate(struct chunk **c, struct player *p) {
	const char *error = "no generation";
	int y, x, tries = 0;
	struct chunk *chunk;

	assert(c);

	/* Generate */
	for (tries = 0; tries < 100 && error; tries++) {
		struct dun_data dun_body;

		error = NULL;

		/* Mark the dungeon as being unready (to avoid artifact loss, etc) */
		character_dungeon = FALSE;

		/* Allocate global data (will be freed when we leave the loop) */
		dun = &dun_body;
		dun->cent = mem_zalloc(z_info->level_room_max * sizeof(struct loc));
		dun->door = mem_zalloc(z_info->level_door_max * sizeof(struct loc));
		dun->wall = mem_zalloc(z_info->wall_pierce_max * sizeof(struct loc));
		dun->tunn = mem_zalloc(z_info->tunn_grid_max * sizeof(struct loc));

		/* Choose a profile and build the level */
		dun->profile = choose_profile(p->depth);
		chunk = dun->profile->builder(p);
		if (!chunk) {
			error = "Failed to find builder";
			mem_free(dun->cent);
			mem_free(dun->door);
			mem_free(dun->wall);
			mem_free(dun->tunn);
			continue;
		}

		/* Ensure quest monsters */
		if (is_quest(chunk->depth)) {
			int i;
			for (i = 1; i < z_info->r_max; i++) {
				monster_race *r_ptr = &r_info[i];
				int y, x;
				
				/* The monster must be an unseen quest monster of this depth. */
				if (r_ptr->cur_num > 0) continue;
				if (!rf_has(r_ptr->flags, RF_QUESTOR)) continue;
				if (r_ptr->level != chunk->depth) continue;
	
				/* Pick a location and place the monster */
				find_empty(chunk, &y, &x);
				place_new_monster(chunk, y, x, r_ptr, TRUE, TRUE, ORIGIN_DROP);
			}
		}

		/* Clear generation flags. */
		for (y = 0; y < chunk->height; y++) {
			for (x = 0; x < chunk->width; x++) {
				sqinfo_off(chunk->squares[y][x].info, SQUARE_WALL_INNER);
				sqinfo_off(chunk->squares[y][x].info, SQUARE_WALL_OUTER);
				sqinfo_off(chunk->squares[y][x].info, SQUARE_WALL_SOLID);
				sqinfo_off(chunk->squares[y][x].info, SQUARE_MON_RESTRICT);
			}
		}

		/* Regenerate levels that overflow their maxima */
		if (cave_monster_max(chunk) >= z_info->level_monster_max)
			error = "too many monsters";

		if (error) ROOM_LOG("Generation restarted: %s.", error);

		mem_free(dun->cent);
		mem_free(dun->door);
		mem_free(dun->wall);
		mem_free(dun->tunn);
	}

	if (error) quit_fmt("cave_generate() failed 100 times!");

	/* Free the old cave, use the new one */
	if (*c)
		cave_free(*c);
	*c = chunk;

	/* Place dungeon squares to trigger feeling (not in town) */
	if (player->depth)
		place_feeling(*c);

	/* Save the town */
	else if (!chunk_find_name("Town")) {
		struct chunk *town = chunk_write(0, 0, z_info->town_hgt,
										 z_info->town_wid, FALSE, FALSE, FALSE);
		town->name = string_make("Town");
		chunk_list_add(town);
	}

	(*c)->feeling = calc_obj_feeling(*c) + calc_mon_feeling(*c);

	/* Validate the dungeon (we could use more checks here) */
	chunk_validate_objects(*c);

	/* The dungeon is ready */
	character_dungeon = TRUE;

	/* Free old and allocate new known level */
	if (cave_k)
		cave_free(cave_k);
	cave_k = cave_new(cave->height, cave->width);
	if (!cave->depth)
		cave_known();

	(*c)->created_at = turn;
}
Beispiel #13
0
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;
}