22 |
#define SLC_NAMES |
#define SLC_NAMES |
23 |
#include "telnetd.h" |
#include "telnetd.h" |
24 |
#include <stdarg.h> |
#include <stdarg.h> |
|
#include <termio.h> |
|
25 |
|
|
26 |
#if defined(AUTHENTICATION) || defined(ENCRYPTION) |
#if defined(AUTHENTICATION) || defined(ENCRYPTION) |
27 |
# include <libtelnet/misc.h> |
# include <libtelnet/misc.h> |
148 |
pfrontp = pbackp = ptyobuf; |
pfrontp = pbackp = ptyobuf; |
149 |
nfrontp = nbackp = netobuf; |
nfrontp = nbackp = netobuf; |
150 |
netip = netibuf; |
netip = netibuf; |
151 |
|
ptyip = ptyibuf; |
152 |
} |
} |
153 |
|
|
154 |
void |
void |
329 |
} |
} |
330 |
|
|
331 |
int |
int |
332 |
|
pty_input_putback (const char *str, size_t len) |
333 |
|
{ |
334 |
|
if (len > &ptyibuf[BUFSIZ] - ptyip) |
335 |
|
len = &ptyibuf[BUFSIZ] - ptyip; |
336 |
|
strncpy (ptyip, str, len); |
337 |
|
pcc += len; |
338 |
|
} |
339 |
|
|
340 |
|
int |
341 |
pty_read () |
pty_read () |
342 |
{ |
{ |
343 |
pcc = readstream (pty, ptyibuf, BUFSIZ); |
pcc = readstream (pty, ptyibuf, BUFSIZ); |
1546 |
|
|
1547 |
|
|
1548 |
#endif |
#endif |
1549 |
|
|
1550 |
|
/* ************************************************************************* */ |
1551 |
|
/* String expansion functions */ |
1552 |
|
|
1553 |
|
#define EXP_STATE_CONTINUE 0 |
1554 |
|
#define EXP_STATE_SUCCESS 1 |
1555 |
|
#define EXP_STATE_ERROR 2 |
1556 |
|
|
1557 |
|
struct line_expander |
1558 |
|
{ |
1559 |
|
int state; /* Current state */ |
1560 |
|
int level; /* The nesting level */ |
1561 |
|
char *source; /* The source string */ |
1562 |
|
char *cp; /* Current position in the source */ |
1563 |
|
struct obstack stk; /* Obstack for expanded version */ |
1564 |
|
}; |
1565 |
|
|
1566 |
|
static char *_var_short_name P((struct line_expander *exp)); |
1567 |
|
static char *_var_long_name P((struct line_expander *exp, |
1568 |
|
char *start, int length)); |
1569 |
|
static char *_expand_var P((struct line_expander *exp)); |
1570 |
|
static void _expand_cond P((struct line_expander *exp)); |
1571 |
|
static void _skip_block P((struct line_expander *exp)); |
1572 |
|
static void _expand_block P((struct line_expander *exp)); |
1573 |
|
|
1574 |
|
/* Expand a variable referenced by its short one-symbol name. |
1575 |
|
Input: exp->cp points to the variable name. |
1576 |
|
FIXME: not implemented */ |
1577 |
|
char * |
1578 |
|
_var_short_name (struct line_expander *exp) |
1579 |
|
{ |
1580 |
|
char *q; |
1581 |
|
char timebuf[64]; |
1582 |
|
time_t t; |
1583 |
|
|
1584 |
|
switch (*exp->cp++) |
1585 |
|
{ |
1586 |
|
case 'a': |
1587 |
|
#ifdef AUTHENTICATION |
1588 |
|
if (auth_level >= 0 && autologin == AUTH_VALID) |
1589 |
|
return xstrdup ("ok"); |
1590 |
|
#endif |
1591 |
|
return NULL; |
1592 |
|
|
1593 |
|
case 'd': |
1594 |
|
time (&t); |
1595 |
|
strftime(timebuf, sizeof (timebuf), |
1596 |
|
"%l:%M%P on %A, %d %B %Y", localtime(&t)); |
1597 |
|
return xstrdup (timebuf); |
1598 |
|
|
1599 |
|
case 'h': |
1600 |
|
return xstrdup (remote_hostname); |
1601 |
|
|
1602 |
|
case 'l': |
1603 |
|
return xstrdup (local_hostname); |
1604 |
|
|
1605 |
|
case 't': |
1606 |
|
q = strchr (line + 1, '/'); |
1607 |
|
if (q) |
1608 |
|
q++; |
1609 |
|
else |
1610 |
|
q = line; |
1611 |
|
return xstrdup (q); |
1612 |
|
|
1613 |
|
case 'T': |
1614 |
|
return terminaltype ? xstrdup (terminaltype) : NULL; |
1615 |
|
|
1616 |
|
case 'u': |
1617 |
|
return user_name ? xstrdup (user_name) : NULL; |
1618 |
|
|
1619 |
|
default: |
1620 |
|
exp->state = EXP_STATE_ERROR; |
1621 |
|
return NULL; |
1622 |
|
} |
1623 |
|
} |
1624 |
|
|
1625 |
|
/* Expand a variable referenced by its long name. |
1626 |
|
Input: exp->cp points to initial '(' |
1627 |
|
FIXME: not implemented */ |
1628 |
|
char * |
1629 |
|
_var_long_name (struct line_expander *exp, char *start, int length) |
1630 |
|
{ |
1631 |
|
exp->state = EXP_STATE_ERROR; |
1632 |
|
return NULL; |
1633 |
|
} |
1634 |
|
|
1635 |
|
/* Expand a variable to its value. |
1636 |
|
Input: exp->cp points one character _past_ % (or ?) */ |
1637 |
|
char * |
1638 |
|
_expand_var (struct line_expander *exp) |
1639 |
|
{ |
1640 |
|
char *p; |
1641 |
|
switch (*exp->cp) |
1642 |
|
{ |
1643 |
|
case '{': |
1644 |
|
/* Collect variable name */ |
1645 |
|
for (p = ++exp->cp; *exp->cp && *exp->cp != '}'; exp->cp++) |
1646 |
|
; |
1647 |
|
if (*exp->cp == 0) |
1648 |
|
{ |
1649 |
|
exp->cp = p; |
1650 |
|
exp->state = EXP_STATE_ERROR; |
1651 |
|
break; |
1652 |
|
} |
1653 |
|
p = _var_long_name (exp, p, exp->cp - p); |
1654 |
|
exp->cp++; |
1655 |
|
break; |
1656 |
|
|
1657 |
|
default: |
1658 |
|
p = _var_short_name (exp); |
1659 |
|
break; |
1660 |
|
} |
1661 |
|
return p; |
1662 |
|
} |
1663 |
|
|
1664 |
|
/* Expand a conditional block. A conditional block is: |
1665 |
|
%?<var>{true-stmt}[{false-stmt}] |
1666 |
|
<var> may be either a one-symbol variable name or (string). The latter |
1667 |
|
is not handled yet. |
1668 |
|
On input exp->cp points to % character */ |
1669 |
|
void |
1670 |
|
_expand_cond (struct line_expander *exp) |
1671 |
|
{ |
1672 |
|
char *p; |
1673 |
|
|
1674 |
|
if (*++exp->cp == '?') |
1675 |
|
{ |
1676 |
|
/* condition */ |
1677 |
|
exp->cp++; |
1678 |
|
p = _expand_var (exp); |
1679 |
|
if (p) |
1680 |
|
{ |
1681 |
|
_expand_block (exp); |
1682 |
|
_skip_block (exp); |
1683 |
|
} |
1684 |
|
else |
1685 |
|
{ |
1686 |
|
_skip_block (exp); |
1687 |
|
_expand_block (exp); |
1688 |
|
} |
1689 |
|
free (p); |
1690 |
|
} |
1691 |
|
else |
1692 |
|
{ |
1693 |
|
p = _expand_var (exp); |
1694 |
|
if (p) |
1695 |
|
obstack_grow (&exp->stk, p, strlen (p)); |
1696 |
|
free (p); |
1697 |
|
} |
1698 |
|
} |
1699 |
|
|
1700 |
|
/* Skip the block. If the exp->cp does not point to the beginning of a |
1701 |
|
block ({ character), the function does nothing */ |
1702 |
|
void |
1703 |
|
_skip_block (struct line_expander *exp) |
1704 |
|
{ |
1705 |
|
int level = exp->level; |
1706 |
|
if (*exp->cp != '{') |
1707 |
|
return; |
1708 |
|
for (; *exp->cp; exp->cp++) |
1709 |
|
{ |
1710 |
|
switch (*exp->cp) |
1711 |
|
{ |
1712 |
|
case '{': |
1713 |
|
exp->level++; |
1714 |
|
break; |
1715 |
|
|
1716 |
|
case '}': |
1717 |
|
exp->level--; |
1718 |
|
if (exp->level == level) |
1719 |
|
{ |
1720 |
|
exp->cp++; |
1721 |
|
return; |
1722 |
|
} |
1723 |
|
} |
1724 |
|
} |
1725 |
|
} |
1726 |
|
|
1727 |
|
/* Expand a block within the formatted line. Stops either when end of source |
1728 |
|
line was reached or the nesting reaches the initial value */ |
1729 |
|
void |
1730 |
|
_expand_block (struct line_expander *exp) |
1731 |
|
{ |
1732 |
|
int level = exp->level; |
1733 |
|
if (*exp->cp == '{') |
1734 |
|
{ |
1735 |
|
exp->level++; |
1736 |
|
exp->cp++;/*FIXME?*/ |
1737 |
|
} |
1738 |
|
while (exp->state == EXP_STATE_CONTINUE) |
1739 |
|
{ |
1740 |
|
for (; *exp->cp && *exp->cp != '%'; exp->cp++) |
1741 |
|
{ |
1742 |
|
switch (*exp->cp) |
1743 |
|
{ |
1744 |
|
case '{': |
1745 |
|
exp->level++; |
1746 |
|
break; |
1747 |
|
|
1748 |
|
case '}': |
1749 |
|
exp->level--; |
1750 |
|
if (exp->level == level) |
1751 |
|
{ |
1752 |
|
exp->cp++; |
1753 |
|
return; |
1754 |
|
} |
1755 |
|
break; |
1756 |
|
|
1757 |
|
case '\\': |
1758 |
|
exp->cp++; |
1759 |
|
break; |
1760 |
|
} |
1761 |
|
obstack_1grow (&exp->stk, *exp->cp); |
1762 |
|
} |
1763 |
|
|
1764 |
|
if (*exp->cp == 0) |
1765 |
|
{ |
1766 |
|
obstack_1grow (&exp->stk, 0); |
1767 |
|
exp->state = EXP_STATE_SUCCESS; |
1768 |
|
break; |
1769 |
|
} |
1770 |
|
else if (*exp->cp == '%' && exp->cp[1] == '%') |
1771 |
|
{ |
1772 |
|
obstack_1grow (&exp->stk, *exp->cp); |
1773 |
|
exp->cp += 2; |
1774 |
|
continue; |
1775 |
|
} |
1776 |
|
|
1777 |
|
_expand_cond (exp); |
1778 |
|
} |
1779 |
|
} |
1780 |
|
|
1781 |
|
/* Expand a format line */ |
1782 |
|
char * |
1783 |
|
expand_line (const char *line) |
1784 |
|
{ |
1785 |
|
char *p = NULL; |
1786 |
|
struct line_expander exp; |
1787 |
|
|
1788 |
|
exp.state = EXP_STATE_CONTINUE; |
1789 |
|
exp.level = 0; |
1790 |
|
exp.source = line; |
1791 |
|
exp.cp = line; |
1792 |
|
obstack_init (&exp.stk); |
1793 |
|
_expand_block (&exp); |
1794 |
|
if (exp.state == EXP_STATE_SUCCESS) |
1795 |
|
p = xstrdup (obstack_finish (&exp.stk)); |
1796 |
|
else |
1797 |
|
{ |
1798 |
|
syslog (LOG_ERR, "can't expand line: %s", line); |
1799 |
|
syslog (LOG_ERR, "stopped near %s", exp.cp ? exp.cp : "(END)"); |
1800 |
|
} |
1801 |
|
obstack_free (&exp.stk, NULL); |
1802 |
|
return p; |
1803 |
|
} |
1804 |
|
|