Exemplo n.º 1
0
static int DBC_read_record_in(FILE *f, StrList list)
{
	char *s1, *tok, *next_tok;
	int capacity, len, rsize, i;

	len = 0;
	capacity = 100;
	s1 = (char*)malloc(capacity);
	while (fgets(s1+len, capacity-len, f) != NULL) {
		len = strlen(s1);
		if (s1[len-1] == '\n') {
			len --;
			s1[len] = 0;
			break;
		}
		if (capacity-1 == len) {
			capacity *= 2;
			s1 = realloc(s1,capacity);
		}
	}

	if (len == 0) {
		free(s1);
		return -1;
	}

	StrList_clear(list);
	tok = s1; next_tok = strchr(tok,' '); *next_tok = 0;
	rsize = atoi(tok);
	for (i=0; i < rsize; i++) {
		char *decod;
		tok = next_tok+1; next_tok = strchr(tok, ' '); *next_tok = 0;
		decod = URL_decode(tok, (unsigned)(next_tok-tok));
		StrList_add(list, decod);
		free(decod);
	}
	free(s1);
	return rsize;
}
Exemplo n.º 2
0
/* return any hrefs found */
static int
http_extract_fn(char *input, char *outbuf, size_t outbuflen)
{
    /* partial copied hrefs from previous calls are saved here */
    static char tempbuf[MaxPathSize];
    /* fill state of tempbuf */
    static int tempbuffill = 0;
    /* parsing state information */
    static enum http_states state;
    /* currently in double quotes (in parsing) */
    static int dqflag;
    char p;
    int offset, found;

    if (outbuf == NULL) {
        /* init */
        dqflag = tempbuffill = 0;
        state = ST_NONE;
        return 0;
    }

    offset = 0;
    found = 0;
    while ((p=input[offset++]) != '\0') {
        /* handle anything that's inside double quotes */
        if (dqflag) {
            /* incomplete href */
            if (state == ST_HREF) {
                /* check if space left in output
                 * buffer */
                if (tempbuffill >= sizeof(tempbuf)) {
                    warnx("href starting with `%.*s'"
                          " too long", 60, tempbuf);
                    /* ignore remainder */
                    tempbuffill = 0;
                    /* need space before "href"
                     * can start again (invalidly,
                     * of course, but we don't
                     * care) */
                    state = ST_TAGAX;
                }

                /* href complete */
                if (p == '\"') {
                    /* complete */
                    dqflag = 0;
                    tempbuf[tempbuffill++] = '\0';
                    /* need space before "href"
                     * can start again (invalidly,
                     * of course, but we don't
                     * care) */
                    state = ST_TAGAX;
                    found = 1;
                    break;
                } else {
                    /* copy one more char */
                    tempbuf[tempbuffill++] = p;
                }
            } else {
                /* leaving double quotes */
                if (p == '\"')
                    dqflag = 0;
            }
            continue;
        }

        /*
         * entering double quotes? (only relevant inside a tag)
         */
        if (state != ST_NONE && p == '\"') {
            dqflag = 1;
            continue;
        }

        /* other cases */
        switch (state) {
        case ST_NONE:
            /* plain text, not in markup */
            if (p == '<')
                state = ST_LT;
            break;
        case ST_LT:
            /* in tag -- "<" already found */
            if (p == '>')
                state = ST_NONE;
            else if (p == 'a' || p == 'A')
                state = ST_LTA;
            else if (!isspace((unsigned char)p))
                state = ST_TAG;
            break;
        case ST_LTA:
            /* in tag -- "<a" already found */
            if (p == '>')
                state = ST_NONE;
            else if (isspace((unsigned char)p))
                state = ST_TAGA;
            else
                state = ST_TAG;
            break;
        case ST_TAG:
            /* in tag, but not "<a" -- disregard */
            if (p == '>')
                state = ST_NONE;
            break;
        case ST_TAGA:
            /* in a-tag -- "<a " already found */
            if (p == '>')
                state = ST_NONE;
            else if (p == 'h' || p == 'H')
                state = ST_H;
            else if (!isspace((unsigned char)p))
                state = ST_TAGAX;
            break;
        case ST_TAGAX:
            /* in unknown keyword in a-tag */
            if (p == '>')
                state = ST_NONE;
            else if (isspace((unsigned char)p))
                state = ST_TAGA;
            break;
        case ST_H:
            /* in a-tag -- "<a h" already found */
            if (p == '>')
                state = ST_NONE;
            else if (p == 'r' || p == 'R')
                state = ST_R;
            else if (isspace((unsigned char)p))
                state = ST_TAGA;
            else
                state = ST_TAGAX;
            break;
        case ST_R:
            /* in a-tag -- "<a hr" already found */
            if (p == '>')
                state = ST_NONE;
            else if (p == 'e' || p == 'E')
                state = ST_E;
            else if (isspace((unsigned char)p))
                state = ST_TAGA;
            else
                state = ST_TAGAX;
            break;
        case ST_E:
            /* in a-tag -- "<a hre" already found */
            if (p == '>')
                state = ST_NONE;
            else if (p == 'f' || p == 'F')
                state = ST_F;
            else if (isspace((unsigned char)p))
                state = ST_TAGA;
            else
                state = ST_TAGAX;
            break;
        case ST_F:
            /* in a-tag -- "<a href" already found */
            if (p == '>')
                state = ST_NONE;
            else if (p == '=')
                state = ST_HREF;
            else if (!isspace((unsigned char)p))
                state = ST_TAGAX;
            break;
        case ST_HREF:
            /* in a-tag -- "<a href=" already found */
            /* XXX: handle missing double quotes? */
            if (p == '>')
                state = ST_NONE;
            /* skip spaces before URL */
            else if (!isspace((unsigned char)p))
                state = ST_TAGA;
            break;
            /* no default case by purpose */
        }
    }

    if (p == '\0')
        return -1;

    if (found) {
        char *q;

        URL_decode(tempbuf);

        /* strip path (XXX) */
        if ((q=strrchr(tempbuf, '/')) == NULL)
            q = tempbuf;

        (void)strlcpy(outbuf, q, outbuflen);
        tempbuffill = 0;
    }

    return offset;
}
Exemplo n.º 3
0
void fixReplaces(string& req_hdrs, bool is_invite) {

  string replaces;
  string refer_to;
  AmUriParser refer_target;
  vector<string> hdrs;                      // headers from Refer-To URI
  vector<string>::iterator replaces_hdr_it; // Replaces header from Refer-To URI

  DBG("Replaces handler: fixing %s request\n", is_invite?"INVITE":"REFER");

  if (is_invite) {
    replaces = getHeader(req_hdrs, SIP_HDR_REPLACES, true);
    if (replaces.empty()) {
      DBG("Replaces handler: no Replaces in INVITE, ignoring\n");
      return;
    }
  } else {
    refer_to = getHeader(req_hdrs, SIP_HDR_REFER_TO, SIP_HDR_REFER_TO_COMPACT, true);
    if (refer_to.empty()) {
      DBG("Replaces handler: empty Refer-To header, ignoring\n");
      return;
    }

    size_t pos=0; size_t end=0;
    if (!refer_target.parse_contact(refer_to, pos, end)) {
      DBG("Replaces handler: unable to parse Refer-To name-addr, ignoring\n");
      return;
    }

    if (refer_target.uri_headers.empty()) {
      DBG("Replaces handler: no headers in Refer-To target, ignoring\n");
      return;
    }

    hdrs = explode(refer_target.uri_headers, ";");
    for (replaces_hdr_it=hdrs.begin(); replaces_hdr_it != hdrs.end(); replaces_hdr_it++) {

      string s = URL_decode(*replaces_hdr_it);
      const char* Replaces_str = "Replaces";
      if ((s.length() >= 8) &&
	  !strncmp(Replaces_str, s.c_str(), 8)) {
	size_t pos = 8;
	while (s.length()>pos && (s[pos] == ' ' || s[pos] == '\t')) pos++;
	if (s[pos] != '=')
	  continue;
	pos++;
	while (s.length()>pos && (s[pos] == ' ' || s[pos] == '\t')) pos++;
	replaces = s.substr(pos);
	break;
      }
    }
    
    if (replaces_hdr_it == hdrs.end()) {
      DBG("Replaces handler: no Replaces headers in Refer-To target, ignoring\n");
      return;
    }
  }

  DBG("Replaces found: '%s'\n", replaces.c_str());
  size_t ftag_begin; size_t ftag_len;
  size_t ttag_begin; size_t ttag_len;
  size_t cid_len=0;
 
  // todo: parse full replaces header and reconstruct including unknown params
  if (!findTag(replaces, "from-tag=", ftag_begin, ftag_len)) {
    WARN("Replaces missing 'from-tag', ignoring\n");
    return;
  }

  if (!findTag(replaces, "to-tag=", ttag_begin, ttag_len)) {
    WARN("Replaces missing 'to-tag', ignoring\n");
    return;
  }
  while (cid_len < replaces.size() && replaces[cid_len] != ';')
    cid_len++;

  string ftag = replaces.substr(ftag_begin, ftag_len);
  string ttag = replaces.substr(ttag_begin, ttag_len);
  string callid = replaces.substr(0, cid_len);
  bool early_only = replaces.find("early-only") != string::npos;

  DBG("Replaces handler: found callid='%s', ftag='%s', ttag='%s'\n",
      callid.c_str(), ftag.c_str(), ttag.c_str());

  SBCCallRegistryEntry other_dlg;
  if (SBCCallRegistry::lookupCall(ttag, other_dlg)) {
    replaces = other_dlg.callid+
      ";from-tag="+other_dlg.ltag+";to-tag="+other_dlg.rtag;
    if (early_only)
      replaces += ";early_only";
    DBG("Replaces handler: mapped Replaces to: '%s'\n", replaces.c_str());

    if (is_invite) {
      removeHeader(req_hdrs, SIP_HDR_REPLACES);
      req_hdrs+=SIP_HDR_COLSP(SIP_HDR_REPLACES)+replaces+CRLF;
    } else {
      string replaces_enc = SIP_HDR_REPLACES "="+URL_encode(replaces);
      string new_hdrs;
      for (vector<string>::iterator it = hdrs.begin(); it != hdrs.end(); it++) {
	if (it != hdrs.begin())
	  new_hdrs+=";";

	if (it != replaces_hdr_it) {
	  // different hdr, just add it
	  new_hdrs+=*it;
	} else {
	  //reconstructed replaces hdr
	  new_hdrs+=replaces_enc;
	}
      }
      refer_target.uri_headers=new_hdrs;
      removeHeader(req_hdrs, SIP_HDR_REFER_TO);
      removeHeader(req_hdrs, SIP_HDR_REFER_TO_COMPACT);
      req_hdrs+=SIP_HDR_COLSP(SIP_HDR_REFER_TO)+refer_target.nameaddr_str()+CRLF;
    }

  } else {
    DBG("Replaces handler: call with tag '%s' not found\n", ttag.c_str());
  }

 
}