Beispiel #1
0
void MergeSlaveClusterTable(int32_t *buffer, int rlen) {
  // Get the slave's cluster table and add to ours
  int i, id,  rep, rep_root, last;
  int q;
  assert(rlen%MPIBUFRECSZ==0);
  assert(rlen<MPIBUFRECSZ*num_seqs);
  last = -1;
  for(i=0; i<rlen; ) {
    id = buffer[i];
    i++;
    rep= buffer[i];
    i++;
#ifdef MPIORIENT
    int witness, orient;
    witness = buffer[i];
    i++;
    orient = buffer[i];
    i++;
#endif
    PLOCK(&write_union_mutex);
    PLOCK(&find_parent_mutex);
    if (last != rep) {
      last = rep;
      rep_root = find_parent(rep);
    }
    id = find_parent(id);
    if (id == rep_root) {
      PUNLOCK(&find_parent_mutex);
      PUNLOCK(&write_union_mutex);
      continue;
    }
    // if (orient) invert_orientation(j);
    q = tree[rep_root].last;
    tree[q].next = id;
    tree[rep_root].last = tree[id].last;
    tree[id].cluster = rep_root;
    if (IS_FLAG(FIX,id)) SET_FLAG(FIX,rep_root);
    assert(tree[tree[rep_root].last].next<0);
    PUNLOCK(&write_union_mutex);
    PUNLOCK(&find_parent_mutex);
  }
}
Beispiel #2
0
int seek_definition(FILE *f, char *config_path) {
    /*
     * Finds the definition of the given value, even if it is defined in a
     * parent class.
     *
     * Returns 0 on success, a positive integer on failure.
     */

    int success;

    // Try the direct way first
    fseek(f, 16, SEEK_SET);
    success = seek_config_path(f, config_path);
    if (success >= 0)
        return success;

    // No containing class
    if (strchr(config_path, '>') == NULL)
        return 1;

    // Try to find the definition
    int i;
    char containing[2048];
    char parent[2048];
    char value[2048];

    strncpy(containing, config_path, sizeof(containing));
    *(strrchr(containing, '>') - 1) = 0;
    for (i = strlen(containing) - 1; i >= 0 && containing[i] == ' '; i--)
        containing[i] = 0;

    fseek(f, 16, SEEK_SET);
    success = seek_config_path(f, containing);

    // Containing class doesn't even exist
    if (success < 0)
        return success;

    // Find parent of the containing class
    success = find_parent(f, containing, parent, sizeof(parent));
    if (success) {
        return success;
    }

    strncpy(value, strrchr(config_path, '>') + 1, sizeof(value));
    trim_leading(value, sizeof(value));

    strcat(parent, " >> ");
    strcat(parent, value);

    return seek_definition(f, parent);
}
Beispiel #3
0
static struct result_data *
find_parent2(search_t *search, const struct sha1 *sha1, filesize_t filesize)
{
	struct result_data key;
	record_t rc;

	g_return_val_if_fail(sha1, NULL);

	rc.sha1 = sha1;
	rc.size = filesize;
	key.record = &rc;
  	return find_parent(search, &key);
}
Beispiel #4
0
bool is_infinite(){
  unsigned int border[4][stagesize];
  int flag = 0;
  bool inf = false;
  for(int j = 0; j < 4; j++){
    for(int i = 0; i < stagesize; i++){
      if(j == 0)
        border[j][i] = find_parent(stage[i][0]);
      if(j == 1)
        border[j][i] = find_parent(stage[stagesize-1][i]);
      if(j == 2)
        border[j][i] = find_parent(stage[i][stagesize-1]);
      else
        border[j][i] = find_parent(stage[0][i]);
    }
  }
  for(int k = 0; k < stagesize; k++){
    if(border[0][k] != 0){
      flag = 0;
      for(int j = 1; j < 4; j++){
        int i = 0;
        bool not_found = true;
        while(not_found && i < stagesize){
          if(border[j][i] == border[0][k]){
            not_found = false;
            flag++;
          }
          else
            i++;
        }
      }
      if(flag == 3)
        inf = true;
    }
  }
  return inf;
}
Beispiel #5
0
void complete_pairwise_cluster(WorkPtr work, int i, int * candidates, int num_cands) {
	int  s, limit;
	int j, rootI, rootJ;

	int num_mat_pos, num_mat_rc;

	if (clonelink) clone_link(work);
		
	if (IGNORE_SEQ(i)) return;
	if (seqInfo[i].len<window_len) return;

	set_up_word_table(work, i);

	for(s=0; s<num_cands; s++) {
		j = candidates[s];
        //printf("    Candidated %d\n",j);
		rootI = mini_find_parent(i);
		rootJ = mini_find_parent(j);
		assert(i<num_seqs);
		if ((rootI != rootJ) && !(IS_FLAG(FIX,rootI)&&IS_FLAG(FIX,rootJ) )) { 
			// only try to cluster if not already clustered
			// and both are not fixed lcusters
			NUM_num_matches++;
			limit = seqInfo[j].len/BASESPERELT-1;

			check_heuristics(i,j,limit,&num_mat_pos,&num_mat_rc);

			if( (num_mat_pos >= NM_threshold) &&  
			   (!IGNORE_SEQ(j)) &&
			   (d2(work,i,j,0)<=theta)) {
				merge_pair(work,rootI,i,rootJ,j,0);
			};

			if ( rc_check &&   
				(num_mat_rc >= NM_threshold)&& 
				(!IGNORE_SEQ(j)) &&
				(d2(work,i,j,1)<=theta)){
				merge_pair(work,rootI,i,rootJ,j,1);
			}
 
		}
	}
	clear_word_table(work,i);
	PLOCK(&find_parent_mutex);
	for(s=0; s<num_cands; s++) 
		tree[candidates[s]].cluster = find_parent(candidates[s]);
	PUNLOCK(&find_parent_mutex);

}
Beispiel #6
0
static void
set_current_part_to_parent (rfc822parse_t msg)
{
  part_t parent;

  assert (msg->current_part);
  parent = find_parent (msg->parts, msg->current_part);
  if (!parent)
    return; /* Already at the top. */

#ifndef NDEBUG
  {
    part_t part;
    for (part = parent->down; part; part = part->right)
      if (part == msg->current_part)
        break;
    assert (part);
  }
#endif
  msg->current_part = parent;

  parent = find_parent (msg->parts, parent);
  msg->boundary = parent? parent->boundary: NULL;
}
Beispiel #7
0
Datei: bst.c Projekt: Cheyans/bst
void bst_insert(bst_t *tree, int data) {
    if(tree == NULL) {
        return;
    } else if(tree->head == NULL) {
        tree->head = new_node(data, NULL);
        return;
    }
    //finds the parent for the new node and determines which leaf to put it on
    bst_n *parent = find_parent(tree->head, tree->head, data);
    bst_n *node = new_node(data, parent);
    if(data >= parent->data) {
        parent->right = node;
    } else {
        parent->left = node;
    }
}
Beispiel #8
0
static part_t
find_parent (part_t tree, part_t target)
{
  part_t part;

  for (part = tree->down; part; part = part->right)
    {
      if (part == target)
        return tree; /* Found. */
      if (part->down)
        {
          part_t tmp = find_parent (part, target);
          if (tmp)
            return tmp;
        }
    }
  return NULL;
}
Beispiel #9
0
std::pair<section*, int> find_parent(section& sec, const std::string& id)
{
	section_list::iterator sit =
		std::find_if(sec.sections.begin(), sec.sections.end(), has_id(id));
	if (sit != sec.sections.end()) {
		return std::make_pair(&sec, std::distance(sec.sections.begin(), sit));
	}
	topic_list::iterator tit =
		std::find_if(sec.topics.begin(), sec.topics.end(), has_id(id));
	if (tit != sec.topics.end()) {
		return std::make_pair(&sec, std::distance(sec.topics.begin(), tit));
	}
	std::pair<section*, int> ret(reinterpret_cast<section*>(NULL), -1);
	for (sit = sec.sections.begin(); sit != sec.sections.end(); ++sit) {
		ret = find_parent(*(*sit), id);
		if (ret.first != NULL) {
			return ret;
		}
	}
	return ret;
}
Beispiel #10
0
Datei: bst.c Projekt: Cheyans/bst
int bst_find(bst_t *tree, int data, int *found) {
    //if tree is empty then we ain't gonna find shit
    if(tree == NULL || tree->head == NULL) {
        *found = 0;
        return -1;
    //check head if it is the right node due to limitations of find_parent and my lack of caring to think of something
    //more elegant
    } else if(tree->head->data == data) {
        *found = 1;
        return data;
    }
    //finds the parent of the node and checks if one of the parent's leaves is the correct node
    bst_n *parent = find_parent(tree->head, tree->head, data);
    if((parent->left != NULL && parent->left->data == data) ||
       (parent->right != NULL && parent->right->data == data)) {
        *found = 1;
        return data;
    }
    *found = 0;
    return -1;
}
int get_closest_leaf_distance(struct node *root, struct node *temp)
{
	if (!root || !temp){
		return -1;
	}
	if (temp->left==NULL && temp->right==NULL){
		return 0;
	}
	int temptoleaf = 9999,leaf = 0;
	get_closer_leaf(temp, leaf, &temptoleaf);
	//printf("Temp to Leaf distance %d\n", temptoleaf);

	int roottoleaf = 9999;
	get_closer_leaf(root, leaf, &roottoleaf);
	//printf("root to Leaf distance %d\n", roottoleaf);

	struct node *parent = find_parent(root, temp);
    printf("%d ", parent->data);
	int parenttoleaf = 9999;
	get_closer_leaf(parent, leaf, &parenttoleaf);
	//printf("parent to Leaf distance %d\n", parenttoleaf);
	
	int roottotemp=get_distance_temp(root, temp);

	int temprootleaf = roottotemp + roottoleaf;
	int tempparentleaf = parenttoleaf + 1;
	//printf("%d %d", temprootleaf, tempparentleaf);
	if (temptoleaf < tempparentleaf && temptoleaf < temprootleaf){
		return temptoleaf;
	}
	else if (tempparentleaf < temptoleaf && tempparentleaf < temprootleaf){
		return tempparentleaf;
	}
	else{
		return temprootleaf;
	}

	return 0;
}
Beispiel #12
0
//在前序线索二叉树中找到节点p_node的前一个节点
//
//            A
//          /   \
//         B     G
//        / \   /  \
//       C   D H   J 
//          / \ \
//         E   F I 
//    在前序线索二叉树中,遍历顺序为"根左右",
//    对上面这个二叉树转化为前序线索二叉树之后,前序遍历为 A B C D E F G H I J 
//    对节点而言,先根A然后左子树B,B作为根,左子树C,右子树D,D作为根节点,左子树E,右子树F...
//    某一节点的前一个节点,
//    1.作为左子树,前一个节点即是其父节点.
//    2.作为右子树,因为是"根左右"的顺序,于是,其前一个节点为兄弟的最右节点.
//
//一.3 先序线索二叉树中节点的前驱
Bin_tree front_in_pre(Bin_tree root, Tree_node *p_node)
{
    Tree_node *front = NULL;
    Tree_node *parent = NULL;
    front = p_node->left_child;              //先指向p_node左孩子
    if(p_node->left_flag == LINK)
    {
        parent = find_parent(root, p_node);  //查找p_node的父节点
        if(parent->left_child == p_node)     //情况1. 作为左节点
        {
            front = parent;
        }
        else                                 //情况2.
        {
            front = parent->left_child;      //查找左子树的最右节点
            while(front->right_flag == LINK)
            {
                front = front->right_child;
            }
        }
    }
    return front;
}
Beispiel #13
0
/* Deletes from |tree| and returns an item matching |item|.
   Returns a null pointer if no matching item found. */
void *tavl_delete(struct tavl_table *tree, const void *item)
{
    struct tavl_node *p;	/* Traverses tree to find node to delete. */
    struct tavl_node *q;	/* Parent of |p|. */
    int dir;			/* Index into |q->tavl_link[]| to get |p|. */
    int cmp;			/* Result of comparison between |item| and |p|. */

    assert(tree != NULL && item != NULL);

    q = (struct tavl_node *)&tree->tavl_root;
    p = tree->tavl_root;
    dir = 0;
    while (p != NULL) {
	cmp = tree->tavl_compare(item, p->tavl_data, tree->tavl_param);

	if (cmp == 0)
	    break;

	dir = cmp > 0;

	q = p;
	if (p->tavl_tag[dir] == TAVL_CHILD)
	    p = p->tavl_link[dir];
	else
	    p = NULL;
    }
    if (p == NULL)
	return NULL;

    item = p->tavl_data;

    if (p->tavl_tag[1] == TAVL_THREAD) {
	if (p->tavl_tag[0] == TAVL_CHILD) {
	    struct tavl_node *t = p->tavl_link[0];

	    while (t->tavl_tag[1] == TAVL_CHILD)
		t = t->tavl_link[1];
	    t->tavl_link[1] = p->tavl_link[1];
	    q->tavl_link[dir] = p->tavl_link[0];
	}
	else {
	    q->tavl_link[dir] = p->tavl_link[dir];
	    if (q != (struct tavl_node *)&tree->tavl_root)
		q->tavl_tag[dir] = TAVL_THREAD;
	}
    }
    else {
	struct tavl_node *r = p->tavl_link[1];

	if (r->tavl_tag[0] == TAVL_THREAD) {
	    r->tavl_link[0] = p->tavl_link[0];
	    r->tavl_tag[0] = p->tavl_tag[0];
	    if (r->tavl_tag[0] == TAVL_CHILD) {
		struct tavl_node *t = r->tavl_link[0];

		while (t->tavl_tag[1] == TAVL_CHILD)
		    t = t->tavl_link[1];
		t->tavl_link[1] = r;
	    }
	    q->tavl_link[dir] = r;
	    r->tavl_balance = p->tavl_balance;
	    q = r;
	    dir = 1;
	}
	else {
	    struct tavl_node *s;

	    while (r != NULL) {
		s = r->tavl_link[0];
		if (s->tavl_tag[0] == TAVL_THREAD)
		    break;

		r = s;
	    }

	    if (s->tavl_tag[1] == TAVL_CHILD)
		r->tavl_link[0] = s->tavl_link[1];
	    else {
		r->tavl_link[0] = s;
		r->tavl_tag[0] = TAVL_THREAD;
	    }

	    s->tavl_link[0] = p->tavl_link[0];
	    if (p->tavl_tag[0] == TAVL_CHILD) {
		struct tavl_node *t = p->tavl_link[0];

		while (t->tavl_tag[1] == TAVL_CHILD)
		    t = t->tavl_link[1];
		t->tavl_link[1] = s;

		s->tavl_tag[0] = TAVL_CHILD;
	    }

	    s->tavl_link[1] = p->tavl_link[1];
	    s->tavl_tag[1] = TAVL_CHILD;

	    q->tavl_link[dir] = s;
	    s->tavl_balance = p->tavl_balance;
	    q = r;
	    dir = 0;
	}
    }

    tree->tavl_alloc->libavl_free(tree->tavl_alloc, p);

    while (q != (struct tavl_node *)&tree->tavl_root) {
	struct tavl_node *y = q;

	q = find_parent(tree, y);

	if (dir == 0) {
	    dir = q->tavl_link[0] != y;
	    y->tavl_balance++;
	    if (y->tavl_balance == +1)
		break;
	    else if (y->tavl_balance == +2) {
		struct tavl_node *x = y->tavl_link[1];

		assert(x != NULL);
		if (x->tavl_balance == -1) {
		    struct tavl_node *w;

		    assert(x->tavl_balance == -1);
		    w = x->tavl_link[0];
		    x->tavl_link[0] = w->tavl_link[1];
		    w->tavl_link[1] = x;
		    y->tavl_link[1] = w->tavl_link[0];
		    w->tavl_link[0] = y;
		    if (w->tavl_balance == +1)
			x->tavl_balance = 0, y->tavl_balance = -1;
		    else if (w->tavl_balance == 0)
			x->tavl_balance = y->tavl_balance = 0;
		    else	/* |w->tavl_balance == -1| */
			x->tavl_balance = +1, y->tavl_balance = 0;
		    w->tavl_balance = 0;
		    if (w->tavl_tag[0] == TAVL_THREAD) {
			y->tavl_tag[1] = TAVL_THREAD;
			y->tavl_link[1] = w;
			w->tavl_tag[0] = TAVL_CHILD;
		    }
		    if (w->tavl_tag[1] == TAVL_THREAD) {
			x->tavl_tag[0] = TAVL_THREAD;
			x->tavl_link[0] = w;
			w->tavl_tag[1] = TAVL_CHILD;
		    }
		    q->tavl_link[dir] = w;
		}
		else {
		    q->tavl_link[dir] = x;

		    if (x->tavl_balance == 0) {
			y->tavl_link[1] = x->tavl_link[0];
			x->tavl_link[0] = y;
			x->tavl_balance = -1;
			y->tavl_balance = +1;
			break;
		    }
		    else {	/* |x->tavl_balance == +1| */

			if (x->tavl_tag[0] == TAVL_CHILD)
			    y->tavl_link[1] = x->tavl_link[0];
			else {
			    y->tavl_tag[1] = TAVL_THREAD;
			    x->tavl_tag[0] = TAVL_CHILD;
			}
			x->tavl_link[0] = y;
			y->tavl_balance = x->tavl_balance = 0;
		    }
		}
	    }
	}
	else {
	    dir = q->tavl_link[0] != y;
	    y->tavl_balance--;
	    if (y->tavl_balance == -1)
		break;
	    else if (y->tavl_balance == -2) {
		struct tavl_node *x = y->tavl_link[0];

		assert(x != NULL);
		if (x->tavl_balance == +1) {
		    struct tavl_node *w;

		    assert(x->tavl_balance == +1);
		    w = x->tavl_link[1];
		    x->tavl_link[1] = w->tavl_link[0];
		    w->tavl_link[0] = x;
		    y->tavl_link[0] = w->tavl_link[1];
		    w->tavl_link[1] = y;
		    if (w->tavl_balance == -1)
			x->tavl_balance = 0, y->tavl_balance = +1;
		    else if (w->tavl_balance == 0)
			x->tavl_balance = y->tavl_balance = 0;
		    else	/* |w->tavl_balance == +1| */
			x->tavl_balance = -1, y->tavl_balance = 0;
		    w->tavl_balance = 0;
		    if (w->tavl_tag[0] == TAVL_THREAD) {
			x->tavl_tag[1] = TAVL_THREAD;
			x->tavl_link[1] = w;
			w->tavl_tag[0] = TAVL_CHILD;
		    }
		    if (w->tavl_tag[1] == TAVL_THREAD) {
			y->tavl_tag[0] = TAVL_THREAD;
			y->tavl_link[0] = w;
			w->tavl_tag[1] = TAVL_CHILD;
		    }
		    q->tavl_link[dir] = w;
		}
		else {
		    q->tavl_link[dir] = x;

		    if (x->tavl_balance == 0) {
			y->tavl_link[0] = x->tavl_link[1];
			x->tavl_link[1] = y;
			x->tavl_balance = +1;
			y->tavl_balance = -1;
			break;
		    }
		    else {	/* |x->tavl_balance == -1| */

			if (x->tavl_tag[1] == TAVL_CHILD)
			    y->tavl_link[0] = x->tavl_link[1];
			else {
			    y->tavl_tag[0] = TAVL_THREAD;
			    x->tavl_tag[1] = TAVL_CHILD;
			}
			x->tavl_link[1] = y;
			y->tavl_balance = x->tavl_balance = 0;
		    }
		}
	    }
	}
    }

    tree->tavl_count--;

    return (void *)item;
}
Beispiel #14
0
void build_roomlist_from_config(GaimRoomlist * roomlist,
                                GHashTable * confighash, gchar * pattern)
{
    gchar **roominst = NULL;
    gchar *altname = NULL;
    gchar *normalized = NULL;
    gchar *lowercase = NULL;
    gchar *found = NULL;
    int level = 0;
    int old_level = 0;
    int i = 0;
    GaimRoomlistRoom *room = NULL;
    GaimRoomlistRoom *parent = NULL;

    g_return_if_fail(roomlist != NULL);
    g_return_if_fail(confighash != NULL);

    int max = gaim_prefs_get_int("/plugins/prpl/gaym/chat_room_instances");

    gchar *roomstr = g_hash_table_lookup(confighash, "roomlist");
    g_return_if_fail(roomstr != NULL);

    gchar **roomarr = g_strsplit(roomstr, "|", -1);

    /**
     * We need to skip the first instance, because they start
     * with a "|", which we've just split by, leaving a blank
     * at the beginning of the list
     */
    for (i = 1; roomarr[i] != NULL; i++) {
        if (roomarr[i][0] == '#') {
            /**
             * This is an actual room string, break it into its
             * component parts, determine the level and the parent,
             * and add this as both a room and a category
             */
            if (pattern != NULL) {
                lowercase = g_utf8_strdown(roomarr[i], -1);
                normalized =
                    g_utf8_normalize(lowercase, -1, G_NORMALIZE_ALL);
                found = g_strstr_len(normalized, -1, pattern);
                g_free(normalized);
                g_free(lowercase);
            }
            if (found != NULL || pattern == NULL) {
                found = NULL;
                roominst = g_strsplit(roomarr[i], " ", 2);
                level = roomlist_level_strip(roominst[1]);
                parent = find_parent(level, old_level, room);
                altname = g_strdup_printf("%s:*", roominst[1]);
                if (max == 0) {
                    room =
                        gaim_roomlist_room_new(GAIM_ROOMLIST_ROOMTYPE_ROOM,
                                               altname, parent);
                } else {
                    room =
                        gaim_roomlist_room_new
                        (GAIM_ROOMLIST_ROOMTYPE_CATEGORY |
                         GAIM_ROOMLIST_ROOMTYPE_ROOM, altname, parent);
                }
                gaim_roomlist_room_add_field(roomlist, room, altname);
                gaim_roomlist_room_add_field(roomlist, room, roominst[0]);
                gaim_roomlist_room_add(roomlist, room);
                g_free(altname);
                g_strfreev(roominst);
                old_level = level;
            }
        } else if (pattern == NULL) {
            /**
             * This is a plain category, determine the level and
             * the parent and add it.
             */
            level = roomlist_level_strip(roomarr[i]);
            parent = find_parent(level, old_level, room);
            room =
                gaim_roomlist_room_new(GAIM_ROOMLIST_ROOMTYPE_CATEGORY,
                                       roomarr[i], parent);
            gaim_roomlist_room_add(roomlist, room);
        }
        old_level = level;
    }
    g_strfreev(roomarr);
    gaim_roomlist_set_in_progress(roomlist, FALSE);
}
Beispiel #15
0
void do_pairwise_cluster(WorkPtr work) {
  int r, s, limit;
  int i, j, rootI, rootJ, *index,k;
  uint16_t w0;
  int num_mat_pos, num_mat_rc,invert, samp_pos, samp_rc;

  index = work->index;
  if (clonelink) clone_link(work);
  //printf("Slave %d-t%d here ib=%d ie=%d;  jb=%d je=%d,\n",
  // myid,work->thread_num,work->i_beg,work->i_end,work->j_beg,work->j_end);
  for(r=work->i_beg; r<work->i_end; r++) {
    i = (index == NULL) ? r : index[r];
    //printf("%d %ld %ld %d\n",i,data,seq[i].seq,seq[i].len);
    if (IGNORE_SEQ(i)) continue;
    if (seqInfo[i].len<window_len) continue;
    set_up_word_table(work, i);
    for(s=MAX(r+1,work->j_beg); s<work->j_end; s++) {
      j = (index == NULL) ? s : index[s];
      rootI = mini_find_parent(i);
      rootJ = mini_find_parent(j);
      if ((rootI != rootJ) && !(IS_FLAG(FIX,rootI)&&IS_FLAG(FIX,rootJ) )) { 
        // only try to cluster if not already clustered
        // and both are not fixed lcusters
	num_mat_pos=num_mat_rc=samp_pos=samp_rc=0;
	NUM_num_matches++;
	limit = seqInfo[j].len/BASESPERELT-1;
	for(k=1; k < limit ;k=k+2) {
	  if (work->tableP[seq[j][k]]) samp_pos ++; 
	  if (work->tableR[seq[j][k]]) samp_rc ++;
	}
	if ((samp_pos<=2) && (samp_rc<= 2) )
	  samp_pos=samp_rc=0;
	else
	  for(k=0; k < limit;k=k+2) {
	    w0  =  seq[j][k];
	    if (work->tableP[w0]) samp_pos++;
	    if (work->tableR[w0]) samp_rc++;
	  }
	if (samp_pos >sample_thresh)
	  num_mat_pos = tv_heuristic_pos(work,i,j);
	if (samp_rc > sample_thresh) 
	  num_mat_rc = tv_heuristic_rc(work,i,j);
	if( (num_mat_pos >= NM_threshold) &&  
            (!IGNORE_SEQ(j)) &&
            (dist(work,i,j,0)<=theta)) {
	  PLOCK(&invert_mutex);
	  invert = (int) (tree[i].orient !=  tree[j].orient);
          PUNLOCK(&invert_mutex);
          if (dump_file != NULL) {
	    PLOCK(&dump_mutex);
	    fprintf(dump_file,"%d: %d %d %d\n",
		    work->thread_num,i,j,1);
	    fflush(dump_file);
	    PUNLOCK(&dump_mutex);
	  }
	  make_uniond2(rootI,rootJ,invert);
	  total_matches++;
	  tree[i].match = j;
          if (tree[j].match==-1) {
	    tree[j].match = i;
	  }
	};
	if ( rc_check &&   
             (num_mat_rc >= NM_threshold)&& 
             (!IGNORE_SEQ(j)) &&
	     (dist(work,i,j,1)<=theta)){
	  PLOCK(&invert_mutex);
	  invert = (tree[i].orient==tree[j].orient);
	  PUNLOCK(&invert_mutex);
	  if (dump_file != NULL) {
	    PLOCK(&dump_mutex);
	    fprintf(dump_file,"%d: %d %d %d\n",
		    work->thread_num,i,j,-1);
	    fflush(dump_file);
	    PUNLOCK(&dump_mutex);
	  }
	  make_uniond2(rootI,rootJ,invert);
	  total_matches++;
	  tree[i].match = j;
	  if (tree[j].match==-1) {
	    tree[j].match = i;
	  }
	} 
      }
    }
    clear_word_table(work,i);
  }
  PLOCK(&find_parent_mutex);
  for(i=0; i<num_seqs; i++) 
    tree[i].cluster = find_parent(i);
  PUNLOCK(&find_parent_mutex);

}
int disjoint_set::find_parent(int v) {
	if (parent[v] == v)
		return v;
	return parent[v] = find_parent(parent[v]);
}
Beispiel #17
0
void kruskal(const graph_t * g)
{
    if (g == NULL) {
        return;
    }

    Edge * edges = new Edge[g->num_edges];
    int e = 0;
    for (int i = 0; i < g->num_vertex; ++i) {
        arc_node_t * p = g->arc_heads[i];
        while (p != NULL) {
            if (i < p->id) {
                edges[e].a = i;
                edges[e].b = p->id;
                edges[e].weight = p->weight;
                ++e;
            }
            p = p->next;
        }
    }

    int * parents = new int[g->num_vertex];
    for (int i = 0; i < g->num_vertex; ++i) {
        parents[i] = -1;
    }

    int e_count = 0;
    int e_end = g->num_edges;
    int max_e = g->num_vertex - 1;
    while (e_count < max_e && e_end > 0) {
        weight_t min = numeric_limits<weight_t>::max();
        int min_i = -1;
        for (int i = 0; i < e_end; ++i) {
            if (edges[i].weight < min) {
                min_i = i;
                min = edges[i].weight;
            }
        }
        int pa = find_parent(parents, edges[min_i].a);
        int pb = find_parent(parents, edges[min_i].b);
        if (pa != pb) {
            cout << edges[min_i].a << " -- " << edges[min_i].b << endl;
            merge(parents, pa, pb);
            ++e_count;
        }

        if (min_i < e_end - 1) {
            Edge temp = edges[min_i];
            edges[min_i] = edges[e_end - 1];
            edges[e_end - 1] = temp;
        }
        --e_end;
    }

    if (e_count < max_e) {
        cerr << "NOT a connected graph" << endl;
    }

    delete[] parents;
    delete[] edges;
}
Beispiel #18
0
void mutt_attach_reply (FILE * fp, struct header *hdr,
			ATTACHPTR ** idx, short idxlen, struct body * cur,
			int flags)
{
	short mime_reply_any = 0;

	short nattach = 0;
	struct header *parent = NULL;
	struct header *tmphdr = NULL;
	short i;

	STATE st;
	char tmpbody[_POSIX_PATH_MAX];
	FILE *tmpfp;

	char prefix[SHORT_STRING];
	int rc;

	if (check_all_msg (idx, idxlen, cur, 0) == -1)
	{
		nattach = count_tagged (idx, idxlen);
		if ((parent = find_parent (idx, idxlen, cur, nattach)) == NULL)
			parent = hdr;
	}

	if (nattach > 1 && !check_can_decode (idx, idxlen, cur))
	{
		if ((rc = query_quadoption (OPT_MIMEFWDREST,
					    ("Can't decode all tagged attachments.  MIME-encapsulate the others?"))) == -1)
			return;
		else if (rc == M_YES)
			mime_reply_any = 1;
	}
	else if (nattach == 1)
		mime_reply_any = 1;

	tmphdr = mutt_new_header ();
	tmphdr->env = mutt_new_envelope ();

	if (attach_reply_envelope_defaults (tmphdr->env, idx, idxlen,
					    parent ? parent : (cur ? cur->hdr : NULL), flags) == -1)
	{
		mutt_free_header (&tmphdr);
		return;
	}

	mutt_mktemp (tmpbody, sizeof (tmpbody));
	if ((tmpfp = safe_fopen (tmpbody, "w")) == NULL)
	{
		mutt_error (("Can't create %s."), tmpbody);
		mutt_free_header (&tmphdr);
		return;
	}

	if (!parent)
	{
		if (cur)
			attach_include_reply (fp, tmpfp, cur->hdr, flags);
		else
		{
			for (i = 0; i < idxlen; i++)
			{
				if (idx[i]->content->tagged)
					attach_include_reply (fp, tmpfp, idx[i]->content->hdr, flags);
			}
		}
	}
	else
	{
		mutt_make_attribution (Context, parent, tmpfp);

		memset (&st, 0, sizeof (STATE));
		st.fpin = fp;
		st.fpout = tmpfp;

		if (!bit_val(options, OPTTEXTFLOWED))
			_mutt_make_string (prefix, sizeof (prefix), NONULL (Prefix),
					   Context, parent, 0);
		else
			strfcpy (prefix, ">", sizeof (prefix));

		st.prefix = prefix;
		st.flags  = M_CHARCONV;

		if (bit_val(options, OPTWEED))
			st.flags |= M_WEED;

		if (bit_val(options, OPTHEADER))
			include_header (1, fp, parent, tmpfp, prefix);

		if (cur)
		{
			if (mutt_can_decode (cur))
			{
				mutt_body_handler (cur, &st);
				state_putc ('\n', &st);
			}
			else
				mutt_copy_body (fp, &tmphdr->content, cur);
		}
		else
		{
			for (i = 0; i < idxlen; i++)
			{
				if (idx[i]->content->tagged && mutt_can_decode (idx[i]->content))
				{
					mutt_body_handler (idx[i]->content, &st);
					state_putc ('\n', &st);
				}
			}
		}

		mutt_make_post_indent (Context, parent, tmpfp);

		if (mime_reply_any && !cur &&
		    copy_problematic_attachments (fp, &tmphdr->content, idx, idxlen, 0) == NULL)
		{
			mutt_free_header (&tmphdr);
			safe_fclose (&tmpfp);
			return;
		}
	}

	safe_fclose (&tmpfp);

	if (ci_send_message (flags, tmphdr, tmpbody, NULL,
			     parent ? parent : (cur ? cur->hdr : NULL)) == 0)
		mutt_set_flag (Context, hdr, M_REPLIED, 1);
}
Beispiel #19
0
int main(void)
{
	void *ctx = tal_strdup(NULL, "toplevel");
	char *a, *b;
	/* If it accesses this, it will crash. */
	char **invalid = (char **)1L;

	plan_tests(41);
	/* Simple matching. */
	ok1(tal_strreg(ctx, "hello world!", "hello") == true);
	ok1(tal_strreg(ctx, "hello world!", "hi") == false);

	/* No parentheses means we don't use any extra args. */
	ok1(tal_strreg(ctx, "hello world!", "hello", invalid) == true);
	ok1(tal_strreg(ctx, "hello world!", "hi", invalid) == false);

	ok1(tal_strreg(ctx, "hello world!", "[a-z]+", invalid) == true);
	ok1(tal_strreg(ctx, "hello world!", "([a-z]+)", &a, invalid) == true);
	/* Found string */
	ok1(streq(a, "hello"));
	/* Allocated off ctx */
	ok1(find_parent(a, ctx));
	tal_free(a);

	ok1(tal_strreg(ctx, "hello world!", "([a-z]*) ([a-z]+)",
		       &a, &b, invalid) == true);
	ok1(streq(a, "hello"));
	ok1(streq(b, "world"));
	ok1(find_parent(a, ctx));
	ok1(find_parent(b, ctx));
	tal_free(a);
	tal_free(b);

	/* * after parentheses returns last match. */
	ok1(tal_strreg(ctx, "hello world!", "([a-z])* ([a-z]+)",
		       &a, &b, invalid) == true);
	ok1(streq(a, "o"));
	ok1(streq(b, "world"));
	tal_free(a);
	tal_free(b);

	/* Nested parentheses are ordered by open brace. */
	ok1(tal_strreg(ctx, "hello world!", "(([a-z]*) world)",
		       &a, &b, invalid) == true);
	ok1(streq(a, "hello world"));
	ok1(streq(b, "hello"));
	tal_free(a);
	tal_free(b);

	/* Nested parentheses are ordered by open brace. */
	ok1(tal_strreg(ctx, "hello world!", "(([a-z]*) world)",
		       &a, &b, invalid) == true);
	ok1(streq(a, "hello world"));
	ok1(streq(b, "hello"));
	tal_free(a);
	tal_free(b);

	/* NULL means we're not interested. */
	ok1(tal_strreg(ctx, "hello world!", "((hello|goodbye) world)",
		       &a, NULL, invalid) == true);
	ok1(streq(a, "hello world"));
	tal_free(a);

	/* No leaks! */
	ok1(no_children(ctx));

	/* NULL arg with take means always fail. */
	ok1(tal_strreg(ctx, take(NULL), "((hello|goodbye) world)",
		       &b, NULL, invalid) == false);

	/* Take string. */
	a = tal_strdup(ctx, "hello world!");
	ok1(tal_strreg(ctx, take(a), "([a-z]+)", &b, invalid) == true);
	ok1(streq(b, "hello"));
	ok1(tal_parent(b) == ctx);
	tal_free(b);
	ok1(no_children(ctx));

	/* Take regex. */
	a = tal_strdup(ctx, "([a-z]+)");
	ok1(tal_strreg(ctx, "hello world!", take(a), &b, invalid) == true);
	ok1(streq(b, "hello"));
	ok1(tal_parent(b) == ctx);
	tal_free(b);
	ok1(no_children(ctx));

	/* Take both. */
	a = tal_strdup(ctx, "([a-z]+)");
	ok1(tal_strreg(ctx, take(tal_strdup(ctx, "hello world!")),
		       take(a), &b, invalid) == true);
	ok1(streq(b, "hello"));
	ok1(tal_parent(b) == ctx);
	tal_free(b);
	ok1(no_children(ctx));

	/* ... even if we fail to match. */
	a = tal_strdup(ctx, "([a-z]+)");
	ok1(tal_strreg(ctx, take(tal_strdup(ctx, "HELLO WORLD!")),
		       take(a), &b, invalid) == false);
	ok1(no_children(ctx));
	tal_free(ctx);

	/* Don't get fooled by \(! */
	ok1(tal_strreg(ctx, "(hello) (world)!", "\\([a-z]*\\) \\([a-z]+\\)",
		       invalid) == true);

	return exit_status();
}
Beispiel #20
0
int find_parent(FILE *f, char *config_path, char *buffer, size_t buffsize) {
    /*
     * Takes a config path and returns the parent class of that class.
     * Assumes the given config path points to an existing class.
     *
     * Returns -1 if the class doesn't have a parent class, -2 if that
     * class cannot be found, 0 on success and a positive integer
     * on failure.
     */

    int i;
    int success;
    bool is_root;
    char containing[2048];
    char name[2048];
    char parent[2048];

    // Loop up class
    fseek(f, 16, SEEK_SET);
    if (seek_config_path(f, config_path))
        return 1;

    // Get parent class name
    if (fgets(parent, sizeof(parent), f) == NULL)
        return 2;
    lower_case(parent);

    if (strlen(parent) == 0)
        return -1;

    // Extract class name and the name of the containing class
    is_root = strchr(config_path, '>') == NULL;
    if (is_root) {
        strncpy(name, config_path, sizeof(name));

        containing[0] = 0;
    } else {
        strncpy(name, strrchr(config_path, '>') + 1, sizeof(name));
        trim_leading(name, sizeof(name));

        strncpy(containing, config_path, sizeof(containing));
        *(strrchr(containing, '>') - 1) = 0;
        for (i = strlen(containing) - 1; i >= 0 && containing[i] == ' '; i--)
            containing[i] = 0;
    }
    lower_case(name);

    // Check parent class inside same containing class
    if (strcmp(name, parent) != 0) {
        sprintf(buffer, "%s >> %s", containing, parent);

        fseek(f, 16, SEEK_SET);
        success = seek_config_path(f, buffer);
        if (success == 0)
            return 0;
    }

    // If this is a root class, we can't do anything at this point
    if (is_root)
        return -2;

    // Try to find the class parent in the parent of the containing class
    success = find_parent(f, containing, buffer, sizeof(buffer));
    if (success > 0)
        return success;
    if (success < 0)
        return -2;

    strcat(buffer, " >> ");
    strcat(buffer, parent);
    return 0;
}
Beispiel #21
0
static int rst_socket_tcp(struct cpt_sock_image *si, loff_t pos, struct sock *sk,
			  struct cpt_context *ctx)
{
	struct tcp_sock *tp = tcp_sk(sk);
	struct sk_buff *skb;
	tp->pred_flags = si->cpt_pred_flags;
	tp->rcv_nxt = si->cpt_rcv_nxt;
	tp->snd_nxt = si->cpt_snd_nxt;
	tp->snd_una = si->cpt_snd_una;
	tp->snd_sml = si->cpt_snd_sml;
	tp->rcv_tstamp = tcp_jiffies_import(si->cpt_rcv_tstamp);
	tp->lsndtime = tcp_jiffies_import(si->cpt_lsndtime);
	tp->tcp_header_len = si->cpt_tcp_header_len;
	inet_csk(sk)->icsk_ack.pending = si->cpt_ack_pending;
	inet_csk(sk)->icsk_ack.quick = si->cpt_quick;
	inet_csk(sk)->icsk_ack.pingpong = si->cpt_pingpong;
	inet_csk(sk)->icsk_ack.blocked = si->cpt_blocked;
	inet_csk(sk)->icsk_ack.ato = si->cpt_ato;
	inet_csk(sk)->icsk_ack.timeout = jiffies_import(si->cpt_ack_timeout);
	inet_csk(sk)->icsk_ack.lrcvtime = tcp_jiffies_import(si->cpt_lrcvtime);
	inet_csk(sk)->icsk_ack.last_seg_size = si->cpt_last_seg_size;
	inet_csk(sk)->icsk_ack.rcv_mss = si->cpt_rcv_mss;
	tp->snd_wl1 = si->cpt_snd_wl1;
	tp->snd_wnd = si->cpt_snd_wnd;
	tp->max_window = si->cpt_max_window;
	inet_csk(sk)->icsk_pmtu_cookie = si->cpt_pmtu_cookie;
	tp->mss_cache = si->cpt_mss_cache;
	tp->rx_opt.mss_clamp = si->cpt_mss_clamp;
	inet_csk(sk)->icsk_ext_hdr_len = si->cpt_ext_header_len;
	inet_csk(sk)->icsk_ca_state = si->cpt_ca_state;
	inet_csk(sk)->icsk_retransmits = si->cpt_retransmits;
	tp->reordering = si->cpt_reordering;
	tp->frto_counter = si->cpt_frto_counter;
	tp->frto_highmark = si->cpt_frto_highmark;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10)
	// // tp->adv_cong = si->cpt_adv_cong;
#endif
	inet_csk(sk)->icsk_accept_queue.rskq_defer_accept = si->cpt_defer_accept;
	inet_csk(sk)->icsk_backoff = si->cpt_backoff;
	tp->srtt = si->cpt_srtt;
	tp->mdev = si->cpt_mdev;
	tp->mdev_max = si->cpt_mdev_max;
	tp->rttvar = si->cpt_rttvar;
	tp->rtt_seq = si->cpt_rtt_seq;
	inet_csk(sk)->icsk_rto = si->cpt_rto;
	tp->packets_out = si->cpt_packets_out;
	tp->retrans_out = si->cpt_retrans_out;
	tp->lost_out = si->cpt_lost_out;
	tp->sacked_out = si->cpt_sacked_out;
	tp->fackets_out = si->cpt_fackets_out;
	tp->snd_ssthresh = si->cpt_snd_ssthresh;
	tp->snd_cwnd = si->cpt_snd_cwnd;
	tp->snd_cwnd_cnt = si->cpt_snd_cwnd_cnt;
	tp->snd_cwnd_clamp = si->cpt_snd_cwnd_clamp;
	tp->snd_cwnd_used = si->cpt_snd_cwnd_used;
	tp->snd_cwnd_stamp = tcp_jiffies_import(si->cpt_snd_cwnd_stamp);
	inet_csk(sk)->icsk_timeout = tcp_jiffies_import(si->cpt_timeout);
	tp->rcv_wnd = si->cpt_rcv_wnd;
	tp->rcv_wup = si->cpt_rcv_wup;
	tp->write_seq = si->cpt_write_seq;
	tp->pushed_seq = si->cpt_pushed_seq;
	tp->copied_seq = si->cpt_copied_seq;
	tp->rx_opt.tstamp_ok = si->cpt_tstamp_ok;
	tp->rx_opt.wscale_ok = si->cpt_wscale_ok;
	tp->rx_opt.sack_ok = si->cpt_sack_ok;
	tp->rx_opt.saw_tstamp = si->cpt_saw_tstamp;
	tp->rx_opt.snd_wscale = si->cpt_snd_wscale;
	tp->rx_opt.rcv_wscale = si->cpt_rcv_wscale;
	tp->nonagle = si->cpt_nonagle;
	tp->keepalive_probes = si->cpt_keepalive_probes;
	tp->rx_opt.rcv_tsval = si->cpt_rcv_tsval;
	tp->rx_opt.rcv_tsecr = si->cpt_rcv_tsecr;
	tp->rx_opt.ts_recent = si->cpt_ts_recent;
	tp->rx_opt.ts_recent_stamp = si->cpt_ts_recent_stamp;
	tp->rx_opt.user_mss = si->cpt_user_mss;
	tp->rx_opt.dsack = si->cpt_dsack;
	tp->duplicate_sack[0].start_seq = si->cpt_sack_array[0];
	tp->duplicate_sack[0].end_seq = si->cpt_sack_array[1];
	tp->selective_acks[0].start_seq = si->cpt_sack_array[2];
	tp->selective_acks[0].end_seq = si->cpt_sack_array[3];
	tp->selective_acks[1].start_seq = si->cpt_sack_array[4];
	tp->selective_acks[1].end_seq = si->cpt_sack_array[5];
	tp->selective_acks[2].start_seq = si->cpt_sack_array[6];
	tp->selective_acks[2].end_seq = si->cpt_sack_array[7];
	tp->selective_acks[3].start_seq = si->cpt_sack_array[8];
	tp->selective_acks[3].end_seq = si->cpt_sack_array[9];

	tp->window_clamp = si->cpt_window_clamp;
	tp->rcv_ssthresh = si->cpt_rcv_ssthresh;
	inet_csk(sk)->icsk_probes_out = si->cpt_probes_out;
	tp->rx_opt.num_sacks = si->cpt_num_sacks;
	tp->advmss = si->cpt_advmss;
	inet_csk(sk)->icsk_syn_retries = si->cpt_syn_retries;
	tp->ecn_flags = si->cpt_ecn_flags;
	tp->prior_ssthresh = si->cpt_prior_ssthresh;
	tp->high_seq = si->cpt_high_seq;
	tp->retrans_stamp = si->cpt_retrans_stamp;
	tp->undo_marker = si->cpt_undo_marker;
	tp->undo_retrans = si->cpt_undo_retrans;
	tp->urg_seq = si->cpt_urg_seq;
	tp->urg_data = si->cpt_urg_data;
	inet_csk(sk)->icsk_pending = si->cpt_pending;
	tp->snd_up = si->cpt_snd_up;
	tp->keepalive_time = si->cpt_keepalive_time;
	tp->keepalive_intvl = si->cpt_keepalive_intvl;
	tp->linger2 = si->cpt_linger2;

	sk->sk_send_head = NULL;
	for (skb = skb_peek(&sk->sk_write_queue);
	     skb && skb != (struct sk_buff*)&sk->sk_write_queue;
	     skb = skb->next) {
		if (!after(tp->snd_nxt, TCP_SKB_CB(skb)->seq)) {
			sk->sk_send_head = skb;
			break;
		}
	}

	if (sk->sk_state != TCP_CLOSE && sk->sk_state != TCP_LISTEN) {
		struct inet_sock *inet = inet_sk(sk);
		if (inet->num == 0) {
			cpt_object_t *lobj = NULL;

			if ((int)si->cpt_parent != -1)
				lobj = lookup_cpt_obj_byindex(CPT_OBJ_SOCKET, si->cpt_parent, ctx);

			if (lobj && lobj->o_obj) {
				inet->num = ntohs(inet->sport);
				local_bh_disable();
				__inet_inherit_port(lobj->o_obj, sk);
				local_bh_enable();
				dprintk_ctx("port inherited from parent\n");
			} else {
				struct sock *lsk = find_parent(inet->sport, ctx);
				if (lsk) {
					inet->num = ntohs(inet->sport);
					local_bh_disable();
					__inet_inherit_port(lsk, sk);
					local_bh_enable();
					dprintk_ctx("port inherited\n");
				} else {
					eprintk_ctx("we are kinda lost...\n");
				}
			}
		}

		sk->sk_prot->hash(sk);

		if (inet_csk(sk)->icsk_ack.pending&ICSK_ACK_TIMER)
			sk_reset_timer(sk, &inet_csk(sk)->icsk_delack_timer, inet_csk(sk)->icsk_ack.timeout);
		if (inet_csk(sk)->icsk_pending)
			sk_reset_timer(sk, &inet_csk(sk)->icsk_retransmit_timer,
				       inet_csk(sk)->icsk_timeout);
		if (sock_flag(sk, SOCK_KEEPOPEN)) {
			unsigned long expires = jiffies_import(si->cpt_ka_timeout);
			if (time_after(jiffies, expires))
				expires = jiffies + HZ;
			sk_reset_timer(sk, &sk->sk_timer, expires);
		}
	}

	if (sk->sk_family == AF_INET6)
		sk->sk_gso_type = SKB_GSO_TCPV6;
	else
		sk->sk_gso_type = SKB_GSO_TCPV4;

	return 0;
}
Beispiel #22
0
static void attach_forward_bodies (FILE * fp, struct header * hdr,
				   ATTACHPTR ** idx, short idxlen,
				   struct body * cur,
				   short nattach)
{
	short i;
	short mime_fwd_all = 0;
	short mime_fwd_any = 1;
	struct header *parent = NULL;
	struct header *tmphdr = NULL;
	struct body **last;
	char tmpbody[_POSIX_PATH_MAX];
	FILE *tmpfp = NULL;

	char prefix[STRING];

	int rc = 0;

	STATE st;

	/*
	 * First, find the parent message.
	 * Note: This could be made an option by just
	 * putting the following lines into an if block.
	 */


	parent = find_parent (idx, idxlen, cur, nattach);

	if (parent == NULL)
		parent = hdr;


	tmphdr = mutt_new_header ();
	tmphdr->env = mutt_new_envelope ();
	mutt_make_forward_subject (tmphdr->env, Context, parent);

	mutt_mktemp (tmpbody, sizeof (tmpbody));
	if ((tmpfp = safe_fopen (tmpbody, "w")) == NULL)
	{
		mutt_error (("Can't open temporary file %s."), tmpbody);
		return;
	}

	mutt_forward_intro (tmpfp, parent);

	/* prepare the prefix here since we'll need it later. */

	if (bit_val(options, OPTFORWQUOTE))
	{
		if (!bit_val(options, OPTTEXTFLOWED))
			_mutt_make_string (prefix, sizeof (prefix), NONULL (Prefix), Context,
					   parent, 0);
		else
			strfcpy (prefix, ">", sizeof (prefix));
	}

	include_header (bit_val(options, OPTFORWQUOTE), fp, parent,
			tmpfp, prefix);


	/*
	 * Now, we have prepared the first part of the message body: The
	 * original message's header.
	 *
	 * The next part is more interesting: either include the message bodies,
	 * or attach them.
	 */

	if ((!cur || mutt_can_decode (cur)) &&
	    (rc = query_quadoption (OPT_MIMEFWD,
				    ("Forward as attachments?"))) == M_YES)
		mime_fwd_all = 1;
	else if (rc == -1)
		goto bail;

	/*
	 * shortcut MIMEFWDREST when there is only one attachment.  Is
	 * this intuitive?
	 */

	if (!mime_fwd_all && !cur && (nattach > 1)
	    && !check_can_decode (idx, idxlen, cur))
	{
		if ((rc = query_quadoption (OPT_MIMEFWDREST,
					    ("Can't decode all tagged attachments.  MIME-forward the others?"))) == -1)
			goto bail;
		else if (rc == M_NO)
			mime_fwd_any = 0;
	}

	/* initialize a state structure */

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

	if (bit_val(options, OPTFORWQUOTE))
		st.prefix = prefix;
	st.flags = M_CHARCONV;
	if (bit_val(options, OPTWEED))
		st.flags |= M_WEED;
	st.fpin = fp;
	st.fpout = tmpfp;

	/* where do we append new MIME parts? */
	last = &tmphdr->content;

	if (cur)
	{
		/* single body case */

		if (!mime_fwd_all && mutt_can_decode (cur))
		{
			mutt_body_handler (cur, &st);
			state_putc ('\n', &st);
		}
		else
		{
			if (mutt_copy_body (fp, last, cur) == -1)
				goto bail;
			last = &((*last)->next);
		}
	}
	else
	{
		/* multiple body case */

		if (!mime_fwd_all)
		{
			for (i = 0; i < idxlen; i++)
			{
				if (idx[i]->content->tagged && mutt_can_decode (idx[i]->content))
				{
					mutt_body_handler (idx[i]->content, &st);
					state_putc ('\n', &st);
				}
			}
		}

		if (mime_fwd_any &&
		    copy_problematic_attachments (fp, last, idx, idxlen, mime_fwd_all) == NULL)
			goto bail;
	}

	mutt_forward_trailer (tmpfp);

	safe_fclose (&tmpfp);
	tmpfp = NULL;

	/* now that we have the template, send it. */
	ci_send_message (0, tmphdr, tmpbody, NULL, parent);
	return;

bail:

	if (tmpfp)
	{
		safe_fclose (&tmpfp);
		mutt_unlink (tmpbody);
	}

	mutt_free_header (&tmphdr);
}