示例#1
0
static int say_add(t_ircconnection* co, t_luneth* luneth)
{
  char* dest;
  char* msg;
  t_id auth;
  t_id dst;

  dest = strtok(NULL, " ");
  msg = strtok(NULL, "");
  if (!dest || !msg)
    return (0);
  msg += strspn(msg, " ");
  if (!*msg)
    return (0);
  auth = database_pplid(luneth->db,
                        co->cmd.prefixnick,
                        str_str(&co->servername),
                        co->cmd.args[0]);
  if (!auth)
    return (luneth_respond_msg(co, luneth, "Failed to find auth"));
  dst = database_pplid(
      luneth->db, dest, str_str(&co->servername), co->cmd.args[0]);
  if (!dst)
    return (luneth_respond_msg(co, luneth, "Failed to find dest"));
  auth = database_insert_say(luneth->db, auth, dst, msg);
  if (!auth)
    return (luneth_respond_msg(co, luneth, "Failed to insert say"));
  return (luneth_respond_msgf(co, luneth, "Say #%u added to database", auth));
}
示例#2
0
CELL *
bi_index(CELL * sp)
{
    size_t idx;
    size_t len;
    const char *p;

    sp--;
    if (TEST2(sp) != TWO_STRINGS)
	cast2_to_s(sp);

    if ((len = string(sp + 1)->len)) {
	idx = (size_t) ((p = str_str(string(sp)->str,
				     string(sp)->len,
				     string(sp + 1)->str,
				     len))
			? p - string(sp)->str + 1
			: 0);
    } else {			/* index of the empty string */
	idx = 1;
    }

    free_STRING(string(sp));
    free_STRING(string(sp + 1));
    sp->type = C_DOUBLE;
    sp->dval = (double) idx;
    return sp;
}
示例#3
0
static int say_rm(t_ircconnection* co, t_luneth* luneth)
{
  char* strid;
  t_say* say;
  t_id id;
  t_id pplid;

  strid = strtok(NULL, " ");
  if (!strid || strtok(NULL, " "))
    return (0);
  pplid = database_pplid(luneth->db,
                         co->cmd.prefixnick,
                         str_str(&co->servername),
                         co->cmd.args[0]);
  if (!pplid)
    return (1);
  id = atoi(strid);
  say = database_say_fromid(luneth->db, id);
  if (!say)
    return (luneth_respond_msgf(co, luneth, "#%u No such say", id));
  if (pplid != say->auth && pplid != say->dest)
  {
    say_delete(say, true);
    return (luneth_respond_msgf(co, luneth, "#%u Not your say", id));
  }
  say_delete(say, true);
  if (database_rm_say(luneth->db, id))
    return (luneth_respond_msgf(co, luneth, "Failed to rm say #%u", id));
  return (luneth_respond_msgf(co, luneth, "Say #%u removed", id));
}
示例#4
0
int main(void)
{
	char str[] = "asd123fgh543df";
	printf("%s\n", str);
	str_str(str);
	printf("%s\n", str);
	return 0;
}
示例#5
0
int longest_dupstr(char *src, char *dst)
{
	int cnt = 0;
	int index;
	int times;
	int pos;
	for (index = 0; index < strlen(src); index++) {
		for (pos = 0; pos <= index; pos++) {
			str_sub(src, dst, pos, strlen(src) - index);
			cnt = str_str(src, dst);
			if (cnt >= 2) {
				return cnt;
			}
		}
	}
	return 0;
}
示例#6
0
int is_substring(char *sub, char *string) {
  char *s;

  if ((s = str_str(string, sub))) {
    int len = strlen(string);
    int sublen = strlen(sub);

    /* check front */
    if ((s == string || isspace(*(s - 1)) || ispunct(*(s - 1))) &&

            /* check end */
            ((s + sublen == string + len) || isspace(s[sublen]) ||
            ispunct(s[sublen])))
      return 1;
  }

  return 0;
}
示例#7
0
static void __sdp_ice(struct stream_params *sp, struct sdp_media *media) {
	struct sdp_attribute *attr;
	struct attribute_candidate *ac;
	struct ice_candidate *cand;
	GQueue *q;
	GList *ql;

	attr = attr_get_by_id_m_s(media, ATTR_ICE_UFRAG);
	if (!attr)
		return;
	sp->ice_ufrag = attr->value;

	SP_SET(sp, ICE);

	q = attr_list_get_by_id(&media->attributes, ATTR_CANDIDATE);
	if (!q)
		goto no_cand;

	for (ql = q->head; ql; ql = ql->next) {
		attr = ql->data;
		ac = &attr->u.candidate;
		if (!ac->parsed)
			continue;
		cand = g_slice_alloc(sizeof(*cand));
		*cand = ac->cand_parsed;
		g_queue_push_tail(&sp->ice_candidates, cand);
	}

no_cand:
	if ((attr = attr_get_by_id(&media->attributes, ATTR_ICE_OPTIONS))) {
		if (str_str(&attr->value, "trickle") >= 0)
			SP_SET(sp, TRICKLE_ICE);
	}
	else if (is_trickle_ice_address(&sp->rtp_endpoint))
		SP_SET(sp, TRICKLE_ICE);

	if (attr_get_by_id(&media->attributes, ATTR_ICE_LITE))
		SP_SET(sp, ICE_LITE);

	attr = attr_get_by_id_m_s(media, ATTR_ICE_PWD);
	if (attr)
		sp->ice_pwd = attr->value;
}
示例#8
0
char *
REmatch(char *str,		/* string to test */
        size_t str_len,		/* ...its length */
        PTR machine,		/* compiled regular expression */
        size_t *lenp)		/* where to return matched-length */
{
    register STATE *m = (STATE *) machine;
    char *s = str;
    char *ss;
    register RT_STATE *stackp;
    int u_flag, t;
    char *str_end = s + str_len;
    RT_POS_ENTRY *sp;
    char *ts;

    /* state of current best match stored here */
    char *cb_ss;		/* the start */
    char *cb_e = 0;		/* the end , pts at first char not matched */
    STATE *m_best = 0;

    *lenp = 0;

    /* check for the easy case */
    if ((m + 1)->s_type == M_ACCEPT && m->s_type == M_STR) {
        if ((ts = str_str(s, str_len, m->s_data.str, (size_t) m->s_len)))
            *lenp = m->s_len;
        return ts;
    }

    u_flag = U_ON;
    cb_ss = ss = (char *) 0;
    stackp = RE_run_stack_empty;
    sp = RE_pos_stack_empty;
    goto reswitch;

refill:
    if (stackp == RE_run_stack_empty) {
        if (cb_ss)
            *lenp = (unsigned) (cb_e - cb_ss);
        return cb_ss;
    }
    ss = stackp->ss;
    s = (stackp--)->s;
    if (cb_ss) {		/* does new state start too late ? */
        if (ss) {
            if (cb_ss < ss || (cb_ss == ss && cb_e == str_end)) {
                goto refill;
            }
        } else if (cb_ss < s || (cb_ss == s && cb_e == str_end)) {
            goto refill;
        }
    }

    m = (stackp + 1)->m;
    sp = RE_pos_stack_base + (stackp + 1)->sp;
    sp->prev_offset = (stackp + 1)->tp;
    u_flag = (stackp + 1)->u;

reswitch:

    switch (m->s_type + u_flag) {
    case M_STR + U_OFF + END_OFF:
        if (strncmp(s, m->s_data.str, (size_t) m->s_len)) {
            goto refill;
        }
        if (!ss) {
            if (cb_ss && s > cb_ss) {
                goto refill;
            } else {
                ss = s;
            }
        }
        s += m->s_len;
        m++;
        goto reswitch;

    case M_STR + U_OFF + END_ON:
        if (strcmp(s, m->s_data.str)) {
            goto refill;
        }
        if (!ss) {
            if (cb_ss && s > cb_ss) {
                goto refill;
            } else {
                ss = s;
            }
        }
        s += m->s_len;
        m++;
        goto reswitch;

    case M_STR + U_ON + END_OFF:
        if (s >= str_end) {
            goto refill;
        }
        if (!(s = str_str(s, (size_t) (str_end - s), m->s_data.str, (size_t) m->s_len))) {
            goto refill;
        }
        if (s >= str + strlen(str)) {
            goto refill;
        }
        push(m, s + 1, sp, ss, U_ON);
        if (!ss) {
            if (cb_ss && s > cb_ss) {
                goto refill;
            } else {
                ss = s;
            }
        }
        s += m->s_len;
        m++;
        u_flag = U_OFF;
        goto reswitch;

    case M_STR + U_ON + END_ON:
        t = (int) ((str_end - s) - m->s_len);
        if (t < 0 || memcmp(ts = s + t, m->s_data.str, (size_t) m->s_len)) {
            goto refill;
        }
        if (!ss) {
            if (cb_ss && ts > cb_ss) {
                goto refill;
            } else {
                ss = ts;
            }
        }
        s = str_end;
        m++;
        u_flag = U_OFF;
        goto reswitch;

    case M_CLASS + U_OFF + END_OFF:
        if (s >= str_end)
            goto refill;
        if (!ison(*m->s_data.bvp, s[0])) {
            goto refill;
        }
        if (!ss) {
            if (cb_ss && s > cb_ss) {
                goto refill;
            } else {
                ss = s;
            }
        }
        s++;
        m++;
        goto reswitch;

    case M_CLASS + U_OFF + END_ON:
        if (s >= str_end)
            goto refill;
        if (s[1] || !ison(*m->s_data.bvp, s[0])) {
            goto refill;
        }
        if (!ss) {
            if (cb_ss && s > cb_ss) {
                goto refill;
            } else {
                ss = s;
            }
        }
        s++;
        m++;
        goto reswitch;

    case M_CLASS + U_ON + END_OFF:
        if (s >= str_end)
            goto refill;
        while (!ison(*m->s_data.bvp, s[0])) {
            if (s >= str_end) {
                goto refill;
            } else {
                s++;
            }
        }
        if (s >= str_end) {
            goto refill;
        }
        s++;
        push(m, s, sp, ss, U_ON);
        if (!ss) {
            if (cb_ss && s - 1 > cb_ss) {
                goto refill;
            } else {
                ss = s - 1;
            }
        }
        m++;
        u_flag = U_OFF;
        goto reswitch;

    case M_CLASS + U_ON + END_ON:
        if ((s >= str_end) || !ison(*m->s_data.bvp, str_end[-1])) {
            goto refill;
        }
        if (!ss) {
            if (cb_ss && str_end - 1 > cb_ss) {
                goto refill;
            } else {
                ss = str_end - 1;
            }
        }
        s = str_end;
        m++;
        u_flag = U_OFF;
        goto reswitch;

    case M_ANY + U_OFF + END_OFF:
        if (s >= str_end) {
            goto refill;
        }
        if (!ss) {
            if (cb_ss && s > cb_ss) {
                goto refill;
            } else {
                ss = s;
            }
        }
        s++;
        m++;
        goto reswitch;

    case M_ANY + U_OFF + END_ON:
        if ((s >= str_end) || ((s + 1) < str_end)) {
            goto refill;
        }
        if (!ss) {
            if (cb_ss && s > cb_ss) {
                goto refill;
            } else {
                ss = s;
            }
        }
        s++;
        m++;
        goto reswitch;

    case M_ANY + U_ON + END_OFF:
        if (s >= str_end) {
            goto refill;
        }
        s++;
        push(m, s, sp, ss, U_ON);
        if (!ss) {
            if (cb_ss && s - 1 > cb_ss) {
                goto refill;
            } else {
                ss = s - 1;
            }
        }
        m++;
        u_flag = U_OFF;
        goto reswitch;

    case M_ANY + U_ON + END_ON:
        if (s >= str_end) {
            goto refill;
        }
        if (!ss) {
            if (cb_ss && str_end - 1 > cb_ss) {
                goto refill;
            } else {
                ss = str_end - 1;
            }
        }
        s = str_end;
        m++;
        u_flag = U_OFF;
        goto reswitch;

    case M_START + U_OFF + END_OFF:
    case M_START + U_ON + END_OFF:
        if (s != str) {
            goto refill;
        }
        ss = s;
        m++;
        u_flag = U_OFF;
        goto reswitch;

    case M_START + U_OFF + END_ON:
    case M_START + U_ON + END_ON:
        if (s != str || (s < str_end)) {
            goto refill;
        }
        ss = s;
        m++;
        u_flag = U_OFF;
        goto reswitch;

    case M_END + U_OFF:
        if (s < str_end) {
            goto refill;
        }
        if (!ss) {
            if (cb_ss && s > cb_ss) {
                goto refill;
            } else {
                ss = s;
            }
        }
        m++;
        goto reswitch;

    case M_END + U_ON:
        s = str_end;
        if (!ss) {
            if (cb_ss && s > cb_ss) {
                goto refill;
            } else {
                ss = s;
            }
        }
        m++;
        u_flag = U_OFF;
        goto reswitch;

        CASE_UANY(M_U):
            if (!ss) {
            if (cb_ss && s > cb_ss) {
                goto refill;
            } else {
                ss = s;
            }
        }
        u_flag = U_ON;
        m++;
        goto reswitch;

        CASE_UANY(M_1J):
            m += m->s_data.jump;
            goto reswitch;

            CASE_UANY(M_SAVE_POS):	/* save position for a later M_2JC */
            /* see also REtest */
            sp = RE_pos_push(sp, stackp, s);
            m++;
            goto reswitch;

            CASE_UANY(M_2JA):	/* take the non jump branch */
            push(m + m->s_data.jump, s, sp, ss, u_flag);
            m++;
            goto reswitch;

            CASE_UANY(M_2JC):	/* take the jump branch if position changed */
            /* see REtest */
            if (RE_pos_pop(&sp, stackp) == s) {
            m++;
            goto reswitch;
        }
        /* fall thru */

        CASE_UANY(M_2JB):	/* take the jump branch */
            push(m + 1, s, sp, ss, u_flag);
            m += m->s_data.jump;
            goto reswitch;

        case M_ACCEPT + U_OFF:
            if (!ss)
                ss = s;
            if (!cb_ss || ss < cb_ss || (ss == cb_ss && s > cb_e)) {
            /* we have a new current best */
            cb_ss = ss;
            cb_e = s;
            m_best = m;
        }
        goto refill;

    case M_ACCEPT + U_ON:
        if (!ss) {
            ss = s;
        } else {
            s = str_end;
        }

        if (!cb_ss || ss < cb_ss || (ss == cb_ss && s > cb_e)) {
            /* we have a new current best */
            cb_ss = ss;
            cb_e = s;
            m_best = m;
        }
        goto refill;

    default:
        RE_panic("unexpected case in REmatch");
    }
}
// A helper function.
//
// Note about this function: This function used to be part of
// NAType and used to use NADatetimeType and NAIntervalType types. To
// make the same functionality available in executor (where NATypes are
// not available) we moved this functionality out of NAType.
// All the required information to find the type is input to this
// function. The helper methods getDatetimeQualifierAsString() and
// getIntervalTypeText() above have code that resemble the code from
// NADatetimeType and NAIntervalType.
//
// This method returns a text representation of the datatype
// based on the datatype information input to this method.
//
// Returns -1 in case of error, 0 if all is ok.
short convertTypeToText_basic(char * text,	   // OUTPUT
			      Lng32 fs_datatype,    // all other vars: INPUT
			      Lng32 length,
			      Lng32 precision,
			      Lng32 scale,
			      rec_datetime_field datetimestart,
			      rec_datetime_field datetimeend,
			      short datetimefractprec,
			      short intervalleadingprec,
			      short upshift,
			      short caseinsensitive,
                              CharInfo::CharSet charSet,
                              const char * collation_name,
                              const char * displaydatatype,
			      short displayCaseSpecific)
{
  short addCharSet = 0;
  short addCollate = 0;

  switch (fs_datatype)
  {
    case REC_BIN64_SIGNED:
      if ((!precision) && (scale == 0))
	str_sprintf(text, "LARGEINT");
      else
	{
	  if (! precision)
	    str_sprintf(text, "NUMERIC(%d, %d)",
			18/*MAX_NUMERIC_PRECISION*/, scale);
	  else
	    str_sprintf(text, "NUMERIC(%d, %d)", precision, scale);
	}
      break;

    case REC_BIN64_UNSIGNED:
      if ((!precision) && (scale == 0))
	str_sprintf(text, "LARGEINT UNSIGNED");
      else
	{
	  if (! precision)
	    str_sprintf(text, "NUMERIC(%d, %d) UNSIGNED",
			18/*MAX_NUMERIC_PRECISION*/, scale);
	  else
	    str_sprintf(text, "NUMERIC(%d, %d) UNSIGNED", precision, scale);
	}
      break;

    case REC_BIN32_SIGNED:
      if (!precision)
	str_sprintf(text, "INT");
      else
	str_sprintf(text, "NUMERIC(%d, %d)", precision, scale);
      break;

    case REC_BIN16_SIGNED:
      if (!precision)
      {
        if (displaydatatype && !str_cmp_c(displaydatatype, "BYTEINT"))
          str_sprintf(text, displaydatatype);
        else
          str_sprintf(text, "SMALLINT");
      }
      else
	str_sprintf(text, "NUMERIC(%d, %d)", precision, scale);

      break;

    case REC_BIN8_SIGNED:
      if (!precision)
        str_sprintf(text, "TINYINT");
      else
	str_sprintf(text, "NUMERIC(%d, %d)", precision, scale);
      break;

    case REC_BIN32_UNSIGNED:
      if (!precision)
	str_sprintf(text, "INT UNSIGNED");
      else
	str_sprintf(text, "NUMERIC(%d, %d) UNSIGNED", precision, scale);
      break;

    case REC_BIN16_UNSIGNED:
      if (!precision)
	str_sprintf(text, "SMALLINT UNSIGNED");
      else
	str_sprintf(text, "NUMERIC(%d, %d) UNSIGNED", precision, scale);
      break;

    case REC_BIN8_UNSIGNED:
      if (!precision)
        str_sprintf(text, "TINYINT UNSIGNED");
      else
	str_sprintf(text, "NUMERIC(%d, %d)  UNSIGNED", precision, scale);
      break;

    case REC_BPINT_UNSIGNED:
      str_sprintf(text, "BIT PRECISION INT(%d) UNSIGNED", precision);
      break;

    case REC_DECIMAL_LSE:
      str_sprintf(text, "DECIMAL(%d, %d)", length, scale);

      break;
    case REC_DECIMAL_UNSIGNED:
      str_sprintf(text, "DECIMAL(%d, %d) UNSIGNED", length, scale);
      break;

    case REC_NUM_BIG_SIGNED:
      str_sprintf(text, "NUMERIC(%d, %d)", precision, scale);
      break;

    case REC_NUM_BIG_UNSIGNED:
      str_sprintf(text, "NUMERIC(%d, %d) UNSIGNED", precision, scale);
      break;

    case REC_FLOAT32:
      if (precision == 0)
	str_sprintf(text, "REAL");
      else
	str_sprintf(text, "FLOAT(%d)", precision);
      break;

    case REC_FLOAT64:
      if (precision == 0)
	str_sprintf(text, "DOUBLE PRECISION");
      else
	str_sprintf(text, "FLOAT(%d)", precision);
      break;

    case REC_BYTE_F_ASCII:
      addCharSet = 1;
#ifdef IS_MP
      if(CharInfo::is_NCHAR_MP(charSet))
	str_sprintf(text, "CHAR(%d)", length/2);
      else
#endif
      if (charSet == CharInfo::UTF8 || charSet == CharInfo::SJIS)
      {
        if(displaydatatype && strlen(displaydatatype) > 0)
        {
          str_sprintf(text, displaydatatype);
          if(str_str(displaydatatype, " CHARACTER SET "))
            addCharSet = 0;
        }
        else
        {
          if (precision/*i.e., charlen*/ > 0) // char len unit is CHAR(S)
          {
            if (precision/*i.e., charlen*/ == 1)
              str_sprintf(text, "CHAR(1 CHAR)");
            else
              str_sprintf(text, "CHAR(%d CHARS)", precision/*i.e., charlen*/);
          }
          else // precision == 0 (char len unit is BYTE[S])
          {
            if (length/*in_bytes*/ == 1)
              str_sprintf(text, "CHAR(1 BYTE)");
            else
              str_sprintf(text, "CHAR(%d BYTES)", length/*in_bytes*/);
          }
        }
      }
      else
	str_sprintf(text, "CHAR(%d)", length);

      addCollate = 1;
      break;

    case REC_BYTE_F_DOUBLE:
      str_sprintf(text, "CHAR(%d)", length/SQL_DBCHAR_SIZE);
      addCharSet = 1;
      addCollate = 1;
      break;

    case REC_BYTE_V_ASCII:
      addCharSet = 1;
#ifdef IS_MP
      if(CharInfo::is_NCHAR_MP(charSet))
	str_sprintf(text, "VARCHAR(%d)", length/2);
      else
#endif
      if (charSet == CharInfo::UTF8 || charSet == CharInfo::SJIS)
      {
        if(displaydatatype && strlen(displaydatatype) > 0)
        {
          str_sprintf(text, displaydatatype);
          if(str_str(displaydatatype, " CHARACTER SET "))
            addCharSet = 0;
        }
        else
        {
          if (precision/*i.e., charlen*/ > 0) // char len unit is CHAR(S)
          {
            if (precision/*i.e., charlen*/ == 1)
              str_sprintf(text, "VARCHAR(1 CHAR)");
            else
              str_sprintf(text, "VARCHAR(%d CHARS)", precision/*i.e., charlen*/);
          }
          else // precision == 0 (char len unit is BYTE[S])
          {
            if (length/*in_bytes*/ == 1)
              str_sprintf(text, "VARCHAR(1 BYTE)");
            else
              str_sprintf(text, "VARCHAR(%d BYTES)", length/*in_bytes*/);
          }
        }
      }
      else
	str_sprintf(text, "VARCHAR(%d)", length);

      addCollate = 1;
      break;

    case REC_BYTE_V_DOUBLE:
      str_sprintf(text, "VARCHAR(%d)", length/SQL_DBCHAR_SIZE);
      addCharSet = 1;
      addCollate = 1;
      break;

    case REC_BYTE_V_ASCII_LONG:
      addCharSet = 1;
      if (charSet == CharInfo::UTF8 || charSet == CharInfo::SJIS)
      {
        if(displaydatatype && strlen(displaydatatype) > 0)
        {
          str_sprintf(text, displaydatatype);
          if(str_str(displaydatatype, " CHARACTER SET "))
            addCharSet = 0;
        }
        else
        {
          if (precision/*i.e., charlen*/ > 0) // char len unit is CHAR(S) - not yet supported
          {
            if (precision/*i.e., charlen*/ == 1)
              str_sprintf(text, "LONG VARCHAR(1 CHAR)");
            else
              str_sprintf(text, "LONG VARCHAR(%d CHARS)", precision/*i.e., charlen*/);
          }
          else // precision == 0 (char len unit is BYTE[S])
          {
            if (length/*in_bytes*/ == 1)
              str_sprintf(text, "LONG VARCHAR(1 BYTE)");
            else
              str_sprintf(text, "LONG VARCHAR(%d BYTES)", length/*in_bytes*/);
          }
        }
      }
      else
	str_sprintf(text, "LONG VARCHAR(%d)", length);

      addCollate = 1;
      break;

    case REC_DATETIME:
      return getDateTimeTypeText(text,
                                 datetimestart,
                                 datetimeend,
                                 datetimefractprec);

    case REC_INT_YEAR:
    case REC_INT_MONTH:
    case REC_INT_YEAR_MONTH:
    case REC_INT_DAY:
    case REC_INT_HOUR:
    case REC_INT_DAY_HOUR:
    case REC_INT_MINUTE:
    case REC_INT_HOUR_MINUTE:
    case REC_INT_DAY_MINUTE:
    case REC_INT_SECOND:
    case REC_INT_MINUTE_SECOND:
    case REC_INT_HOUR_SECOND:
    case REC_INT_DAY_SECOND:
    case REC_INT_FRACTION:
      return getIntervalTypeText(text,
                                 datetimestart,
                                 intervalleadingprec,
                                 datetimeend,
                                 datetimefractprec);
      break;

   case REC_BLOB:
     if (precision > 0)
       str_sprintf(text, "BLOB(length %d M)",
		   precision);
     else
       str_sprintf(text, "BLOB");
     break;

   case REC_CLOB:
     if (precision > 0)
       str_sprintf(text, "CLOB(length %d M)",
		   precision);
     else
       str_sprintf(text, "CLOB");
     break;

   case REC_BOOLEAN:
     str_sprintf(text, "BOOLEAN");
     break;

    default:
      str_sprintf(text, "**ERROR (unknown type %d)", fs_datatype);
      return -1; // error case
  }

  if (addCharSet)
  {
    str_sprintf(&text[str_len(text)],
                " CHARACTER SET %s",
                CharInfo::getCharSetName(charSet));
  }

  if (addCollate && (collation_name != NULL))
  {
    str_sprintf(&text[str_len(text)],
                " COLLATE %s",
                collation_name);
  }

  if (DFS2REC::isAnyCharacter(fs_datatype))
    {
      if (upshift)
	str_sprintf(&text[str_len(text)], " UPSHIFT");

      if (caseinsensitive)
	str_sprintf(&text[str_len(text)], " NOT CASESPECIFIC");
      else if (displayCaseSpecific)
	str_sprintf(&text[str_len(text)], " CASESPECIFIC");
    }


  return 0;
}
示例#10
0
char *
FINgets(FIN * fin, size_t *len_p)
{
    char *p;
    char *q = 0;
    size_t match_len;
    size_t r;

  restart:

    if ((p = fin->buffp) >= fin->limit) {	/* need a refill */
	if (fin->flags & EOF_FLAG) {
	    if (fin->flags & MAIN_FLAG) {
		fin = next_main(0);
		goto restart;
	    } else {
		*len_p = 0;
		return (char *) 0;
	    }
	}

	if (fin->fp) {
	    /* line buffering */
	    if (!fgets(fin->buff, BUFFSZ + 1, fin->fp)) {
		fin->flags |= EOF_FLAG;
		fin->buff[0] = 0;
		fin->buffp = fin->buff;
		fin->limit = fin->buffp;
		goto restart;	/* might be main_fin */
	    } else {		/* return this line */
		/* find eol */
		p = fin->buff;
		while (*p != '\n' && *p != 0)
		    p++;

		*p = 0;
		*len_p = (unsigned) (p - fin->buff);
		fin->buffp = p;
		fin->limit = fin->buffp + strlen(fin->buffp);
		return fin->buff;
	    }
	} else {
	    /* block buffering */
	    r = fillbuff(fin->fd, fin->buff, (size_t) (fin->nbuffs * BUFFSZ));
	    if (r == 0) {
		fin->flags |= EOF_FLAG;
		fin->buffp = fin->buff;
		fin->limit = fin->buffp;
		goto restart;	/* might be main */
	    } else if (r < fin->nbuffs * BUFFSZ) {
		fin->flags |= EOF_FLAG;
	    }

	    fin->limit = fin->buff + r;
	    p = fin->buffp = fin->buff;

	    if (fin->flags & START_FLAG) {
		fin->flags &= ~START_FLAG;
		if (rs_shadow.type == SEP_MLR) {
		    /* trim blank lines from front of file */
		    while (*p == '\n')
			p++;
		    fin->buffp = p;
		    if (p >= fin->limit)
			goto restart;
		}
	    }
	}
    }

  retry:

    switch (rs_shadow.type) {
    case SEP_CHAR:
	q = memchr(p, rs_shadow.c, (size_t) (fin->limit - p));
	match_len = 1;
	break;

    case SEP_STR:
	q = str_str(p,
		    (size_t) (fin->limit - p),
		    ((STRING *) rs_shadow.ptr)->str,
		    match_len = ((STRING *) rs_shadow.ptr)->len);
	break;

    case SEP_MLR:
    case SEP_RE:
	q = re_pos_match(p, (size_t) (fin->limit - p), rs_shadow.ptr, &match_len);
	/* if the match is at the end, there might still be
	   more to match in the file */
	if (q && q[match_len] == 0 && !(fin->flags & EOF_FLAG))
	    q = (char *) 0;
	break;

    default:
	bozo("type of rs_shadow");
    }

    if (q) {
	/* the easy and normal case */
	*q = 0;
	*len_p = (unsigned) (q - p);
	fin->buffp = q + match_len;
	return p;
    }

    if (fin->flags & EOF_FLAG) {
	/* last line without a record terminator */
	*len_p = r = (unsigned) (fin->limit - p);
	fin->buffp = p + r;

	if (rs_shadow.type == SEP_MLR && fin->buffp[-1] == '\n'
	    && r != 0) {
	    (*len_p)--;
	    *--fin->buffp = 0;
	    fin->limit--;
	}
	return p;
    }

    if (p == fin->buff) {
	/* current record is too big for the input buffer, grow buffer */
	p = enlarge_fin_buffer(fin);
    } else {
	/* move a partial line to front of buffer and try again */
	size_t rr;
	size_t amount = (size_t) (fin->limit - p);
	size_t blocks = fin->nbuffs * BUFFSZ;

	r = amount;
	if (blocks < r) {
	    fin->flags |= EOF_FLAG;
	    return 0;
	}

	p = (char *) memmove(fin->buff, p, r);
	q = p + r;
	rr = blocks - r;

	if ((r = fillbuff(fin->fd, q, rr)) < rr) {
	    fin->flags |= EOF_FLAG;
	    fin->limit = fin->buff + amount + r;
	}
    }
    goto retry;
}
示例#11
0
char *
REmatch(char *str,		/* string to test */
	unsigned str_len,	/* ...its length */
	PTR machine,		/* compiled regular expression */
	unsigned *lenp)		/* where to return matched-length */
{
    register STATE *m = (STATE *) machine;
    register char *s = str;
    char *ss;
    register RT_STATE *stackp;
    int u_flag, t;
    char *str_end = s + str_len;
    char *ts;

    /* state of current best match stored here */
    char *cb_ss;		/* the start */
    char *cb_e = 0;		/* the end , pts at first char not matched */

    *lenp = 0;

    /* check for the easy case */
    if ((m + 1)->s_type == M_ACCEPT && m->s_type == M_STR) {
	if ((ts = str_str(s, str_len, m->s_data.str, m->s_len)))
	    *lenp = m->s_len;
	return ts;
    }

    u_flag = U_ON;
    cb_ss = ss = (char *) 0;
    stackp = RE_run_stack_empty;
    goto reswitch;

  refill:
    if (stackp == RE_run_stack_empty) {
	if (cb_ss)
	    *lenp = (unsigned) (cb_e - cb_ss);
	return cb_ss;
    }
    ss = stackp->ss;
    s = (stackp--)->s;
    if (cb_ss) {		/* does new state start too late ? */
	if (ss) {
	    if (cb_ss < ss)
		goto refill;
	} else if (cb_ss < s) {
	    goto refill;
	}
    }

    m = (stackp + 1)->m;
    u_flag = (stackp + 1)->u;

  reswitch:

    switch (m->s_type + u_flag) {
    case M_STR + U_OFF + END_OFF:
	if (strncmp(s, m->s_data.str, m->s_len))
	    goto refill;
	if (!ss) {
	    if (cb_ss && s > cb_ss)
		goto refill;
	    else
		ss = s;
	}
	s += m->s_len;
	m++;
	goto reswitch;

    case M_STR + U_OFF + END_ON:
	if (strcmp(s, m->s_data.str))
	    goto refill;
	if (!ss) {
	    if (cb_ss && s > cb_ss) {
		goto refill;
	    } else {
		ss = s;
	    }
	}
	s += m->s_len;
	m++;
	goto reswitch;

    case M_STR + U_ON + END_OFF:
	if (!(s = str_str(s, str_len, m->s_data.str, m->s_len)))
	    goto refill;
	if (s >= str + strlen(str))
	    goto refill;
	push(m, s + 1, ss, U_ON);
	if (!ss) {
	    if (cb_ss && s > cb_ss) {
		goto refill;
	    } else {
		ss = s;
	    }
	}
	s += m->s_len;
	m++;
	u_flag = U_OFF;
	goto reswitch;

    case M_STR + U_ON + END_ON:
	t = (str_end - s) - m->s_len;
	if (t < 0 || memcmp(ts = s + t, m->s_data.str, m->s_len))
	    goto refill;
	if (!ss) {
	    if (cb_ss && ts > cb_ss)
		goto refill;
	    else
		ss = ts;
	}
	s = str_end;
	m++;
	u_flag = U_OFF;
	goto reswitch;

    case M_CLASS + U_OFF + END_OFF:
	if (!ison(*m->s_data.bvp, s[0]))
	    goto refill;
	if (!ss) {
	    if (cb_ss && s > cb_ss)
		goto refill;
	    else
		ss = s;
	}
	s++;
	m++;
	goto reswitch;

    case M_CLASS + U_OFF + END_ON:
	if (s[1] || !ison(*m->s_data.bvp, s[0]))
	    goto refill;
	if (!ss) {
	    if (cb_ss && s > cb_ss)
		goto refill;
	    else
		ss = s;
	}
	s++;
	m++;
	goto reswitch;

    case M_CLASS + U_ON + END_OFF:
	while (!ison(*m->s_data.bvp, s[0])) {
	    if (s[0] == 0)
		goto refill;
	    else
		s++;
	}
	s++;
	push(m, s, ss, U_ON);
	if (!ss) {
	    if (cb_ss && s - 1 > cb_ss)
		goto refill;
	    else
		ss = s - 1;
	}
	m++;
	u_flag = U_OFF;
	goto reswitch;

    case M_CLASS + U_ON + END_ON:
	if (s[0] == 0 || !ison(*m->s_data.bvp, str_end[-1]))
	    goto refill;
	if (!ss) {
	    if (cb_ss && str_end - 1 > cb_ss)
		goto refill;
	    else
		ss = str_end - 1;
	}
	s = str_end;
	m++;
	u_flag = U_OFF;
	goto reswitch;

    case M_ANY + U_OFF + END_OFF:
	if (s[0] == 0)
	    goto refill;
	if (!ss) {
	    if (cb_ss && s > cb_ss)
		goto refill;
	    else
		ss = s;
	}
	s++;
	m++;
	goto reswitch;

    case M_ANY + U_OFF + END_ON:
	if (s[0] == 0 || s[1] != 0)
	    goto refill;
	if (!ss) {
	    if (cb_ss && s > cb_ss)
		goto refill;
	    else
		ss = s;
	}
	s++;
	m++;
	goto reswitch;

    case M_ANY + U_ON + END_OFF:
	if (s[0] == 0)
	    goto refill;
	s++;
	push(m, s, ss, U_ON);
	if (!ss) {
	    if (cb_ss && s - 1 > cb_ss)
		goto refill;
	    else
		ss = s - 1;
	}
	m++;
	u_flag = U_OFF;
	goto reswitch;

    case M_ANY + U_ON + END_ON:
	if (s[0] == 0)
	    goto refill;
	if (!ss) {
	    if (cb_ss && str_end - 1 > cb_ss)
		goto refill;
	    else
		ss = str_end - 1;
	}
	s = str_end;
	m++;
	u_flag = U_OFF;
	goto reswitch;

    case M_START + U_OFF + END_OFF:
    case M_START + U_ON + END_OFF:
	if (s != str)
	    goto refill;
	ss = s;
	m++;
	u_flag = U_OFF;
	goto reswitch;

    case M_START + U_OFF + END_ON:
    case M_START + U_ON + END_ON:
	if (s != str || s[0] != 0)
	    goto refill;
	ss = s;
	m++;
	u_flag = U_OFF;
	goto reswitch;

    case M_END + U_OFF:
	if (s[0] != 0)
	    goto refill;
	if (!ss) {
	    if (cb_ss && s > cb_ss)
		goto refill;
	    else
		ss = s;
	}
	m++;
	goto reswitch;

    case M_END + U_ON:
	s = str_end;
	if (!ss) {
	    if (cb_ss && s > cb_ss)
		goto refill;
	    else
		ss = s;
	}
	m++;
	u_flag = U_OFF;
	goto reswitch;

      CASE_UANY(M_U):
	if (!ss) {
	    if (cb_ss && s > cb_ss)
		goto refill;
	    else
		ss = s;
	}
	u_flag = U_ON;
	m++;
	goto reswitch;

      CASE_UANY(M_1J):
	m += m->s_data.jump;
	goto reswitch;

      CASE_UANY(M_2JA):	/* take the non jump branch */
	push(m + m->s_data.jump, s, ss, u_flag);
	m++;
	goto reswitch;

      CASE_UANY(M_2JB):	/* take the jump branch */
	push(m + 1, s, ss, u_flag);
	m += m->s_data.jump;
	goto reswitch;

    case M_ACCEPT + U_OFF:
	if (!ss)
	    ss = s;
	if (!cb_ss || ss < cb_ss || (ss == cb_ss && s > cb_e)) {
	    /* we have a new current best */
	    cb_ss = ss;
	    cb_e = s;
	}
	goto refill;

    case M_ACCEPT + U_ON:
	if (!ss) {
	    ss = s;
	} else {
	    s = str_end;
	}

	if (!cb_ss || ss < cb_ss || (ss == cb_ss && s > cb_e)) {
	    /* we have a new current best */
	    cb_ss = ss;
	    cb_e = s;
	}
	goto refill;

    default:
	RE_panic("unexpected case in REmatch");
    }
}
示例#12
0
/**
* Checks for common mob problems and reports them to ch.
*
* @param char_data *mob The mob to audit.
* @param char_data *ch The person to report to.
* @return bool TRUE if any problems were reported; FALSE if all good.
*/
bool audit_mobile(char_data *mob, char_data *ch) {
	extern adv_data *get_adventure_for_vnum(rmt_vnum vnum);
	
	bool is_adventure = (get_adventure_for_vnum(GET_MOB_VNUM(mob)) != NULL);
	char temp[MAX_STRING_LENGTH], *ptr;
	bool problem = FALSE;

	if (!str_cmp(GET_PC_NAME(mob), "mobile new")) {
		olc_audit_msg(ch, GET_MOB_VNUM(mob), "Keywords not set");
		problem = TRUE;
	}
	
	ptr = GET_PC_NAME(mob);
	do {
		ptr = any_one_arg(ptr, temp);
		if (*temp && !str_str(GET_SHORT_DESC(mob), temp) && !str_str(GET_LONG_DESC(mob), temp)) {
			olc_audit_msg(ch, GET_MOB_VNUM(mob), "Keyword '%s' not found in strings", temp);
			problem = TRUE;
		}
	} while (*ptr);
	
	if (!str_cmp(GET_SHORT_DESC(mob), "a new mobile")) {
		olc_audit_msg(ch, GET_MOB_VNUM(mob), "Short desc not set");
		problem = TRUE;
	}
	any_one_arg(GET_SHORT_DESC(mob), temp);
	if ((fill_word(temp) || reserved_word(temp)) && isupper(*temp)) {
		olc_audit_msg(ch, GET_MOB_VNUM(mob), "Short desc capitalized");
		problem = TRUE;
	}
	if (ispunct(GET_SHORT_DESC(mob)[strlen(GET_SHORT_DESC(mob)) - 1])) {
		olc_audit_msg(ch, GET_MOB_VNUM(mob), "Short desc has punctuation");
		problem = TRUE;
	}
	
	ptr = GET_SHORT_DESC(mob);
	do {
		ptr = any_one_arg(ptr, temp);
		// remove trailing punctuation
		while (*temp && ispunct(temp[strlen(temp)-1])) {
			temp[strlen(temp)-1] = '\0';
		}
		if (*temp && !fill_word(temp) && !reserved_word(temp) && !isname(temp, GET_PC_NAME(mob))) {
			olc_audit_msg(ch, GET_MOB_VNUM(mob), "Suggested missing keyword '%s'", temp);
			problem = TRUE;
		}
	} while (*ptr);
	
	if (!str_cmp(GET_LONG_DESC(mob), "A new mobile is standing here.\r\n")) {
		olc_audit_msg(ch, GET_MOB_VNUM(mob), "Long desc not set");
		problem = TRUE;
	}
	if (!ispunct(GET_LONG_DESC(mob)[strlen(GET_LONG_DESC(mob)) - 3])) {
		olc_audit_msg(ch, GET_MOB_VNUM(mob), "Long desc missing punctuation");
		problem = TRUE;
	}
	if (islower(*GET_LONG_DESC(mob))) {
		olc_audit_msg(ch, GET_MOB_VNUM(mob), "Long desc not capitalized");
		problem = TRUE;
	}
	if (!is_adventure && GET_MAX_SCALE_LEVEL(mob) == 0) {
		olc_audit_msg(ch, GET_MOB_VNUM(mob), "No maximum scale level on non-adventure mob");
		problem = TRUE;
	}
	if (MOB_ATTACK_TYPE(mob) == TYPE_RESERVED) {
		olc_audit_msg(ch, GET_MOB_VNUM(mob), "Invalid attack type");
		problem = TRUE;
	}
	if (MOB_FLAGGED(mob, MOB_ANIMAL) && !has_interaction(mob->interactions, INTERACT_SKIN)) {
		olc_audit_msg(ch, GET_MOB_VNUM(mob), "Animal has no skin");
		problem = TRUE;
	}
	if (MOB_FLAGGED(mob, MOB_ANIMAL) && !has_interaction(mob->interactions, INTERACT_BUTCHER)) {
		olc_audit_msg(ch, GET_MOB_VNUM(mob), "Animal can't be butchered");
		problem = TRUE;
	}
	
	return problem;
}
示例#13
0
/*
 * test if str ~ /machine/
 */
int
REtest(char *str,		/* string to test */
       size_t len,		/* ...its length */
       PTR machine)		/* compiled regular-expression */
{
    register STATE *m = (STATE *) machine;
    char *s = str;
    register RT_STATE *stackp;
    int u_flag;
    char *str_end = str + len;
    RT_POS_ENTRY *sp;
    int t;			/*convenient temps */
    STATE *tm;

    /* handle the easy case quickly */
    if ((m + 1)->s_type == M_ACCEPT && m->s_type == M_STR) {
        return str_str(s, len, m->s_data.str, (size_t) m->s_len) != (char *) 0;
    } else {
        u_flag = U_ON;
        stackp = RE_run_stack_empty;
        sp = RE_pos_stack_empty;
        goto reswitch;
    }

refill:
    if (stackp == RE_run_stack_empty)
        return 0;
    m = stackp->m;
    s = stackp->s;
    sp = RE_pos_stack_base + stackp->sp;
    sp->prev_offset = stackp->tp;
    u_flag = (stackp--)->u;

reswitch:

    switch (m->s_type + u_flag) {
    case M_STR + U_OFF + END_OFF:
        if (strncmp(s, m->s_data.str, (size_t) m->s_len))
            goto refill;
        s += m->s_len;
        m++;
        goto reswitch;

    case M_STR + U_OFF + END_ON:
        if (strcmp(s, m->s_data.str))
            goto refill;
        s += m->s_len;
        m++;
        goto reswitch;

    case M_STR + U_ON + END_OFF:
        if (!(s = str_str(s, (size_t) (str_end - s), m->s_data.str, (size_t) m->s_len)))
            goto refill;
        push(m, s + 1, sp, U_ON);
        s += m->s_len;
        m++;
        u_flag = U_OFF;
        goto reswitch;

    case M_STR + U_ON + END_ON:
        t = (str_end - s) - m->s_len;
        if (t < 0 || memcmp(s + t, m->s_data.str, (size_t) m->s_len))
            goto refill;
        s = str_end;
        m++;
        u_flag = U_OFF;
        goto reswitch;

    case M_CLASS + U_OFF + END_OFF:
        if (s >= str_end || !ison(*m->s_data.bvp, s[0]))
            goto refill;
        s++;
        m++;
        goto reswitch;

    case M_CLASS + U_OFF + END_ON:
        if (s >= str_end)
            goto refill;
        if ((s + 1) < str_end || !ison(*m->s_data.bvp, s[0]))
            goto refill;
        s++;
        m++;
        goto reswitch;

    case M_CLASS + U_ON + END_OFF:
        for (;;) {
            if (s >= str_end)
                goto refill;
            else if (ison(*m->s_data.bvp, s[0]))
                break;
            s++;
        }
        s++;
        push(m, s, sp, U_ON);
        m++;
        u_flag = U_OFF;
        goto reswitch;

    case M_CLASS + U_ON + END_ON:
        if (s >= str_end || !ison(*m->s_data.bvp, str_end[-1]))
            goto refill;
        s = str_end;
        m++;
        u_flag = U_OFF;
        goto reswitch;

    case M_ANY + U_OFF + END_OFF:
        if (s >= str_end)
            goto refill;
        s++;
        m++;
        goto reswitch;

    case M_ANY + U_OFF + END_ON:
        if (s >= str_end || (s + 1) < str_end)
            goto refill;
        s++;
        m++;
        goto reswitch;

    case M_ANY + U_ON + END_OFF:
        if (s >= str_end)
            goto refill;
        s++;
        push(m, s, sp, U_ON);
        m++;
        u_flag = U_OFF;
        goto reswitch;

    case M_ANY + U_ON + END_ON:
        if (s >= str_end)
            goto refill;
        s = str_end;
        m++;
        u_flag = U_OFF;
        goto reswitch;

    case M_START + U_OFF + END_OFF:
    case M_START + U_ON + END_OFF:
        if (s != str)
            goto refill;
        m++;
        u_flag = U_OFF;
        goto reswitch;

    case M_START + U_OFF + END_ON:
    case M_START + U_ON + END_ON:
        if (s != str || s < str_end)
            goto refill;
        m++;
        u_flag = U_OFF;
        goto reswitch;

    case M_END + U_OFF:
        if (s < str_end)
            goto refill;
        m++;
        goto reswitch;

    case M_END + U_ON:
        s += strlen(s);
        m++;
        u_flag = U_OFF;
        goto reswitch;

        CASE_UANY(M_U):
            u_flag = U_ON;
            m++;
            goto reswitch;

            CASE_UANY(M_1J):
            m += m->s_data.jump;
            goto reswitch;

            CASE_UANY(M_SAVE_POS):	/* save position for a later M_2JC */
            sp = RE_pos_push(sp, stackp, s);
            m++;
            goto reswitch;

            CASE_UANY(M_2JA):	/* take the non jump branch */
            /* don't stack an ACCEPT */
            if ((tm = m + m->s_data.jump)->s_type == M_ACCEPT)
                return 1;
            push(tm, s, sp, u_flag);
            m++;
            goto reswitch;

            CASE_UANY(M_2JC):	/* take the jump branch if position changed */
            if (RE_pos_pop(&sp, stackp) == s) {
            /* did not advance: do not jump back */
            m++;
            goto reswitch;
        }
        /* fall thru */

        CASE_UANY(M_2JB):	/* take the jump branch */
            /* don't stack an ACCEPT */
            if ((tm = m + 1)->s_type == M_ACCEPT)
                return 1;
            push(tm, s, sp, u_flag);
            m += m->s_data.jump;
            goto reswitch;

            CASE_UANY(M_ACCEPT):
            return 1;

        default:
            RE_panic("unexpected case in REtest");
        }
    }
示例#14
0
int rhizome_direct_parse_http_request(rhizome_http_request *r)
{
  const char *submitBareFileURI=confValueGet("rhizome.api.addfile.uri", NULL);
  DEBUGF("uri=%s", submitBareFileURI ? alloca_str_toprint(submitBareFileURI) : "NULL");
  
  /* Switching to writing, so update the call-back */
  r->alarm.poll.events=POLLOUT;
  watch(&r->alarm);
  // Parse the HTTP request into verb, path, protocol, headers and content.
  char *const request_end = r->request + r->request_length;
  char *verb = r->request;
  char *path = NULL;
  char *proto = NULL;
  size_t pathlen = 0;
  char *headers = NULL;
  int headerlen = 0;
  char *content = NULL;
  int contentlen = 0;
  char *p;
  if ((str_startswith(verb, "GET", &p) || str_startswith(verb, "POST", &p)) && isspace(*p)) {
    *p++ = '\0';
    path = p;
    while (p < request_end && !isspace(*p))
      ++p;
    if (p < request_end) {
      pathlen = p - path;
      *p++ = '\0';
      proto = p;
      if ( str_startswith(p, "HTTP/1.", &p)
	&& (str_startswith(p, "0", &p) || str_startswith(p, "1", &p))
	&& (str_startswith(p, "\r\n", &headers) || str_startswith(p, "\n", &headers))
      ) {
	*p = '\0';
	char *eoh = str_str(headers, "\r\n\r\n", request_end - p);
	if (eoh) {
	  content = eoh + 4;
	  headerlen = content - headers;
	  contentlen = request_end - content;
	}
      }
    }
  }
  if (content == NULL) {
    if (debug & DEBUG_RHIZOME_TX)
      DEBUGF("Received malformed HTTP request %s", alloca_toprint(160, (const char *)r->request, r->request_length));
    return rhizome_server_simple_http_response(r, 400, "<html><h1>Malformed request</h1></html>\r\n");
  }
  INFOF("RHIZOME HTTP SERVER, %s %s %s", verb, alloca_toprint(-1, path, pathlen), proto);
  if (debug & DEBUG_RHIZOME_TX)
    DEBUGF("headers %s", alloca_toprint(-1, headers, headerlen));
  if (strcmp(verb, "GET") == 0 && strcmp(path, "/favicon.ico") == 0) {
    r->request_type = RHIZOME_HTTP_REQUEST_FAVICON;
    rhizome_server_http_response_header(r, 200, "image/vnd.microsoft.icon", favicon_len);
  } else if (strcmp(verb, "POST") == 0
      && (   strcmp(path, "/rhizome/import") == 0 
	  || strcmp(path, "/rhizome/enquiry") == 0
	  || (submitBareFileURI && strcmp(path, submitBareFileURI) == 0)
	 )
  ) {
    const char *cl_str=str_str(headers,"Content-Length: ",headerlen);
    const char *ct_str=str_str(headers,"Content-Type: multipart/form-data; boundary=",headerlen);
    if (!cl_str)
      return rhizome_server_simple_http_response(r,400,"<html><h1>Missing Content-Length header</h1></html>\r\n");
    if (!ct_str)
      return rhizome_server_simple_http_response(r,400,"<html><h1>Missing or unsupported Content-Type header</h1></html>\r\n");
    /* ok, we have content-type and content-length, now make sure they are well formed. */
    long long content_length;
    if (sscanf(cl_str,"Content-Length: %lld",&content_length)!=1)
      return rhizome_server_simple_http_response(r,400,"<html><h1>Malformed Content-Length header</h1></html>\r\n");
    char boundary_string[1024];
    int i;
    ct_str+=strlen("Content-Type: multipart/form-data; boundary=");
    for(i=0;i<1023&&*ct_str&&*ct_str!='\n'&&*ct_str!='\r';i++,ct_str++)
      boundary_string[i]=*ct_str;
    boundary_string[i] = '\0';
    if (i<4||i>128)
      return rhizome_server_simple_http_response(r,400,"<html><h1>Malformed Content-Type header</h1></html>\r\n");

    DEBUGF("content_length=%lld, boundary_string=%s contentlen=%d", (long long) content_length, alloca_str_toprint(boundary_string), contentlen);

    /* Now start receiving and parsing multi-part data.  If we already received some of the
	post-header data, process that first.  Tell the HTTP request that it has moved to multipart
	form data parsing, and what the actual requested action is.
    */

    /* Remember boundary string and source path.
	Put the preceeding -- on the front to make our life easier when
	parsing the rest later. */
    strbuf bs = strbuf_local(r->boundary_string, sizeof r->boundary_string);
    strbuf_puts(bs, "--");
    strbuf_puts(bs, boundary_string);
    if (strbuf_overrun(bs))
      return rhizome_server_simple_http_response(r,500,"<html><h1>Internal server error: Multipart boundary string too long</h1></html>\r\n");
    strbuf ps = strbuf_local(r->path, sizeof r->path);
    strbuf_puts(ps, path);
    if (strbuf_overrun(ps))
      return rhizome_server_simple_http_response(r,500,"<html><h1>Internal server error: Path too long</h1></html>\r\n");
    r->boundary_string_length = strbuf_len(bs);
    r->source_index = 0;
    r->source_count = content_length;
    r->request_type = RHIZOME_HTTP_REQUEST_RECEIVING_MULTIPART;
    r->request_length = 0;
    r->source_flags = 0;

    /* Find the end of the headers and start of any body bytes that we have read
	so far. Copy the bytes to a separate buffer, because r->request and 
	r->request_length get used internally in the parser.
      */
    if (contentlen) {
      char buffer[contentlen];
      bcopy(content, buffer, contentlen);
      rhizome_direct_process_post_multipart_bytes(r, buffer, contentlen);
    }

    /* Handle the rest of the transfer asynchronously. */
    return 0;
  } else {
    rhizome_server_simple_http_response(r, 404, "<html><h1>Not found (OTHER)</h1></html>\r\n");
  }
  
  /* Try sending data immediately. */
  rhizome_server_http_send_bytes(r);

  return 0;
}