/* * check_slc * * Check the special characters in use and notify the client if any have * changed. Only those characters that are capable of being changed are * likely to have changed. If a local change occurs, kick the support level * and flags up to the defaults. */ void check_slc(void) { int i; for (i = 1; i <= NSLC; i++) { #if defined(USE_TERMIO) && (VEOF == VMIN) /* * In a perfect world this would be a neat little * function. But in this world, we should not notify * client of changes to the VEOF char when * ICANON is off, because it is not representing * a special character. */ if (i == SLC_EOF) { if (!tty_isediting()) continue; else if (slctab[i].sptr) oldeofc = *(slctab[i].sptr); } #endif /* USE_TERMIO and VEOF==VMIN */ if (slctab[i].sptr && (*(slctab[i].sptr) != slctab[i].current.val)) { slctab[i].current.val = *(slctab[i].sptr); if (*(slctab[i].sptr) == (cc_t)_POSIX_VDISABLE) { slctab[i].current.flag = SLC_NOSUPPORT; } else { slctab[i].current.flag = slctab[i].defset.flag; } add_slc((unsigned char)i, slctab[i].current.flag, slctab[i].current.val); } } }
/* * process_slc * * Figure out what to do about the client's slc */ void process_slc(unsigned char func, unsigned char flag, cc_t val) { register int hislevel, mylevel, ack; /* * Ensure that we know something about this function */ if (func > NSLC) { add_slc(func, SLC_NOSUPPORT, 0); return; } /* * Process the special case requests of 0 SLC_DEFAULT 0 * and 0 SLC_VARIABLE 0. Be a little forgiving here, don't * worry about whether the value is actually 0 or not. */ if (func == 0) { if ((flag = flag & SLC_LEVELBITS) == SLC_DEFAULT) { default_slc(); send_slc(); } else if (flag == SLC_VARIABLE) { send_slc(); } return; } /* * Appears to be a function that we know something about. So * get on with it and see what we know. */ hislevel = flag & SLC_LEVELBITS; mylevel = slctab[func].current.flag & SLC_LEVELBITS; ack = flag & SLC_ACK; /* * ignore the command if: * the function value and level are the same as what we already have; * or the level is the same and the ack bit is set */ if (hislevel == mylevel && (val == slctab[func].current.val || ack)) { return; } else if (ack) { /* * If we get here, we got an ack, but the levels don't match. * This shouldn't happen. If it does, it is probably because * we have sent two requests to set a variable without getting * a response between them, and this is the first response. * So, ignore it, and wait for the next response. */ return; } else { change_slc(func, flag, val); } }
/* * send_slc * * Write out the current special characters to the client. */ void send_slc(void) { int i; /* * Send out list of triplets of special characters * to client. We only send info on the characters * that are currently supported. */ for (i = 1; i <= NSLC; i++) { if ((slctab[i].defset.flag & SLC_LEVELBITS) == SLC_NOSUPPORT) continue; add_slc((unsigned char)i, slctab[i].current.flag, slctab[i].current.val); } }
/* * check_slc * * Check the special characters in use and notify the client if any have * changed. Only those characters that are capable of being changed are * likely to have changed. If a local change occurs, kick the support level * and flags up to the defaults. */ void check_slc () { register int i; for (i = 1; i <= NSLC; i++) { if (i == SLC_EOF && term_change_eof ()) continue; if (slctab[i].sptr && (*(slctab[i].sptr) != slctab[i].current.val)) { slctab[i].current.val = *(slctab[i].sptr); if (*(slctab[i].sptr) == (cc_t) _POSIX_VDISABLE) slctab[i].current.flag = SLC_NOSUPPORT; else slctab[i].current.flag = slctab[i].defset.flag; add_slc ((unsigned char) i, slctab[i].current.flag, slctab[i].current.val); } } } /* check_slc */
/* * change_slc * * Process a request to change one of our special characters. * Compare client's request with what we are capable of supporting. */ void change_slc (register char func_c, register char flag, register cc_t val) { register int func = func_c; register int hislevel, mylevel; hislevel = flag & SLC_LEVELBITS; mylevel = slctab[func].defset.flag & SLC_LEVELBITS; /* * If client is setting a function to NOSUPPORT * or DEFAULT, then we can easily and directly * accomodate the request. */ if (hislevel == SLC_NOSUPPORT) { slctab[func].current.flag = flag; slctab[func].current.val = (cc_t) _POSIX_VDISABLE; flag |= SLC_ACK; add_slc (func, flag, val); return; } if (hislevel == SLC_DEFAULT) { /* * Special case here. If client tells us to use * the default on a function we don't support, then * return NOSUPPORT instead of what we may have as a * default level of DEFAULT. */ if (mylevel == SLC_DEFAULT) { slctab[func].current.flag = SLC_NOSUPPORT; } else { slctab[func].current.flag = slctab[func].defset.flag; } slctab[func].current.val = slctab[func].defset.val; add_slc (func, slctab[func].current.flag, slctab[func].current.val); return; } /* * Client wants us to change to a new value or he * is telling us that he can't change to our value. * Some of the slc's we support and can change, * some we do support but can't change, * and others we don't support at all. * If we can change it then we have a pointer to * the place to put the new value, so change it, * otherwise, continue the negotiation. */ if (slctab[func].sptr) { /* * We can change this one. */ slctab[func].current.val = val; *(slctab[func].sptr) = val; slctab[func].current.flag = flag; flag |= SLC_ACK; slcchange = 1; add_slc (func, flag, val); } else { /* * It is not possible for us to support this * request as he asks. * * If our level is DEFAULT, then just ack whatever was * sent. * * If he can't change and we can't change, * then degenerate to NOSUPPORT. * * Otherwise we send our level back to him, (CANTCHANGE * or NOSUPPORT) and if CANTCHANGE, send * our value as well. */ if (mylevel == SLC_DEFAULT) { slctab[func].current.flag = flag; slctab[func].current.val = val; flag |= SLC_ACK; } else if (hislevel == SLC_CANTCHANGE && mylevel == SLC_CANTCHANGE) { flag &= ~SLC_LEVELBITS; flag |= SLC_NOSUPPORT; slctab[func].current.flag = flag; } else { flag &= ~SLC_LEVELBITS; flag |= mylevel; slctab[func].current.flag = flag; if (mylevel == SLC_CANTCHANGE) { slctab[func].current.val = slctab[func].defset.val; val = slctab[func].current.val; } } add_slc (func, flag, val); } } /* end of change_slc */