Esempio n. 1
0
/*
 * Pop: delete all element created at the current level
 */
void egeq_pop(egeq_t *egeq) {
  egeq_levstack_t *stack;
  uint32_t i;

  stack = &egeq->stack;
  assert(stack->current_level > 0);

  if (stack->current_level == stack->top_level) {
    assert(stack->nmarks > 0);
    i = stack->nmarks - 1;
    assert(stack->data[i].level == stack->current_level);
    remove_level(&egeq->bank, &egeq->htbl, stack->data[i].blk_id, stack->data[i].index);
    egeq_htbl_cleanup_if_needed(&egeq->htbl);
    pop_top_mark(stack);
  }

  stack->current_level --;
}
Esempio n. 2
0
void edit_or_remove(al_defs *al, char name[255]) {
  draw_background(al);
  al_draw_text(al->menu_font, al_map_rgb(150,150,150), al->width/2,
      120, ALLEGRO_ALIGN_CENTRE, "Press E to edit, R to remove");
  al_flip_display();
  ALLEGRO_EVENT ev;
  bool quit=false;
  while(!quit) {
    al_wait_for_event(al->queue, &ev);
    if(ev.type==ALLEGRO_EVENT_KEY_DOWN) {
      switch(ev.keyboard.keycode){
        case ALLEGRO_KEY_E:
          quit=true;
          edit_level(al, name);
          break;
        case ALLEGRO_KEY_R:
          quit=true;
          remove_level(name);
      }
    }
  }
}
Esempio n. 3
0
/*************************************************************************
 * TESTS ON SINGLE DATA STRUCTURES LIKE INODES
 *
 * - This procedure is the central routine for working on the directory
 *   tree. A backtracking mechanism with no recursive procedure-overhead
 *   is used to avoid memory allocation and stack overflow problems.
 * - It is called as "step 2" during the checking process after working
 *   on unique data-structures and allocation all needed buffers for
 *   tables etc. 
 * - The root-inode was validated during a separate step in check_unique().
 *
 * Parameter  : root_de    = The directory-entry of the local root which
 *			     has to be examined
 *		root_bnr   = The number of the directory block which keeps
 *			     the root entry
 *		root_offs  = The offset in this directory block
 * Return     : TRUE    : under all normal checking conditions
 *		FALSE   : if a fatal error occurs
 *
 *************************************************************************/
word
check_inodes ( struct dir_elem *root_de, daddr_t root_bnr, word root_offs )
{
 word spare;				/* # of entries in the direct.	*/
 daddr_t bnr;				/* For temporary storage	*/
 word offset;
 word depth;				/* To keep track about the dis-	*/
 					/* tance from the root-direct.	*/

 struct buf *bpar;			/* Points to the current parent	*/
					/* directory - block		*/
 struct buf *blpt;			/* For symbolic-link reference- */
 					/* path block			*/
 tree_e head;
 word first_time;			/* Used to signal, if an entry	*/
					/* is scanned the first time	*/
 tree_e *parent;			/* Pointer to the actual parent */
					/* tree-element			*/
 tree_e *tpt;				/* Pointer to the actual wor-	*/
					/* king element.		*/
 struct dir_elem *de_pt;		/* Used for temporary storage	*/

 /*----------------------  Init operations  ----------------------------*/

 head.bnr = root_bnr;			/* Init the head element	*/
 head.offset = root_offs;
 head.parent_used = TRUE;
					/* Copy the root entry		*/
 memcpy ( (void *) &head.de, (void *) root_de, sizeof (struct dir_elem) );
 
 head.enxt = (tree_e *) NULL;		/* Zero the head-pointers	*/
 head.eprv = (tree_e *) NULL;
 head.lnxt = (tree_e *) NULL;
 head.lprv = (tree_e *) NULL;
					/* Clear the comparison struct	*/
 memset ( &dir_cmp, 0, sizeof (struct dir_elem) );

 strcpy ( path, "/" );			/* Set the name of the root	*/
 strcat ( path, head.de.de_name );	/* of the filesystem		*/

 spare = 0;				/* No entry at the beginning	*/
 first_time = TRUE;			/* Start up value		*/
 parent = &head;			/* At the beginning the head 	*/
 tpt    = &head;			/* element is the only one.	*/

 remove_de_hash ();			/* Free previously used hash-	*/
					/* table elements		*/
 changes_de = 0;			/* Nothing changed so far...	*/
 depth = 0;				/* We start on root-position	*/

 /*---------------  Traverse the whole directory tree  -----------------*/

 for ( ;; )
 {
					/* Get the next entry to check  */
	de_pt = get_next_entry ( &parent->de.de_inode, first_time, 
				 &bnr, &offset );
	first_time = FALSE;		/* We want to get all other en-	*/
					/* tries from this directory	*/
					/* We have got an entry ?	*/
	if ( de_pt != (struct dir_elem *) NULL )
	{
		strncpy (actual_path, path, 512);
#if 0
		IOdebug ("%sChecking  %s / [%s]",
			    S_INFO, path, de_pt->de_name);
#endif		
					/* An entry was extracted. Now	*/
					/* check it's validity		*/
		if ( validate_entry ( de_pt, path, UNKNOWN, TRUE ) )
		{			
					/* Put the entry name into the	*/
					/* appropriate hash-queue	*/
			append_de_hash ( de_pt->de_name );
			
					/* We have to increment the 	*/
			spare++;	/* total count of entries	*/
			
/*--------------  Storage of symbolic-link information  ----------------*/

					/* Was it a symbolic link ?	*/
			if ( de_pt->de_inode.i_mode == Type_Link )
			{		/* Read the block with the re-	*/
					/* ference path in buffer-cache	*/
				blpt = bread ( 0, de_pt->de_inode.i_db[0], 
					       1, SAVEA );

					/* Append the link to the hash-	*/
					/* table for symbolic links	*/
				append_link_hash ( bnr, offset, 
						   parent->bnr, parent->offset,
						   blpt->b_un.b_link->name);
					/* One more symbolic link found */
				found_links++;
					/* The ref-block is not used	*/
					/* anymore			*/
				brelse ( blpt->b_tbp, TAIL );
			}

/*-----  Appending new elements to the hierarchical directory-tree  ----*/

			if ( de_pt->de_inode.i_mode == Type_Directory )
			{
					/* Increment the counter for 	*/
					/* the number of valid directo- */
					/* ries in a cylinder group.	*/
				add_dir ( bnr );
				found_dirs++;
								
				if ( tpt == parent )
					/* Add a new directory level	*/
					tpt = append_level ( tpt );	
				else
					/* .. or a new entry		*/
					tpt = append_entry ( tpt );
					/* Save the entry's location	*/
				tpt->bnr = bnr;
				tpt->offset = offset;
					/* Save the entry's content	*/
				memcpy ( &tpt->de, de_pt, sizeof (struct dir_elem) );	
					/* At this time NOT used as a 	*/
					/* parent-dir			*/
				tpt->parent_used = FALSE;
#if DEBUG
IOdebug ("	check_inodes :	New element created for %s (bnr= %d, off= %d)",
	 tpt->de.de_name, tpt->bnr, tpt->offset );
#endif
			}
					/* Update the actual number of	*/
					/* file checked.		*/
			if ( de_pt->de_inode.i_mode == Type_File )
				found_files++;
		}
		else			/* If the validation does not	*/
		{			/* succeeds:			*/
					/* We have to make a note, if	*/
					/* /lost+found will be deleted ! */
			if ( depth == 0 &&
			     ! strcmp ( de_pt->de_name, "lost+found" ) )
			{
				IOdebug ("%sUnusable /lost+found-dir !", S_WARNING);
				lost_found = FALSE;
			}
								
			IOdebug ("%sThe entry is invalid and will be deleted!",
				  S_SERIOUS);
				  
			if ( ! no_corrections )
			{
				    	/* We cannot make use anymore	*/
				    	/* of the corrupted entry and	*/
				    	/* delete it.			*/
				memset ( (void *) de_pt, 0, sizeof (struct dir_elem) );
					/* Note the deletion		*/
				fst.deleted_inodes++;
				changes_de++;
			}
		}
	}

/*------  After checking a complete directory with all entries: --------*/

	else				/* One directory fully scanned:	*/
	{			
#if DEBUG
IOdebug ("	check_inodes :	Have examined all entries. Change the directory");
IOdebug ("			Current parent = %s     'used' = %d",
	 parent->de.de_name, parent->parent_used);
IOdebug ("			Current entry  = %s     'used' = %d",
	 tpt->de.de_name, tpt->parent_used);
#endif

 /*-------  Go on with the last directory of the current sub-dir  ------*/

		if ( tpt->enxt == (tree_e *) NULL && 
		     tpt->lnxt == (tree_e *) NULL &&
		     tpt != parent &&
		     ! tpt->parent_used )		     
		{			
#if DEBUG
IOdebug ("	check_inodes :	Take the last sub-dir as parent directory");
#endif

#if DEBUG
IOdebug ("	check_inodes :  Spare value found = %d , counted = %d",
	 parent->de.de_inode.i_spare, spare );
#endif
					/* Different # of entries ? 	*/
			if ( spare != parent->de.de_inode.i_spare )
			{		/* Save the new spare value	*/
					/* Read the parent-directory 	*/
#if DEBUG
IOdebug ("	check_inodes :	Correct number of entries (spare value)");
#endif
				bpar = bread ( 0, parent->bnr, 1, SAVEA );

					/* Change the entry		*/
				if ( parent->bnr == 1 )
				{	/* Special handling for root	*/
					bpar->b_un.b_sum->root_dir.de_inode.i_spare = 
					spare;
					bpar->b_un.b_sum->root_dir.de_inode.i_size =
					spare * sizeof(struct dir_elem);
				}
				else
				{
					bpar->b_un.b_dir[parent->offset].de_inode.i_spare =
					spare;		
					bpar->b_un.b_dir[parent->offset].de_inode.i_size =
					spare * sizeof(struct dir_elem);		
				}
			 		/* ... and write it back.	*/
				test_bwrite ( bpar );
			}
					/* Prepare the tree-element	*/
					/* for a new pass as "parent":	*/
			parent = tpt;
			parent->parent_used = TRUE;
			first_time = TRUE;
			spare = 0;
					/* Append to the pathname-string*/
			strcat ( path , "/" );
					/* ... a new sub-dir branch	*/
			strcat ( path , parent->de.de_name );
					/* One level lower than the	*/
			depth++;	/* root-directory		*/
					/* Clear the name-hash-table	*/
			remove_de_hash ();
					/* Begin with the first entry..	*/
			continue;	/* and scan again all entries.	*/
		}

 /*--------------------  Backtracking conditions  ----------------------*/

		if ( tpt->enxt == (tree_e *) NULL && 
		     tpt->lnxt == (tree_e *) NULL &&
		     tpt == parent &&
		     tpt->parent_used )
		{
#if DEBUG
IOdebug ("	check_inodes :	Use backtracking to get a new parent-dir");
#endif

#if DEBUG
IOdebug ("	check_inodes :  Spare value found = %d , counted = %d",
	 parent->de.de_inode.i_spare, spare );
#endif
					/* Different # of entries ?	*/
			if ( spare != parent->de.de_inode.i_spare )	
			{		
#if DEBUG
IOdebug ("	check_inodes :	Correct number of entries (spare value)");
#endif
					/* Save the new spare value	*/
					/* Read the directory block	*/
				bpar = bread ( 0, parent->bnr, 1, SAVEA );

					/* Change the entry		*/
				if ( parent->bnr == 1 )
				{	/* Special handling for root	*/
					bpar->b_un.b_sum->root_dir.de_inode.i_spare = 
					spare;
					bpar->b_un.b_sum->root_dir.de_inode.i_size =
					spare * sizeof(struct dir_elem);
				}
				else
				{
					bpar->b_un.b_dir[parent->offset].de_inode.i_spare =
					spare;		
					bpar->b_un.b_dir[parent->offset].de_inode.i_size =
					spare * sizeof(struct dir_elem);		
				}
					/* ... and write it back.	*/
				test_bwrite ( bpar );
			}
					/* Look for a directory, which 	*/
					/* wasn't used as a "parent"	*/
			do
			{		/* THE MAIN EXIT-POINT !	*/
				if ( tpt->eprv == (tree_e *) NULL &&
				     tpt->lprv == (tree_e *) NULL )
					return TRUE;

					/* The "move-back" operation	*/
				if ( tpt->lprv != (tree_e *) NULL )
				{
					/* Remove the lowest level	*/
					parent = remove_level ( tpt );
					depth--;
				}
				else	/* Remove the last entry from	*/
					/* the directory		*/
					parent = remove_entry ( tpt );
					/* Adjust the work-pointer	*/
				tpt = parent;
					/* Cut the pathname string and	*/
				*( strrchr ( path , '/' ) ) = '\0';
#if DEBUG
IOdebug ("	check_inodes :	Backtracking to path = %s (depth: %d)", 
	 path, depth );
#endif				
			}		/* try it again until an unused	*/
					/* dir-entry is found		*/
			while ( tpt->parent_used );

					/* Append the new sub-dir	*/
			if ( tpt->de.de_name )
			{
				strcat ( path, "/" );
				strcat ( path, tpt->de.de_name );
			}
					/* Prepare the tree-element as	*/
					/* the new parent-directory	*/
			tpt->parent_used = TRUE;
			first_time = TRUE;
			spare = 0;
					/* Clear the hash-table		*/
			remove_de_hash ();
					/* ... and go to the beginning	*/
			continue;	/* Now we will examine the en-	*/
					/* tries of the "new" directory.*/
		}
	}
 } /* end of <for (;;)> */

}