/[inetutils]/inetutils/telnetd/utility.c
ViewVC logotype

Diff of /inetutils/telnetd/utility.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.9 by gray, Fri Apr 5 00:02:43 2002 UTC revision 1.10 by gray, Sun Apr 7 14:32:33 2002 UTC
# Line 22  Line 22 
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>
# Line 149  io_setup () Line 148  io_setup ()
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
# Line 329  pty_get_char (int peek) Line 329  pty_get_char (int peek)
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);
# Line 1537  telnet_spin() Line 1546  telnet_spin()
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          

Legend:
Removed from v.1.9  
changed lines
  Added in v.1.10

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26