~ubuntu-branches/ubuntu/oneiric/openvpn/oneiric

« back to all changes in this revision

Viewing changes to misc.c

  • Committer: Bazaar Package Importer
  • Author(s): Thierry Carrez
  • Date: 2008-10-07 16:30:44 UTC
  • mfrom: (1.1.11 upstream) (10.1.1 lenny)
  • Revision ID: james.westby@ubuntu.com-20081007163044-ixx04wg588z1972e
Tags: 2.1~rc11-1ubuntu1
* Merge with Debian (LP: #279655), remaining diffs:
  - debian/openvpn.init.d: Added 'status' action to init script, show
    per-VPN result messages and add "--script-security 2" by default for
    backwards compatibility
  - debian/control: Added lsb-base>=3.2-14 depend to allow status_of_proc()
* Fixes regression when calling commands with arguments (LP: #277447)

Show diffs side-by-side

added added

removed removed

Lines of Context:
220
220
      ASSERT (arg);
221
221
      setenv_str (es, "script_type", script_type);
222
222
      argv_printf (&argv,
223
 
                  "%s %s %d %d %s %s %s",
 
223
                  "%sc %s %d %d %s %s %s",
224
224
                  command,
225
225
                  arg,
226
226
                  tun_mtu, link_mtu,
1190
1190
    return false;
1191
1191
}
1192
1192
 
1193
 
/*
1194
 
 * Return the next largest power of 2
1195
 
 * or u if u is a power of 2.
1196
 
 */
1197
 
unsigned int
1198
 
adjust_power_of_2 (unsigned int u)
1199
 
{
1200
 
  unsigned int ret = 1;
1201
 
 
1202
 
  while (ret < u)
1203
 
    {
1204
 
      ret <<= 1;
1205
 
      ASSERT (ret > 0);
1206
 
    }
1207
 
 
1208
 
  return ret;
1209
 
}
1210
 
 
1211
1193
#ifdef HAVE_GETPASS
1212
1194
 
1213
1195
static FILE *
1666
1648
  sleep (n);
1667
1649
}
1668
1650
 
1669
 
#if 0
1670
 
/*
1671
 
 * Configure PATH.  On Windows, sometimes PATH is not set correctly
1672
 
 * by default.
1673
 
 */
1674
 
void
1675
 
configure_path (void)
1676
 
{
1677
 
#ifdef WIN32
1678
 
  FILE *fp;
1679
 
  fp = fopen ("c:\\windows\\system32\\route.exe", "rb");
1680
 
  if (fp)
1681
 
    {
1682
 
      const int bufsiz = 4096;
1683
 
      struct gc_arena gc = gc_new ();
1684
 
      struct buffer oldpath = alloc_buf_gc (bufsiz, &gc);
1685
 
      struct buffer newpath = alloc_buf_gc (bufsiz, &gc);
1686
 
      const char* delim = ";";
1687
 
      DWORD status;
1688
 
      fclose (fp);
1689
 
      status = GetEnvironmentVariable ("PATH", BPTR(&oldpath), (DWORD)BCAP(&oldpath));
1690
 
#if 0
1691
 
      status = 0;
1692
 
#endif
1693
 
      if (!status)
1694
 
        {
1695
 
          *BPTR(&oldpath) = '\0';
1696
 
          delim = "";
1697
 
        }
1698
 
      buf_printf (&newpath, "C:\\WINDOWS\\System32;C:\\WINDOWS;C:\\WINDOWS\\System32\\Wbem%s%s",
1699
 
                  delim,
1700
 
                  BSTR(&oldpath));
1701
 
      SetEnvironmentVariable ("PATH", BSTR(&newpath));
1702
 
#if 0
1703
 
      status = GetEnvironmentVariable ("PATH", BPTR(&oldpath), (DWORD)BCAP(&oldpath));
1704
 
      if (status > 0)
1705
 
        printf ("PATH: %s\n", BSTR(&oldpath));
1706
 
#endif
1707
 
      gc_free (&gc);
1708
 
    }
1709
 
#endif
1710
 
}
1711
 
#endif
 
1651
/*
 
1652
 * Return the next largest power of 2
 
1653
 * or u if u is a power of 2.
 
1654
 */
 
1655
size_t
 
1656
adjust_power_of_2 (size_t u)
 
1657
{
 
1658
  size_t ret = 1;
 
1659
 
 
1660
  while (ret < u)
 
1661
    {
 
1662
      ret <<= 1;
 
1663
      ASSERT (ret > 0);
 
1664
    }
 
1665
 
 
1666
  return ret;
 
1667
}
 
1668
 
 
1669
/*
 
1670
 * A printf-like function (that only recognizes a subset of standard printf
 
1671
 * format operators) that prints arguments to an argv list instead
 
1672
 * of a standard string.  This is used to build up argv arrays for passing
 
1673
 * to execve.
 
1674
 */
 
1675
 
 
1676
void
 
1677
argv_init (struct argv *a)
 
1678
{
 
1679
  a->capacity = 0;
 
1680
  a->argc = 0;
 
1681
  a->argv = NULL;
 
1682
}
 
1683
 
 
1684
struct argv
 
1685
argv_new (void)
 
1686
{
 
1687
  struct argv ret;
 
1688
  argv_init (&ret);
 
1689
  return ret;
 
1690
}
 
1691
 
 
1692
void
 
1693
argv_reset (struct argv *a)
 
1694
{
 
1695
  size_t i;
 
1696
  for (i = 0; i < a->argc; ++i)
 
1697
    free (a->argv[i]);
 
1698
  free (a->argv);
 
1699
  argv_init (a);
 
1700
}
 
1701
 
 
1702
static void
 
1703
argv_extend (struct argv *a, const size_t newcap)
 
1704
{
 
1705
  if (newcap > a->capacity)
 
1706
    {
 
1707
      char **newargv;
 
1708
      size_t i;
 
1709
      ALLOC_ARRAY_CLEAR (newargv, char *, newcap);
 
1710
      for (i = 0; i < a->argc; ++i)
 
1711
        newargv[i] = a->argv[i];
 
1712
      free (a->argv);
 
1713
      a->argv = newargv;
 
1714
      a->capacity = newcap;
 
1715
    }
 
1716
}
 
1717
 
 
1718
static void
 
1719
argv_grow (struct argv *a, const size_t add)
 
1720
{
 
1721
  const size_t newargc = a->argc + add + 1;
 
1722
  ASSERT (newargc > a->argc);
 
1723
  argv_extend (a, adjust_power_of_2 (newargc));
 
1724
}
 
1725
 
 
1726
static void
 
1727
argv_append (struct argv *a, char *str) /* str must have been malloced or be NULL */
 
1728
{
 
1729
  argv_grow (a, 1);
 
1730
  a->argv[a->argc++] = str;
 
1731
}
 
1732
 
 
1733
struct argv
 
1734
argv_clone (const struct argv *a, const size_t headroom)
 
1735
{
 
1736
  struct argv r;
 
1737
  size_t i;
 
1738
 
 
1739
  argv_init (&r);
 
1740
  for (i = 0; i < headroom; ++i)
 
1741
    argv_append (&r, NULL);
 
1742
  if (a)
 
1743
    {
 
1744
      for (i = 0; i < a->argc; ++i)
 
1745
        argv_append (&r, string_alloc (a->argv[i], NULL));
 
1746
    }
 
1747
  return r;
 
1748
}
 
1749
 
 
1750
struct argv
 
1751
argv_insert_head (const struct argv *a, const char *head)
 
1752
{
 
1753
  struct argv r;
 
1754
 
 
1755
  r = argv_clone (a, 1);
 
1756
  r.argv[0] = string_alloc (head, NULL);
 
1757
 
 
1758
  return r;
 
1759
}
 
1760
 
 
1761
char *
 
1762
argv_term (const char **f)
 
1763
{
 
1764
  const char *p = *f;
 
1765
  const char *term = NULL;
 
1766
  size_t termlen = 0;
 
1767
 
 
1768
  if (*p == '\0')
 
1769
    return NULL;
 
1770
 
 
1771
  while (true)
 
1772
    {
 
1773
      const int c = *p;
 
1774
      if (c == '\0')
 
1775
        break;
 
1776
      if (term)
 
1777
        {
 
1778
          if (!isspace (c))
 
1779
            ++termlen;
 
1780
          else
 
1781
            break;
 
1782
        }
 
1783
      else
 
1784
        {
 
1785
          if (!isspace (c))
 
1786
            {
 
1787
              term = p;
 
1788
              termlen = 1;
 
1789
            }
 
1790
        }
 
1791
      ++p;
 
1792
    }
 
1793
  *f = p;
 
1794
 
 
1795
  if (term)
 
1796
    {
 
1797
      char *ret;
 
1798
      ASSERT (termlen > 0);
 
1799
      ret = malloc (termlen + 1);
 
1800
      check_malloc_return (ret);
 
1801
      memcpy (ret, term, termlen);
 
1802
      ret[termlen] = '\0';
 
1803
      return ret;
 
1804
    }
 
1805
  else
 
1806
    return NULL;
 
1807
}
 
1808
 
 
1809
const char *
 
1810
argv_str (const struct argv *a, struct gc_arena *gc, const unsigned int flags)
 
1811
{
 
1812
  if (a->argv)
 
1813
    return print_argv ((const char **)a->argv, gc, flags);
 
1814
  else
 
1815
    return "";
 
1816
}
 
1817
 
 
1818
void
 
1819
argv_msg (const int msglev, const struct argv *a)
 
1820
{
 
1821
  struct gc_arena gc = gc_new ();
 
1822
  msg (msglev, "%s", argv_str (a, &gc, 0));
 
1823
  gc_free (&gc);
 
1824
}
 
1825
 
 
1826
void
 
1827
argv_msg_prefix (const int msglev, const struct argv *a, const char *prefix)
 
1828
{
 
1829
  struct gc_arena gc = gc_new ();
 
1830
  msg (msglev, "%s: %s", prefix, argv_str (a, &gc, 0));
 
1831
  gc_free (&gc);
 
1832
}
 
1833
 
 
1834
void
 
1835
argv_printf (struct argv *a, const char *format, ...)
 
1836
{
 
1837
  va_list arglist;
 
1838
  va_start (arglist, format);
 
1839
  argv_printf_arglist (a, format, 0, arglist);
 
1840
  va_end (arglist);
 
1841
 }
 
1842
 
 
1843
void
 
1844
argv_printf_cat (struct argv *a, const char *format, ...)
 
1845
{
 
1846
  va_list arglist;
 
1847
  va_start (arglist, format);
 
1848
  argv_printf_arglist (a, format, APA_CAT, arglist);
 
1849
  va_end (arglist);
 
1850
}
 
1851
 
 
1852
void
 
1853
argv_printf_arglist (struct argv *a, const char *format, const unsigned int flags, va_list arglist)
 
1854
{
 
1855
  struct gc_arena gc = gc_new ();
 
1856
  char *term;
 
1857
  const char *f = format;
 
1858
 
 
1859
  if (!(flags & APA_CAT))
 
1860
    argv_reset (a);
 
1861
  argv_extend (a, 1); /* ensure trailing NULL */
 
1862
 
 
1863
  while ((term = argv_term (&f)) != NULL) 
 
1864
    {
 
1865
      if (term[0] == '%')
 
1866
        {
 
1867
          if (!strcmp (term, "%s"))
 
1868
            {
 
1869
              char *s = va_arg (arglist, char *);
 
1870
              if (!s)
 
1871
                s = "";
 
1872
              argv_append (a, string_alloc (s, NULL));
 
1873
            }
 
1874
          else if (!strcmp (term, "%sc"))
 
1875
            {
 
1876
              char *s = va_arg (arglist, char *);
 
1877
              if (s)
 
1878
                {
 
1879
                  int nparms;
 
1880
                  char *parms[MAX_PARMS+1];
 
1881
                  int i;
 
1882
 
 
1883
                  nparms = parse_line (s, parms, MAX_PARMS, "SCRIPT-ARGV", 0, M_FATAL, &gc);
 
1884
                  for (i = 0; i < nparms; ++i)
 
1885
                    argv_append (a, string_alloc (parms[i], NULL));
 
1886
                }
 
1887
              else
 
1888
                argv_append (a, string_alloc ("", NULL));
 
1889
            }
 
1890
          else if (!strcmp (term, "%d"))
 
1891
            {
 
1892
              char numstr[64];
 
1893
              openvpn_snprintf (numstr, sizeof (numstr), "%d", va_arg (arglist, int));
 
1894
              argv_append (a, string_alloc (numstr, NULL));
 
1895
            }
 
1896
          else if (!strcmp (term, "%u"))
 
1897
            {
 
1898
              char numstr[64];
 
1899
              openvpn_snprintf (numstr, sizeof (numstr), "%u", va_arg (arglist, unsigned int));
 
1900
              argv_append (a, string_alloc (numstr, NULL));
 
1901
            }
 
1902
          else if (!strcmp (term, "%s/%d"))
 
1903
            {
 
1904
              char numstr[64];
 
1905
              char *s = va_arg (arglist, char *);
 
1906
 
 
1907
              if (!s)
 
1908
                s = "";
 
1909
 
 
1910
              openvpn_snprintf (numstr, sizeof (numstr), "%d", va_arg (arglist, int));
 
1911
 
 
1912
              {
 
1913
                const size_t len = strlen(s) + strlen(numstr) + 2;
 
1914
                char *combined = (char *) malloc (len);
 
1915
                check_malloc_return (combined);
 
1916
 
 
1917
                strcpy (combined, s);
 
1918
                strcat (combined, "/");
 
1919
                strcat (combined, numstr);
 
1920
                argv_append (a, combined);
 
1921
              }
 
1922
            }
 
1923
          else if (!strcmp (term, "%s%s"))
 
1924
            {
 
1925
              char *s1 = va_arg (arglist, char *);
 
1926
              char *s2 = va_arg (arglist, char *);
 
1927
              char *combined;
 
1928
 
 
1929
              if (!s1) s1 = "";
 
1930
              if (!s2) s2 = "";
 
1931
              combined = (char *) malloc (strlen(s1) + strlen(s2) + 1);
 
1932
              check_malloc_return (combined);
 
1933
              strcpy (combined, s1);
 
1934
              strcat (combined, s2);
 
1935
              argv_append (a, combined);
 
1936
            }
 
1937
          else
 
1938
            ASSERT (0);
 
1939
          free (term);
 
1940
        }
 
1941
      else
 
1942
        {
 
1943
          argv_append (a, term);
 
1944
        }
 
1945
    }
 
1946
  gc_free (&gc);
 
1947
}
1712
1948
 
1713
1949
#ifdef ARGV_TEST
1714
1950
void
1715
1951
argv_test (void)
1716
1952
{
1717
1953
  struct gc_arena gc = gc_new ();
1718
 
  char line[512];
1719
1954
  const char *s;
1720
1955
 
1721
1956
  struct argv a;
1729
1964
#endif
1730
1965
 
1731
1966
  argv_msg_prefix (M_INFO, &a, "ARGV");
1732
 
  openvpn_execve_check (&a, NULL, 0, "command failed");
 
1967
  //openvpn_execve_check (&a, NULL, 0, "command failed");
1733
1968
 
1734
1969
  argv_printf (&a, "this is a %s test of int %d unsigned %u", "FOO", -69, 42);
1735
1970
  s = argv_str (&a, &gc, PA_BRACKET);
1742
1977
    printf ("%s\n", s);
1743
1978
  }
1744
1979
 
1745
 
  argv_printf (&a, "foo bar %d", 99);
1746
 
  s = argv_str (&a, &gc, PA_BRACKET);
1747
 
  argv_reset (&a);
1748
 
  printf ("%s\n", s);
1749
 
 
1750
 
  s = argv_str (&a, &gc, PA_BRACKET);
1751
 
  argv_reset (&a);
1752
 
  printf ("%s\n", s);
1753
 
 
1754
 
  argv_printf (&a, "foo bar %d", 99);
1755
 
  argv_printf_cat (&a, "bar %d foo", 42);
 
1980
  argv_printf (&a, "%sc foo bar %d", "\"multi term\" command      following \\\"spaces", 99);
 
1981
  s = argv_str (&a, &gc, PA_BRACKET);
 
1982
  argv_reset (&a);
 
1983
  printf ("%s\n", s);
 
1984
 
 
1985
  s = argv_str (&a, &gc, PA_BRACKET);
 
1986
  argv_reset (&a);
 
1987
  printf ("%s\n", s);
 
1988
 
 
1989
  argv_printf (&a, "foo bar %d", 99);
 
1990
  argv_printf_cat (&a, "bar %d foo %sc", 42, "nonesuch");
1756
1991
  argv_printf_cat (&a, "cool %s %d u %s/%d end", "frood", 4, "hello", 7);
1757
1992
  s = argv_str (&a, &gc, PA_BRACKET);
1758
1993
  printf ("%s\n", s);
1759
1994
 
1760
1995
#if 0
1761
 
  while (fgets (line, sizeof(line), stdin) != NULL)
1762
 
    {
1763
 
      char *term;
1764
 
      const char *f = line;
1765
 
      int i = 0;
 
1996
  {
 
1997
    char line[512];
 
1998
    while (fgets (line, sizeof(line), stdin) != NULL)
 
1999
      {
 
2000
        char *term;
 
2001
        const char *f = line;
 
2002
        int i = 0;
1766
2003
 
1767
 
      while ((term = argv_term (&f)) != NULL) 
1768
 
        {
1769
 
          printf ("[%d] '%s'\n", i, term);
1770
 
          ++i;
1771
 
          free (term);
1772
 
        }
1773
 
    }
 
2004
        while ((term = argv_term (&f)) != NULL) 
 
2005
          {
 
2006
            printf ("[%d] '%s'\n", i, term);
 
2007
            ++i;
 
2008
            free (term);
 
2009
          }
 
2010
      }
 
2011
  }
1774
2012
#endif
1775
2013
 
1776
2014
  argv_reset (&a);