parse3tuple.cxx
上传用户:sy_wanhua
上传日期:2013-07-25
资源大小:3048k
文件大小:16k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

C/C++

  1. /* ====================================================================
  2.  * The Vovida Software License, Version 1.0 
  3.  * 
  4.  * Copyright (c) 2000 Vovida Networks, Inc.  All rights reserved.
  5.  * 
  6.  * Redistribution and use in source and binary forms, with or without
  7.  * modification, are permitted provided that the following conditions
  8.  * are met:
  9.  * 
  10.  * 1. Redistributions of source code must retain the above copyright
  11.  *    notice, this list of conditions and the following disclaimer.
  12.  * 
  13.  * 2. Redistributions in binary form must reproduce the above copyright
  14.  *    notice, this list of conditions and the following disclaimer in
  15.  *    the documentation and/or other materials provided with the
  16.  *    distribution.
  17.  * 
  18.  * 3. The names "VOCAL", "Vovida Open Communication Application Library",
  19.  *    and "Vovida Open Communication Application Library (VOCAL)" must
  20.  *    not be used to endorse or promote products derived from this
  21.  *    software without prior written permission. For written
  22.  *    permission, please contact vocal@vovida.org.
  23.  *
  24.  * 4. Products derived from this software may not be called "VOCAL", nor
  25.  *    may "VOCAL" appear in their name, without prior written
  26.  *    permission of Vovida Networks, Inc.
  27.  * 
  28.  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
  29.  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  30.  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
  31.  * NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL VOVIDA
  32.  * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
  33.  * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
  34.  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  35.  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  36.  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
  37.  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  38.  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
  39.  * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
  40.  * DAMAGE.
  41.  * 
  42.  * ====================================================================
  43.  * 
  44.  * This software consists of voluntary contributions made by Vovida
  45.  * Networks, Inc. and many individuals on behalf of Vovida Networks,
  46.  * Inc.  For more information on Vovida Networks, Inc., please see
  47.  * <http://www.vovida.org/>.
  48.  *
  49.  */
  50. static const char* const parse3tuple_cxx_Version =
  51.     "$Id: parse3tuple.cxx,v 1.2 2001/05/17 22:10:25 chok Exp $";
  52. #include <stdio.h>
  53. #include <cassert>
  54. #include <cstring>
  55. #include "global.h"
  56. #include "parse3tuple.h"
  57. #include "cpLog.h"
  58. /* if you use LDAP you need to link with -lldap -llber */
  59. //#define USE_LDAP
  60. /* if you use XML you need to link with -lxml -lz */
  61. //#define USE_XML
  62. #ifdef USE_LDAP
  63. #include <lber.h>
  64. #include <ldap.h>
  65. #endif
  66. #ifdef USE_XML
  67. #include <gnome-xml/parser.h>
  68. #endif
  69. bool parse3tupleFile (char* fname, void (*parse) (char*, char*, char*));
  70. bool parse3tupleLDAP (char* fname, void (*parse) (char*, char*, char*));
  71. bool parse3tupleXML (char* fname, void (*parse) (char*, char*, char*));
  72. /*
  73.  * Parse some configuration data
  74.  *    if the name ends .xml is assumed to be an XML file 
  75.  *    if the name begins in ldap: it is assumed to be a LDAP url
  76.  *    otherwise it is assumed to be a text file with 3tuples
  77.  */
  78. bool
  79. parse3tuple (char* fname, void (*parse) (char*, char*, char*))
  80. {
  81.     static const char ldap[] = "ldap:";
  82.     static const char xml[] = ".xml";
  83.     bool ret = false;
  84.     if ( !strncmp(fname, ldap, strlen(ldap) ) )
  85.     {
  86.         // it's an LDAP url
  87.         ret = parse3tupleLDAP(fname, parse);
  88.     }
  89.     else if ( strlen(fname) > 4 ? !strncmp(fname + strlen(fname) - strlen(xml), xml, strlen(xml)) : false )
  90.     {
  91.         // it's an XML url
  92.         ret = parse3tupleXML(fname, parse);
  93.     }
  94.     else
  95.     {
  96.         // assume it's a 3tuple file name
  97.         ret = parse3tupleFile(fname, parse);
  98.     }
  99.     return ret;
  100. }
  101. /*
  102.  * This function loads configuration out of a XML file. 
  103.  *
  104.  * The DTD for the file is 
  105.  *      <!ELEMENT config (item)* >
  106.  *      <!ELEMENT item (tag,type,value)>
  107.  *      <!ELEMENT tag (#PCDATA)>
  108.  *      <!ELEMENT type (#PCDATA)>
  109.  *      <!ELEMENT value (#PCDATA)>
  110.  *
  111.  * An example config file would might look like 
  112.  *      <?xml version = "1.0" ?>
  113.  *      <!DOCTYPE config SYSTEM "config.dtd">
  114.  *      <!-- <?xml-stylesheet type="text/xsl" href="test.xsl"?> -->
  115.  *      
  116.  *      <configuration>
  117.  *      
  118.  *      <item>
  119.  *         <tag> myTag1 </tag>
  120.  *         <type> myType1 </type>
  121.  *         <value> myValue1 </value>
  122.  *      </item>
  123.  *      
  124.  *      <item>
  125.  *         <tag> myTag2 </tag>
  126.  *         <type> myType2 </type>
  127.  *         <value> myValue2 </value>
  128.  *      </item>
  129.  *      
  130.  *      </configuration>
  131.  *
  132.  * An xml file that would allow this xml file to be vied in IE 5 is 
  133.  *      <?xml version = "1.0" ?>
  134.  *      <xsl:stylesheet xmlns:xsl="http://www.w3.org/TR/WD-xsl">
  135.  *      
  136.  *      <xsl:template match="/">
  137.  *      <HTML>
  138.  *      <BODY>
  139.  *      
  140.  *      <xsl:for-each select="configuration/item">
  141.  *      
  142.  *      <xsl:value-of select="tag"/> 
  143.  *      <xsl:value-of select="type"/> 
  144.  *      <xsl:value-of select="value"/> 
  145.  *      <BR/>
  146.  *      
  147.  *      </xsl:for-each>
  148.  *      
  149.  *      </BODY>
  150.  *      </HTML>
  151.  *      </xsl:template>
  152.  *      </xsl:stylesheet>
  153.  */
  154. bool
  155. parse3tupleXML (char* fname, void (*parse) (char*, char*, char*))
  156. {
  157. #ifdef USE_XML // define if XML is supported
  158.     xmlDocPtr doc = NULL;
  159.     doc = xmlParseFile(fname);
  160.     if (!doc)
  161.     {
  162.         cpLog (LOG_ERR, "Cannot process XML file: %s", fname);
  163.         return false;
  164.     }
  165.     xmlNodePtr cur = doc->root;
  166.     assert( cur );
  167.     while ( strcmp( reinterpret_cast < const char * > (cur->name)
  168.                     , "configuration" ) )
  169.     {
  170.         cur = cur->next;
  171.         if ( cur == NULL )
  172.         {
  173.             cpLog (LOG_ERR, "no configuration section in XML file: %s", fname);
  174.             return false;
  175.         }
  176.     }
  177.     assert( cur );
  178.     // step into the configuration data
  179.     cur = cur->childs;
  180.     while (cur != NULL)
  181.     {
  182.         assert( !strcmp( reinterpret_cast < const char * > (cur->name), "item") );
  183.         char tag [TAG_MAX_LENGTH];
  184.         char type [TYPE_MAX_LENGTH];
  185.         char* value;
  186.         xmlNodePtr ptr = cur->childs;
  187.         assert( ptr);
  188.         assert( !strcmp( reinterpret_cast < const char * > (ptr->name), "tag") );
  189.         strncpy( tag ,
  190.                  reinterpret_cast < const char * > (xmlNodeListGetString(doc, ptr->childs, 1)),
  191.                  TAG_MAX_LENGTH );
  192.         ptr = ptr->next;
  193.         assert( ptr);
  194.         assert( !strcmp( reinterpret_cast < const char * > (ptr->name), "type") );
  195.         strncpy( type ,
  196.                  reinterpret_cast < const char * > (xmlNodeListGetString(doc, ptr->childs, 1)),
  197.                  TYPE_MAX_LENGTH );
  198.         ptr = ptr->next;
  199.         assert( ptr);
  200.         assert( !strcmp( reinterpret_cast < const char * > (ptr->name), "value") );
  201.         // make a copy just to be sure no one trashed the main data structure
  202.         value = const_cast < char* > (
  203.                     reinterpret_cast < const char * > (
  204.                         xmlNodeListGetString(doc, ptr->childs, 1)));
  205.         assert(value);
  206.         // call the parse function with the 3 tuple
  207.         (*parse) (tag, type, value);
  208.         // move to next item
  209.         cur = cur->next;
  210.     }
  211. #else
  212.     cpLog (LOG_ERR, "No suuport for XML file: %s", fname);
  213.     return false;
  214. #endif
  215.     return true;
  216. }
  217. /**
  218.  *  This functions parses a 3 tuple objects out of the LDAP 
  219.  *
  220.  *  The passed in url must confom to rfc1959. A example might be
  221.  *     "ldap://localhost/dc=vovida,dc=com"
  222.  * 
  223.  *  You can view the data base from netscape with the url
  224.  *      ldap://localhost/dc=vovida,dc=com?tag,type,value?one?objectclass=3tuple
  225.  *
  226.  *  The ldif for a tuple should look something like
  227.  *     dn: cn=myTag2, dc=vovida, dc=com
  228.  *     cn: myTag2
  229.  *     tag: theTageName
  230.  *     type: someTypeLike_String
  231.  *     value: someValueLike_4
  232.  *     objectclass: 3tuple
  233.  *
  234.  *  This could be added with something like 
  235.  *     ldapadd -D "cn=root,dc=vovida,dc=com" -v -w secret < foobar.ldif
  236.  * 
  237.  *   Note is must have the objectclass of 3tuple
  238.  *
  239.  */
  240. bool
  241. parse3tupleLDAP (char* url, void (*parse) (char*, char*, char*))
  242. {
  243. #ifdef USE_LDAP // define if LDAP is supported
  244.     if ( !ldap_is_ldap_url(url))
  245.     {
  246.         cpLog (LOG_ERR, "Bad LDAP URL: %s", url);
  247.         return false;
  248.     }
  249.     LDAPURLDesc* ldapUrl = NULL;
  250.     int err;
  251.     err = ldap_url_parse( url, &ldapUrl );
  252.     if ( err )
  253.     {
  254.         switch (err)
  255.         {
  256.             case LDAP_URL_ERR_NOTLDAP:
  257.             {
  258.                 cpLog (LOG_ERR, "Bad LDAP URL: %s ", url);
  259.                 return false;
  260.             }
  261.             break;
  262.             case LDAP_URL_ERR_NODN:
  263.             {
  264.                 cpLog (LOG_ERR, "Bad LDAP URL - no DN: %s ", url);
  265.                 return false;
  266.             }
  267.             break;
  268.             case LDAP_URL_ERR_BADSCOPE:
  269.             {
  270.                 cpLog (LOG_ERR, "Bad LDAP URL - bad scope : error %s ", url);
  271.                 return false;
  272.             }
  273.             break;
  274.             case LDAP_URL_ERR_MEM:
  275.             {
  276.                 cpLog (LOG_ERR, "Bad LDAP URL: error %d ", err);
  277.                 return false;
  278.             }
  279.             break;
  280.             default:
  281.             {
  282.                 cpLog (LOG_ERR, "Bad LDAP URL: error %d ", err);
  283.                 return false;
  284.             }
  285.         }
  286.     }
  287.     cpLog (LOG_DEBUG, "LDAP host: %s", ldapUrl->lud_host );
  288.     cpLog (LOG_DEBUG, "LDAP port: %d", ldapUrl->lud_port );
  289.     char* host = ldapUrl->lud_host;
  290.     int port = ldapUrl->lud_port;
  291.     if ( port == 0 )
  292.     {
  293.         port = LDAP_PORT;
  294.     }
  295.     LDAP *ld = NULL;
  296.     ld = ldap_init(host, port);
  297.     if (!ld)
  298.     {
  299.         assert(0);
  300.         return false;
  301.     }
  302.     char* who = "";  // set this to the DN of the object you have a passwd for
  303.     char* passwd = "";  // set this to the passwd
  304.     err = ldap_simple_bind_s(ld, who, passwd);
  305.     if ( err )
  306.     {
  307.         cpLog (LOG_ERR, "LDAP problem in simple bind  %s ", ldap_err2string(err));
  308.         return false;
  309.     }
  310.     cpLog (LOG_DEBUG, "LDAP dn: %s", ldapUrl->lud_dn );
  311.     cpLog (LOG_DEBUG, "LDAP scope: %d", ldapUrl->lud_scope );
  312.     cpLog (LOG_DEBUG, "LDAP filter: %s", ldapUrl->lud_filter );
  313.     if ( ldapUrl->lud_attrs )
  314.     {
  315.         cpLog (LOG_DEBUG, "LDAP attr[0]: %s", ldapUrl->lud_attrs[0] );
  316.     }
  317.     char *base = ldapUrl->lud_dn;
  318.     int scope = LDAP_SCOPE_ONELEVEL;  //ldapUrl->lud_scope ;
  319.     char *filter = "objectclass=3tuple";  // ldapUrl->lud_filter;
  320.     char *attrs[4];
  321.     attrs[0] = "tag";
  322.     attrs[1] = "type";
  323.     attrs[2] = "value";
  324.     attrs[3] = NULL;
  325.     int attrsonly = 0 ;
  326.     LDAPMessage *res;
  327.     err = ldap_search_s(ld, base, scope, filter, attrs, attrsonly, &res);
  328.     if ( err )
  329.     {
  330.         cpLog (LOG_ERR, "LDAP problem in search %s ", ldap_err2string(err));
  331.         return false;
  332.     }
  333.     int count = ldap_count_entries(ld, res);
  334.     cpLog (LOG_DEBUG, "LDAP search return %d entries", count );
  335.     for ( LDAPMessage* msg = ldap_first_entry(ld, res);
  336.             msg != NULL;
  337.             msg = ldap_next_entry(ld, msg) )
  338.     {
  339.         cpLog (LOG_DEBUG, "LDAP got messg ");
  340.         if ( msg )
  341.         {
  342.             BerElement* ber = NULL;
  343.             /*
  344.              * This bit of code is good to fine all the attributes types
  345.              * 
  346.              *  char * attr = ldap_first_attribute(ld,msg,&ber);
  347.              *  while ( attr != NULL )
  348.              *  {
  349.              *     cpLog (LOG_DEBUG, "LDAP attr=%s",attr);
  350.              *     attr=ldap_next_attribute(ld,msg,ber);
  351.              *  }
  352.              *  ber = NULL;
  353.              *
  354.              */
  355.             char **data;
  356.             char tag [TAG_MAX_LENGTH];
  357.             char type [TYPE_MAX_LENGTH];
  358.             // get the tag  ----------------------
  359.             data = ldap_get_values(ld, msg, "tag");
  360.             if ( data == NULL )
  361.             {
  362.                 cpLog (LOG_ERR, "LDAP in tag data %s ",
  363.                        ldap_err2string(ld->ld_errno));
  364.                 return false;
  365.             }
  366.             assert( data[0] );
  367.             cpLog (LOG_DEBUG, "LDAP tag=%s", data[0] );
  368.             strncpy( tag , data[0], TAG_MAX_LENGTH );
  369.             // get the type -----------------------
  370.             data = ldap_get_values(ld, msg, "type");
  371.             if ( data == NULL )
  372.             {
  373.                 cpLog (LOG_ERR, "LDAP in type data %s ",
  374.                        ldap_err2string(ld->ld_errno));
  375.                 return false;
  376.             }
  377.             assert( data[0] );
  378.             cpLog (LOG_DEBUG, "LDAP type=%s", data[0] );
  379.             strncpy( type , data[0], TYPE_MAX_LENGTH );
  380.             // get the value ---------------------
  381.             data = ldap_get_values(ld, msg, "value");
  382.             if ( data == NULL )
  383.             {
  384.                 cpLog (LOG_ERR, "LDAP in value data %s ",
  385.                        ldap_err2string(ld->ld_errno));
  386.                 return false;
  387.             }
  388.             assert( data[0] );
  389.             cpLog (LOG_DEBUG, "LDAP value=%s", data[0] );
  390.             // call the parse function with the 3 tuple
  391.             (*parse) (tag, type, data[0]);
  392.         }
  393.     }
  394.     err = ldap_msgfree(res);
  395.     if ( err == -1 )
  396.     {
  397.         cpLog (LOG_ERR, "LDAP problem in msgfree ");
  398.         return false;
  399.     }
  400.     res = NULL;
  401.     err = ldap_unbind_s(ld);
  402.     if ( err )
  403.     {
  404.         cpLog (LOG_ERR, "LDAP problem in unbind %s ", ldap_err2string(err));
  405.         return false;
  406.     }
  407.     ld = NULL;
  408.     ldap_free_urldesc( ldapUrl );
  409.     ldapUrl = NULL;
  410. #else
  411.     cpLog (LOG_ERR, "No support for LDAP data: %s", url);
  412.     return false;
  413. #endif
  414.     return true;
  415. }
  416. /*
  417.  * parse3tuple() parses file fname line by line. Each line is expected
  418.  * to have 3 fields, <tag>-<type>-<value>, separated by blanks or tabs.
  419.  * Lines starting with '#' are comments. Empty lines are ignored.
  420.  * The value field contains a number of characters, even field separators
  421.  * like blanks and tabs, up to the end of the line.
  422.  * User of this utility provides a call back function with 3 arguments
  423.  * (pointers to the tag, type and value strings) to validate and use the
  424.  * data.
  425.  */
  426. bool
  427. parse3tuple (const char* fname, void (*parse) (char*, char*, char*))
  428. {
  429.     return parse3tupleFile (const_cast < char* > (fname), parse);
  430. }
  431. void
  432. removeTrailingBlanks( char* line )
  433. {
  434.     for ( int i = strlen( line ) - 1; i > 0; i-- )
  435.     {
  436.         if ( line[i] == ' ' || line[i] == 't' )
  437.         {
  438.             line[i] = '';
  439.         }
  440.         else
  441.         {
  442.             return ;
  443.         }
  444.     }
  445. }
  446. bool
  447. parse3tupleFile (char* fname, void (*parse) (char*, char*, char*))
  448. {
  449.     char line [TUPLE3_MAX_LENGTH];
  450.     char tag [TAG_MAX_LENGTH];
  451.     char type [TYPE_MAX_LENGTH];
  452.     int lineCnt;
  453.     int lineLen = 0;
  454.     int argCnt;
  455.     int valuePos = 0;
  456.     FILE* fd = fopen (fname , "r");
  457.     if (fd)
  458.     {
  459.         for (lineCnt = 1; fgets (line, TUPLE3_MAX_LENGTH, fd); lineCnt++, valuePos = 0)
  460.         {
  461.             lineLen = strlen(line);
  462.             assert( lineLen > 0 );
  463.             line [lineLen - 1] = 0;    /* remove n */
  464.             if (lineLen > 1)
  465.             {
  466.                 if (line [lineLen - 2] == 'r')
  467.                 {
  468.                     line [lineLen - 2] = 0;    /* remove r too */
  469.                 }
  470.             }
  471.             removeTrailingBlanks( line );
  472.             if ((argCnt = sscanf (line, "%s%s%*[ t]%n", tag, type, &valuePos)) == 2)
  473.             {
  474.                 if (line[0] != '#')
  475.                 {
  476.                     if (valuePos == 0)
  477.                     {
  478.                         cpLog (LOG_WARNING,
  479.                                "Line %d has too few arguments: %s",
  480.                                lineCnt,
  481.                                line);
  482.                     }
  483.                     else
  484.                     {
  485.                         (*parse) (tag, type, line + valuePos);
  486.                     }
  487.                 }
  488.             }
  489.             else
  490.             {
  491.                 if (argCnt == 1 && line[0] != '#')
  492.                 {
  493.                     cpLog (LOG_WARNING,
  494.                            "Line %d has too few arguments: %s",
  495.                            lineCnt,
  496.                            line);
  497.                 }
  498.             }
  499.         }
  500.         fclose (fd);
  501.     }
  502.     else
  503.     {
  504.         cpLog (LOG_ERR, "Cannot open file: %s", fname);
  505.         return false;
  506.     }
  507.     return true;
  508. }    /* parse3tuple */
  509. int
  510. strConst2i (const char* str, const char* strTable[], const int tableSize)
  511. {
  512.     int i;
  513.     for (i = 0; i < tableSize; i++)
  514.     {
  515.         if (strcmp (str, strTable [i]) == 0)
  516.         {
  517.             break;
  518.         }
  519.     }
  520.     return i;
  521. }    // strConst2i