Beispiel #1
0
String f_exec(const String& command, VRefParam output /* = null */,
              VRefParam return_var /* = null */) {
  ShellExecContext ctx;
  FILE *fp = ctx.exec(command.c_str());
  if (!fp) return "";
  StringBuffer sbuf;
  sbuf.read(fp);

  Array lines = StringUtil::Explode(sbuf.detach(), "\n").toArray();
  int ret = ctx.exit();
  if (WIFEXITED(ret)) ret = WEXITSTATUS(ret);
  return_var = ret;
  int count = lines.size();
  if (count > 0 && lines[count - 1].toString().empty()) {
    count--; // remove explode()'s last empty line
  }
  if (!output.is(KindOfArray)) {
    output = Array(ArrayData::Create());
  }

  for (int i = 0; i < count; i++) {
    output.append(lines[i]);
  }

  if (!count || lines.empty()) {
    return String();
  }

  return f_rtrim(lines[count - 1].toString());
}
bool f_dns_get_mx(CStrRef hostname, VRefParam mxhosts,
                  VRefParam weights /* = null */) {
    IOStatusHelper io("dns_get_mx", hostname.data());
    int count, qdc;
    unsigned short type, weight;
    unsigned char ans[MAXPACKET];
    char buf[MAXHOSTNAMELEN];
    unsigned char *cp, *end;

    mxhosts = Array::Create();
    weights = Array::Create();

    /* Go! */
    struct __res_state *res;
    res = ResolverInit::s_res.get()->getResolver();
    if (res == NULL) {
        return false;
    }

    int i = res_nsearch(res, hostname.data(), C_IN, DNS_T_MX,
                        (unsigned char*)&ans, sizeof(ans));
    if (i < 0) {
        res_nclose(res);
        php_dns_free_res(res);
        return false;
    }
    if (i > (int)sizeof(ans)) {
        i = sizeof(ans);
    }
    HEADER *hp = (HEADER *)&ans;
    cp = (unsigned char *)&ans + HFIXEDSZ;
    end = (unsigned char *)&ans +i;
    for (qdc = ntohs((unsigned short)hp->qdcount); qdc--; cp += i + QFIXEDSZ) {
        if ((i = dn_skipname(cp, end)) < 0 ) {
            res_nclose(res);
            php_dns_free_res(res);
            return false;
        }
    }
    count = ntohs((unsigned short)hp->ancount);
    while (--count >= 0 && cp < end) {
        if ((i = dn_skipname(cp, end)) < 0 ) {
            res_nclose(res);
            php_dns_free_res(res);
            return false;
        }
        cp += i;
        GETSHORT(type, cp);
        cp += INT16SZ + INT32SZ;
        GETSHORT(i, cp);
        if (type != DNS_T_MX) {
            cp += i;
            continue;
        }
        GETSHORT(weight, cp);
        if ((i = dn_expand(ans, end, cp, buf, sizeof(buf)-1)) < 0) {
            res_nclose(res);
            php_dns_free_res(res);
            return false;
        }
        cp += i;
        mxhosts.append(String(buf, CopyString));
        weights.append(weight);
    }
    res_nclose(res);
    php_dns_free_res(res);
    return true;
}
Beispiel #3
0
Variant f_icu_match(CStrRef pattern, CStrRef subject,
                    VRefParam matches /* = null */, int64_t flags /* = 0 */) {
  UErrorCode status = U_ZERO_ERROR;

  if (matches.isReferenced()) {
    matches = Array();
  }

  // Create hash map key by concatenating pattern and flags.
  StringBuffer bpattern;
  bpattern.append(pattern);
  bpattern.append(':');
  bpattern.append(flags);
  String spattern = bpattern.detach();

  // Find compiled pattern matcher in hash map or add it.
  PatternStringMap::accessor accessor;
  const RegexPattern* rpattern;
  if (s_patternCacheMap.find(accessor, spattern.get())) {
    rpattern = accessor->second;
  } else {
    // First 32 bits are reserved for ICU-specific flags.
    rpattern = RegexPattern::compile(
      UnicodeString::fromUTF8(pattern.data()), (flags & 0xFFFFFFFF), status);
    if (U_FAILURE(status)) {
      return false;
    }

    if (s_patternCacheMap.insert(
      accessor, StringData::GetStaticString(spattern.get()))) {
      accessor->second = rpattern;
    } else {
      delete rpattern;
      rpattern = accessor->second;
    }
  }

  // Build regex matcher from compiled pattern and passed-in subject.
  UnicodeString usubject = UnicodeString::fromUTF8(subject.data());
  boost::scoped_ptr<RegexMatcher> matcher(rpattern->matcher(usubject, status));
  if (U_FAILURE(status)) {
    return false;
  }

  // Return 0 or 1 depending on whether or not a match was found and
  // (optionally), set matched (sub-)patterns for passed-in reference.
  int matched = 0;
  if (matcher->find()) {
    matched = 1;

    if (matches.isReferenced()) {
      int32_t count = matcher->groupCount();

      for (int32_t i = 0; i <= count; i++) {
        UnicodeString ustring = matcher->group(i, status);
        if (U_FAILURE(status)) {
          return false;
        }

        // Convert UnicodeString back to UTF-8.
        std::string string;
        ustring.toUTF8String(string);
        String match = String(string);

        if (flags & k_UREGEX_OFFSET_CAPTURE) {
          // start() returns the index in UnicodeString, which
          // normally means the index into an array of 16-bit
          // code "units" (not "points").
          int32_t start = matcher->start(i, status);
          if (U_FAILURE(status)) {
            return false;
          }

          start = usubject.countChar32(0, start);
          matches->append(CREATE_VECTOR2(match, start));
        } else {
          matches->append(match);
        }
      }
    }
  }

  return matched;
}
Variant f_dns_get_record(CStrRef hostname, int type /* = -1 */,
                         VRefParam authns /* = null */,
                         VRefParam addtl /* = null */) {
    IOStatusHelper io("dns_get_record", hostname.data(), type);
    if (type < 0) type = PHP_DNS_ALL;
    if (type & ~PHP_DNS_ALL && type != PHP_DNS_ANY) {
        raise_warning("Type '%d' not supported", type);
        return false;
    }

    /* Initialize the return array */
    Array ret;
    authns = Array::Create();
    addtl = Array::Create();

    unsigned char *cp = NULL, *end = NULL;
    int qd, an, ns = 0, ar = 0;
    querybuf answer;

    /* - We emulate an or'ed type mask by querying type by type.
     *   (Steps 0 - NUMTYPES-1 )
     *   If additional info is wanted we check again with DNS_T_ANY
     *   (step NUMTYPES / NUMTYPES+1 )
     *   store_results is used to skip storing the results retrieved in step
     *   NUMTYPES+1 when results were already fetched.
     * - In case of PHP_DNS_ANY we use the directly fetch DNS_T_ANY.
     *   (step NUMTYPES+1 )
     */
    bool first_query = true;
    bool store_results = true;
    for (int t = (type == PHP_DNS_ANY ? (PHP_DNS_NUM_TYPES + 1) : 0);
            t < PHP_DNS_NUM_TYPES + 2 || first_query; t++) {
        first_query = false;
        int type_to_fetch;
        switch (t) {
        case 0:
            type_to_fetch = type & PHP_DNS_A     ? DNS_T_A     : 0;
            break;
        case 1:
            type_to_fetch = type & PHP_DNS_NS    ? DNS_T_NS    : 0;
            break;
        case 2:
            type_to_fetch = type & PHP_DNS_CNAME ? DNS_T_CNAME : 0;
            break;
        case 3:
            type_to_fetch = type & PHP_DNS_SOA   ? DNS_T_SOA   : 0;
            break;
        case 4:
            type_to_fetch = type & PHP_DNS_PTR   ? DNS_T_PTR   : 0;
            break;
        case 5:
            type_to_fetch = type & PHP_DNS_HINFO ? DNS_T_HINFO : 0;
            break;
        case 6:
            type_to_fetch = type & PHP_DNS_MX    ? DNS_T_MX    : 0;
            break;
        case 7:
            type_to_fetch = type & PHP_DNS_TXT   ? DNS_T_TXT   : 0;
            break;
        case 8:
            type_to_fetch = type & PHP_DNS_AAAA  ? DNS_T_AAAA  : 0;
            break;
        case 9:
            type_to_fetch = type & PHP_DNS_SRV   ? DNS_T_SRV   : 0;
            break;
        case 10:
            type_to_fetch = type & PHP_DNS_NAPTR ? DNS_T_NAPTR : 0;
            break;
        case 11:
            type_to_fetch = type & PHP_DNS_A6    ? DNS_T_A6    : 0;
            break;
        case PHP_DNS_NUM_TYPES:
            store_results = false;
            continue;
        default:
        case (PHP_DNS_NUM_TYPES + 1):
            type_to_fetch = DNS_T_ANY;
            break;
        }
        if (!type_to_fetch) continue;

        struct __res_state *res;
        res = ResolverInit::s_res.get()->getResolver();
        if (res == NULL) {
            return false;
        }

        int n = res_nsearch(res, hostname.data(), C_IN, type_to_fetch,
                            answer.qb2, sizeof answer);
        if (n < 0) {
            res_nclose(res);
            php_dns_free_res(res);
            continue;
        }

        HEADER *hp;
        cp = answer.qb2 + HFIXEDSZ;
        end = answer.qb2 + n;
        hp = (HEADER *)&answer;
        qd = ntohs(hp->qdcount);
        an = ntohs(hp->ancount);
        ns = ntohs(hp->nscount);
        ar = ntohs(hp->arcount);

        /* Skip QD entries, they're only used by dn_expand later on */
        while (qd-- > 0) {
            n = dn_skipname(cp, end);
            if (n < 0) {
                raise_warning("Unable to parse DNS data received");
                res_nclose(res);
                php_dns_free_res(res);
                return false;
            }
            cp += n + QFIXEDSZ;
        }

        /* YAY! Our real answers! */
        while (an-- && cp && cp < end) {
            Array retval;
            cp = php_parserr(cp, &answer, type_to_fetch, store_results, retval);
            if (!retval.empty() && store_results) {
                ret.append(retval);
            }
        }
        res_nclose(res);
        php_dns_free_res(res);
    }

    /* List of Authoritative Name Servers */
    while (ns-- > 0 && cp && cp < end) {
        Array retval;
        cp = php_parserr(cp, &answer, DNS_T_ANY, true, retval);
        if (!retval.empty()) {
            authns.append(retval);
        }
    }

    /* Additional records associated with authoritative name servers */
    while (ar-- > 0 && cp && cp < end) {
        Array retval;
        cp = php_parserr(cp, &answer, DNS_T_ANY, true, retval);
        if (!retval.empty()) {
            addtl.append(retval);
        }
    }

    return ret;
}