예제 #1
0
파일: uxproxy.c 프로젝트: 0x0all/s2putty
static void sk_localproxy_close (Socket s)
{
    Local_Proxy_Socket ps = (Local_Proxy_Socket) s;

    del234(localproxy_by_fromfd, ps);
    del234(localproxy_by_tofd, ps);

    uxsel_del(ps->to_cmd);
    uxsel_del(ps->from_cmd);
    close(ps->to_cmd);
    close(ps->from_cmd);

    sfree(ps);
}
예제 #2
0
파일: sftp.c 프로젝트: lalbornoz/FySTY
struct sftp_request *sftp_find_request(struct sftp_packet *pktin)
{
    unsigned id;
    struct sftp_request *req;

    if (!pktin) {
	fxp_internal_error("did not receive a valid SFTP packet\n");
	return NULL;
    }

    id = get_uint32(pktin);
    if (get_err(pktin)) {
	fxp_internal_error("did not receive a valid SFTP packet\n");
	return NULL;
    }

    req = find234(sftp_requests, &id, sftp_reqfind);
    if (!req || !req->registered) {
	fxp_internal_error("request ID mismatch\n");
	return NULL;
    }

    del234(sftp_requests, req);

    return req;
}
예제 #3
0
/**
 * delete an entity from working list of a worker
 * - jwl : pointer to the workers list
 * - sid : id of the entity (connection to Jabber - usually SHOULD be FROM
 *   header of the incoming SIP message
 * - _pid : process id of the worker
 */
void xj_wlist_del(xj_wlist jwl, xj_jkey jkey, int _pid)
{
	int i;
	void *p;
	if(jwl==NULL || jkey==NULL || jkey->id==NULL || jkey->id->s==NULL)
		return;
	for(i=0; i < jwl->len; i++)
		if(jwl->workers[i].pid == _pid)
			break;
	if(i >= jwl->len)
	{
		LM_DBG("%d: key <%.*s> not found in [%d]...\n",
			_pid, jkey->id->len, jkey->id->s, i);
		return;
	}
#ifdef XJ_EXTRA_DEBUG
	LM_DBG("%d: trying to delete entry for <%.*s>...\n",
		_pid, jkey->id->len, jkey->id->s);
#endif
	lock_set_get(jwl->sems, i);
	p = del234(jwl->workers[i].sip_ids, (void*)jkey);

	if(p != NULL)
	{
		jwl->workers[i].nr--;
#ifdef XJ_EXTRA_DEBUG
		LM_DBG("%d: sip id <%.*s> deleted\n", _pid,
			jkey->id->len, jkey->id->s);
#endif
		xj_jkey_free_p(p);
	}

	lock_set_release(jwl->sems, i);
}
예제 #4
0
int  xj_jcon_del_jconf(xj_jcon jbc, str *sid, char dl, int flag)
{
	xj_jconf jcf = NULL, p = NULL;
	
	if(!jbc || !sid || !sid->s || sid->len <= 0)
		return -1;
#ifdef XJ_EXTRA_DEBUG
	DBG("XJAB: xj_jcon_del_jconf: deleting conference of <%.*s>\n",
			sid->len, sid->s);
#endif	
	if((jcf = xj_jconf_new(sid))==NULL)
		return -1;
	if(xj_jconf_init_sip(jcf, jbc->jkey->id, dl))
	{
		xj_jconf_free(jcf);
		return -1;
	}
	
	p = del234(jbc->jconf, (void*)jcf);

	if(p != NULL)
	{
		if(flag == XJ_JCMD_UNSUBSCRIBE)
			xj_jcon_jconf_presence(jbc, jcf, "unavailable", NULL);
		jbc->nrjconf--;
		xj_jconf_free(p);
#ifdef XJ_EXTRA_DEBUG
		DBG("XJAB: xj_jcon_del_jconf: conference deleted\n");
#endif
	}

	xj_jconf_free(jcf);

	return 0;
}
예제 #5
0
파일: winhandl.c 프로젝트: Ugnis/Far-NetBox
static void handle_destroy(struct handle *h)
{
    if (h->type == HT_OUTPUT)
	bufchain_clear(&h->u.o.queued_data);
    CloseHandle(h->u.g.ev_from_main);
    CloseHandle(h->u.g.ev_to_main);
    del234(handles_by_evtomain, h);
    sfree(h);
}
예제 #6
0
파일: uxproxy.c 프로젝트: Joungkyun/HPuTTY
static void sk_localproxy_close (Socket s)
{
    Local_Proxy_Socket ps = (Local_Proxy_Socket) s;

    if (ps->to_cmd >= 0) {
        del234(localproxy_by_tofd, ps);
        uxsel_del(ps->to_cmd);
        close(ps->to_cmd);
    }

    del234(localproxy_by_fromfd, ps);
    uxsel_del(ps->from_cmd);
    close(ps->from_cmd);

    bufchain_clear(&ps->pending_input_data);
    bufchain_clear(&ps->pending_output_data);
    sfree(ps);
}
예제 #7
0
파일: uxsel.c 프로젝트: bestustc/PuTTY
void uxsel_del(int fd)
{
    struct fd *oldfd = find234(fds, &fd, uxsel_fd_findcmp);
    if (oldfd) {
	if (oldfd->id)
            uxsel_input_remove(oldfd->id);
	del234(fds, oldfd);
	sfree(oldfd);
    }
}
예제 #8
0
/*
 * Call to expire all timers associated with a given context.
 */
void expire_timer_context(void *ctx) {
	init_timers();

	/*
	 * We don't bother to check the return value; if the context
	 * already wasn't in the tree (presumably because no timers
	 * ever actually got scheduled for it) then that's fine and we
	 * simply don't need to do anything.
	 */
	del234(timer_contexts, ctx);
}
예제 #9
0
파일: tree234.c 프로젝트: rdebath/sgt
void deltest(void *elem) {
    int i;

    i = 0;
    while (i < arraylen && cmp(elem, array[i]) > 0)
        i++;
    /* now i points to the first element >= elem */
    if (i >= arraylen || cmp(elem, array[i]) != 0)
        return;                        /* don't do it! */
    else {
        while (i < arraylen-1) {
            array[i] = array[i+1];
            i++;
        }
        arraylen--;                    /* delete elem from array */
    }

    del234(tree, elem);

    verify();
}
예제 #10
0
void delpostest(int i) {
    int index = i;
    void *elem = array[i], *ret;

    /* i points to the right element */
    while (i < arraylen-1) {
	array[i] = array[i+1];
	i++;
    }
    arraylen--;			       /* delete elem from array */

    if (tree->cmp)
	ret = del234(tree, elem);
    else
	ret = delpos234(tree, index);

    if (ret != elem) {
	error("del returned %p, expected %p", ret, elem);
    }

    verify();
}
예제 #11
0
파일: uxproxy.c 프로젝트: 4myPAL/PuTTYTray
static int localproxy_try_send(Local_Proxy_Socket ps)
{
    int sent = 0;

    while (bufchain_size(&ps->pending_output_data) > 0) {
	void *data;
	int len, ret;

	bufchain_prefix(&ps->pending_output_data, &data, &len);
	ret = write(ps->to_cmd, data, len);
	if (ret < 0 && errno != EWOULDBLOCK) {
	    /* We're inside the Unix frontend here, so we know
	     * that the frontend handle is unnecessary. */
	    logevent(NULL, strerror(errno));
	    fatalbox("%s", strerror(errno));
	} else if (ret <= 0) {
	    break;
	} else {
	    bufchain_consume(&ps->pending_output_data, ret);
	    sent += ret;
	}
    }

    if (ps->outgoingeof == EOF_PENDING) {
        del234(localproxy_by_tofd, ps);
        close(ps->to_cmd);
        uxsel_del(ps->to_cmd);
        ps->to_cmd = -1;
        ps->outgoingeof = EOF_SENT;
    }

    if (bufchain_size(&ps->pending_output_data) == 0)
	uxsel_del(ps->to_cmd);
    else
	uxsel_set(ps->to_cmd, 2, localproxy_select_result);

    return sent;
}
예제 #12
0
파일: uxproxy.c 프로젝트: ISTweak/putty
static int localproxy_try_send(Local_Proxy_Socket ps)
{
    int sent = 0;

    while (bufchain_size(&ps->pending_output_data) > 0) {
	void *data;
	int len, ret;

	bufchain_prefix(&ps->pending_output_data, &data, &len);
	ret = write(ps->to_cmd, data, len);
	if (ret < 0 && errno != EWOULDBLOCK) {
            plug_closing(ps->plug, strerror(errno), errno, 0);
            return 0;
	} else if (ret <= 0) {
	    break;
	} else {
	    bufchain_consume(&ps->pending_output_data, ret);
	    sent += ret;
	}
    }

    if (ps->outgoingeof == EOF_PENDING) {
        del234(localproxy_by_tofd, ps);
        close(ps->to_cmd);
        uxsel_del(ps->to_cmd);
        ps->to_cmd = -1;
        ps->outgoingeof = EOF_SENT;
    }

    if (bufchain_size(&ps->pending_output_data) == 0)
	uxsel_del(ps->to_cmd);
    else
	uxsel_set(ps->to_cmd, 2, localproxy_select_result);

    return sent;
}
예제 #13
0
int pty_real_select_result(Pty pty, int event, int status)
{
    char buf[4096];
    int ret;
    int finished = FALSE;

    if (event < 0) {
	/*
	 * We've been called because our child process did
	 * something. `status' tells us what.
	 */
	if ((WIFEXITED(status) || WIFSIGNALED(status))) {
	    /*
	     * The primary child process died. We could keep
	     * the terminal open for remaining subprocesses to
	     * output to, but conventional wisdom seems to feel
	     * that that's the Wrong Thing for an xterm-alike,
	     * so we bail out now (though we don't necessarily
	     * _close_ the window, depending on the state of
	     * Close On Exit). This would be easy enough to
	     * change or make configurable if necessary.
	     */
	    pty->exit_code = status;
	    pty->child_dead = TRUE;
	    del234(ptys_by_pid, pty);
	    finished = TRUE;
	}
    } else {
	if (event == 1) {

	    ret = read(pty->master_fd, buf, sizeof(buf));

	    /*
	     * Clean termination condition is that either ret == 0, or ret
	     * < 0 and errno == EIO. Not sure why the latter, but it seems
	     * to happen. Boo.
	     */
	    if (ret == 0 || (ret < 0 && errno == EIO)) {
		/*
		 * We assume a clean exit if the pty has closed but the
		 * actual child process hasn't. The only way I can
		 * imagine this happening is if it detaches itself from
		 * the pty and goes daemonic - in which case the
		 * expected usage model would precisely _not_ be for
		 * the pterm window to hang around!
		 */
		finished = TRUE;
		if (!pty->child_dead)
		    pty->exit_code = 0;
	    } else if (ret < 0) {
		perror("read pty master");
		exit(1);
	    } else if (ret > 0) {
		from_backend(pty->frontend, 0, buf, ret);
	    }
	} else if (event == 2) {
            /*
             * Attempt to send data down the pty.
             */
            pty_try_write(pty);
        }
    }

    if (finished && !pty->finished) {
	int close_on_exit;

	uxsel_del(pty->master_fd);
	pty_close(pty);
	pty->master_fd = -1;

	pty->finished = TRUE;

	/*
	 * This is a slight layering-violation sort of hack: only
	 * if we're not closing on exit (COE is set to Never, or to
	 * Only On Clean and it wasn't a clean exit) do we output a
	 * `terminated' message.
	 */
	close_on_exit = conf_get_int(pty->conf, CONF_close_on_exit);
	if (close_on_exit == FORCE_OFF ||
	    (close_on_exit == AUTO && pty->exit_code != 0)) {
	    char message[512];
            message[0] = '\0';
	    if (WIFEXITED(pty->exit_code))
		sprintf(message, "\r\n[pterm: process terminated with exit"
			" code %d]\r\n", WEXITSTATUS(pty->exit_code));
	    else if (WIFSIGNALED(pty->exit_code))
#ifdef HAVE_NO_STRSIGNAL
		sprintf(message, "\r\n[pterm: process terminated on signal"
			" %d]\r\n", WTERMSIG(pty->exit_code));
#else
		sprintf(message, "\r\n[pterm: process terminated on signal"
			" %d (%.400s)]\r\n", WTERMSIG(pty->exit_code),
			strsignal(WTERMSIG(pty->exit_code)));
#endif
	    from_backend(pty->frontend, 0, message, strlen(message));
	}

	notify_remote_exit(pty->frontend);
    }

    return !finished;
}
예제 #14
0
/*
 * Generate a new complete random closed loop for the given grid.
 *
 * The method is to generate a WHITE/BLACK colouring of all the faces,
 * such that the WHITE faces will define the inside of the path, and the
 * BLACK faces define the outside.
 * To do this, we initially colour all faces GREY.  The infinite space outside
 * the grid is coloured BLACK, and we choose a random face to colour WHITE.
 * Then we gradually grow the BLACK and the WHITE regions, eliminating GREY
 * faces, until the grid is filled with BLACK/WHITE.  As we grow the regions,
 * we avoid creating loops of a single colour, to preserve the topological
 * shape of the WHITE and BLACK regions.
 * We also try to make the boundary as loopy and twisty as possible, to avoid
 * generating paths that are uninteresting.
 * The algorithm works by choosing a BLACK/WHITE colour, then choosing a GREY
 * face that can be coloured with that colour (without violating the
 * topological shape of that region).  It's not obvious, but I think this
 * algorithm is guaranteed to terminate without leaving any GREY faces behind.
 * Indeed, if there are any GREY faces at all, both the WHITE and BLACK
 * regions can be grown.
 * This is checked using assert()ions, and I haven't seen any failures yet.
 *
 * Hand-wavy proof: imagine what can go wrong...
 *
 * Could the white faces get completely cut off by the black faces, and still
 * leave some grey faces remaining?
 * No, because then the black faces would form a loop around both the white
 * faces and the grey faces, which is disallowed because we continually
 * maintain the correct topological shape of the black region.
 * Similarly, the black faces can never get cut off by the white faces.  That
 * means both the WHITE and BLACK regions always have some room to grow into
 * the GREY regions.
 * Could it be that we can't colour some GREY face, because there are too many
 * WHITE/BLACK transitions as we walk round the face? (see the
 * can_colour_face() function for details)
 * No.  Imagine otherwise, and we see WHITE/BLACK/WHITE/BLACK as we walk
 * around the face.  The two WHITE faces would be connected by a WHITE path,
 * and the BLACK faces would be connected by a BLACK path.  These paths would
 * have to cross, which is impossible.
 * Another thing that could go wrong: perhaps we can't find any GREY face to
 * colour WHITE, because it would create a loop-violation or a corner-violation
 * with the other WHITE faces?
 * This is a little bit tricky to prove impossible.  Imagine you have such a
 * GREY face (that is, if you coloured it WHITE, you would create a WHITE loop
 * or corner violation).
 * That would cut all the non-white area into two blobs.  One of those blobs
 * must be free of BLACK faces (because the BLACK stuff is a connected blob).
 * So we have a connected GREY area, completely surrounded by WHITE
 * (including the GREY face we've tentatively coloured WHITE).
 * A well-known result in graph theory says that you can always find a GREY
 * face whose removal leaves the remaining GREY area connected.  And it says
 * there are at least two such faces, so we can always choose the one that
 * isn't the "tentative" GREY face.  Colouring that face WHITE leaves
 * everything nice and connected, including that "tentative" GREY face which
 * acts as a gateway to the rest of the non-WHITE grid.
 */
void generate_loop(grid *g, char *board, random_state *rs,
                   loopgen_bias_fn_t bias, void *biasctx)
{
    int i, j;
    int num_faces = g->num_faces;
    struct face_score *face_scores; /* Array of face_score objects */
    struct face_score *fs; /* Points somewhere in the above list */
    struct grid_face *cur_face;
    tree234 *lightable_faces_sorted;
    tree234 *darkable_faces_sorted;
    int *face_list;
    int do_random_pass;

    /* Make a board */
    memset(board, FACE_GREY, num_faces);
    
    /* Create and initialise the list of face_scores */
    face_scores = snewn(num_faces, struct face_score);
    for (i = 0; i < num_faces; i++) {
        face_scores[i].random = random_bits(rs, 31);
        face_scores[i].black_score = face_scores[i].white_score = 0;
    }
    
    /* Colour a random, finite face white.  The infinite face is implicitly
     * coloured black.  Together, they will seed the random growth process
     * for the black and white areas. */
    i = random_upto(rs, num_faces);
    board[i] = FACE_WHITE;

    /* We need a way of favouring faces that will increase our loopiness.
     * We do this by maintaining a list of all candidate faces sorted by
     * their score and choose randomly from that with appropriate skew.
     * In order to avoid consistently biasing towards particular faces, we
     * need the sort order _within_ each group of scores to be completely
     * random.  But it would be abusing the hospitality of the tree234 data
     * structure if our comparison function were nondeterministic :-).  So with
     * each face we associate a random number that does not change during a
     * particular run of the generator, and use that as a secondary sort key.
     * Yes, this means we will be biased towards particular random faces in
     * any one run but that doesn't actually matter. */

    lightable_faces_sorted = newtree234(white_sort_cmpfn);
    darkable_faces_sorted = newtree234(black_sort_cmpfn);

    /* Initialise the lists of lightable and darkable faces.  This is
     * slightly different from the code inside the while-loop, because we need
     * to check every face of the board (the grid structure does not keep a
     * list of the infinite face's neighbours). */
    for (i = 0; i < num_faces; i++) {
        grid_face *f = g->faces + i;
        struct face_score *fs = face_scores + i;
        if (board[i] != FACE_GREY) continue;
        /* We need the full colourability check here, it's not enough simply
         * to check neighbourhood.  On some grids, a neighbour of the infinite
         * face is not necessarily darkable. */
        if (can_colour_face(g, board, i, FACE_BLACK)) {
            fs->black_score = face_score(g, board, f, FACE_BLACK);
            add234(darkable_faces_sorted, fs);
        }
        if (can_colour_face(g, board, i, FACE_WHITE)) {
            fs->white_score = face_score(g, board, f, FACE_WHITE);
            add234(lightable_faces_sorted, fs);
        }
    }

    /* Colour faces one at a time until no more faces are colourable. */
    while (TRUE)
    {
        enum face_colour colour;
        tree234 *faces_to_pick;
        int c_lightable = count234(lightable_faces_sorted);
        int c_darkable = count234(darkable_faces_sorted);
        if (c_lightable == 0 && c_darkable == 0) {
            /* No more faces we can use at all. */
            break;
        }
	assert(c_lightable != 0 && c_darkable != 0);

        /* Choose a colour, and colour the best available face
         * with that colour. */
        colour = random_upto(rs, 2) ? FACE_WHITE : FACE_BLACK;

        if (colour == FACE_WHITE)
            faces_to_pick = lightable_faces_sorted;
        else
            faces_to_pick = darkable_faces_sorted;
        if (bias) {
            /*
             * Go through all the candidate faces and pick the one the
             * bias function likes best, breaking ties using the
             * ordering in our tree234 (which is why we replace only
             * if score > bestscore, not >=).
             */
            int j, k;
            struct face_score *best = NULL;
            int score, bestscore = 0;

            for (j = 0;
                 (fs = (struct face_score *)index234(faces_to_pick, j))!=NULL;
                 j++) {

                assert(fs);
                k = fs - face_scores;
                assert(board[k] == FACE_GREY);
                board[k] = colour;
                score = bias(biasctx, board, k);
                board[k] = FACE_GREY;
                bias(biasctx, board, k); /* let bias know we put it back */

                if (!best || score > bestscore) {
                    bestscore = score;
                    best = fs;
                }
            }
            fs = best;
        } else {
            fs = (struct face_score *)index234(faces_to_pick, 0);
        }
        assert(fs);
        i = fs - face_scores;
        assert(board[i] == FACE_GREY);
        board[i] = colour;
        if (bias)
            bias(biasctx, board, i); /* notify bias function of the change */

        /* Remove this newly-coloured face from the lists.  These lists should
         * only contain grey faces. */
        del234(lightable_faces_sorted, fs);
        del234(darkable_faces_sorted, fs);

        /* Remember which face we've just coloured */
        cur_face = g->faces + i;

        /* The face we've just coloured potentially affects the colourability
         * and the scores of any neighbouring faces (touching at a corner or
         * edge).  So the search needs to be conducted around all faces
         * touching the one we've just lit.  Iterate over its corners, then
         * over each corner's faces.  For each such face, we remove it from
         * the lists, recalculate any scores, then add it back to the lists
         * (depending on whether it is lightable, darkable or both). */
        for (i = 0; i < cur_face->order; i++) {
            grid_dot *d = cur_face->dots[i];
            for (j = 0; j < d->order; j++) {
                grid_face *f = d->faces[j];
                int fi; /* face index of f */

                if (f == NULL)
                    continue;
                if (f == cur_face)
                    continue;
                
                /* If the face is already coloured, it won't be on our
                 * lightable/darkable lists anyway, so we can skip it without 
                 * bothering with the removal step. */
                if (FACE_COLOUR(f) != FACE_GREY) continue; 

                /* Find the face index and face_score* corresponding to f */
                fi = f - g->faces;                
                fs = face_scores + fi;

                /* Remove from lightable list if it's in there.  We do this,
                 * even if it is still lightable, because the score might
                 * be different, and we need to remove-then-add to maintain
                 * correct sort order. */
                del234(lightable_faces_sorted, fs);
                if (can_colour_face(g, board, fi, FACE_WHITE)) {
                    fs->white_score = face_score(g, board, f, FACE_WHITE);
                    add234(lightable_faces_sorted, fs);
                }
                /* Do the same for darkable list. */
                del234(darkable_faces_sorted, fs);
                if (can_colour_face(g, board, fi, FACE_BLACK)) {
                    fs->black_score = face_score(g, board, f, FACE_BLACK);
                    add234(darkable_faces_sorted, fs);
                }
            }
        }
    }

    /* Clean up */
    freetree234(lightable_faces_sorted);
    freetree234(darkable_faces_sorted);
    sfree(face_scores);

    /* The next step requires a shuffled list of all faces */
    face_list = snewn(num_faces, int);
    for (i = 0; i < num_faces; ++i) {
        face_list[i] = i;
    }
    shuffle(face_list, num_faces, sizeof(int), rs);

    /* The above loop-generation algorithm can often leave large clumps
     * of faces of one colour.  In extreme cases, the resulting path can be 
     * degenerate and not very satisfying to solve.
     * This next step alleviates this problem:
     * Go through the shuffled list, and flip the colour of any face we can
     * legally flip, and which is adjacent to only one face of the opposite
     * colour - this tends to grow 'tendrils' into any clumps.
     * Repeat until we can find no more faces to flip.  This will
     * eventually terminate, because each flip increases the loop's
     * perimeter, which cannot increase for ever.
     * The resulting path will have maximal loopiness (in the sense that it
     * cannot be improved "locally".  Unfortunately, this allows a player to
     * make some illicit deductions.  To combat this (and make the path more
     * interesting), we do one final pass making random flips. */

    /* Set to TRUE for final pass */
    do_random_pass = FALSE;

    while (TRUE) {
        /* Remember whether a flip occurred during this pass */
        int flipped = FALSE;

        for (i = 0; i < num_faces; ++i) {
            int j = face_list[i];
            enum face_colour opp =
                (board[j] == FACE_WHITE) ? FACE_BLACK : FACE_WHITE;
            if (can_colour_face(g, board, j, opp)) {
                grid_face *face = g->faces +j;
                if (do_random_pass) {
                    /* final random pass */
                    if (!random_upto(rs, 10))
                        board[j] = opp;
                } else {
                    /* normal pass - flip when neighbour count is 1 */
                    if (face_num_neighbours(g, board, face, opp) == 1) {
                        board[j] = opp;
                        flipped = TRUE;
                    }
                }
            }
        }

        if (do_random_pass) break;
        if (!flipped) do_random_pass = TRUE;
    }

    sfree(face_list);
}