| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132 | /* * Centralised functions for the Interactor trait. */#include "putty.h"Seat *interactor_borrow_seat(Interactor *itr){    Seat *clientseat = interactor_get_seat(itr);    if (!clientseat)        return NULL;    /* If the client has already had its Seat borrowed, then look     * through the existing TempSeat to find the underlying one. */    if (is_tempseat(clientseat))        return tempseat_get_real(clientseat);    /* Otherwise, make a new TempSeat and give that to the client. */    { // WINSCP    Seat *tempseat = tempseat_new(clientseat);    interactor_set_seat(itr, tempseat);    return clientseat;    } // WINSCP}static Interactor *interactor_toplevel(Interactor *itr, unsigned *level_out){    /*     * Find the Interactor at the top of the chain, so that all the     * Interactors in a stack can share that one's last-to-talk field.     * Also, count how far we had to go to get to it, to put in the     * message.     */    Interactor *itr_top = itr;    unsigned level = 0;    while (itr_top->parent) {        itr_top = itr_top->parent;        level++;    }    if (level_out)        *level_out = level;    return itr_top;}void interactor_return_seat(Interactor *itr){    Seat *tempseat = interactor_get_seat(itr);    if (!is_tempseat(tempseat))        return;                        /* no-op */    /*     * We're about to hand this seat back to the parent Interactor to     * do its own thing with. It will typically expect to start in the     * same state as if the seat had never been borrowed, i.e. in the     * starting trust state.     *     * However, this may be overridden by the tempseat_flush call.     */    { // WINSCP    Seat *realseat = tempseat_get_real(tempseat);    seat_set_trust_status(realseat, true);    tempseat_flush(tempseat);    interactor_set_seat(itr, realseat);    tempseat_free(tempseat);    /*     * If we have a parent Interactor, and anyone has ever called     * interactor_announce, then all Interactors from now on will     * announce themselves even if they have nothing to say.     */    { // WINSCP    Interactor *itr_top = interactor_toplevel(itr, NULL);    if (itr_top->last_to_talk)        interactor_announce(itr);    } // WINSCP    } // WINSCP}InteractionReadySeat interactor_announce(Interactor *itr){    Seat *seat = interactor_get_seat(itr);    assert(!is_tempseat(seat) &&           "Shouldn't call announce when someone else is using our seat");    { // WINSCP    InteractionReadySeat iseat;    iseat.seat = seat;    { // WINSCP    unsigned level;    Interactor *itr_top = interactor_toplevel(itr, &level);    /*     * Generally, we should announce ourself if the previous     * Interactor that said anything was not us. That includes if     * there was no previous Interactor to talk (i.e. if we're the     * first to say anything) - *except* that the primary Interactor     * doesn't need to announce itself, if no proxy has intervened     * before it.     */    bool need_announcement = (itr_top->last_to_talk != itr);    if (!itr->parent && !itr_top->last_to_talk)        need_announcement = false;    if (need_announcement) {        const char *prefix = "";        if (itr_top->last_to_talk != NULL)            seat_antispoof_msg(iseat, ""); /* leave a separating blank line */        { // WINSCP        char *desc = interactor_description(itr);        char *adjective = (level == 0 ? dupstr("primary") :                           level == 1 ? dupstr("proxy") :                           dupprintf("proxy^%u", level));        char *msg = dupprintf("%sMaking %s %s", prefix, adjective, desc);        sfree(adjective);        sfree(desc);        // WINSCP We could comment out whole this function        // WINSCP seat_antispoof_msg(iseat, msg);        sfree(msg);        itr_top->last_to_talk = itr;        } // WINSCP    }    return iseat;    } // WINSCP    } // WINSCP}
 |