Пример #1
0
void ItemList::init_actions()
{
    PasspotPlugin *plugin = dynamic_cast<PasspotPlugin*>(get_plugin().pointer());
    assert(NULL != plugin);

    // add article
    _new_action = new QAction(plugin->load_icon("passpot/add_item"), tr("添加(&A)"), this);
    _new_action->setStatusTip(tr("添加新记录"));
    _new_action->setToolTip(tr("添加新记录"));
    connect(_new_action, SIGNAL(triggered()), this, SLOT(add_item()));

    _edit_action = new QAction(plugin->load_icon("passpot/edit_item"), tr("编辑(&E)"), this);
    _edit_action->setStatusTip(tr("编辑当前记录"));
    _edit_action->setToolTip(tr("编辑当前记录"));
    connect(_edit_action, SIGNAL(triggered()), this, SLOT(edit_item()));

    _move_to_trash_action = new QAction(plugin->load_icon("passpot/move_to_trash"), tr("移动到回收站(&T)"), this);
    _move_to_trash_action->setStatusTip(tr("将当前记录移动到回收站"));
    _move_to_trash_action->setToolTip(tr("将当前记录移动到回收站"));
    connect(_move_to_trash_action, SIGNAL(triggered()), this, SLOT(move_to_trash()));

    // delete article
    _delete_action = new QAction(plugin->load_icon("passpot/delete"), tr("删除(&D)"), this);
    _delete_action->setStatusTip(tr("永久删除当前记录"));
    _delete_action->setToolTip(tr("永久删除当前记录"));
    connect(_delete_action, SIGNAL(triggered()), this, SLOT(delete_item()));
}
Пример #2
0
/*
 * Removes items from the macro list; use purgeOnly to specify which items
 * to purge.  Returns PURGE_NOACTION if nothing was done, PURGE_PURGED if
 * a matching item was purged, or PURGE_SKIPPED if an item with the correct
 * name was found but which wasn't allowed to be purged due to purgeOnly.
 */
static int purge_from_list( int purgeOnly, const char *name )
/***********************************************************/
{
    ListElem    *curElem = macroList;
    int         retcode = PURGE_NOACTION;

    /*** Try to find the item ***/
    while( curElem != NULL ) {
        if( !strcmp( name, curElem->name ) ) {
            if( (purgeOnly==PURGE_ALL)  ||  (purgeOnly==PURGE_DEFINE && curElem->type==DEFINE) ) {
                /*** Found one we're allowed to delete ***/
                delete_item( curElem );
                retcode = PURGE_PURGED;
                break;
            } else {
                /*** Found one we're not allowed to delete ***/
                retcode = PURGE_SKIPPED;
                break;
            }
        }
        curElem = curElem->next;
    }

    return( retcode );
}
Пример #3
0
void delete_item(cst_item *item)
{
    cst_item *ds, *nds;

    if (item->n != NULL) 
    { 
	item->n->p = item->p;
	item->n->u = item->u;  /* in trees if this is first daughter */
    }
    if (item->p != NULL) item->p->n = item->n;
    if (item->u != NULL) item->u->d = item->n; /* when first daughter */
    
    if (item->relation)
    {
	if (item->relation->head == item)
	    item->relation->head = item->n;
	if (item->relation->tail == item)
	    item->relation->tail = item->p;
    }

    /* Delete all the daughters of item */
    for (ds = item->d; ds; ds=nds)
    {
	nds = ds->n;
	delete_item(ds);
    }
    
    item_unref_contents(item);
    cst_utt_free(item->relation->utterance, item);
}
Пример #4
0
/*
 * Get the next define string in the list.  Returns NULL if nothing to get.
 */
char *GetNextDefineMacro( void )
/******************************/
{
    ListElem    *curElem = macroList;
    char        *str;
    size_t      len;

    while( curElem != NULL ) {
        if( curElem->type == DEFINE ) {
            /*** Allocate a buffer to hold it ***/
            len = strlen( curElem->name );      /* room for NAME */
            if( curElem->value != NULL ) {
                len++;                          /* room for = */
                len += strlen( curElem->value );/* room for VALUE */
            }
            len++;                              /* room for '\0' */
            str = AllocMem( len );

            /*** Fill in the buffer ***/
            strcpy( str, curElem->name );
            if( curElem->value != NULL ) {
                strcat( str, "=" );
                strcat( str, curElem->value );
            }

            /*** Clean up and go home ***/
            delete_item( curElem );
            return( str );
        }
        curElem = curElem->next;
    }

    return( NULL );
}
Пример #5
0
static protocol_binary_response_status delete_handler(const void *cookie,
                                                      const void *key,
                                                      uint16_t keylen,
                                                      uint64_t cas) {
  (void)cookie;
  protocol_binary_response_status rval= PROTOCOL_BINARY_RESPONSE_SUCCESS;

  if (cas != 0)
  {
    struct item *item= get_item(key, keylen);
    if (item != NULL)
    {
      if (item->cas != cas)
      {
        release_item(item);
        return PROTOCOL_BINARY_RESPONSE_KEY_EEXISTS;
      }
      release_item(item);
    }
  }

  if (!delete_item(key, keylen))
  {
    rval= PROTOCOL_BINARY_RESPONSE_KEY_ENOENT;
  }

  return rval;
}
Пример #6
0
void main()
{
    int len, pos, *del;
    plist pl = NULL;
    del = (int*)malloc(sizeof(int));
    pl = init_list();
    isEmpty_list(pl);
    insert_item(pl, 1, 1);
    insert_item(pl, 2, 3);
    insert_item(pl, 3, 5);
    insert_item(pl, 4, 7);
    insert_item(pl, 5, 9);
    insert_item(pl, 6, 11);
    display(pl);
    len = len_list(pl);
    printf("link list len: %d\n", len);
    pos = locate_item(pl, 7);
    printf("num 7 pos: %d\n", pos);
    delete_item(pl, 3, del);
    printf("delete pos 3 num: %d\n", *del);
    display(pl);
    printf("link list traverse...\n");
    pl = traverse_list(pl);
    display(pl);
    destroy_list(pl);
    getch();
}
Пример #7
0
int main(){

	srand(time(0));
	//Creating memory managers
	mm_t *MM = malloc(sizeof(mm_t));
	mm_init(MM,1500,sizeof(node));
	
	mm_t *MM2 = malloc(sizeof(mm_t));
	mm_init(MM2,3,sizeof(dl_list));
	
	//Creating Lists
    dl_list *dl_1 = mm_get(MM2);
    dl_list *dl_2 = mm_get(MM2);
    dl_list *dl_3 = mm_get(MM2);
    
    dl_list_init(dl_1);
    dl_list_init(dl_2);
    dl_list_init(dl_3);
	
	int i;
	for(i = 0; i<500; i++)
		insert_item(dl_1,i,MM);
	
	print_list(dl_1);
	
	for(i = 0; i<500; i++)
		insert_item(dl_2,rand()%500,MM);

	print_list(dl_2);
	
	for(i = 0; i<500; i++)
		insert_item(dl_3,get_element(dl_1,i)+get_element(dl_2,i),MM);
		
	print_list(dl_3);
	
	//Deleting items from list 1
	for(i = 0; i<100; i++)
		delete_item(dl_1,get_element(dl_3,i),MM);
	
	print_list(dl_1);
	
	//Joining lists
	join_lists(dl_2,dl_1);
	join_lists(dl_3,dl_2);
	
	print_list(dl_3);
	
	empty_list(dl_3,MM);
	
	//Deallocating and freeing
	mm_put(MM,dl_1);
	mm_put(MM,dl_2);
	mm_put(MM,dl_3);
	free(MM);
	free(MM2);

    return 0;
}
Пример #8
0
void btree_page_data::remove_items(
                      const int item_count,    // In: Number of records to remove
                      const w_keystr_t &high)  // In: high fence after record removal
{
    // Use this function with caution

    // A special helper function to remove 'item_count' largest items from the storage
    // this function is only used by full logging page rebalance restart operation
    // to recover the source page after a system crash
    // the caller resets the fence keys on source page which eliminate some
    // of the records from source page
    // this function removes the largest 'item_count' items from the page
    // because they belong to destination page after the rebalance
    // After the removal, item count changed but no change to ghost count

    w_assert1(btree_level >= 1);
    w_assert1(nitems > item_count);          // Must have at least one record which is the fency key record
    w_assert3(_items_are_consistent());

    if ((0 == item_count) || (1 == nitems))  // If 1 == nitems, we only have a fence key record
        return;

    DBGOUT3( << "btree_page_data::reset_item_count - before deletion item count: " << nitems
             << ", new high fence key: " << high);

    int remaining = item_count;
    char* high_key_p = (char *)high.buffer_as_keystr();
    size_t high_key_length = (size_t)high.get_length_as_keystr();
    while (0 < remaining)
    {
        w_assert1(1 < nitems);
        // Find the records with key >= new high fence key and delete them
        int item_index = 1;  // Start with index 1 since 0 is for the fence key record
        uint16_t* key_length;;
        size_t item_len;

        int cmp;
        const int data_offset = sizeof(uint16_t);  // To skipover the portion which contains the size of variable data
        for (int i = item_index; i < nitems; ++i)
        {
            key_length = (uint16_t*)item_data(i);
            item_len = *key_length++;

            cmp = ::memcmp(high_key_p, item_data(i)+data_offset, (high_key_length<=item_len)? high_key_length : item_len);
            if ((0 > cmp) || ((0 == cmp) && (high_key_length <= item_len)))
            {
                // The item is larger than the new high fence key or the same as high fence key (high fence is ghost)
                DBGOUT3( << "btree_page_data::reset_item_count - delete record index: " << i);

                // Delete the item, which changes nitems but no change to nghosts
                // therefore break out the loop and start the loop again if we have more items to remove
                delete_item(i);
                break;
            }
        }

        --remaining;
    }
Пример #9
0
int main()
{
    int suc,num_suc;
    int del_val;
    int num;
    node *root;
    int choice=1,menu_choice;
    
    root=(node *)malloc(sizeof(node));
    printf("enter the value at the node: ");
    scanf("%d",&num);
    printf("\n");
	
    root->data=num;
    root->lchild=NULL;
    root->rchild=NULL;
    
    while(choice==1)
      {
	printf("what do you want to do:\n\n1.>insert a node\n2.>delete a node\n3.>print the tree in inorder\n4.>exit\n\n");
	printf("please enter your choice: ");
	scanf("%d",&menu_choice);
	printf("\n");
	
	if(menu_choice==1)
	  {
	    insert(root);
	  }
	
	else if(menu_choice==2)
	  {
	    del_val=delete_item(root);
	    if(del_val!=0)
	      printf("\n%d has been successfully deleted\n",del_val);
	  }
	
	else if(menu_choice==3)
	  {
            printf("\n"); 
            print_tree(root);
            printf("NULL\n\n"); 
	  }
        
	else if(menu_choice==4) 
	  exit(-1);
	
	printf("enter 1 to go to the main menu or '0' to exit: ");
	scanf("%d",&choice);
	printf("\n");
	
	if(choice==0)
	  exit(-1);
	printf("\n");
      }
    
    return 0;
}
Пример #10
0
struct item *add_item(struct page *pg, long money, const struct string *desc, const struct string *comment)
{
	struct item *p;
	if ((p = add_dummy_item(pg)) == NULL) return NULL;
	if (item_set(p, money, desc, comment) == NULL) {
		delete_item(p);
		return NULL;
	}
	return p;
}
Пример #11
0
static void move_item(struct btree_page *from, int from_pos,
		      struct btree_page *to, int to_pos)
{
	if (from->height)
		insert_ptr(to, to_pos, PAGE_KEY(from, from_pos),
			   *PAGE_PTR(from, from_pos));
	else
		insert_data(to, to_pos, PAGE_KEY(from, from_pos),
			    PAGE_DATA(from, from_pos));

	delete_item(from, from_pos);
}
Пример #12
0
void delete_items_from_data(struct data *dt)
{
	struct ulist_item *p, *q, *t;
	for (p = dt->pages.first; p != NULL; p = p->next) {
		struct page *pg = get_page(p);
		for (q = pg->items.first; q != NULL; q = t) {
			struct item *it = get_item(q);
			t = q->next;
			if (is_set(it->flag, ITEM_TO_BE_DELETED)) delete_item(it);
		}
		if (ulist_is_empty(&pg->items)) add_dummy_item(pg);
	}
}
Пример #13
0
void list_delete(LIST *list, void (*delete_item)(void *data))
{
	LIST_ITEM *p, *q;
	p = list->top;

	while (p) {
		q = p->next;
		if ((delete_item) && (p->data)) {
			delete_item(p->data);
		};
		free(p);
		p = q;
	};

	free(list);
	return;
}
Пример #14
0
static protocol_binary_response_status prepend_handler(const void *cookie,
                                                       const void *key,
                                                       uint16_t keylen,
                                                       const void* val,
                                                       uint32_t vallen,
                                                       uint64_t cas,
                                                       uint64_t *result_cas) {
  (void)cookie;
  protocol_binary_response_status rval= PROTOCOL_BINARY_RESPONSE_SUCCESS;

  struct item *item= get_item(key, keylen);
  struct item *nitem= NULL;

  if (item == NULL)
  {
    rval= PROTOCOL_BINARY_RESPONSE_KEY_ENOENT;
  }
  else if (cas != 0 && cas != item->cas)
  {
    rval= PROTOCOL_BINARY_RESPONSE_KEY_EEXISTS;
  }
  else if ((nitem= create_item(key, keylen, NULL, item->size + vallen,
                                 item->flags, item->exp)) == NULL)
  {
    rval= PROTOCOL_BINARY_RESPONSE_ENOMEM;
  }
  else
  {
    memcpy(nitem->data, val, vallen);
    memcpy(((char*)(nitem->data)) + vallen, item->data, item->size);
    release_item(item);
    item= NULL;
    delete_item(key, keylen);
    put_item(nitem);
    *result_cas= nitem->cas;
  }

  if (item)
    release_item(item);

  if (nitem)
    release_item(nitem);

  return rval;
}
Пример #15
0
/* Returns -1 on error, 0 on missing dir, and 1 on present dir. */
static int validate_backup_dir(void)
{
	STRUCT_STAT st;

	if (do_lstat(backup_dir_buf, &st) < 0) {
		if (errno == ENOENT)
			return 0;
		rsyserr(FERROR, errno, "backup lstat %s failed", backup_dir_buf);
		return -1;
	}
	if (!S_ISDIR(st.st_mode)) {
		int flags = get_del_for_flag(st.st_mode) | DEL_FOR_BACKUP | DEL_RECURSE;
		if (delete_item(backup_dir_buf, st.st_mode, flags) == 0)
			return 0;
		return -1;
	}
	return 1;
}
Пример #16
0
static protocol_binary_response_status decrement_handler(const void *cookie,
                                                         const void *key,
                                                         uint16_t keylen,
                                                         uint64_t delta,
                                                         uint64_t initial,
                                                         uint32_t expiration,
                                                         uint64_t *result,
                                                         uint64_t *result_cas) {
    protocol_binary_response_status rval= PROTOCOL_BINARY_RESPONSE_SUCCESS;
    uint64_t val= initial;
    item_t *item;

    (void)cookie;
    mutex_lock(&storage_lock);

    item = get_item(key, keylen);

    if (item != NULL) {
        if (delta > *(uint64_t*)item->data)
            val= 0;
        else
            val= *(uint64_t*)item->data - delta;

        expiration= (uint32_t)item->exp;
        release_item(item);
        delete_item(key, keylen);
    }

    item= create_item(key, keylen, NULL, sizeof(initial), 0, (time_t)expiration);
    if (item == 0) {
        rval= PROTOCOL_BINARY_RESPONSE_ENOMEM;
    } else {
        memcpy(item->data, &val, sizeof(val));
        put_item(item);
        *result= val;
        *result_cas= item->cas;
        release_item(item);
    }

    mutex_unlock(&storage_lock);
    return rval;
}
Пример #17
0
void	free_data(t_data *data)
{
  int	i;

  i = -1;
  free_buttons(data->menu->buttons);
  while (++i < 14)
    {
      bunny_free(data->tab[i].name);
      bunny_delete_clipable(&data->tab[i].front->clipable);
      delete_item(data->tab[i].item);
      if (i == 0 || i == 1 || i == 4 || i == 9)
	bunny_delete_clipable(&data->tab[i].back->clipable);
      else if (i == 3 || i == 5 || i == 6)
	{
	  bunny_delete_clipable(&data->tab[i].back->clipable);
	  bunny_delete_clipable(&data->tab[i].middle->clipable);
	}
    }
}
Пример #18
0
static protocol_binary_response_status replace_handler(const void *cookie,
                                                       const void *key,
                                                       uint16_t keylen,
                                                       const void* data,
                                                       uint32_t datalen,
                                                       uint32_t flags,
                                                       uint32_t exptime,
                                                       uint64_t cas,
                                                       uint64_t *result_cas) {
  (void)cookie;
  protocol_binary_response_status rval= PROTOCOL_BINARY_RESPONSE_SUCCESS;
  struct item* item= get_item(key, keylen);

  if (item == NULL)
  {
    rval= PROTOCOL_BINARY_RESPONSE_KEY_ENOENT;
  }
  else if (cas == 0 || cas == item->cas)
  {
    release_item(item);
    delete_item(key, keylen);
    item= create_item(key, keylen, data, datalen, flags, (time_t)exptime);
    if (item == 0)
    {
      rval= PROTOCOL_BINARY_RESPONSE_ENOMEM;
    }
    else
    {
      put_item(item);
      *result_cas= item->cas;
      release_item(item);
    }
  }
  else
  {
    rval= PROTOCOL_BINARY_RESPONSE_KEY_EEXISTS;
    release_item(item);
  }

  return rval;
}
Пример #19
0
static protocol_binary_response_status increment_handler(const void *cookie,
                                                         const void *key,
                                                         uint16_t keylen,
                                                         uint64_t delta,
                                                         uint64_t initial,
                                                         uint32_t expiration,
                                                         uint64_t *result,
                                                         uint64_t *result_cas) {
    protocol_binary_response_status rval= PROTOCOL_BINARY_RESPONSE_SUCCESS;
    uint64_t val= initial;
    item_t *item;
    
    (void)cookie;
    mutex_lock(&storage_lock);

    item = get_item(key, keylen);

    if (item != NULL) {
        val= (*(uint64_t*)item->data) + delta;
        expiration= (uint32_t)item->exp;
        release_item(item);
        delete_item(key, keylen);
    }

    item= create_item(key, keylen, NULL, sizeof(initial), 0, (time_t)expiration);
    if (item == NULL) {
        rval= PROTOCOL_BINARY_RESPONSE_ENOMEM;
    } else {
        char buffer[1024] = {0}; // FIXME: does this need to be so big ~ajc
        memcpy(buffer, key, keylen);
        memcpy(item->data, &val, sizeof(val));
        put_item(item);
        *result= val;
        *result_cas= item->cas;
        release_item(item);
    }

    mutex_unlock(&storage_lock);

    return rval;
}
Пример #20
0
static protocol_binary_response_status set_handler(const void *cookie,
                                                   const void *key,
                                                   uint16_t keylen,
                                                   const void* data,
                                                   uint32_t datalen,
                                                   uint32_t flags,
                                                   uint32_t exptime,
                                                   uint64_t cas,
                                                   uint64_t *result_cas) {
  (void)cookie;
  protocol_binary_response_status rval= PROTOCOL_BINARY_RESPONSE_SUCCESS;

  if (cas != 0)
  {
    struct item* item= get_item(key, keylen);
    if (item != NULL && cas != item->cas)
    {
      /* Invalid CAS value */
      release_item(item);
      return PROTOCOL_BINARY_RESPONSE_KEY_EEXISTS;
    }
  }

  delete_item(key, keylen);
  struct item* item= create_item(key, keylen, data, datalen, flags, (time_t)exptime);
  if (item == 0)
  {
    rval= PROTOCOL_BINARY_RESPONSE_ENOMEM;
  }
  else
  {
    put_item(item);
    *result_cas= item->cas;
    release_item(item);
  }

  return rval;
}
Пример #21
0
/*
 * Get the next undefine string in the list.  Returns NULL if nothing to get.
 */
char *GetNextUndefineMacro( void )
/********************************/
{
    ListElem    *curElem = macroList;
    char        *str;
    size_t      len;

    while( curElem != NULL ) {
        if( curElem->type == UNDEFINE ) {
            /*** Copy the macro name ***/
            len = strlen( curElem->name ) + 1;  /* room for NAME\0 */
            str = AllocMem( len );
            strcpy( str, curElem->name );

            /*** Clean up and go home ***/
            delete_item( curElem );
            return( str );
        }
        curElem = curElem->next;
    }

    return( NULL );
}
Пример #22
0
static protocol_binary_response_status append_handler(const void *cookie,
                                                      const void *key,
                                                      uint16_t keylen,
                                                      const void* val,
                                                      uint32_t vallen,
                                                      uint64_t cas,
                                                      uint64_t *result_cas)
{
    protocol_binary_response_status rval= PROTOCOL_BINARY_RESPONSE_SUCCESS;
    item_t *item, *nitem;

    mutex_lock(&storage_lock);
    (void)cookie;

    item= get_item(key, keylen);

    if (item == NULL) {
        rval= PROTOCOL_BINARY_RESPONSE_KEY_ENOENT;
    } else if (cas != 0 && cas != item->cas) {
        rval= PROTOCOL_BINARY_RESPONSE_KEY_EEXISTS;
    } else if ((nitem= create_item(key, keylen, NULL, item->size + vallen,
                                   item->flags, item->exp)) == NULL) {
        release_item(item);
        rval= PROTOCOL_BINARY_RESPONSE_ENOMEM;
    } else {
        memcpy(nitem->data, item->data, item->size);
        memcpy(((char*)(nitem->data)) + item->size, val, vallen);
        release_item(item);
        delete_item(key, keylen);
        put_item(nitem);
        *result_cas= nitem->cas;
        release_item(nitem);
    }

    mutex_unlock(&storage_lock);
    return rval;
}
Пример #23
0
/* check directory item and try to recover something */
static int verify_directory_item (reiserfs_filsys_t fs, struct buffer_head * bh,
				  int item_num)
{
    struct item_head * ih;
    struct item_head tmp;
    char * item;
    struct reiserfs_de_head * deh;
    char * name;
    int name_len;
    int bad;
    int i, j;
#if 0
    int bad_entries; /* how many bad neighboring entries */
    int total_entry_len;
    char * entries, * end;
#endif
    int dirty;
    int entry_count;
    int hash_code;
    int bad_locations;

#ifdef DEBUG_VERIFY_DENTRY
    char * direntries;
#endif


    ih = B_N_PITEM_HEAD (bh, item_num);
    item = B_I_PITEM (bh,ih);
    deh = (struct reiserfs_de_head *)item;

    dirty = 0;
    bad_locations = 0;
    entry_count = ih_entry_count (ih);


    /* check deh_location */
    for (i = 0; i < ih_entry_count (ih); i ++) {
	/* silently fix deh_state */
	if (deh [i].deh_state != (1 << DEH_Visible)) {
	    deh [i].deh_state = cpu_to_le16 (1 << DEH_Visible);
	    mark_buffer_dirty (bh);
	}
	if (dir_entry_bad_location (deh + i, ih, !i))
	    mark_de_bad_location (deh + i);
    }

#ifdef DEBUG_VERIFY_DENTRY
    direntries = getmem (ih_entry_count (ih) * sizeof (int));

    printf ("entries with bad locations: ");
    for (i = 0; i < ih_entry_count (ih); i ++) {
	if (de_bad_location (deh + i))
	    printf ("%d ", i);
    }
    printf ("\n");
#endif /* DEBUG_VERIFY_DENTRY */


    /* find entries names in which have mismatching deh_offset */
    for (i = ih_entry_count (ih) - 1; i >= 0; i --) {
	if (de_bad (deh + i))
	    /* bad location */
	    continue;

	if (i) {
	    if (deh_location (deh + i - 1) < deh_location (deh + i))
		mark_de_bad_location (deh + i - 1);
	}

	name = name_in_entry (deh + i, i);
	/* we found a name, but we not always we can get its length as
           it depends on deh_location of previous entry */
	name_len = try_to_get_name_length (ih, deh + i, i);

#ifdef DEBUG_VERIFY_DENTRY
	if (name_len == 0)
	    printf ("trying to find name length for %d-th entry\n", i);
#endif /* DEBUG_VERIFY_DENTRY */
	if (is_dot (name, name_len)) {
	    if (i != 0)
		fsck_log ("block %lu: item %d: \".\" is %d-th entry\n",
			  bh->b_blocknr, item_num, i);
	    /* check and fix "." */
	    
	    if (deh_offset (deh + i) != DOT_OFFSET) {
		set_deh_offset(&(deh[i]), DOT_OFFSET);
		mark_buffer_dirty (bh);
	    }
	    /* "." must point to the directory it is in */
	    if (not_of_one_file (&(deh[i].deh_dir_id), &(ih->ih_key))) { /* endian safe */
		fsck_log ("verify_direntry: block %lu, item %H has entry \".\" "
			  "pointing to (%K) instead of (%K)\n", 
			  bh->b_blocknr, ih,
			  &(deh[i].deh_dir_id), &(ih->ih_key));
		deh[i].deh_dir_id = ih->ih_key.k_dir_id; /* both LE */
		deh[i].deh_objectid = ih->ih_key.k_objectid; /* both LE */
		mark_buffer_dirty (bh);
	    }
	} else if (is_dot_dot (name, name_len)) {
	    if (i != 1)
		fsck_log ("block %lu: item %d: \"..\" is %d-th entry\n",
			  bh->b_blocknr, item_num, i);
	    
	    /* check and fix ".." */
	    if (deh_offset (deh + i) != DOT_DOT_OFFSET)
		set_deh_offset(&(deh[i]), DOT_DOT_OFFSET);
	} else {
	    int min_length, max_length;

	    /* check other name */

	    if (name_len == 0) {
		/* we do not know the length of name - we will try to find it */
		min_length = 1;
		max_length = item + ih_item_len (ih) - name;
	    } else
		/* we kow name length, so we will try only one name length */
		min_length = max_length = name_len;

	    for (j = min_length; j <= max_length; j ++) {
		hash_code = find_hash_in_use (name, j,
					      GET_HASH_VALUE (deh_offset (deh + i)),
					      rs_hash (fs->s_rs));
		add_hash_hit (fs, hash_code);
		if (code2func (hash_code) != 0) {
		    /* deh_offset matches to some hash of the name */
		    if (!name_len) {
			fsck_log ("pass0: block %lu, item %H: entry %d. found a name \"%.*s\" "
				  "matching to deh_offset %u. FIXME: should set deh_location "
				  "of previous entry (not ready)\n",
				  bh->b_blocknr, ih, i, j, name, deh_offset (deh + i));
			/* FIXME: if next byte is 0 we think that the name is aligned to 8 byte boundary */
			if (i) {
			    set_deh_location( &(deh[i - 1]),
                                deh_location (deh + i) +
                                ((name[j] || SB_VERSION (fs) ==
                                REISERFS_VERSION_1) ? j : ROUND_UP (j)));
			    mark_de_good_location (deh + i - 1);
			    mark_buffer_dirty (bh);
			}
		    }
		    break;
		}
	    }
	    if (j == max_length + 1) {
		/* deh_offset does not match to anything. it will be
		   deleted for now, but maybe we could just fix a
		   deh_offset if it is in ordeer */
		mark_de_bad_offset (deh + i);
	    }
	}
    } /* for */



#if 0
    /* find entries names in which have mismatching deh_offset */
    for (i = 0; i < ih_entry_count (ih); i ++) {
	if (de_bad (deh + i))
	    /* bad location */
	    continue;

	name = name_in_entry (deh + i, i);
	/* we found a name, but we not always we can get its length as
           it depends on deh_location of previous entry */
	name_len = try_to_get_name_length (ih, deh + i, i);

	if (i == 0 && is_dot (name, name_len)) {
	    
	    /* check and fix "." */
	    
	    if (deh_offset (deh + i) != DOT_OFFSET) {
		deh[i].deh_offset = cpu_to_le32 (DOT_OFFSET);
	    }
	    /* "." must point to the directory it is in */
	    if (not_of_one_file (&(deh[i].deh_dir_id), &(ih->ih_key))) {
		fsck_log ("verify_direntry: block %lu, item %H has entry \".\" "
			  "pointing to (%K) instead of (%K)\n", 
			  bh->b_blocknr, ih,
			  &(deh[i].deh_dir_id), &(ih->ih_key));
		deh[i].deh_dir_id = ih->ih_key.k_dir_id; /* both 32 bit LE */
		deh[i].deh_objectid = ih->ih_key.k_objectid; /* both 32 bit LE */
		mark_buffer_dirty (bh);
	    }
	} else if (i == 1 && is_dot_dot (name, name_len)) {
	    
	    /* check and fix ".." */

	    if (deh_offset (deh + i) != DOT_DOT_OFFSET)
		deh[i].deh_offset = cpu_to_le32 (DOT_DOT_OFFSET);
	} else {
	    int min_length, max_length;

	    /* check other name */

	    if (name_len == 0) {
		/* we do not know the length of name - we will try to find it */
		min_length = 1;
		max_length = item + ih_item_len (ih) - name;
	    } else
		/* we kow name length, so we will try only one name length */
		min_length = max_length = name_len;

	    for (j = min_length; j <= max_length; j ++) {
		hash_code = find_hash_in_use (name, j,
					      GET_HASH_VALUE (deh_offset (deh + i)),
					      rs_hash (fs->s_rs));
		add_hash_hit (fs, hash_code);
		if (code2func (hash_code) != 0) {
		    /* deh_offset matches to some hash of the name */
		    if (!name_len) {
			fsck_log ("pass0: block %lu, item %H: entry %d. found a name \"%.*s\" "
				  "matching to deh_offset %u. FIXME: should set deh_location "
				  "of previous entry (not ready)\n",
				  bh->b_blocknr, ih, i, j, name, deh_offset (deh + i));
			/* FIXME: if next byte is 0 we think that the name is aligned to 8 byte boundary */
			deh[i - 1].deh_location = cpu_to_le16 (deh_location (deh + i) +
							       ((name[j] || SB_VERSION (fs) == REISERFS_VERSION_1) ? j : ROUND_UP (j)));
		    }
		    break;
		}
	    }
	    if (j == max_length + 1) {
		/* deh_offset does not match to anything. it will be
		   deleted for now, but maybe we could just fix a
		   deh_offset if it is in ordeer */
		mark_de_bad_offset (deh + i);
	    }
	}
   }
 #endif

 #ifdef DEBUG_VERIFY_DENTRY
     printf ("entries with mismatching deh_offsets: ");
     for (i = 0; i < ih_entry_count (ih); i ++) {
       if (de_bad_offset (deh + i))
           printf ("%d ", i);
     }
     printf ("\n");
 #endif /* DEBUG_VERIFY_DENTRY */


     /* correct deh_locations such that code cutting entries will not get
        screwed up */
     {
       int prev_loc;
       int loc_fixed;


       prev_loc = ih_item_len (ih);
       for (i = 0; i < ih_entry_count (ih); i ++) {
           loc_fixed = 0;
           if (de_bad_location (deh + i)) {
               set_deh_location(&(deh[i]), prev_loc/* - 1*/);
               mark_buffer_dirty (bh);
               loc_fixed = 1;
           } else {
               if (deh_location (deh + i) >= prev_loc) {
                   set_deh_location(&(deh[i]), prev_loc/* - 1*/);
                   mark_buffer_dirty (bh);
                   loc_fixed = 1;
               }
           }

           prev_loc = deh_location (deh + i);

           if (i == ih_entry_count (ih) - 1) {
               /* last entry starts right after an array of dir entry headers */
               if (!de_bad (deh + i) &&
                   deh_location (deh + i) != (DEH_SIZE * ih_entry_count (ih))) {

                   /* free space in the directory item */
                   fsck_log ("verify_direntry: block %lu, item %H has free
pace\n",
                             bh->b_blocknr, ih);
                   cut_entry (fs, bh, item_num, ih_entry_count (ih), 0);
               }
               if (deh_location (deh + i) != (DEH_SIZE * ih_entry_count (ih)))
               {

                   set_deh_location(&(deh[i]), DEH_SIZE * ih_entry_count (ih));
                   loc_fixed = 1;
                   mark_buffer_dirty (bh);
               }
           }

 #ifdef DEBUG_VERIFY_DENTRY
           if (loc_fixed)
               direntries [i] = 1;
 #endif
       } /* for */

 #ifdef DEBUG_VERIFY_DENTRY
       printf ("entries with fixed deh_locations: ");
       for (i = 0; i < ih_entry_count (ih); i ++) {
           if (direntries [i])
               printf ("%d ", i);
       }
       printf ("\n");
 #endif /* DEBUG_VERIFY_DENTRY */

     }

 #ifdef DEBUG_VERIFY_DENTRY
     printf (" N  location name\n");
     for (i = 0; i < ih_entry_count (ih); i ++) {
       if (de_bad (deh + i) ||
           (i && de_bad (deh + i - 1)) || /* previous entry marked bad */
           (i < ih_entry_count (ih) - 1 && de_bad (deh + i + 1))) { /* next
ntry is marked bad */
           /* print only entries to be deleted and their nearest neighbors */
           printf ("%3d: %8d ", i, deh_location (deh + i));
           if (de_bad (deh + i))
               printf ("will be deleted\n");
           else
               printf ("\"%.*s\"\n", name_length (ih, deh + i, i),
                       name_in_entry (deh + i, i));
       }
     }
 #endif

     bad = 0;
     tmp = *ih;

     /* delete entries which are marked bad */
     for (i = 0; i < ih_entry_count (ih); i ++) {
       deh = B_I_DEH (bh, ih) + i;
       if (de_bad (deh)) {
           bad ++;
           if (ih_entry_count (ih) == 1) {
               delete_item (fs, bh, item_num);
               break;
           } else {
               cut_entry (fs, bh, item_num, i, 1);
           }
	   i --;
	}
    }
    
    if (bad == ih_entry_count (&tmp)) {
	fsck_log ("pass0: block %lu, item %H - all entries were deleted\n", bh->b_blocknr, &tmp);
	return 0;
    }

    deh = B_I_DEH (bh, ih);
    if (get_offset (&ih->ih_key) != deh_offset (deh)) {
	fsck_log ("verify_direntry: block %lu, item %H:  k_offset and deh_offset %u mismatched\n",
		  bh->b_blocknr, ih, deh_offset (deh));
	set_offset (KEY_FORMAT_1, &ih->ih_key, deh_offset (deh));
	mark_buffer_dirty (bh);
    }
    
    if (bad)
	fsck_log ("pass0: block %lu, item %H: %d entries were deleted of \n",
		  bh->b_blocknr, &tmp, bad);
	
    return 0;

#if 0

    /* FIXME: temporary */
    if (bad_locations > ih_entry_count (ih) / 2) {
	fsck_log ("pass0: block %u: item %d (%H) had too bad directory - deleted\n",
		  bh->b_blocknr, item_num, ih);
	delete_item (fs, bh, item_num);
	return 0;
    }

    if (!dirty)
	return 0;
    
    /* something is broken */

    fsck_log ("pass0: block %lu: %d-th item (%H) has %d bad entries..",
	      bh->b_blocknr, item_num, ih, dirty);

    if (get_offset (&ih->ih_key) == DOT_OFFSET) {
	/* first item of directory - make sure that "." and ".." are in place */
	if (deh_offset (deh) != DOT_OFFSET || name_in_entry (deh, 0)[0] != '.') {
	    set_deh_offset(deh, DOT_OFFSET);
	    name_in_entry (deh, 0)[0] = '.';
	}
	if (deh_offset (deh + 1) != DOT_DOT_OFFSET ||
	    name_in_entry (deh + 1, 1)[0] != '.' || name_in_entry (deh + 1, 1)[1] != '.') {
	    set_deh_offset((deh + 1), DOT_DOT_OFFSET);
	    name_in_entry (deh + 1, 1)[0] = '.';
	    name_in_entry (deh + 1, 1)[1] = '.';
	}
    }

    end = item + ih_item_len (ih);
    deh += ih_entry_count (ih);
    entries = (char *)deh;
    total_entry_len = ih_item_len (ih) - DEH_SIZE * ih_entry_count (ih);
    i = ih_entry_count (ih);

    bad_entries = 0;
    do {
	i --;
	deh --;
	name_len = prob_name (fs, &entries, total_entry_len, deh_offset (deh));
	if (!name_len) {
	    if (!bad_entries) {
                set_deh_location(deh, entries - item);
	    } else {
                set_deh_location(deh, deh_location((deh + 1)) + 1 );
	    }
	    bad_entries ++;
	    
	    /*fsck_log ("verify_directory_item: entry %d: in string \'%s\' there is no substring matching hash %ld\n",
	      i, bad_name (entries, total_entry_len), masked_offset);*/
	    mark_de_bad (deh);
	    continue;
	}
	bad_entries = 0;
	/*fsck_log ("verify_directory_item: entry %d: found \"%s\" name matching hash %ld\n",
	  i, bad_name (entries, name_len), masked_offset);*/
	
	/* 'entries' points now to the name which match given offset -
           so, set deh_location */
        set_deh_location(deh, entries - item);
	deh->deh_state = 0;
	mark_de_visible (deh);
	
	entries += name_len;
	total_entry_len = end - entries;
	/* skip padding zeros */
	while (!*entries) {
	    entries ++;
	    total_entry_len --;
	}
	/* 'entries' points now at the place where next (previous)
           entry should start */
    } while ((char *)deh != item);
    
    
    /* fixme: this will not work if all entries are to be deleted */
    for (i = 0; i < ih_entry_count (ih); i ++, deh ++) {
	deh = (struct reiserfs_de_head *)B_I_PITEM (bh, ih) + i;
	if (de_bad (deh)) {
	    if (ih_entry_count (ih) == 1) {
		delete_item (fs, bh, i);
		break;
	    } else {
		cut_entry (fs, bh, item_num, i);
	    }
	    i --;
	}
/*
  fsck_log ("verify_directory_item: %d-th entry is to be deleted: "
  "\"%s\" does not match to hash %lu\n", 
  i, bad_name (name_in_entry (deh, i), name_length (ih, deh, i)),
  deh_offset (deh));
*/
    }
    
    fsck_log ("%d entries were deleted\n", entry_count - ih_entry_count (ih));
    mark_buffer_dirty (bh);

    
    return 0;

#endif
}
Пример #24
0
void jrb_delete_node(JRB n)
{
  JRB s, p, gp;
  char ir;

  if (isint(n)) {
    fprintf(stderr, "Cannot delete an internal node: 0x%p\n", (void *)n);
    exit(1);
  }
  if (ishead(n)) {
    fprintf(stderr, "Cannot delete the head of an jrb_tree: 0x%p\n", (void *)n);
    exit(1);
  }
  delete_item(n); /* Delete it from the list */
  p = n->parent;  /* The only node */
  if (isroot(n)) {
    p->parent = p;
    free(n);
    return;
  }
  s = sibling(n);    /* The only node after deletion */
  if (isroot(p)) {
    s->parent = p->parent;
    s->parent->parent = s;
    setroot(s);
    free(p);
    free(n);
    return;
  }
  gp = p->parent;  /* Set parent to sibling */
  s->parent = gp;
  if (isleft(p)) {
    gp->flink = s;
    setleft(s);
  } else {
    gp->blink = s;
    setright(s);
  }
  ir = isred(p);
  free(p);
  free(n);

  if (isext(s)) {      /* Update proper rext and lext values */
    p = lprev(s);
    if (!ishead(p)) setrext(p, s);
    p = rprev(s);
    if (!ishead(p)) setlext(p, s);
  } else if (isblack(s)) {
    fprintf(stderr, "DELETION PROB -- sib is black, internal\n");
    exit(1);
  } else {
    p = lprev(s);
    if (!ishead(p)) setrext(p, s->flink);
    p = rprev(s);
    if (!ishead(p)) setlext(p, s->blink);
    setblack(s);
    return;
  }

  if (ir) return;

  /* Recolor */

  n = s;
  p = n->parent;
  s = sibling(n);
  while(isblack(p) && isblack(s) && isint(s) &&
        isblack(s->flink) && isblack(s->blink)) {
    setred(s);
    n = p;
    if (isroot(n)) return;
    p = n->parent;
    s = sibling(n);
  }

  if (isblack(p) && isred(s)) {  /* Rotation 2.3b */
    single_rotate(p, isright(n));
    setred(p);
    setblack(s);
    s = sibling(n);
  }

  { JRB x, z; char il;

    if (isext(s)) {
      fprintf(stderr, "DELETION ERROR: sibling not internal\n");
      exit(1);
    }

    il = isleft(n);
    x = il ? s->flink : s->blink ;
    z = sibling(x);

    if (isred(z)) {  /* Rotation 2.3f */
      single_rotate(p, !il);
      setblack(z);
      if (isred(p)) setred(s); else setblack(s);
      setblack(p);
    } else if (isblack(x)) {   /* Recoloring only (2.3c) */
      if (isred(s) || isblack(p)) {
        fprintf(stderr, "DELETION ERROR: 2.3c not quite right\n");
        exit(1);
      }
      setblack(p);
      setred(s);
      return;
    } else if (isred(p)) { /* 2.3d */
      single_rotate(s, il);
      single_rotate(p, !il);
      setblack(x);
      setred(s);
      return;
    } else {  /* 2.3e */
      single_rotate(s, il);
      single_rotate(p, !il);
      setblack(x);
      return;
    }
  }
}
Пример #25
0
/* Receive a command from the client and execute it. */
static void handle_command (const int client_id)
{
	int cmd;
	int err = 0;
	struct client *cli = &clients[client_id];

	if (!get_int(cli->socket, &cmd)) {
		logit ("Failed to get command from the client");
		close (cli->socket);
		del_client (cli);
		return;
	}

	switch (cmd) {
		case CMD_QUIT:
			logit ("Exit request from the client");
			close (cli->socket);
			del_client (cli);
			server_quit = 1;
			break;
		case CMD_LIST_CLEAR:
			logit ("Clearing the list");
			audio_plist_clear ();
			break;
		case CMD_LIST_ADD:
			if (!req_list_add(cli))
				err = 1;
			break;
		case CMD_PLAY:
			if (!req_play(cli))
				err = 1;
			break;
		case CMD_DISCONNECT:
			logit ("Client disconnected");
			close (cli->socket);
			del_client (cli);
			break;
		case CMD_PAUSE:
			audio_pause ();
			break;
		case CMD_UNPAUSE:
			audio_unpause ();
			break;
		case CMD_STOP:
			audio_stop ();
			break;
		case CMD_GET_CTIME:
			if (!send_data_int(cli, MAX(0, audio_get_time())))
				err = 1;
			break;
		case CMD_SEEK:
			if (!req_seek(cli))
				err = 1;
			break;
		case CMD_JUMP_TO:
			if (!req_jump_to(cli))
				err = 1;
			break;
		case CMD_GET_SNAME:
			if (!send_sname(cli))
				err = 1;
			break;
		case CMD_GET_STATE:
			if (!send_data_int(cli, audio_get_state()))
				err = 1;
			break;
		case CMD_GET_BITRATE:
			if (!send_data_int(cli, sound_info.bitrate))
				err = 1;
			break;
		case CMD_GET_AVG_BITRATE:
			if (!send_data_int(cli, sound_info.avg_bitrate))
				err = 1;
			break;
		case CMD_GET_RATE:
			if (!send_data_int(cli, sound_info.rate))
				err = 1;
			break;
		case CMD_GET_CHANNELS:
			if (!send_data_int(cli, sound_info.channels))
				err = 1;
			break;
		case CMD_NEXT:
			audio_next ();
			break;
		case CMD_PREV:
			audio_prev ();
			break;
		case CMD_PING:
			if (!send_int(cli->socket, EV_PONG))
				err = 1;
			break;
		case CMD_GET_OPTION:
			if (!send_option(cli))
				err = 1;
			break;
		case CMD_SET_OPTION:
			if (!get_set_option(cli))
				err = 1;
			break;
		case CMD_GET_MIXER:
			if (!send_data_int(cli, audio_get_mixer()))
				err = 1;
			break;
		case CMD_SET_MIXER:
			if (!set_mixer(cli))
				err = 1;
			break;
		case CMD_DELETE:
			if (!delete_item(cli))
				err = 1;
			break;
		case CMD_SEND_PLIST_EVENTS:
			cli->wants_plist_events = 1;
			logit ("Request for events");
			break;
		case CMD_GET_PLIST:
			if (!get_client_plist(cli))
				err = 1;
			break;
		case CMD_SEND_PLIST:
			if (!req_send_plist(cli))
				err = 1;
			break;
		case CMD_CAN_SEND_PLIST:
			cli->can_send_plist = 1;
			break;
		case CMD_CLI_PLIST_ADD:
		case CMD_CLI_PLIST_DEL:
		case CMD_CLI_PLIST_CLEAR:
		case CMD_CLI_PLIST_MOVE:
			if (!plist_sync_cmd(cli, cmd))
				err = 1;
			break;
		case CMD_LOCK:
			if (!client_lock(cli))
				err = 1;
			break;
		case CMD_UNLOCK:
			if (!client_unlock(cli))
				err = 1;
			break;
		case CMD_GET_SERIAL:
			if (!send_serial(cli))
				err = 1;
			break;
		case CMD_PLIST_GET_SERIAL:
			if (!req_plist_get_serial(cli))
				err = 1;
			break;
		case CMD_PLIST_SET_SERIAL:
			if (!req_plist_set_serial(cli))
				err = 1;
			break;
		case CMD_GET_TAGS:
			if (!req_get_tags(cli))
				err = 1;
			break;
		case CMD_TOGGLE_MIXER_CHANNEL:
			req_toggle_mixer_channel ();
			break;
		case CMD_TOGGLE_SOFTMIXER:
			req_toggle_softmixer ();
			break;
		case CMD_GET_MIXER_CHANNEL_NAME:
			if (!req_get_mixer_channel_name(cli))
				err = 1;
			break;
		case CMD_GET_FILE_TAGS:
			if (!get_file_tags(client_id))
				err = 1;
			break;
		case CMD_ABORT_TAGS_REQUESTS:
			if (!abort_tags_requests(client_id))
				err = 1;
			break;
		case CMD_LIST_MOVE:
			if (!req_list_move(cli))
				err = 1;
			break;
		case CMD_TOGGLE_EQUALIZER:
			req_toggle_equalizer();
			break;
		case CMD_EQUALIZER_REFRESH:
			req_equalizer_refresh();
			break;
		case CMD_EQUALIZER_PREV:
			req_equalizer_prev();
			break;
		case CMD_EQUALIZER_NEXT:
			req_equalizer_next();
			break;
		case CMD_TOGGLE_MAKE_MONO:
			req_toggle_make_mono();
			break;
		case CMD_QUEUE_ADD:
			if (!req_queue_add(cli))
				err = 1;
			break;
		case CMD_QUEUE_DEL:
			if (!req_queue_del(cli))
				err = 1;
			break;
		case CMD_QUEUE_CLEAR:
			logit ("Clearing the queue");
			audio_queue_clear ();
			add_event_all (EV_QUEUE_CLEAR, NULL);
			break;
		case CMD_QUEUE_MOVE:
			if (!req_queue_move(cli))
				err = 1;
			break;
		case CMD_GET_QUEUE:
			if (!req_send_queue(cli))
				err = 1;
			break;
		default:
			logit ("Bad command (0x%x) from the client", cmd);
			err = 1;
	}

	if (err) {
		logit ("Closing client connection due to error");
		close (cli->socket);
		del_client (cli);
	}
}
Пример #26
0
void command_paste(doc *d, char **args, int nargs)
{
  cursor precursor = d->c;
  doc n;
  int change = 0;
  int i, j, nlines, ii, jj;
  if (nargs != 1) return paste_usage();
  n = to_doc(args[0]);

  lock(d);

  if (n.size != 1) goto error;

  nlines = d->l[d->c.line].n;

  /* take into account subline of cursor to paste */
  for (i = 0, ii = 0; i < n.l[0].size; i++, ii++) {
    item *s = &n.l[0].i[i], *dst;
    new_item(&d->l[d->c.line], d->c.item+ii);
    dst = &d->l[d->c.line].i[d->c.item+ii];
    for (j = 0, jj = 0; j < s->size; j++, jj++) {
      switch (s->i[j].t) {
      case CLEF: if (s->i[j].clef.s + d->c.subline >= nlines) {jj--;continue;}
        new_vertical_item(dst, jj, CLEF,
            s->i[j].clef.t, s->i[j].clef.s + d->c.subline, s->i[j].clef.p);
        break;
      case ARMATURE:if(s->i[j].armature.s+d->c.subline>=nlines){jj--;continue;}
        new_vertical_item(dst, jj, ARMATURE,
            s->i[j].armature.t, s->i[j].armature.s + d->c.subline,
            s->i[j].armature.p);
        break;
      case NOTE: if (s->i[j].note.s + d->c.subline >= nlines){jj--;continue;}
        new_vertical_item(dst, jj, NOTE,
            s->i[j].note.duration, s->i[j].note.dots, s->i[j].note.alteration,
            s->i[j].note.s + d->c.subline, s->i[j].note.p, s->i[j].note.st,
            s->i[j].note.l, s->i[j].note.m, s->i[j].note.o);
        break;
      case SILENCE: if(s->i[j].silence.s+d->c.subline>=nlines){jj--;continue;}
        new_vertical_item(dst, jj, SILENCE,
            s->i[j].silence.duration, s->i[j].silence.dots,
            s->i[j].silence.s + d->c.subline, s->i[j].silence.p);
        break;
      case BAR: /* always works */
        new_vertical_item(dst, jj, BAR);
        break;
      }
    }
    if (dst->size == 0) {
      delete_item(&d->l[d->c.line], d->c.item+ii);
      ii--;
      continue;
    }
    for (j = 0; j < s->tsize; j++)
      new_text(dst, s->t[j].t, s->t[j].dx, s->t[j].dy);
    change = 1;
  }

  if (change == 0) goto error;

  d->dirty = 1;
  unlock(d);
  resize(d);
  new_history(d, precursor);

  delete_doc(&n);
  return;

error:
  unlock(d);
  printf("cannot paste '%s'\n", args[0]);
  delete_doc(&n);
}
Пример #27
0
/* FIXME: we can improve fixing of broken keys: we can ssfe direct items which
   go after stat data and have broken keys */
static void pass0_correct_leaf (reiserfs_filsys_t fs,
				struct buffer_head * bh)
{
    int i, j;
    struct item_head * ih;
    __u32 * ind_item;
    unsigned long unfm_ptr;
    int dirty = 0;

 start_again:

    ih = B_N_PITEM_HEAD (bh, 0);
    for (i = 0; i < node_item_number (bh); i ++, ih ++) {
	if (ih->ih_key.k_dir_id == 0 || ih->ih_key.k_objectid == 0) {
	    /* sometimes stat datas get k_objectid==0 or k_dir_id==0 */
	    if (i == (node_item_number (bh) - 1)) {
		/* */
		if (i == 0) {
		    fsck_log ("block %lu: item %d: (%H) is alone in the block\n",
			      bh->b_blocknr, i, ih);
		    return;
		}
		/* delete last item */
		delete_item (fs, bh, i - 1);
		return;
	    }

	    /* there is next item: if it is not stat data - take its k_dir_id
               and k_objectid. if key order will be still wrong - the changed
               item will be deleted */
	    if (!is_stat_data_ih (ih + 1)) {
		fsck_log ("block %lu: item %d: (%H) fixed to ", bh->b_blocknr, i, ih);
		ih->ih_key.k_dir_id = (ih + 1)->ih_key.k_dir_id;
		ih->ih_key.k_objectid = (ih + 1)->ih_key.k_objectid;
		set_offset (KEY_FORMAT_1, &ih->ih_key, 0);
		set_type (KEY_FORMAT_1, &ih->ih_key, TYPE_STAT_DATA);
		fsck_log ("(%H)\n", ih);
		dirty = 1;
	    } else if (i == 0) {
		delete_item (fs, bh, i);
		goto start_again;
	    }
	}

	/* this recovers corruptions like the below: 
	   1774 1732 0 0
	   116262638 1732 1 3
	   1774 1736 0 0 */
	if (i && is_stat_data_ih (ih - 1) && !is_stat_data_ih (ih)) {
	    if (ih->ih_key.k_objectid != (ih - 1)->ih_key.k_objectid ||
		ih->ih_key.k_dir_id != (ih - 1)->ih_key.k_dir_id ||
		get_offset (&ih->ih_key) != 1) {
		if (is_direntry_ih (ih)) {
		    fsck_log ("block %lu: item %d: no \".\" entry found in "
			      "the first item of a directory\n", bh->b_blocknr, i);
		} else {
		    fsck_log ("block %lu: item %d: (%H) fixed to ", 
			  bh->b_blocknr, i, ih);
		    ih->ih_key.k_dir_id = (ih - 1)->ih_key.k_dir_id;
		    ih->ih_key.k_objectid = (ih - 1)->ih_key.k_objectid;
		    
		    if (ih_item_len (ih - 1) == SD_SIZE) {
			/* stat data is new, therefore this item is new too */
			set_offset (KEY_FORMAT_2, &(ih->ih_key), 1);
			if (ih_entry_count (ih) != 0xffff)
			    set_type (KEY_FORMAT_2, &(ih->ih_key), TYPE_INDIRECT);
			else
			    set_type (KEY_FORMAT_2, &(ih->ih_key), TYPE_DIRECT);
			set_ih_key_format (ih, KEY_FORMAT_2);
		    } else {
			/* stat data is old, therefore this item is old too */
			set_offset (KEY_FORMAT_1, &(ih->ih_key), 1);
			if (ih_entry_count (ih) != 0xffff)
			    set_type (KEY_FORMAT_1, &(ih->ih_key), TYPE_INDIRECT);
			else
			    set_type (KEY_FORMAT_1, &(ih->ih_key), TYPE_DIRECT);
			set_ih_key_format (ih, KEY_FORMAT_1);
		    }
		    fsck_log ("%H\n", ih);
		    dirty = 1;
		}
	    }
	}

	/* FIXME: corruptions like:
	   56702 66802 1 2
	   56702 65536 0 0
	   56702 66803 1 2
	   do not get recovered (both last items will be deleted) */
	/* delete item if it is not in correct order of object items */
	if (i && not_of_one_file (&ih->ih_key, &(ih - 1)->ih_key) &&
	    !is_stat_data_ih (ih)) {
	    fsck_log ("block %lu: item %d: %H follows non stat item %H - deleted\n",
		      bh->b_blocknr, i, ih, ih - 1);
	    delete_item (fs, bh, i);
	    goto start_again;
	}

	if (i &&  comp_keys (&(ih - 1)->ih_key, &ih->ih_key) != -1) {
	    /* previous item has key not smaller than the key of currect item */
	    if (is_stat_data_ih (ih - 1) && !is_stat_data_ih (ih)) {
		/* fix key of stat data such as if it was stat data of that item */
		fsck_log ("pass0: block %lu: %d-th item %k is out of order, made a stat data of %d-th (%k)\n",
			  bh->b_blocknr, i - 1, &(ih - 1)->ih_key, i, &ih->ih_key);
		(ih - 1)->ih_key.k_dir_id = ih->ih_key.k_dir_id;
		(ih - 1)->ih_key.k_objectid = ih->ih_key.k_objectid;
		set_offset (KEY_FORMAT_1, &(ih - 1)->ih_key, 0);
		set_type (KEY_FORMAT_1, &(ih - 1)->ih_key, TYPE_STAT_DATA);
		dirty = 1;
	    } else {
		/* ok, we have to delete one of these two - decide which one */
		int retval;

		/* something will be deleted */
		dirty = 1;
		retval = upper_correct (bh, ih - 1, i - 1);
		switch (retval) {
		case 0:
		    /* delete upper item */
		    fsck_log ("pass0: block %lu: %d-th (upper) item (%k) is out of order, deleted\n",
			      bh->b_blocknr, i - 1, &(ih - 1)->ih_key);
		    delete_item (fs, bh, i - 1);
		    goto start_again;

		case 1:
		    /* delete lower item */
		    fsck_log ("pass0: block %lu: %d-th (lower) item (%k) is out of order, deleted\n",
			      bh->b_blocknr, i, &ih->ih_key);
		    delete_item (fs, bh, i);
		    goto start_again;

		default:
		    /* upper item was the first item of a node */
		}

		retval = lower_correct (bh, ih, i);
		switch (retval) {
		case 0:
		    /* delete lower item */
		    fsck_log ("pass0: block %lu: %d-th (lower) item (%k) is out of order, deleted\n",
			      bh->b_blocknr, i, &ih->ih_key);
		    delete_item (fs, bh, i);
		    goto start_again;

		case 1:
		    /* delete upper item */
		    fsck_log ("pass0: block %lu: %d-th (upper) item (%k) is out of order, deleted\n",
			      bh->b_blocknr, i - 1, &(ih - 1)->ih_key);
		    delete_item (fs, bh, i - 1);
		    goto start_again;

		default:
		    /* there wer only two items in a node, so we could not
                       decide what to delete, go and ask user */
		}
		fsck_log ("pass0: which of these items looks better (other will be deleted)?\n"
			  "%H\n%H\n", ih - 1, ih);
		if (fsck_user_confirmed (fs, "1 or 2?", "1\n", 1))
		    delete_item (fs, bh, i - 1);
		else
		    delete_item (fs, bh, i);
		goto start_again;
	    }
	}

	if (is_stat_data_ih (ih) && (ih_item_len (ih) != SD_SIZE &&
				     ih_item_len (ih) != SD_V1_SIZE)) {
	    fsck_log ("pass0: block %lu, stat data of wrong length %H - deleted\n",
		      bh, ih);
	    delete_item (fs, bh, i);
	    goto start_again;
	}

	dirty += correct_key_format (ih);

	if (is_stat_data_ih (ih)) {
	    ;/*correct_stat_data (fs, bh, i);*/
	}

	if (is_direntry_ih (ih)) {
	    verify_directory_item (fs, bh, i);
	    continue;
	}

	if (!is_indirect_ih (ih))
	    continue;
	
	ind_item = (__u32 *)B_I_PITEM (bh, ih);
	for (j = 0; j < I_UNFM_NUM (ih); j ++) {
	    unfm_ptr = le32_to_cpu (ind_item [j]);
	    if (!unfm_ptr)
		continue;
	    
	    if (fsck_mode (fs) == FSCK_ZERO_FILES) {
		/* FIXME: this is temporary mode of fsck */
		ind_item [j] = 0;
		reiserfs_bitmap_clear_bit (fsck_new_bitmap(fs), unfm_ptr);
		tmp_zeroed ++;
		dirty = 1;
		continue;
	    }

	    if (not_data_block (fs, unfm_ptr) || /* journal area or bitmap or super block */
		unfm_ptr >= SB_BLOCK_COUNT (fs)) {/* garbage in pointer */

		stats (fs)->wrong_pointers ++;
		/*
		fsck_log ("pass0: %d-th pointer (%lu) in item %k (leaf block %lu) is wrong\n",
			  j, unfm_ptr, &ih->ih_key, bh->b_blocknr);
		*/
		ind_item [j] = 0;
		dirty = 1;
		continue;
	    }
#if 0
	    if (!was_block_used (unfm_ptr)) {
	      /* this will get to a pool of allocable blocks */
	      ind_item [j] = 0;
	      dirty = 1;
	      stat_wrong_pointer_found (fs);
	      continue;
	    }
#endif
	    /* mark block in bitmaps of unformatted nodes */
	    register_unfm (unfm_ptr);
	}
    }

    /* mark all objectids in use */
    ih = B_N_PITEM_HEAD (bh, 0);
    for (i = 0; i < node_item_number (bh); i ++, ih ++) {
	mark_objectid_really_used (proper_id_map (fs), le32_to_cpu (ih->ih_key.k_dir_id));
	mark_objectid_really_used (proper_id_map (fs), le32_to_cpu (ih->ih_key.k_objectid));
    }

    if (node_item_number (bh) < 1) {
	/* pass 1 will skip this */
	stats(fs)->all_contents_removed ++;
	fsck_log ("pass0: block %lu got all items deleted\n",
		  bh->b_blocknr);
    } else {
	/* pass1 will use this bitmap */
	pass0_mark_leaf (bh->b_blocknr);

    }
    if (dirty) {
	stats(fs)->leaves_corrected ++;
	mark_buffer_dirty (bh);
    }
}


static int is_bad_sd (struct item_head * ih, char * item)
{
    struct stat_data * sd = (struct stat_data *)item;

    if (le32_to_cpu(ih->ih_key.u.k_offset_v1.k_offset) || le32_to_cpu(ih->ih_key.u.k_offset_v1.k_uniqueness)) {
	reiserfs_warning (stderr, "Bad SD? %H\n", ih);
	return 1;
    }

    if (ih_item_len (ih) == SD_V1_SIZE) {
	/* looks like old stat data */
	if (ih_key_format (ih) != KEY_FORMAT_1)
	    fsck_log ("item %H has wrong format\n", ih);
	return 0;
    }

    if (!S_ISDIR (sd_v2_mode(sd)) && !S_ISREG(sd_v2_mode(sd)) &&
	!S_ISCHR (sd_v2_mode(sd)) && !S_ISBLK(sd_v2_mode(sd)) &&
	!S_ISLNK (sd_v2_mode(sd)) && !S_ISFIFO(sd_v2_mode(sd)) &&
	!S_ISSOCK(sd_v2_mode(sd))) {	
	/*fsck_log ("file %k unexpected mode encountered 0%o\n", &ih->ih_key, sd_v2_mode(sd))*/;
    }
    return 0;
}


int is_bad_directory (struct item_head * ih, char * item, int dev, int blocksize)
{
    int i;
    char * name;
    int namelen, entrylen;
    struct reiserfs_de_head * deh = (struct reiserfs_de_head *)item;
    __u32 prev_offset = 0;
    __u16 prev_location = ih_item_len (ih);
    int min_entry_size = 1;/* we have no way to understand whether the
                              filesystem were created in 3.6 format or
                              converted to it. So, we assume that minimal name
                              length is 1 */

    if (ih_item_len (ih) / (DEH_SIZE + min_entry_size) < ih_entry_count (ih))
	/* entry count is too big */
	return 1;

    for (i = 0; i < ih_entry_count (ih); i ++, deh ++) {
	entrylen = entry_length(ih, deh, i);
	if (entrylen > REISERFS_MAX_NAME_LEN (blocksize)) {
	    return 1;
	}
	if (deh_offset (deh) <= prev_offset) {
	    return 1;
	}
	prev_offset = deh_offset (deh);

	if (deh_location(deh) + entrylen != prev_location) {
	    return 1;
	}
	prev_location = deh_location (deh);

	namelen = name_length (ih, deh, i);
	name = name_in_entry (deh, i);
	if (!is_properly_hashed (fs, name, namelen, deh_offset (deh))) {
	    return 1;
	}
    }
    return 0;
}


/* change incorrect block adresses by 0. Do not consider such item as incorrect */
static int is_bad_indirect (struct item_head * ih, char * item, int dev, int blocksize)
{
    int i;
    int bad = 0;
    int blocks;

    if (ih_item_len(ih) % UNFM_P_SIZE) {
	fsck_log ("is_bad_indirect: indirect item of %H of invalid length\n", ih);
	return 1;
    }

    blocks = SB_BLOCK_COUNT (fs);
  
    for (i = 0; i < I_UNFM_NUM (ih); i ++) {
	__u32 * ind = (__u32 *)item;

	if (le32_to_cpu (ind[i]) >= blocks) {
	    bad ++;
	    fsck_log ("is_bad_indirect: %d-th pointer of item %H looks bad (%lu)\n",
		      i, ih, le32_to_cpu (ind [i]));
	    continue;
	}
    }
    return bad;
}
Пример #28
0
/* The directory is about to be deleted: if DEL_RECURSE is given, delete all
 * its contents, otherwise just checks for content.  Returns DR_SUCCESS or
 * DR_NOT_EMPTY.  Note that fname must point to a MAXPATHLEN buffer!  (The
 * buffer is used for recursion, but returned unchanged.)
 */
static enum delret delete_dir_contents(char *fname, uint16 flags)
{
	struct file_list *dirlist;
	enum delret ret;
	unsigned remainder;
	void *save_filters;
	int j, dlen;
	char *p;

	if (DEBUG_GTE(DEL, 3)) {
		rprintf(FINFO, "delete_dir_contents(%s) flags=%d\n",
			fname, flags);
	}

	dlen = strlen(fname);
	save_filters = push_local_filters(fname, dlen);

	non_perishable_cnt = 0;
	dirlist = get_dirlist(fname, dlen, 0);
	ret = non_perishable_cnt ? DR_NOT_EMPTY : DR_SUCCESS;

	if (!dirlist->used)
		goto done;

	if (!(flags & DEL_RECURSE)) {
		ret = DR_NOT_EMPTY;
		goto done;
	}

	p = fname + dlen;
	if (dlen != 1 || *fname != '/')
		*p++ = '/';
	remainder = MAXPATHLEN - (p - fname);

	/* We do our own recursion, so make delete_item() non-recursive. */
	flags = (flags & ~(DEL_RECURSE|DEL_MAKE_ROOM|DEL_NO_UID_WRITE))
	      | DEL_DIR_IS_EMPTY;

	for (j = dirlist->used; j--; ) {
		struct file_struct *fp = dirlist->files[j];

		if (fp->flags & FLAG_MOUNT_DIR && S_ISDIR(fp->mode)) {
			if (DEBUG_GTE(DEL, 1)) {
				rprintf(FINFO,
				    "mount point, %s, pins parent directory\n",
				    f_name(fp, NULL));
			}
			ret = DR_NOT_EMPTY;
			continue;
		}

		strlcpy(p, fp->basename, remainder);
		if (!(fp->mode & S_IWUSR) && !am_root && fp->flags & FLAG_OWNED_BY_US)
			do_chmod(fname, fp->mode | S_IWUSR);
		/* Save stack by recursing to ourself directly. */
		if (S_ISDIR(fp->mode)) {
			if (delete_dir_contents(fname, flags | DEL_RECURSE) != DR_SUCCESS)
				ret = DR_NOT_EMPTY;
		}
		if (delete_item(fname, fp->mode, flags) != DR_SUCCESS)
			ret = DR_NOT_EMPTY;
	}

	fname[dlen] = '\0';

  done:
	flist_free(dirlist);
	pop_local_filters(save_filters);

	if (ret == DR_NOT_EMPTY) {
		rprintf(FINFO, "cannot delete non-empty directory: %s\n",
			fname);
	}
	return ret;
}
Пример #29
0
int btree_delete(btree_t bt, const void *key)
{
	const struct btree_def *def = bt->def;
	const int halfsize = def->branches / 2;
	struct btree_page *path[MAX_HEIGHT] = {0};
	int slot[MAX_HEIGHT] = {0};
	int h;

	check_btree(bt);

	/* Trace a path to the item to be deleted */
	if (!key) {
		if (bt->slot[0] < 0)
			return 1;

		memcpy(path, bt->path, sizeof(path));
		memcpy(slot, bt->slot, sizeof(slot));
	} else if (!trace_path(bt, key, path, slot)) {
		return 1;
	}

	/* Select the next item if we're deleting at the cursor */
	if (bt->slot[0] == slot[0] && bt->path[0] == path[0])
		cursor_next(bt);

	/* Delete from the leaf node. If it's still full enough, then we don't
	 * need to do anything else.
	 */
	delete_item(path[0], slot[0]);
	if (path[0]->num_children >= halfsize)
		return 0;

	/* Trace back up the tree, fixing underfull nodes. If we can fix by
	 * borrowing, do it and we're done. Otherwise, we need to fix by
	 * merging, which may result in another underfull node, and we need
	 * to continue.
	 */
	for (h = 1; h <= bt->root->height; h++) {
		struct btree_page *p = path[h];
		struct btree_page *c = path[h - 1];
		int s = slot[h];

		if (s > 0) {
			/* Borrow/merge from lower page */
			struct btree_page *d = *PAGE_PTR(p, s - 1);

			if (d->num_children > halfsize) {
				move_item(d, d->num_children - 1, c, 0);
				memcpy(PAGE_KEY(p, s), PAGE_KEY(c, 0),
				       def->key_size);
				return 0;
			}

			merge_pages(d, c);
			delete_item(p, s);
			free(c);
		} else {
			/* Borrow/merge from higher page */
			struct btree_page *d = *PAGE_PTR(p, s + 1);

			if (d->num_children > halfsize) {
				move_item(d, 0, c, c->num_children);
				memcpy(PAGE_KEY(p, s + 1),
				       PAGE_KEY(d, 0),
				       def->key_size);
				return 0;
			}

			merge_pages(c, d);
			delete_item(p, s + 1);
			free(d);
		}

		if (p->num_children >= halfsize)
			return 0;
	}

	/* If the root contains only a single pointer to another page,
	 * shrink the tree. This does not affect the cursor.
	 */
	if (bt->root->height && bt->root->num_children == 1) {
		struct btree_page *old = bt->root;

		bt->root = *PAGE_PTR(old, 0);
		free(old);
	}

	return 0;
}
bool BlockchainTransactions::Delete(const std::string& id)
{
    return delete_item(id);
}