Esempio n. 1
0
static int32_t
parse_breakpoint_no(char* args)
{
  char* ps = args;
  uint32_t l;

  if((*ps == '0')||(strlen(ps) >= BPNO_LETTER_NUM)) {
    return 0;
  }

  while( !(ISBLANK(*ps)||ISCNTRL(*ps)) ) {
    if(!ISDIGIT(*ps)) {
      return 0;
    }
    ps++;
  }

  STRTOUL(l, args);
  return l;
}
Esempio n. 2
0
static bool
parse_bool (char *token, bool min, bool max)
{
  while (*token && ISSPACE(*token))
    ++token;

  if (ISDIGIT (*token))
    return parse_unsigned (token, min, max);

  /* FIXME: handle min and max.  */
  if (!strcasecmp (token, "true")) {
    return true;
  } else if (!strcasecmp (token, "false")) {
    return false;
  } else {
    emsg ("%s:%d: %s should be either false or true",
          preferences_file (), firstline, token);
    return false; /* Never reached.  */
  }
}
Esempio n. 3
0
extern int
operand2sig (char const *operand, char *signame)
{
    int signum;

    if (ISDIGIT (*operand))
    {
        char *endp;
        long int l = (errno = 0, strtol (operand, &endp, 10));
        int i = l;
        signum = (operand == endp || *endp || errno || i != l ? -1
                  : WIFSIGNALED (i) ? WTERMSIG (i) : i);
    }
    else
    {
        /* Convert signal to upper case in the C locale, not in the
           current locale.  Don't assume ASCII; it might be EBCDIC.  */
        char *upcased = xstrdup (operand);
        char *p;
        for (p = upcased; *p; p++)
            if (strchr ("abcdefghijklmnopqrstuvwxyz", *p))
                *p += 'A' - 'a';

        /* Look for the signal name, possibly prefixed by "SIG",
           and possibly lowercased.  */
        if (!(str2sig (upcased, &signum) == 0
                || (upcased[0] == 'S' && upcased[1] == 'I' && upcased[2] == 'G'
                    && str2sig (upcased + 3, &signum) == 0)))
            signum = -1;

        free (upcased);
    }

    if (signum < 0 || sig2str (signum, signame) != 0)
    {
        error (0, 0, _("%s: invalid signal"), operand);
        return -1;
    }

    return signum;
}
Esempio n. 4
0
File: typeck.c Progetto: AHelper/gcc
static tree
parse_signature_type (const unsigned char **ptr, const unsigned char *limit)
{
  tree type;
  gcc_assert (*ptr < limit);

  switch (**ptr)
    {
    case 'B':  (*ptr)++;  return byte_type_node;
    case 'C':  (*ptr)++;  return char_type_node;
    case 'D':  (*ptr)++;  return double_type_node;
    case 'F':  (*ptr)++;  return float_type_node;
    case 'S':  (*ptr)++;  return short_type_node;
    case 'I':  (*ptr)++;  return int_type_node;
    case 'J':  (*ptr)++;  return long_type_node;
    case 'Z':  (*ptr)++;  return boolean_type_node;
    case 'V':  (*ptr)++;  return void_type_node;
    case '[':
      for ((*ptr)++; (*ptr) < limit && ISDIGIT (**ptr); ) (*ptr)++;
      type = parse_signature_type (ptr, limit);
      type = build_java_array_type (type, -1); 
      break;
    case 'L':
      {
	const unsigned char *start = ++(*ptr);
	const unsigned char *str = start;
	for ( ; ; str++)
	  {
	    gcc_assert (str < limit);
	    if (*str == ';')
	      break;
	  }
	*ptr = str+1;
	type = lookup_class (unmangle_classname ((const char *) start, str - start));
	break;
      }
    default:
      gcc_unreachable ();
    }
  return promote_type (type);
}
Esempio n. 5
0
/*
 * Curl_sasl_decode_mech()
 *
 * Convert a SASL mechanism name into a token.
 *
 * Parameters:
 *
 * ptr    [in]     - The mechanism string.
 * maxlen [in]     - Maximum mechanism string length.
 * len    [out]    - If not NULL, effective name length.
 *
 * Returns the SASL mechanism token or 0 if no match.
 */
unsigned int Curl_sasl_decode_mech(const char *ptr, size_t maxlen, size_t *len)
{
  unsigned int i;
  char c;

  for(i = 0; mechtable[i].name; i++) {
    if(maxlen >= mechtable[i].len &&
       !memcmp(ptr, mechtable[i].name, mechtable[i].len)) {
      if(len)
        *len = mechtable[i].len;

      if(maxlen == mechtable[i].len)
        return mechtable[i].bit;

      c = ptr[mechtable[i].len];
      if(!ISUPPER(c) && !ISDIGIT(c) && c != '-' && c != '_')
        return mechtable[i].bit;
    }
  }

  return 0;
}
Esempio n. 6
0
static int
add_field_list ( char *str )
{
  int added = 0;
  int file = -1, field = -1;
  int dot_found = 0;

  for (; *str; str++)
    {
      if (*str == ',' || isblank (*str))
	{
	  added += add_field (file, field);
	  file = field = -1;
	  dot_found = 0;
	}
      else if (*str == '.')
	dot_found = 1;
      else if (ISDIGIT (*str))
	{
	  if (!dot_found)
	    {
	      if (file == -1)
		file = 0;
	      file = file * 10 + *str - '0';
	    }
	  else
	    {
	      if (field == -1)
		field = 0;
	      field = field * 10 + *str - '0';
	    }
	}
      else
	return 0;
    }

  added += add_field (file, field);
  return added;
}
Esempio n. 7
0
static int
str2signum (char const *signame)
{
  if (ISDIGIT (*signame))
    {
      char *endp;
      long int n = strtol (signame, &endp, 10);
      if (! *endp && n <= SIGNUM_BOUND)
        return n;
    }
  else
    {
      unsigned int i;
      for (i = 0; i < NUMNAME_ENTRIES; i++)
        if (strcmp (numname_table[i].name, signame) == 0)
          return numname_table[i].num;

      {
        char *endp;
        int rtmin = SIGRTMIN;
        int rtmax = SIGRTMAX;

        if (0 < rtmin && strncmp (signame, "RTMIN", 5) == 0)
          {
            long int n = strtol (signame + 5, &endp, 10);
            if (! *endp && 0 <= n && n <= rtmax - rtmin)
              return rtmin + n;
          }
        else if (0 < rtmax && strncmp (signame, "RTMAX", 5) == 0)
          {
            long int n = strtol (signame + 5, &endp, 10);
            if (! *endp && rtmin - rtmax <= n && n <= 0)
              return rtmax + n;
          }
      }
    }

  return -1;
}
Esempio n. 8
0
File: class.c Progetto: genki/ruby
int
rb_scan_args(int argc, const VALUE *argv, const char *fmt, ...)
{
    int n, i = 0;
    const char *p = fmt;
    VALUE *var;
    va_list vargs;

    va_start(vargs, fmt);

    if (*p == '*') goto rest_arg;

    if (ISDIGIT(*p)) {
	n = *p - '0';
	if (n > argc)
	    rb_raise(rb_eArgError, "wrong number of arguments (%d for %d)", argc, n);
	for (i=0; i<n; i++) {
	    var = va_arg(vargs, VALUE*);
	    if (var) *var = argv[i];
	}
	p++;
    }
Esempio n. 9
0
static char *
whatreg (unsigned int *preg, char *src)
{
  unsigned int new_reg;

  /* src[0] is already known to be a digit.  */
  if (ISDIGIT (src[1]))
    {
      new_reg = (src[0] - '0') * 10 + src[1] - '0';
      src += 2;
    }
  else
    {
      new_reg = (src[0] - '0');
      src += 1;
    }

  if (src[0] != 0 && src[0] != ',' && src[0] != '(' && src[0] != ')')
    return NULL;

  *preg = new_reg;
  return src;
}
Esempio n. 10
0
  SymbolTable::Kind SymbolTable::detect_kind(const char* str, size_t size) {
    const char one = str[0];

    // A constant begins with an uppercase letter.
    if(one >= 'A' && one <= 'Z') {
      // Make sure that the rest of it is only alphanumerics
      for(size_t i = 1; i < size; i++) {
        if((isalnum(str[i]) || str[i] == '_') == false)
          return SymbolTable::Normal;
      }
      return SymbolTable::Constant;
    }

    if(one == '@') {
      // A class variable begins with @@
      if(size > 1 && str[1] == '@') {
        return SymbolTable::CVar;
      }

      // An instance variable can't start with a digit and can't be just @.
      if((size == 1) || (size > 1 && ISDIGIT(str[1]))) {
        return SymbolTable::Normal;
      }

      // An instance variable begins with @
      return SymbolTable::IVar;
    }

    // A system variable begins with __
    if(size > 2 && one == '_' && str[1] == '_') {
      return SymbolTable::System;
    }

    // Everything else is normal
    return SymbolTable::Normal;
  }
Esempio n. 11
0
static bool
decode_num (uintmax_t *num, char const *arg, uintmax_t maxval,
	    char const *keyword)
{
  uintmax_t u;
  char *arg_lim;

  if (! (ISDIGIT (*arg)
	 && (errno = 0, u = strtoumax (arg, &arg_lim, 10), !*arg_lim)))
    {
      ERROR ((0, 0, _("Malformed extended header: invalid %s=%s"),
	      keyword, arg));
      return false;
    }

  if (! (u <= maxval && errno != ERANGE))
    {
      out_of_range_header (keyword, arg, 0, maxval);
      return false;
    }

  *num = u;
  return true;
}
Esempio n. 12
0
static int
ctor_prio (const char *name)
{
  /* The name will look something like _GLOBAL_$I$65535$test02__Fv.
     There might be extra leading underscores, and the $ characters
     might be something else.  The I might be a D.  */

  while (*name == '_')
    ++name;

  if (! CONST_STRNEQ (name, "GLOBAL_"))
    return -1;

  name += sizeof "GLOBAL_" - 1;

  if (name[0] != name[2])
    return -1;
  if (name[1] != 'I' && name[1] != 'D')
    return -1;
  if (! ISDIGIT (name[3]))
    return -1;

  return atoi (name + 3);
}
Esempio n. 13
0
/* Define __GNUC__, __GNUC_MINOR__ and __GNUC_PATCHLEVEL__.  */
static void
define__GNUC__ (void)
{
  /* The format of the version string, enforced below, is
     ([^0-9]*-)?[0-9]+[.][0-9]+([.][0-9]+)?([- ].*)?  */
  const char *q, *v = version_string;

  while (*v && ! ISDIGIT (*v))
    v++;
  if (!*v || (v > version_string && v[-1] != '-'))
    abort ();

  q = v;
  while (ISDIGIT (*v))
    v++;
  builtin_define_with_value_n ("__GNUC__", q, v - q);
  if (c_dialect_cxx ())
    builtin_define_with_value_n ("__GNUG__", q, v - q);

  if (*v != '.' || !ISDIGIT (v[1]))
    abort ();
  q = ++v;
  while (ISDIGIT (*v))
    v++;
  builtin_define_with_value_n ("__GNUC_MINOR__", q, v - q);

  if (*v == '.')
    {
      if (!ISDIGIT (v[1]))
	abort ();
      q = ++v;
      while (ISDIGIT (*v))
	v++;
      builtin_define_with_value_n ("__GNUC_PATCHLEVEL__", q, v - q);
    }
  else
    builtin_define_with_value_n ("__GNUC_PATCHLEVEL__", "0", 1);

  if (*v && *v != ' ' && *v != '-')
    abort ();
}
Esempio n. 14
0
File: http.c Progetto: aosm/wget
/* Parse the `Content-Range' header and extract the information it
   contains.  Returns 1 if successful, -1 otherwise.  */
static int
http_process_range (const char *hdr, void *arg)
{
  struct http_process_range_closure *closure
    = (struct http_process_range_closure *)arg;
  long num;

  /* Certain versions of Nutscape proxy server send out
     `Content-Length' without "bytes" specifier, which is a breach of
     RFC2068 (as well as the HTTP/1.1 draft which was current at the
     time).  But hell, I must support it...  */
  if (!strncasecmp (hdr, "bytes", 5))
    {
      hdr += 5;
      hdr += skip_lws (hdr);
      if (!*hdr)
	return 0;
    }
  if (!ISDIGIT (*hdr))
    return 0;
  for (num = 0; ISDIGIT (*hdr); hdr++)
    num = 10 * num + (*hdr - '0');
  if (*hdr != '-' || !ISDIGIT (*(hdr + 1)))
    return 0;
  closure->first_byte_pos = num;
  ++hdr;
  for (num = 0; ISDIGIT (*hdr); hdr++)
    num = 10 * num + (*hdr - '0');
  if (*hdr != '/' || !ISDIGIT (*(hdr + 1)))
    return 0;
  closure->last_byte_pos = num;
  ++hdr;
  for (num = 0; ISDIGIT (*hdr); hdr++)
    num = 10 * num + (*hdr - '0');
  closure->entity_length = num;
  return 1;
}
Esempio n. 15
0
size_t Curl_ftp_parselist(char *buffer, size_t size, size_t nmemb,
                          void *connptr)
{
  size_t bufflen = size*nmemb;
  struct connectdata *conn = (struct connectdata *)connptr;
  struct ftp_wc_tmpdata *tmpdata = conn->data->wildcard.tmp;
  struct ftp_parselist_data *parser = tmpdata->parser;
  struct curl_fileinfo *finfo;
  unsigned long i = 0;
  CURLcode result;

  if(parser->error) { /* error in previous call */
    /* scenario:
     * 1. call => OK..
     * 2. call => OUT_OF_MEMORY (or other error)
     * 3. (last) call => is skipped RIGHT HERE and the error is hadled later
     *    in wc_statemach()
     */
    return bufflen;
  }

  if(parser->os_type == OS_TYPE_UNKNOWN && bufflen > 0) {
    /* considering info about FILE response format */
    parser->os_type = (buffer[0] >= '0' && buffer[0] <= '9') ?
                       OS_TYPE_WIN_NT : OS_TYPE_UNIX;
  }

  while(i < bufflen) { /* FSM */

    char c = buffer[i];
    if(!parser->file_data) { /* tmp file data is not allocated yet */
      parser->file_data = Curl_fileinfo_alloc();
      if(!parser->file_data) {
        parser->error = CURLE_OUT_OF_MEMORY;
        return bufflen;
      }
      parser->file_data->b_data = malloc(FTP_BUFFER_ALLOCSIZE);
      if(!parser->file_data->b_data) {
        PL_ERROR(conn, CURLE_OUT_OF_MEMORY);
        return bufflen;
      }
      parser->file_data->b_size = FTP_BUFFER_ALLOCSIZE;
      parser->item_offset = 0;
      parser->item_length = 0;
    }

    finfo = parser->file_data;
    finfo->b_data[finfo->b_used++] = c;

    if(finfo->b_used >= finfo->b_size - 1) {
      /* if it is important, extend buffer space for file data */
      char *tmp = realloc(finfo->b_data,
                          finfo->b_size + FTP_BUFFER_ALLOCSIZE);
      if(tmp) {
        finfo->b_size += FTP_BUFFER_ALLOCSIZE;
        finfo->b_data = tmp;
      }
      else {
        Curl_fileinfo_dtor(NULL, parser->file_data);
        parser->file_data = NULL;
        parser->error = CURLE_OUT_OF_MEMORY;
        PL_ERROR(conn, CURLE_OUT_OF_MEMORY);
        return bufflen;
      }
    }

    switch (parser->os_type) {
    case OS_TYPE_UNIX:
      switch (parser->state.UNIX.main) {
      case PL_UNIX_TOTALSIZE:
        switch(parser->state.UNIX.sub.total_dirsize) {
        case PL_UNIX_TOTALSIZE_INIT:
          if(c == 't') {
            parser->state.UNIX.sub.total_dirsize = PL_UNIX_TOTALSIZE_READING;
            parser->item_length++;
          }
          else {
            parser->state.UNIX.main = PL_UNIX_FILETYPE;
            /* start FSM again not considering size of directory */
            finfo->b_used = 0;
            i--;
          }
          break;
        case PL_UNIX_TOTALSIZE_READING:
          parser->item_length++;
          if(c == '\r') {
            parser->item_length--;
            finfo->b_used--;
          }
          else if(c == '\n') {
            finfo->b_data[parser->item_length - 1] = 0;
            if(strncmp("total ", finfo->b_data, 6) == 0) {
              char *endptr = finfo->b_data+6;
              /* here we can deal with directory size, pass the leading white
                 spaces and then the digits */
              while(ISSPACE(*endptr))
                endptr++;
              while(ISDIGIT(*endptr))
                endptr++;
              if(*endptr != 0) {
                PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST);
                return bufflen;
              }
              else {
                parser->state.UNIX.main = PL_UNIX_FILETYPE;
                finfo->b_used = 0;
              }
            }
            else {
              PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST);
              return bufflen;
            }
          }
          break;
        }
        break;
      case PL_UNIX_FILETYPE:
        switch (c) {
        case '-':
          finfo->filetype = CURLFILETYPE_FILE;
          break;
        case 'd':
          finfo->filetype = CURLFILETYPE_DIRECTORY;
          break;
        case 'l':
          finfo->filetype = CURLFILETYPE_SYMLINK;
          break;
        case 'p':
          finfo->filetype = CURLFILETYPE_NAMEDPIPE;
          break;
        case 's':
          finfo->filetype = CURLFILETYPE_SOCKET;
          break;
        case 'c':
          finfo->filetype = CURLFILETYPE_DEVICE_CHAR;
          break;
        case 'b':
          finfo->filetype = CURLFILETYPE_DEVICE_BLOCK;
          break;
        case 'D':
          finfo->filetype = CURLFILETYPE_DOOR;
          break;
        default:
          PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST);
          return bufflen;
        }
        parser->state.UNIX.main = PL_UNIX_PERMISSION;
        parser->item_length = 0;
        parser->item_offset = 1;
        break;
      case PL_UNIX_PERMISSION:
        parser->item_length++;
        if(parser->item_length <= 9) {
          if(!strchr("rwx-tTsS", c)) {
            PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST);
            return bufflen;
          }
        }
        else if(parser->item_length == 10) {
          unsigned int perm;
          if(c != ' ') {
            PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST);
            return bufflen;
          }
          finfo->b_data[10] = 0; /* terminate permissions */
          perm = ftp_pl_get_permission(finfo->b_data + parser->item_offset);
          if(perm & FTP_LP_MALFORMATED_PERM) {
            PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST);
            return bufflen;
          }
          parser->file_data->flags |= CURLFINFOFLAG_KNOWN_PERM;
          parser->file_data->perm = perm;
          parser->offsets.perm = parser->item_offset;

          parser->item_length = 0;
          parser->state.UNIX.main = PL_UNIX_HLINKS;
          parser->state.UNIX.sub.hlinks = PL_UNIX_HLINKS_PRESPACE;
        }
        break;
      case PL_UNIX_HLINKS:
        switch(parser->state.UNIX.sub.hlinks) {
        case PL_UNIX_HLINKS_PRESPACE:
          if(c != ' ') {
            if(c >= '0' && c <= '9') {
              parser->item_offset = finfo->b_used - 1;
              parser->item_length = 1;
              parser->state.UNIX.sub.hlinks = PL_UNIX_HLINKS_NUMBER;
            }
            else {
              PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST);
              return bufflen;
            }
          }
          break;
        case PL_UNIX_HLINKS_NUMBER:
          parser->item_length ++;
          if(c == ' ') {
            char *p;
            long int hlinks;
            finfo->b_data[parser->item_offset + parser->item_length - 1] = 0;
            hlinks = strtol(finfo->b_data + parser->item_offset, &p, 10);
            if(p[0] == '\0' && hlinks != LONG_MAX && hlinks != LONG_MIN) {
              parser->file_data->flags |= CURLFINFOFLAG_KNOWN_HLINKCOUNT;
              parser->file_data->hardlinks = hlinks;
            }
            parser->item_length = 0;
            parser->item_offset = 0;
            parser->state.UNIX.main = PL_UNIX_USER;
            parser->state.UNIX.sub.user = PL_UNIX_USER_PRESPACE;
          }
          else if(c < '0' || c > '9') {
            PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST);
            return bufflen;
          }
          break;
        }
        break;
      case PL_UNIX_USER:
        switch(parser->state.UNIX.sub.user) {
        case PL_UNIX_USER_PRESPACE:
          if(c != ' ') {
            parser->item_offset = finfo->b_used - 1;
            parser->item_length = 1;
            parser->state.UNIX.sub.user = PL_UNIX_USER_PARSING;
          }
          break;
        case PL_UNIX_USER_PARSING:
          parser->item_length++;
          if(c == ' ') {
            finfo->b_data[parser->item_offset + parser->item_length - 1] = 0;
            parser->offsets.user = parser->item_offset;
            parser->state.UNIX.main = PL_UNIX_GROUP;
            parser->state.UNIX.sub.group = PL_UNIX_GROUP_PRESPACE;
            parser->item_offset = 0;
            parser->item_length = 0;
          }
          break;
        }
        break;
      case PL_UNIX_GROUP:
        switch(parser->state.UNIX.sub.group) {
        case PL_UNIX_GROUP_PRESPACE:
          if(c != ' ') {
            parser->item_offset = finfo->b_used - 1;
            parser->item_length = 1;
            parser->state.UNIX.sub.group = PL_UNIX_GROUP_NAME;
          }
          break;
        case PL_UNIX_GROUP_NAME:
          parser->item_length++;
          if(c == ' ') {
            finfo->b_data[parser->item_offset + parser->item_length - 1] = 0;
            parser->offsets.group = parser->item_offset;
            parser->state.UNIX.main = PL_UNIX_SIZE;
            parser->state.UNIX.sub.size = PL_UNIX_SIZE_PRESPACE;
            parser->item_offset = 0;
            parser->item_length = 0;
          }
          break;
        }
        break;
      case PL_UNIX_SIZE:
        switch(parser->state.UNIX.sub.size) {
        case PL_UNIX_SIZE_PRESPACE:
          if(c != ' ') {
            if(c >= '0' && c <= '9') {
              parser->item_offset = finfo->b_used - 1;
              parser->item_length = 1;
              parser->state.UNIX.sub.size = PL_UNIX_SIZE_NUMBER;
            }
            else {
              PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST);
              return bufflen;
            }
          }
          break;
        case PL_UNIX_SIZE_NUMBER:
          parser->item_length++;
          if(c == ' ') {
            char *p;
            curl_off_t fsize;
            finfo->b_data[parser->item_offset + parser->item_length - 1] = 0;
            fsize = curlx_strtoofft(finfo->b_data+parser->item_offset, &p, 10);
            if(p[0] == '\0' && fsize != CURL_OFF_T_MAX &&
                               fsize != CURL_OFF_T_MIN) {
              parser->file_data->flags |= CURLFINFOFLAG_KNOWN_SIZE;
              parser->file_data->size = fsize;
            }
            parser->item_length = 0;
            parser->item_offset = 0;
            parser->state.UNIX.main = PL_UNIX_TIME;
            parser->state.UNIX.sub.time = PL_UNIX_TIME_PREPART1;
          }
          else if(!ISDIGIT(c)) {
            PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST);
            return bufflen;
          }
          break;
        }
        break;
      case PL_UNIX_TIME:
        switch(parser->state.UNIX.sub.time) {
        case PL_UNIX_TIME_PREPART1:
          if(c != ' ') {
            if(ISALNUM(c)) {
              parser->item_offset = finfo->b_used -1;
              parser->item_length = 1;
              parser->state.UNIX.sub.time = PL_UNIX_TIME_PART1;
            }
            else {
              PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST);
              return bufflen;
            }
          }
          break;
        case PL_UNIX_TIME_PART1:
          parser->item_length++;
          if(c == ' ') {
            parser->state.UNIX.sub.time = PL_UNIX_TIME_PREPART2;
          }
          else if(!ISALNUM(c) && c != '.') {
            PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST);
            return bufflen;
          }
          break;
        case PL_UNIX_TIME_PREPART2:
          parser->item_length++;
          if(c != ' ') {
            if(ISALNUM(c)) {
              parser->state.UNIX.sub.time = PL_UNIX_TIME_PART2;
            }
            else {
              PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST);
              return bufflen;
            }
          }
          break;
        case PL_UNIX_TIME_PART2:
          parser->item_length++;
          if(c == ' ') {
            parser->state.UNIX.sub.time = PL_UNIX_TIME_PREPART3;
          }
          else if(!ISALNUM(c) && c != '.') {
            PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST);
            return bufflen;
          }
          break;
        case PL_UNIX_TIME_PREPART3:
          parser->item_length++;
          if(c != ' ') {
            if(ISALNUM(c)) {
              parser->state.UNIX.sub.time = PL_UNIX_TIME_PART3;
            }
            else {
              PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST);
              return bufflen;
            }
          }
          break;
        case PL_UNIX_TIME_PART3:
          parser->item_length++;
          if(c == ' ') {
            finfo->b_data[parser->item_offset + parser->item_length -1] = 0;
            parser->offsets.time = parser->item_offset;
            if(ftp_pl_gettime(parser, finfo->b_data + parser->item_offset)) {
              parser->file_data->flags |= CURLFINFOFLAG_KNOWN_TIME;
            }
            if(finfo->filetype == CURLFILETYPE_SYMLINK) {
              parser->state.UNIX.main = PL_UNIX_SYMLINK;
              parser->state.UNIX.sub.symlink = PL_UNIX_SYMLINK_PRESPACE;
            }
            else {
              parser->state.UNIX.main = PL_UNIX_FILENAME;
              parser->state.UNIX.sub.filename = PL_UNIX_FILENAME_PRESPACE;
            }
          }
          else if(!ISALNUM(c) && c != '.' && c != ':') {
            PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST);
            return bufflen;
          }
          break;
        }
        break;
      case PL_UNIX_FILENAME:
        switch(parser->state.UNIX.sub.filename) {
        case PL_UNIX_FILENAME_PRESPACE:
          if(c != ' ') {
            parser->item_offset = finfo->b_used - 1;
            parser->item_length = 1;
            parser->state.UNIX.sub.filename = PL_UNIX_FILENAME_NAME;
          }
          break;
        case PL_UNIX_FILENAME_NAME:
          parser->item_length++;
          if(c == '\r') {
            parser->item_length--;
            parser->state.UNIX.sub.filename = PL_UNIX_FILENAME_WINDOWSEOL;
          }
          else if(c == '\n') {
            finfo->b_data[parser->item_offset + parser->item_length - 1] = 0;
            parser->offsets.filename = parser->item_offset;
            parser->state.UNIX.main = PL_UNIX_FILETYPE;
            result = ftp_pl_insert_finfo(conn, finfo);
            if(result) {
              PL_ERROR(conn, result);
              return bufflen;
            }
          }
          break;
        case PL_UNIX_FILENAME_WINDOWSEOL:
          if(c == '\n') {
            finfo->b_data[parser->item_offset + parser->item_length] = 0;
            parser->offsets.filename = parser->item_offset;
            parser->state.UNIX.main = PL_UNIX_FILETYPE;
            result = ftp_pl_insert_finfo(conn, finfo);
            if(result) {
              PL_ERROR(conn, result);
              return bufflen;
            }
          }
          else {
            PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST);
            return bufflen;
          }
          break;
        }
        break;
      case PL_UNIX_SYMLINK:
        switch(parser->state.UNIX.sub.symlink) {
        case PL_UNIX_SYMLINK_PRESPACE:
          if(c != ' ') {
            parser->item_offset = finfo->b_used - 1;
            parser->item_length = 1;
            parser->state.UNIX.sub.symlink = PL_UNIX_SYMLINK_NAME;
          }
          break;
        case PL_UNIX_SYMLINK_NAME:
          parser->item_length++;
          if(c == ' ') {
            parser->state.UNIX.sub.symlink = PL_UNIX_SYMLINK_PRETARGET1;
          }
          else if(c == '\r' || c == '\n') {
            PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST);
            return bufflen;
          }
          break;
        case PL_UNIX_SYMLINK_PRETARGET1:
          parser->item_length++;
          if(c == '-') {
            parser->state.UNIX.sub.symlink = PL_UNIX_SYMLINK_PRETARGET2;
          }
          else if(c == '\r' || c == '\n') {
            PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST);
            return bufflen;
          }
          else {
            parser->state.UNIX.sub.symlink = PL_UNIX_SYMLINK_NAME;
          }
          break;
        case PL_UNIX_SYMLINK_PRETARGET2:
          parser->item_length++;
          if(c == '>') {
            parser->state.UNIX.sub.symlink = PL_UNIX_SYMLINK_PRETARGET3;
          }
          else if(c == '\r' || c == '\n') {
            PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST);
            return bufflen;
          }
          else {
            parser->state.UNIX.sub.symlink = PL_UNIX_SYMLINK_NAME;
          }
          break;
        case PL_UNIX_SYMLINK_PRETARGET3:
          parser->item_length++;
          if(c == ' ') {
            parser->state.UNIX.sub.symlink = PL_UNIX_SYMLINK_PRETARGET4;
            /* now place where is symlink following */
            finfo->b_data[parser->item_offset + parser->item_length - 4] = 0;
            parser->offsets.filename = parser->item_offset;
            parser->item_length = 0;
            parser->item_offset = 0;
          }
          else if(c == '\r' || c == '\n') {
            PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST);
            return bufflen;
          }
          else {
            parser->state.UNIX.sub.symlink = PL_UNIX_SYMLINK_NAME;
          }
          break;
        case PL_UNIX_SYMLINK_PRETARGET4:
          if(c != '\r' && c != '\n') {
            parser->state.UNIX.sub.symlink = PL_UNIX_SYMLINK_TARGET;
            parser->item_offset = finfo->b_used - 1;
            parser->item_length = 1;
          }
          else {
            PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST);
            return bufflen;
          }
          break;
        case PL_UNIX_SYMLINK_TARGET:
          parser->item_length ++;
          if(c == '\r') {
            parser->item_length --;
            parser->state.UNIX.sub.symlink = PL_UNIX_SYMLINK_WINDOWSEOL;
          }
          else if(c == '\n') {
            finfo->b_data[parser->item_offset + parser->item_length - 1] = 0;
            parser->offsets.symlink_target = parser->item_offset;
            result = ftp_pl_insert_finfo(conn, finfo);
            if(result) {
              PL_ERROR(conn, result);
              return bufflen;
            }
            parser->state.UNIX.main = PL_UNIX_FILETYPE;
          }
          break;
        case PL_UNIX_SYMLINK_WINDOWSEOL:
          if(c == '\n') {
            finfo->b_data[parser->item_offset + parser->item_length - 1] = 0;
            parser->offsets.symlink_target = parser->item_offset;
            result = ftp_pl_insert_finfo(conn, finfo);
            if(result) {
              PL_ERROR(conn, result);
              return bufflen;
            }
            parser->state.UNIX.main = PL_UNIX_FILETYPE;
          }
          else {
            PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST);
            return bufflen;
          }
          break;
        }
        break;
      }
      break;
    case OS_TYPE_WIN_NT:
      switch(parser->state.NT.main) {
      case PL_WINNT_DATE:
        parser->item_length++;
        if(parser->item_length < 9) {
          if(!strchr("0123456789-", c)) { /* only simple control */
            PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST);
            return bufflen;
          }
        }
        else if(parser->item_length == 9) {
          if(c == ' ') {
            parser->state.NT.main = PL_WINNT_TIME;
            parser->state.NT.sub.time = PL_WINNT_TIME_PRESPACE;
          }
          else {
            PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST);
            return bufflen;
          }
        }
        else {
          PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST);
          return bufflen;
        }
        break;
      case PL_WINNT_TIME:
        parser->item_length++;
        switch(parser->state.NT.sub.time) {
        case PL_WINNT_TIME_PRESPACE:
          if(!ISSPACE(c)) {
            parser->state.NT.sub.time = PL_WINNT_TIME_TIME;
          }
          break;
        case PL_WINNT_TIME_TIME:
          if(c == ' ') {
            parser->offsets.time = parser->item_offset;
            finfo->b_data[parser->item_offset + parser->item_length -1] = 0;
            parser->state.NT.main = PL_WINNT_DIRORSIZE;
            parser->state.NT.sub.dirorsize = PL_WINNT_DIRORSIZE_PRESPACE;
            parser->item_length = 0;
          }
          else if(!strchr("APM0123456789:", c)) {
            PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST);
            return bufflen;
          }
          break;
        }
        break;
      case PL_WINNT_DIRORSIZE:
        switch(parser->state.NT.sub.dirorsize) {
        case PL_WINNT_DIRORSIZE_PRESPACE:
          if(c == ' ') {

          }
          else {
            parser->item_offset = finfo->b_used - 1;
            parser->item_length = 1;
            parser->state.NT.sub.dirorsize = PL_WINNT_DIRORSIZE_CONTENT;
          }
          break;
        case PL_WINNT_DIRORSIZE_CONTENT:
          parser->item_length ++;
          if(c == ' ') {
            finfo->b_data[parser->item_offset + parser->item_length - 1] = 0;
            if(strcmp("<DIR>", finfo->b_data + parser->item_offset) == 0) {
              finfo->filetype = CURLFILETYPE_DIRECTORY;
              finfo->size = 0;
            }
            else {
              char *endptr;
              finfo->size = curlx_strtoofft(finfo->b_data +
                                            parser->item_offset,
                                            &endptr, 10);
              if(!*endptr) {
                if(finfo->size == CURL_OFF_T_MAX ||
                   finfo->size == CURL_OFF_T_MIN) {
                  if(errno == ERANGE) {
                    PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST);
                    return bufflen;
                  }
                }
              }
              else {
                PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST);
                return bufflen;
              }
              /* correct file type */
              parser->file_data->filetype = CURLFILETYPE_FILE;
            }

            parser->file_data->flags |= CURLFINFOFLAG_KNOWN_SIZE;
            parser->item_length = 0;
            parser->state.NT.main = PL_WINNT_FILENAME;
            parser->state.NT.sub.filename = PL_WINNT_FILENAME_PRESPACE;
          }
          break;
        }
        break;
      case PL_WINNT_FILENAME:
        switch (parser->state.NT.sub.filename) {
        case PL_WINNT_FILENAME_PRESPACE:
          if(c != ' ') {
            parser->item_offset = finfo->b_used -1;
            parser->item_length = 1;
            parser->state.NT.sub.filename = PL_WINNT_FILENAME_CONTENT;
          }
          break;
        case PL_WINNT_FILENAME_CONTENT:
          parser->item_length++;
          if(c == '\r') {
            parser->state.NT.sub.filename = PL_WINNT_FILENAME_WINEOL;
            finfo->b_data[finfo->b_used - 1] = 0;
          }
          else if(c == '\n') {
            parser->offsets.filename = parser->item_offset;
            finfo->b_data[finfo->b_used - 1] = 0;
            parser->offsets.filename = parser->item_offset;
            result = ftp_pl_insert_finfo(conn, finfo);
            if(result) {
              PL_ERROR(conn, result);
              return bufflen;
            }
            parser->state.NT.main = PL_WINNT_DATE;
            parser->state.NT.sub.filename = PL_WINNT_FILENAME_PRESPACE;
          }
          break;
        case PL_WINNT_FILENAME_WINEOL:
          if(c == '\n') {
            parser->offsets.filename = parser->item_offset;
            result = ftp_pl_insert_finfo(conn, finfo);
            if(result) {
              PL_ERROR(conn, result);
              return bufflen;
            }
            parser->state.NT.main = PL_WINNT_DATE;
            parser->state.NT.sub.filename = PL_WINNT_FILENAME_PRESPACE;
          }
          else {
            PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST);
            return bufflen;
          }
          break;
        }
        break;
      }
      break;
    default:
      return bufflen + 1;
    }

    i++;
  }

  return bufflen;
}
Esempio n. 16
0
static enum numbered_backup_result
numbered_backup (char **buffer, size_t buffer_size, size_t filelen)
{
  enum numbered_backup_result result = BACKUP_IS_NEW;
  DIR *dirp;
  struct dirent *dp;
  char *buf = *buffer;
  size_t versionlenmax = 1;
  char *base = last_component (buf);
  size_t base_offset = base - buf;
  size_t baselen = base_len (base);

  /* Temporarily modify the buffer into its parent directory name,
     open the directory, and then restore the buffer.  */
  char tmp[sizeof "."];
  memcpy (tmp, base, sizeof ".");
  strcpy (base, ".");
  dirp = opendir (buf);
  memcpy (base, tmp, sizeof ".");
  strcpy (base + baselen, ".~1~");

  if (!dirp)
    return result;

  while ((dp = readdir (dirp)) != NULL)
    {
      char const *p;
      char *q;
      bool all_9s;
      size_t versionlen;
      size_t new_buflen;

      if (! REAL_DIR_ENTRY (dp) || _D_EXACT_NAMLEN (dp) < baselen + 4)
        continue;

      if (memcmp (buf + base_offset, dp->d_name, baselen + 2) != 0)
        continue;

      p = dp->d_name + baselen + 2;

      /* Check whether this file has a version number and if so,
         whether it is larger.  Use string operations rather than
         integer arithmetic, to avoid problems with integer overflow.  */

      if (! ('1' <= *p && *p <= '9'))
        continue;
      all_9s = (*p == '9');
      for (versionlen = 1; ISDIGIT (p[versionlen]); versionlen++)
        all_9s &= (p[versionlen] == '9');

      if (! (p[versionlen] == '~' && !p[versionlen + 1]
             && (versionlenmax < versionlen
                 || (versionlenmax == versionlen
                     && memcmp (buf + filelen + 2, p, versionlen) <= 0))))
        continue;

      /* This directory has the largest version number seen so far.
         Append this highest numbered extension to the file name,
         prepending '0' to the number if it is all 9s.  */

      versionlenmax = all_9s + versionlen;
      result = (all_9s ? BACKUP_IS_LONGER : BACKUP_IS_SAME_LENGTH);
      new_buflen = filelen + 2 + versionlenmax + 1;
      if (buffer_size <= new_buflen)
        {
          buf = xnrealloc (buf, 2, new_buflen);
          buffer_size = new_buflen * 2;
        }
      q = buf + filelen;
      *q++ = '.';
      *q++ = '~';
      *q = '0';
      q += all_9s;
      memcpy (q, p, versionlen + 2);

      /* Add 1 to the version number.  */

      q += versionlen;
      while (*--q == '9')
        *q = '0';
      ++*q;
    }

  closedir (dirp);
  *buffer = buf;
  return result;
}
Esempio n. 17
0
static int ProcessRequest(struct httprequest *req)
{
  char *line=&req->reqbuf[req->checkindex];
  bool chunked = FALSE;
  static char request[REQUEST_KEYWORD_SIZE];
  static char doc[MAXDOCNAMELEN];
  static char prot_str[5];
  char logbuf[256];
  int prot_major, prot_minor;
  char *end;
  int error;
  end = strstr(line, END_OF_HEADERS);

  logmsg("ProcessRequest() called with testno %ld and line [%s]",
         req->testno, line);

  /* try to figure out the request characteristics as soon as possible, but
     only once! */
  if((req->testno == DOCNUMBER_NOTHING) &&
     sscanf(line,
            "%" REQUEST_KEYWORD_SIZE_TXT"s %" MAXDOCNAMELEN_TXT "s %4s/%d.%d",
            request,
            doc,
            prot_str,
            &prot_major,
            &prot_minor) == 5) {
    char *ptr;

    if(!strcmp(prot_str, "HTTP")) {
        req->protocol = RPROT_HTTP;
    }
    else if(!strcmp(prot_str, "RTSP")) {
        req->protocol = RPROT_RTSP;
    }
    else {
        req->protocol = RPROT_NONE;
        logmsg("got unknown protocol %s", prot_str);
        return 1;
    }

    req->prot_version = prot_major*10 + prot_minor;

    /* find the last slash */
    ptr = strrchr(doc, '/');

    /* get the number after it */
    if(ptr) {
      FILE *stream;
      char *filename;

      if((strlen(doc) + strlen(request)) < 200)
        sprintf(logbuf, "Got request: %s %s %s/%d.%d",
                request, doc, prot_str, prot_major, prot_minor);
      else
        sprintf(logbuf, "Got a *HUGE* request %s/%d.%d",
                prot_str, prot_major, prot_minor);
      logmsg("%s", logbuf);

      if(!strncmp("/verifiedserver", ptr, 15)) {
        logmsg("Are-we-friendly question received");
        req->testno = DOCNUMBER_WERULEZ;
        return 1; /* done */
      }

      if(!strncmp("/quit", ptr, 5)) {
        logmsg("Request-to-quit received");
        req->testno = DOCNUMBER_QUIT;
        return 1; /* done */
      }

      ptr++; /* skip the slash */

      /* skip all non-numericals following the slash */
      while(*ptr && !ISDIGIT(*ptr))
        ptr++;

      req->testno = strtol(ptr, &ptr, 10);

      if(req->testno > 10000) {
        req->partno = req->testno % 10000;
        req->testno /= 10000;
      }
      else
        req->partno = 0;

      sprintf(logbuf, "Requested test number %ld part %ld",
              req->testno, req->partno);
      logmsg("%s", logbuf);

      filename = test2file(req->testno);

      stream=fopen(filename, "rb");
      if(!stream) {
        error = ERRNO;
        logmsg("fopen() failed with error: %d %s", error, strerror(error));
        logmsg("Error opening file: %s", filename);
        logmsg("Couldn't open test file %ld", req->testno);
        req->open = FALSE; /* closes connection */
        return 1; /* done */
      }
      else {
        char *cmd = NULL;
        size_t cmdsize = 0;
        int num=0;

        int rtp_channel = 0;
        int rtp_size = 0;
        int rtp_partno = -1;
        int i = 0;
        char *rtp_scratch = NULL;

        /* get the custom server control "commands" */
        cmd = (char *)spitout(stream, "reply", "servercmd", &cmdsize);
        ptr = cmd;
        fclose(stream);

        if(cmdsize) {
          logmsg("Found a reply-servercmd section!");
          do {
            if(!strncmp(CMD_AUTH_REQUIRED, ptr, strlen(CMD_AUTH_REQUIRED))) {
              logmsg("instructed to require authorization header");
              req->auth_req = TRUE;
            }
            else if(!strncmp(CMD_IDLE, ptr, strlen(CMD_IDLE))) {
              logmsg("instructed to idle");
              req->rcmd = RCMD_IDLE;
              req->open = TRUE;
            }
            else if(!strncmp(CMD_STREAM, ptr, strlen(CMD_STREAM))) {
              logmsg("instructed to stream");
              req->rcmd = RCMD_STREAM;
            }
            else if(1 == sscanf(ptr, "pipe: %d", &num)) {
              logmsg("instructed to allow a pipe size of %d", num);
              if(num < 0)
                logmsg("negative pipe size ignored");
              else if(num > 0)
                req->pipe = num-1; /* decrease by one since we don't count the
                                      first request in this number */
            }
            else if(1 == sscanf(ptr, "skip: %d", &num)) {
              logmsg("instructed to skip this number of bytes %d", num);
              req->skip = num;
            }
            else if(3 == sscanf(ptr, "rtp: part %d channel %d size %d",
                                &rtp_partno, &rtp_channel, &rtp_size)) {

              if(rtp_partno == req->partno) {
                logmsg("RTP: part %d channel %d size %d",
                       rtp_partno, rtp_channel, rtp_size);

                /* Make our scratch buffer enough to fit all the
                 * desired data and one for padding */
                rtp_scratch = malloc(rtp_size + 4 + RTP_DATA_SIZE);

                /* RTP is signalled with a $ */
                rtp_scratch[0] = '$';

                /* The channel follows and is one byte */
                rtp_scratch[1] = (char)(rtp_channel & 0xFF);

                /* Length follows and is a two byte short in network order */
                *((unsigned short *)(&rtp_scratch[2])) =
                  htons((unsigned short)rtp_size);

                /* Fill it with junk data */
                for(i = 0; i < rtp_size; i+= RTP_DATA_SIZE) {
                  memcpy(rtp_scratch + 4 + i, RTP_DATA, RTP_DATA_SIZE);
                }

                if(req->rtp_buffer == NULL) {
                  req->rtp_buffer = rtp_scratch;
                  req->rtp_buffersize = rtp_size + 4;
                } else {
                  req->rtp_buffer = realloc(req->rtp_buffer, req->rtp_buffersize + rtp_size + 4);
                  memcpy(req->rtp_buffer + req->rtp_buffersize, rtp_scratch, rtp_size + 4);
                  req->rtp_buffersize += rtp_size + 4;
                  free(rtp_scratch);
                }
                logmsg("rtp_buffersize is %zu, rtp_size is %d.", req->rtp_buffersize, rtp_size);

              }
            }
            else {
              logmsg("funny instruction found: %s", ptr);
            }

            ptr = strchr(ptr, '\n');
            if(ptr)
              ptr++;
            else
              ptr = NULL;
          } while(ptr && *ptr);
          logmsg("Done parsing server commands");
        }
      }
    }
    else {
      if(sscanf(req->reqbuf, "CONNECT %" MAXDOCNAMELEN_TXT "s HTTP/%d.%d",
                doc, &prot_major, &prot_minor) == 3) {
        sprintf(logbuf, "Received a CONNECT %s HTTP/%d.%d request",
                doc, prot_major, prot_minor);
        logmsg("%s", logbuf);

        if(req->prot_version == 10)
          req->open = FALSE; /* HTTP 1.0 closes connection by default */

        if(!strncmp(doc, "bad", 3))
          /* if the host name starts with bad, we fake an error here */
          req->testno = DOCNUMBER_BADCONNECT;
        else if(!strncmp(doc, "test", 4)) {
          /* if the host name starts with test, the port number used in the
             CONNECT line will be used as test number! */
          char *portp = strchr(doc, ':');
          if(portp)
            req->testno = atoi(portp+1);
          else
            req->testno = DOCNUMBER_CONNECT;
        }
        else
          req->testno = DOCNUMBER_CONNECT;
      }
      else {
        logmsg("Did not find test number in PATH");
        req->testno = DOCNUMBER_404;
      }
    }
  }

  if(!end) {
    /* we don't have a complete request yet! */
    logmsg("ProcessRequest returned without a complete request");
    return 0; /* not complete yet */
  }
  logmsg("ProcessRequest found a complete request");

  if(req->pipe)
    /* we do have a full set, advance the checkindex to after the end of the
       headers, for the pipelining case mostly */
    req->checkindex += (end - line) + strlen(END_OF_HEADERS);

  /* **** Persistence ****
   *
   * If the request is a HTTP/1.0 one, we close the connection unconditionally
   * when we're done.
   *
   * If the request is a HTTP/1.1 one, we MUST check for a "Connection:"
   * header that might say "close". If it does, we close a connection when
   * this request is processed. Otherwise, we keep the connection alive for X
   * seconds.
   */

  do {
    if(got_exit_signal)
      return 1; /* done */

    if((req->cl==0) && curlx_strnequal("Content-Length:", line, 15)) {
      /* If we don't ignore content-length, we read it and we read the whole
         request including the body before we return. If we've been told to
         ignore the content-length, we will return as soon as all headers
         have been received */
      size_t cl = strtol(line+15, &line, 10);
      req->cl = cl - req->skip;

      logmsg("Found Content-Length: %zu in the request", cl);
      if(req->skip)
        logmsg("... but will abort after %zu bytes", req->cl);
      break;
    }
    else if(curlx_strnequal("Transfer-Encoding: chunked", line,
                            strlen("Transfer-Encoding: chunked"))) {
      /* chunked data coming in */
      chunked = TRUE;
    }

    if(chunked) {
      if(strstr(req->reqbuf, "\r\n0\r\n\r\n"))
        /* end of chunks reached */
        return 1; /* done */
      else
        return 0; /* not done */
    }

    line = strchr(line, '\n');
    if(line)
      line++;

  } while(line);

  if(!req->auth && strstr(req->reqbuf, "Authorization:")) {
    req->auth = TRUE; /* Authorization: header present! */
    if(req->auth_req)
      logmsg("Authorization header found, as required");
  }

  if(!req->digest && strstr(req->reqbuf, "Authorization: Digest")) {
    /* If the client is passing this Digest-header, we set the part number
       to 1000. Not only to spice up the complexity of this, but to make
       Digest stuff to work in the test suite. */
    req->partno += 1000;
    req->digest = TRUE; /* header found */
    logmsg("Received Digest request, sending back data %ld", req->partno);
  }
  else if(!req->ntlm &&
          strstr(req->reqbuf, "Authorization: NTLM TlRMTVNTUAAD")) {
    /* If the client is passing this type-3 NTLM header */
    req->partno += 1002;
    req->ntlm = TRUE; /* NTLM found */
    logmsg("Received NTLM type-3, sending back data %ld", req->partno);
    if(req->cl) {
      logmsg("  Expecting %zu POSTed bytes", req->cl);
    }
  }
  else if(!req->ntlm &&
          strstr(req->reqbuf, "Authorization: NTLM TlRMTVNTUAAB")) {
    /* If the client is passing this type-1 NTLM header */
    req->partno += 1001;
    req->ntlm = TRUE; /* NTLM found */
    logmsg("Received NTLM type-1, sending back data %ld", req->partno);
  }
  else if((req->partno >= 1000) && strstr(req->reqbuf, "Authorization: Basic")) {
    /* If the client is passing this Basic-header and the part number is already
       >=1000, we add 1 to the part number.  This allows simple Basic authentication
       negotiation to work in the test suite. */
    req->partno += 1;
    logmsg("Received Basic request, sending back data %ld", req->partno);
  }
  if(strstr(req->reqbuf, "Connection: close"))
    req->open = FALSE; /* close connection after this request */

  if(!req->pipe &&
     req->open &&
     req->prot_version >= 11 &&
     end &&
     req->reqbuf + req->offset > end + strlen(END_OF_HEADERS) &&
     (!strncmp(req->reqbuf, "GET", strlen("GET")) ||
      !strncmp(req->reqbuf, "HEAD", strlen("HEAD")))) {
    /* If we have a persistent connection, HTTP version >= 1.1
       and GET/HEAD request, enable pipelining. */
    req->checkindex = (end - req->reqbuf) + strlen(END_OF_HEADERS);
    req->pipelining = TRUE;
  }

  while(req->pipe) {
    if(got_exit_signal)
      return 1; /* done */
    /* scan for more header ends within this chunk */
    line = &req->reqbuf[req->checkindex];
    end = strstr(line, END_OF_HEADERS);
    if(!end)
      break;
    req->checkindex += (end - line) + strlen(END_OF_HEADERS);
    req->pipe--;
  }

  /* If authentication is required and no auth was provided, end now. This
     makes the server NOT wait for PUT/POST data and you can then make the
     test case send a rejection before any such data has been sent. Test case
     154 uses this.*/
  if(req->auth_req && !req->auth)
    return 1; /* done */

  if(req->cl > 0) {
    if(req->cl <= req->offset - (end - req->reqbuf) - strlen(END_OF_HEADERS))
      return 1; /* done */
    else
      return 0; /* not complete yet */
  }

  return 1; /* done */
}
Esempio n. 18
0
int
_doprnt (const char *format, va_list ap, FILE *stream)
{
  const char * ptr = format;
  char specifier[128];
  int total_printed = 0;
  
  while (*ptr != '\0')
    {
      if (*ptr != '%') /* While we have regular characters, print them.  */
	PRINT_CHAR(*ptr);
      else /* We got a format specifier! */
	{
	  char * sptr = specifier;
	  int wide_width = 0, short_width = 0;
	  
	  *sptr++ = *ptr++; /* Copy the % and move forward.  */

	  while (strchr ("-+ #0", *ptr)) /* Move past flags.  */
	    *sptr++ = *ptr++;

	  if (*ptr == '*')
	    COPY_VA_INT;
	  else
	    while (ISDIGIT(*ptr)) /* Handle explicit numeric value.  */
	      *sptr++ = *ptr++;
	  
	  if (*ptr == '.')
	    {
	      *sptr++ = *ptr++; /* Copy and go past the period.  */
	      if (*ptr == '*')
		COPY_VA_INT;
	      else
		while (ISDIGIT(*ptr)) /* Handle explicit numeric value.  */
		  *sptr++ = *ptr++;
	    }
	  while (strchr ("hlL", *ptr))
	    {
	      switch (*ptr)
		{
		case 'h':
		  short_width = 1;
		  break;
		case 'l':
		  wide_width++;
		  break;
		case 'L':
		  wide_width = 2;
		  break;
		default:
		  abort();
		}
	      *sptr++ = *ptr++;
	    }

	  switch (*ptr)
	    {
	    case 'd':
	    case 'i':
	    case 'o':
	    case 'u':
	    case 'x':
	    case 'X':
	    case 'c':
	      {
		/* Short values are promoted to int, so just copy it
                   as an int and trust the C library printf to cast it
                   to the right width.  */
		if (short_width)
		  PRINT_TYPE(int);
		else
		  {
		    switch (wide_width)
		      {
		      case 0:
			PRINT_TYPE(int);
			break;
		      case 1:
			PRINT_TYPE(long);
			break;
		      case 2:
		      default:
#if defined(__GNUC__) || defined(HAVE_LONG_LONG)
			PRINT_TYPE(long long);
#else
			PRINT_TYPE(long); /* Fake it and hope for the best.  */
#endif
			break;
		      } /* End of switch (wide_width) */
		  } /* End of else statement */
	      } /* End of integer case */
	      break;
	    case 'f':
	    case 'e':
	    case 'E':
	    case 'g':
	    case 'G':
	      {
		if (wide_width == 0)
		  PRINT_TYPE(double);
		else
		  {
#if defined(__GNUC__) || defined(HAVE_LONG_DOUBLE)
		    PRINT_TYPE(long double);
#else
		    PRINT_TYPE(double); /* Fake it and hope for the best.  */
#endif
		  }
	      }
	      break;
	    case 's':
	      PRINT_TYPE(char *);
	      break;
	    case 'p':
	      PRINT_TYPE(void *);
	      break;
	    case '%':
	      PRINT_CHAR('%');
	      break;
	    default:
	      abort();
	    } /* End of switch (*ptr) */
	} /* End of else statement */
    }

  return total_printed;
}
Esempio n. 19
0
/* returns 1 (true) if pattern is OK, 0 if is bad ("p" is pattern pointer) */
static int setcharset(unsigned char **p, unsigned char *charset)
{
  setcharset_state state = CURLFNM_SCHS_DEFAULT;
  unsigned char rangestart = 0;
  unsigned char lastchar   = 0;
  bool something_found = FALSE;
  unsigned char c;
  for(;;) {
    c = **p;
    switch(state) {
    case CURLFNM_SCHS_DEFAULT:
      if(ISALNUM(c)) { /* ASCII value */
        rangestart = c;
        charset[c] = 1;
        (*p)++;
        state = CURLFNM_SCHS_MAYRANGE;
        something_found = TRUE;
      }
      else if(c == ']') {
        if(something_found)
          return SETCHARSET_OK;
        else
          something_found = TRUE;
        state = CURLFNM_SCHS_RIGHTBR;
        charset[c] = 1;
        (*p)++;
      }
      else if(c == '[') {
        char c2 = *((*p)+1);
        if(c2 == ':') { /* there has to be a keyword */
          (*p) += 2;
          if(parsekeyword(p, charset)) {
            state = CURLFNM_SCHS_DEFAULT;
          }
          else
            return SETCHARSET_FAIL;
        }
        else {
          charset[c] = 1;
          (*p)++;
        }
        something_found = TRUE;
      }
      else if(c == '?' || c == '*') {
        something_found = TRUE;
        charset[c] = 1;
        (*p)++;
      }
      else if(c == '^' || c == '!') {
        if(!something_found) {
          if(charset[CURLFNM_NEGATE]) {
            charset[c] = 1;
            something_found = TRUE;
          }
          else
            charset[CURLFNM_NEGATE] = 1; /* negate charset */
        }
        else
          charset[c] = 1;
        (*p)++;
      }
      else if(c == '\\') {
        c = *(++(*p));
        if(ISPRINT((c))) {
          something_found = TRUE;
          state = CURLFNM_SCHS_MAYRANGE;
          charset[c] = 1;
          rangestart = c;
          (*p)++;
        }
        else
          return SETCHARSET_FAIL;
      }
      else if(c == '\0') {
        return SETCHARSET_FAIL;
      }
      else {
        charset[c] = 1;
        (*p)++;
        something_found = TRUE;
      }
      break;
    case CURLFNM_SCHS_MAYRANGE:
      if(c == '-') {
        charset[c] = 1;
        (*p)++;
        lastchar = '-';
        state = CURLFNM_SCHS_MAYRANGE2;
      }
      else if(c == '[') {
        state = CURLFNM_SCHS_DEFAULT;
      }
      else if(ISALNUM(c)) {
        charset[c] = 1;
        (*p)++;
      }
      else if(c == '\\') {
        c = *(++(*p));
        if(ISPRINT(c)) {
          charset[c] = 1;
          (*p)++;
        }
        else
          return SETCHARSET_FAIL;
      }
      else if(c == ']') {
        return SETCHARSET_OK;
      }
      else
        return SETCHARSET_FAIL;
      break;
    case CURLFNM_SCHS_MAYRANGE2:
      if(c == '\\') {
        c = *(++(*p));
        if(!ISPRINT(c))
          return SETCHARSET_FAIL;
      }
      if(c == ']') {
        return SETCHARSET_OK;
      }
      else if(c == '\\') {
        c = *(++(*p));
        if(ISPRINT(c)) {
          charset[c] = 1;
          state = CURLFNM_SCHS_DEFAULT;
          (*p)++;
        }
        else
          return SETCHARSET_FAIL;
      }
      if(c >= rangestart) {
        if((ISLOWER(c) && ISLOWER(rangestart)) ||
           (ISDIGIT(c) && ISDIGIT(rangestart)) ||
           (ISUPPER(c) && ISUPPER(rangestart))) {
          charset[lastchar] = 0;
          rangestart++;
          while(rangestart++ <= c)
            charset[rangestart-1] = 1;
          (*p)++;
          state = CURLFNM_SCHS_DEFAULT;
        }
        else
          return SETCHARSET_FAIL;
      }
      break;
    case CURLFNM_SCHS_RIGHTBR:
      if(c == '[') {
        state = CURLFNM_SCHS_RIGHTBRLEFTBR;
        charset[c] = 1;
        (*p)++;
      }
      else if(c == ']') {
        return SETCHARSET_OK;
      }
      else if(c == '\0') {
        return SETCHARSET_FAIL;
      }
      else if(ISPRINT(c)) {
        charset[c] = 1;
        (*p)++;
        state = CURLFNM_SCHS_DEFAULT;
      }
      else
        /* used 'goto fail' instead of 'return SETCHARSET_FAIL' to avoid a
         * nonsense warning 'statement not reached' at end of the fnc when
         * compiling on Solaris */
        goto fail;
      break;
    case CURLFNM_SCHS_RIGHTBRLEFTBR:
      if(c == ']') {
        return SETCHARSET_OK;
      }
      else {
        state  = CURLFNM_SCHS_DEFAULT;
        charset[c] = 1;
        (*p)++;
      }
      break;
    }
  }
fail:
  return SETCHARSET_FAIL;
}
Esempio n. 20
0
void
initialize ( int argc, char** argv )
{
  xmalloc_set_program_name (argv[0]);

  switch (argc)
    {
    case 1:
      break;

    case 2:
      if (strcmp (argv[1], "-v") == 0)
        do_version ();
      if (freopen (argv[1], "r", stdin) == (FILE*)NULL)
        {
          fprintf (stderr, "Error %d (%s) reopening %s as stdin\n",
                   errno, xstrerror (errno), argv[1] );
          exit (EXIT_FAILURE);
        }
      break;

    default:
      fputs ("fixincl ERROR:  too many command line arguments\n", stderr);
      exit (EXIT_FAILURE);
    }

#ifdef SIGCHLD
  /* We *MUST* set SIGCHLD to SIG_DFL so that the wait4() call will
     receive the signal.  A different setting is inheritable */
  signal (SIGCHLD, SIG_DFL);
#endif

  initialize_opts ();

  if (ISDIGIT ( *pz_verbose ))
    verbose_level = (te_verbose)atoi( pz_verbose );
  else
    switch (*pz_verbose) {
    case 's':
    case 'S':
      verbose_level = VERB_SILENT;     break;

    case 'f':
    case 'F':
      verbose_level = VERB_FIXES;      break;

    case 'a':
    case 'A':
      verbose_level = VERB_APPLIES;    break;

    default:
    case 'p':
    case 'P':
      verbose_level = VERB_PROGRESS;   break;

    case 't':
    case 'T':
      verbose_level = VERB_TESTS;      break;

    case 'e':
    case 'E':
      verbose_level = VERB_EVERYTHING; break;
    }
  if (verbose_level >= VERB_EVERYTHING) {
    verbose_level = VERB_EVERYTHING;
    fputs ("fixinc verbosity:  EVERYTHING\n", stderr);
  }
  while ((pz_find_base[0] == '.') && (pz_find_base[1] == '/'))
    pz_find_base += 2;
  if ((pz_find_base[0] != '.') || (pz_find_base[1] != NUL))
    find_base_len = strlen( pz_find_base );

  /*  Compile all the regular expressions now.
      That way, it is done only once for the whole run.
      */
  run_compiles ();

# ifdef SEPARATE_FIX_PROC
  /* NULL as the first argument to `tempnam' causes it to DTRT
     wrt the temporary directory where the file will be created.  */
  pz_temp_file = tempnam( NULL, "fxinc" );
# endif

  signal (SIGQUIT, SIG_IGN);
  signal (SIGIOT,  SIG_IGN);
  signal (SIGPIPE, SIG_IGN);
  signal (SIGALRM, SIG_IGN);
  signal (SIGTERM, SIG_IGN);
}
Esempio n. 21
0
/*History:
2015-01-29 17:28 初步看了下,没有例子,不知道实际解析时的情况,比较糊涂。最好是自己写例子测试一下的。另外看起来得了解一点html语法。

*/
const char *
htmlfindurl(const char *buf, int bufsize, int *size, int init)
{
    const char *p, *ph;
    state_t *s;

    /* NULL-terminated list of tags and modifiers someone would want to
       follow -- feel free to edit to suit your needs: */
    //z 允许的 html tags;声明为static ,只要一份即可。
    static struct tag_attr html_allow[] =
    {
        //z tag : attr 值对
        { "a", "href" },
        { "img", "src" },
        { "img", "href" },
        { "body", "background" },
        { "frame", "src" },
        { "iframe", "src" },
        { "fig", "src" },
        { "overlay", "src" },
        { "applet", "code" },
        { "script", "src" },
        { "embed", "src" },
        { "bgsound", "src" },
        { "area", "href" },
        { "img", "lowsrc" },
        { "input", "src" },
        { "layer", "src" },
        { "table", "background"},
        { "th", "background"},
        { "td", "background"},
        /* Tags below this line are treated specially.  */
        { "base", "href" },
        { "meta", "content" },
        { NULL, NULL }//z 最后以NULL作为结尾
    };

    s = &global_state;

    if (init)
    {
        DEBUGP (("Resetting a parser state.\n"));
        memset (s, 0, sizeof (*s));
    }

    while (1)
    {
        //z 如果 bufsize 为0,跳出循环
        if (!bufsize)
            break;

        /* Let's look for a tag, if we are not already in one.  */
        //z 首先寻找 tag
        if (!s->at_value)
        {
            /* Find '<'.  */
            //z 找到 <
            if (*buf != '<')
                for (; bufsize && *buf != '<'; ++buf, --bufsize);

            //z 如果 bufsize 为0 ,那么到达了结尾
            if (!bufsize)
                break;

            /* Skip spaces.  */
            //z 在处理的时候,跳过空格
            for (++buf, --bufsize; bufsize && ISSPACE (*buf) && *buf != '>';
                    ++buf, --bufsize);

            if (!bufsize)
                break;

            p = buf;

            /* Find the tag end.  */
            //z 直到找到空格或者找到 >,或者找到 =,或者到达结尾。
            for (; bufsize && !ISSPACE (*buf) && *buf != '>' && *buf != '=';
                    ++buf, --bufsize);

            if (!bufsize)
                break;

            //z 如果找到了 =
            if (*buf == '=')
            {
                /* <tag=something> is illegal.  Just skip it.  */
                ++buf, --bufsize;

                continue;
            }

            if (p == buf)
            {
                /* *buf == '>'.  */
                ++buf, --bufsize;

                continue;
            }

            s->tag = strdupdelim (p, buf);

            if (*buf == '>')
            {
                free (s->tag);
                s->tag = NULL;
                ++buf, --bufsize;
                continue;
            }
        }
        else                      /* s->at_value */
        {
            //z 这意思是在查找 value 。
            /* Reset AT_VALUE.  */
            s->at_value = 0;
            /* If in quotes, just skip out of them and continue living.  */
            if (s->in_quote)
            {
                s->in_quote = 0;
                for (; bufsize && *buf != s->quote_char; ++buf, --bufsize);

                if (!bufsize)
                    break;
                ++buf, --bufsize;
            }

            if (!bufsize)
                break;

            if (*buf == '>')
            {
                FREE_MAYBE (s->tag);
                FREE_MAYBE (s->attr);
                s->tag = s->attr = NULL;
                continue;
            }
        }

        /* Find the attributes.  */
        do
        {
            FREE_MAYBE (s->attr);
            s->attr = NULL;

            if (!bufsize)
                break;
            /* Skip the spaces if we have them.  We don't have them at
            places like <img alt="something"src="something-else">.
            ^ no spaces here */

            if (ISSPACE (*buf))
                for (++buf, --bufsize; bufsize && ISSPACE (*buf) && *buf != '>';
                        ++buf, --bufsize);

            if (!bufsize || *buf == '>')
                break;

            if (*buf == '=')
            {
                /* This is the case of <tag = something>, which is
                  illegal.  Just skip it.  */
                ++buf, --bufsize;
                continue;
            }

            p = buf;
            /* Find the attribute end.  */
            for (; bufsize && !ISSPACE (*buf) && *buf != '>' && *buf != '=';
                    ++buf, --bufsize);

            if (!bufsize || *buf == '>')
                break;

            //z 找到这其间的值为 attr 。
            /* Construct the attribute.  */
            s->attr = strdupdelim (p, buf);
            /* Now we must skip the spaces to find '='.  */
            if (*buf != '=')
            {
                for (; bufsize && ISSPACE (*buf) && *buf != '>'; ++buf, --bufsize);
                if (!bufsize || *buf == '>')
                    break;
            }

            /* If we still don't have '=', something is amiss.  */
            //z 是否找到了 = ,如果没有找到 = ,可能出现了错误。
            if (*buf != '=')
                continue;

            /* Find the beginning of attribute value by skipping the
            spaces.  */
            ++buf, --bufsize;
            //z 越过若干个空白字符。
            for (; bufsize && ISSPACE (*buf) && *buf != '>'; ++buf, --bufsize);
            //z 是否结束或者找到了‘>’
            if (!bufsize || *buf == '>')
                break;
            ph = NULL;
            /* The value of an attribute can, but does not have to be
            quoted.  */
            //z 如果当前字符为 ' 或者 " , 进入引号状态
            if (*buf == '\"' || *buf == '\'')
            {
                //z 进入 quote 状态
                s->in_quote = 1;
                //z 记住当前的字符串,方便寻找到下一个做比对。
                s->quote_char = *buf;
                //z p 指向引号内第一个字符
                p = buf + 1;
                //z 步进,直到找到另一个引号,或者遇到了回车
                for (++buf, --bufsize;
                        bufsize && *buf != s->quote_char && *buf != '\n';
                        ++buf, --bufsize)

                    //z 如果当前字符串为 # , 记录下其位置
                    if (*buf == '#')
                        ph = buf;
                if (!bufsize)
                {
                    //z 如果到达了字符结尾,结束 in_quote 状态
                    s->in_quote = 0;
                    break;
                }
                //z 如果遇到了 '\n' ,继续下一轮。
                if (*buf == '\n')
                {
                    /* #### Is the following logic good?

                     Obviously no longer in quote.  It might be well
                     to check whether '>' was encountered, but that
                     would be encouraging writers of invalid HTMLs,
                      and we don't want that, now do we?  */
                    s->in_quote = 0;
                    continue;
                }
            }
            else
            {
                p = buf;

                for (; bufsize && !ISSPACE (*buf) && *buf != '>'; ++buf, --bufsize)
                    if (*buf == '#')
                        ph = buf;
                if (!bufsize)
                    break;
            }

            //z URI 中的# ( found unprotected 是什么意思? ) # 可能表示的意思是一个 html marker 或者 color spec 。
            /* If '#' was found unprotected in a URI, it is probably an
            HTML marker, or color spec.  */
            //z 如果有 # ,那么将 ph 视作结束?
            *size = (ph ? ph : buf) - p;
            /* The URI is liable to be returned if:
            1) *size != 0;
            2) its tag and attribute are found in html_allow.  */
            //z 实际可能表示的例子有 : <a href="http://www.w3school.com.cn/">Visit W3School</a> 这个样子
            if (*size && idmatch (html_allow, s->tag, s->attr))
            {
                if (!strcasecmp (s->tag, "base") && !strcasecmp (s->attr, "href"))
                {
                    FREE_MAYBE (s->base);
                    s->base = strdupdelim (p, buf);
                }
                //z 比对 meta 和 content
                else if (!strcasecmp (s->tag, "meta") && !strcasecmp (s->attr, "content"))
                {
                    /* Some pages use a META tag to specify that the page
                    be refreshed by a new page after a given number of
                    seconds.  We need to attempt to extract an URL for
                    the new page from the other garbage present.  The
                    general format for this is:
                    <META HTTP-EQUIV=Refresh CONTENT="0; URL=index2.html">

                     So we just need to skip past the "0; URL="
                     garbage to get to the URL.  META tags are also
                     used for specifying random things like the page
                     author's name and what editor was used to create
                     it.  So we need to be careful to ignore them and
                      not assume that an URL will be present at all.  */
                    //z 只要是数字,那么持续向前
                    for (; *size && ISDIGIT (*p); p++, *size -= 1);

                    //z 查看是否会遇到 ;
                    if (*p == ';')
                    {
                        //z 跳过 space。
                        for (p++, *size -= 1; *size && ISSPACE (*p); p++, *size -= 1) ;
                        //z 比对,是否找到了 URL,
                        if (!strncasecmp (p, "URL=", 4))
                        {
                            //z 如果在 meta 中找到了 URL
                            p += 4, *size -= 4;
                            s->at_value = 1;
                            //z 这意思是直接返回 p?
                            return p;
                        }
                    }
                }
                else
                {
                    s->at_value = 1;
                    return p;
                }
            }

            /* Exit from quote.  */
            if (*buf == s->quote_char)
            {
                s->in_quote = 0;
                ++buf, --bufsize;
            }
        }
        while (*buf != '>');

        FREE_MAYBE (s->tag);
        FREE_MAYBE (s->attr);
        s->tag = s->attr = NULL;

        if (!bufsize)
            break;
    }

    FREE_MAYBE (s->tag);
    FREE_MAYBE (s->attr);
    FREE_MAYBE (s->base);

    memset (s, 0, sizeof (*s));	/* just to be sure */
    DEBUGP (("HTML parser ends here (state destroyed).\n"));

    return NULL;
}
Esempio n. 22
0
static CURLcode glob_range(URLGlob *glob, char **patternp,
                           size_t *posp, unsigned long *amount,
                           int globindex)
{
  /* processes a range expression with the point behind the opening '['
     - char range: e.g. "a-z]", "B-Q]"
     - num range: e.g. "0-9]", "17-2000]"
     - num range with leading zeros: e.g. "001-999]"
     expression is checked for well-formedness and collected until the next ']'
  */
  URLPattern *pat;
  int rc;
  char *pattern = *patternp;
  char *c;

  pat = &glob->pattern[glob->size];
  pat->globindex = globindex;

  if(ISALPHA(*pattern)) {
    /* character range detected */
    char min_c;
    char max_c;
    int step=1;

    pat->type = UPTCharRange;

    rc = sscanf(pattern, "%c-%c", &min_c, &max_c);

    if((rc == 2) && (pattern[3] == ':')) {
      char *endp;
      unsigned long lstep;
      errno = 0;
      lstep = strtoul(&pattern[4], &endp, 10);
      if(errno || (*endp != ']'))
        step = -1;
      else {
        pattern = endp+1;
        step = (int)lstep;
        if(step > (max_c - min_c))
          step = -1;
      }
    }
    else
      pattern += 4;

    *posp += (pattern - *patternp);

    if((rc != 2) || (min_c >= max_c) || ((max_c - min_c) > ('z' - 'a')) ||
       (step <= 0) )
      /* the pattern is not well-formed */
      return GLOBERROR("bad range", *posp, CURLE_URL_MALFORMAT);

    /* if there was a ":[num]" thing, use that as step or else use 1 */
    pat->content.CharRange.step = step;
    pat->content.CharRange.ptr_c = pat->content.CharRange.min_c = min_c;
    pat->content.CharRange.max_c = max_c;

    if(multiply(amount, (pat->content.CharRange.max_c -
                          pat->content.CharRange.min_c) /
                         pat->content.CharRange.step + 1) )
      return GLOBERROR("range overflow", *posp, CURLE_URL_MALFORMAT);
  }
  else if(ISDIGIT(*pattern)) {
    /* numeric range detected */
    unsigned long min_n;
    unsigned long max_n = 0;
    unsigned long step_n = 0;
    char *endp;

    pat->type = UPTNumRange;
    pat->content.NumRange.padlength = 0;

    if(*pattern == '0') {
      /* leading zero specified, count them! */
      c = pattern;
      while(ISDIGIT(*c)) {
        c++;
        ++pat->content.NumRange.padlength; /* padding length is set for all
                                              instances of this pattern */
      }
    }

    errno = 0;
    min_n = strtoul(pattern, &endp, 10);
    if(errno || (endp == pattern))
      endp=NULL;
    else {
      if(*endp != '-')
        endp = NULL;
      else {
        pattern = endp+1;
        errno = 0;
        max_n = strtoul(pattern, &endp, 10);
        if(errno || (*endp == ':')) {
          pattern = endp+1;
          errno = 0;
          step_n = strtoul(pattern, &endp, 10);
          if(errno)
            /* over/underflow situation */
            endp = NULL;
        }
        else
          step_n = 1;
        if(endp && (*endp == ']')) {
          pattern= endp+1;
        }
        else
          endp = NULL;
      }
    }

    *posp += (pattern - *patternp);

    if(!endp || (min_n > max_n) || (step_n > (max_n - min_n)) ||
       (step_n <= 0) )
      /* the pattern is not well-formed */
      return GLOBERROR("bad range", *posp, CURLE_URL_MALFORMAT);

    /* typecasting to ints are fine here since we make sure above that we
       are within 31 bits */
    pat->content.NumRange.ptr_n = pat->content.NumRange.min_n = min_n;
    pat->content.NumRange.max_n = max_n;
    pat->content.NumRange.step = step_n;

    if(multiply(amount, (pat->content.NumRange.max_n -
                         pat->content.NumRange.min_n) /
                        pat->content.NumRange.step + 1) )
      return GLOBERROR("range overflow", *posp, CURLE_URL_MALFORMAT);
  }
  else
    return GLOBERROR("bad range specification", *posp, CURLE_URL_MALFORMAT);

  *patternp = pattern;
  return CURLE_OK;
}
Esempio n. 23
0
static int
core_sym_class (asymbol *sym)
{
  symbol_info syminfo;
  const char *name;
  char sym_prefix;
  int i;

  if (sym->section == NULL || (sym->flags & BSF_DEBUGGING) != 0)
    return 0;

  /* Must be a text symbol, and static text symbols
     don't qualify if ignore_static_funcs set.   */
  if (ignore_static_funcs && (sym->flags & BSF_LOCAL))
    {
      DBG (AOUTDEBUG, printf ("[core_sym_class] %s: not a function\n",
			      sym->name));
      return 0;
    }

  bfd_get_symbol_info (core_bfd, sym, &syminfo);
  i = syminfo.type;

  if (i == 'T')
    return i;			/* It's a global symbol.  */

  if (i == 'W')
    /* Treat weak symbols as text symbols.  FIXME: a weak symbol may
       also be a data symbol.  */
    return 'T';

  if (i != 't')
    {
      /* Not a static text symbol.  */
      DBG (AOUTDEBUG, printf ("[core_sym_class] %s is of class %c\n",
			      sym->name, i));
      return 0;
    }

  /* Do some more filtering on static function-names.  */
  if (ignore_static_funcs)
    return 0;

  /* Can't zero-length name or funny characters in name, where
     `funny' includes: `.' (.o file names) and `$' (Pascal labels).  */
  if (!sym->name || sym->name[0] == '\0')
    return 0;

  for (name = sym->name; *name; ++name)
    {
      if (*name == '$')
        return 0;

      while (*name == '.')
	{
	  /* Allow both nested subprograms (which end with ".NNN", where N is
	     a digit) and GCC cloned functions (which contain ".clone").
	     Allow for multiple iterations of both - apparently GCC can clone
	     clones and subprograms.  */
	  int digit_seen = 0;
#define CLONE_NAME      ".clone."
#define CLONE_NAME_LEN  strlen (CLONE_NAME)
	      
	  if (strlen (name) > CLONE_NAME_LEN
	      && strncmp (name, CLONE_NAME, CLONE_NAME_LEN) == 0)
	    name += CLONE_NAME_LEN - 1;

	  for (name++; *name; name++)
	    if (digit_seen && *name == '.')
	      break;
	    else if (ISDIGIT (*name))
	      digit_seen = 1;
	    else
	      return 0;
	}
    }

  /* On systems where the C compiler adds an underscore to all
     names, static names without underscores seem usually to be
     labels in hand written assembler in the library.  We don't want
     these names.  This is certainly necessary on a Sparc running
     SunOS 4.1 (try profiling a program that does a lot of
     division). I don't know whether it has harmful side effects on
     other systems.  Perhaps it should be made configurable.  */
  sym_prefix = bfd_get_symbol_leading_char (core_bfd);

  if ((sym_prefix && sym_prefix != sym->name[0])
      /* GCC may add special symbols to help gdb figure out the file
	language.  We want to ignore these, since sometimes they mask
	the real function.  (dj@ctron)  */
      || !strncmp (sym->name, "__gnu_compiled", 14)
      || !strncmp (sym->name, "___gnu_compiled", 15))
    {
      return 0;
    }

  /* If the object file supports marking of function symbols, then
     we can zap anything that doesn't have BSF_FUNCTION set.  */
  if (ignore_non_functions && (sym->flags & BSF_FUNCTION) == 0)
    return 0;

  return 't';			/* It's a static text symbol.  */
}
Esempio n. 24
0
static int
alias_rtsp_out(struct libalias *la, struct ip *pip,
               struct alias_link *lnk,
               char *data,
               const char *port_str)
{
    int hlen, tlen, dlen;
    struct tcphdr *tc;
    int i, j, pos, state, port_dlen, new_dlen, delta;
    u_short p[2], new_len;
    u_short sport, eport, base_port;
    u_short salias = 0, ealias = 0, base_alias = 0;
    const char *transport_str = "transport:";
    char newdata[2048], *port_data, *port_newdata, stemp[80];
    int links_created = 0, pkt_updated = 0;
    struct alias_link *rtsp_lnk = NULL;
    struct in_addr null_addr;

    /* Calculate data length of TCP packet */
    tc = (struct tcphdr *)ip_next(pip);
    hlen = (pip->ip_hl + tc->th_off) << 2;
    tlen = ntohs(pip->ip_len);
    dlen = tlen - hlen;

    /* Find keyword, "Transport: " */
    pos = search_string(data, dlen, transport_str);
    if (pos < 0) {
        return (-1);
    }
    port_data = data + pos;
    port_dlen = dlen - pos;

    memcpy(newdata, data, pos);
    port_newdata = newdata + pos;

    while (port_dlen > (int)strlen(port_str)) {
        /* Find keyword, appropriate port string */
        pos = search_string(port_data, port_dlen, port_str);
        if (pos < 0) {
            break;
        }
        memcpy(port_newdata, port_data, pos + 1);
        port_newdata += (pos + 1);

        p[0] = p[1] = 0;
        sport = eport = 0;
        state = 0;
        for (i = pos; i < port_dlen; i++) {
            switch (state) {
            case 0:
                if (port_data[i] == '=') {
                    state++;
                }
                break;
            case 1:
                if (ISDIGIT(port_data[i])) {
                    p[0] = p[0] * 10 + port_data[i] - '0';
                } else {
                    if (port_data[i] == ';') {
                        state = 3;
                    }
                    if (port_data[i] == '-') {
                        state++;
                    }
                }
                break;
            case 2:
                if (ISDIGIT(port_data[i])) {
                    p[1] = p[1] * 10 + port_data[i] - '0';
                } else {
                    state++;
                }
                break;
            case 3:
                base_port = p[0];
                sport = htons(p[0]);
                eport = htons(p[1]);

                if (!links_created) {

                    links_created = 1;
                    /*
                     * Find an even numbered port
                     * number base that satisfies the
                     * contiguous number of ports we
                     * need
                     */
                    null_addr.s_addr = 0;
                    if (0 == (salias = FindNewPortGroup(la, null_addr,
                                                        FindAliasAddress(la, pip->ip_src),
                                                        sport, 0,
                                                        RTSP_PORT_GROUP,
                                                        IPPROTO_UDP, 1))) {
#ifdef LIBALIAS_DEBUG
                        fprintf(stderr,
                                "PacketAlias/RTSP: Cannot find contiguous RTSP data ports\n");
#endif
                    } else {

                        base_alias = ntohs(salias);
                        for (j = 0; j < RTSP_PORT_GROUP; j++) {
                            /*
                             * Establish link
                             * to port found in
                             * RTSP packet
                             */
                            rtsp_lnk = FindRtspOut(la, GetOriginalAddress(lnk), null_addr,
                                                   htons(base_port + j), htons(base_alias + j),
                                                   IPPROTO_UDP);
                            if (rtsp_lnk != NULL) {
#ifndef NO_FW_PUNCH
                                /*
                                 * Punch
                                 * hole in
                                 * firewall
                                 */
                                PunchFWHole(rtsp_lnk);
#endif
                            } else {
#ifdef LIBALIAS_DEBUG
                                fprintf(stderr,
                                        "PacketAlias/RTSP: Cannot allocate RTSP data ports\n");
#endif
                                break;
                            }
                        }
                    }
                    ealias = htons(base_alias + (RTSP_PORT_GROUP - 1));
                }
                if (salias && rtsp_lnk) {

                    pkt_updated = 1;

                    /* Copy into IP packet */
                    sprintf(stemp, "%d", ntohs(salias));
                    memcpy(port_newdata, stemp, strlen(stemp));
                    port_newdata += strlen(stemp);

                    if (eport != 0) {
                        *port_newdata = '-';
                        port_newdata++;

                        /* Copy into IP packet */
                        sprintf(stemp, "%d", ntohs(ealias));
                        memcpy(port_newdata, stemp, strlen(stemp));
                        port_newdata += strlen(stemp);
                    }
                    *port_newdata = ';';
                    port_newdata++;
                }
                state++;
                break;
            }
            if (state > 3) {
                break;
            }
        }
        port_data += i;
        port_dlen -= i;
    }

    if (!pkt_updated)
        return (-1);

    memcpy(port_newdata, port_data, port_dlen);
    port_newdata += port_dlen;
    *port_newdata = '\0';

    /* Create new packet */
    new_dlen = port_newdata - newdata;
    memcpy(data, newdata, new_dlen);

    SetAckModified(lnk);
    tc = (struct tcphdr *)ip_next(pip);
    delta = GetDeltaSeqOut(tc->th_seq, lnk);
    AddSeq(lnk, delta + new_dlen - dlen, pip->ip_hl, pip->ip_len,
           tc->th_seq, tc->th_off);

    new_len = htons(hlen + new_dlen);
    DifferentialChecksum(&pip->ip_sum,
                         &new_len,
                         &pip->ip_len,
                         1);
    pip->ip_len = new_len;

    tc->th_sum = 0;
#ifdef _KERNEL
    tc->th_x2 = 1;
#else
    tc->th_sum = TcpChecksum(pip);
#endif
    return (0);
}
Esempio n. 25
0
static int loop(const unsigned char *pattern, const unsigned char *string)
{
  loop_state state = CURLFNM_LOOP_DEFAULT;
  unsigned char *p = (unsigned char *)pattern;
  unsigned char *s = (unsigned char *)string;
  unsigned char charset[CURLFNM_CHSET_SIZE] = { 0 };
  int rc = 0;

  for(;;) {
    switch(state) {
    case CURLFNM_LOOP_DEFAULT:
      if(*p == '*') {
        while(*(p+1) == '*') /* eliminate multiple stars */
          p++;
        if(*s == '\0' && *(p+1) == '\0')
          return CURL_FNMATCH_MATCH;
        rc = loop(p + 1, s); /* *.txt matches .txt <=> .txt matches .txt */
        if(rc == CURL_FNMATCH_MATCH)
          return CURL_FNMATCH_MATCH;
        if(*s) /* let the star eat up one character */
          s++;
        else
          return CURL_FNMATCH_NOMATCH;
      }
      else if(*p == '?') {
        if(ISPRINT(*s)) {
          s++;
          p++;
        }
        else if(*s == '\0')
          return CURL_FNMATCH_NOMATCH;
        else
          return CURL_FNMATCH_FAIL; /* cannot deal with other character */
      }
      else if(*p == '\0') {
        if(*s == '\0')
          return CURL_FNMATCH_MATCH;
        else
          return CURL_FNMATCH_NOMATCH;
      }
      else if(*p == '\\') {
        state = CURLFNM_LOOP_BACKSLASH;
        p++;
      }
      else if(*p == '[') {
        unsigned char *pp = p+1; /* cannot handle with pointer to register */
        if(setcharset(&pp, charset)) {
          int found = FALSE;
          if(charset[(unsigned int)*s])
            found = TRUE;
          else if(charset[CURLFNM_ALNUM])
            found = ISALNUM(*s);
          else if(charset[CURLFNM_ALPHA])
            found = ISALPHA(*s);
          else if(charset[CURLFNM_DIGIT])
            found = ISDIGIT(*s);
          else if(charset[CURLFNM_XDIGIT])
            found = ISXDIGIT(*s);
          else if(charset[CURLFNM_PRINT])
            found = ISPRINT(*s);
          else if(charset[CURLFNM_SPACE])
            found = ISSPACE(*s);
          else if(charset[CURLFNM_UPPER])
            found = ISUPPER(*s);
          else if(charset[CURLFNM_LOWER])
            found = ISLOWER(*s);
          else if(charset[CURLFNM_BLANK])
            found = ISBLANK(*s);
          else if(charset[CURLFNM_GRAPH])
            found = ISGRAPH(*s);

          if(charset[CURLFNM_NEGATE])
            found = !found;

          if(found) {
            p = pp+1;
            s++;
            memset(charset, 0, CURLFNM_CHSET_SIZE);
          }
          else
            return CURL_FNMATCH_NOMATCH;
        }
        else
          return CURL_FNMATCH_FAIL;
      }
      else {
        if(*p++ != *s++)
          return CURL_FNMATCH_NOMATCH;
      }
      break;
    case CURLFNM_LOOP_BACKSLASH:
      if(ISPRINT(*p)) {
        if(*p++ == *s++)
          state = CURLFNM_LOOP_DEFAULT;
        else
          return CURL_FNMATCH_NOMATCH;
      }
      else
        return CURL_FNMATCH_FAIL;
      break;
    }
  }
}
Esempio n. 26
0
/* Function that checks for an ending smtp status code at the start of the
   given string, but also detects the supported authentication mechanisms
   from  the EHLO AUTH response. */
static int smtp_endofresp(struct pingpong *pp, int *resp)
{
  char *line = pp->linestart_resp;
  size_t len = pp->nread_resp;
  struct connectdata *conn = pp->conn;
  struct smtp_conn *smtpc = &conn->proto.smtpc;
  int result;
  size_t wordlen;

  if(len < 4 || !ISDIGIT(line[0]) || !ISDIGIT(line[1]) || !ISDIGIT(line[2]))
    return FALSE;       /* Nothing for us */

  /* Extract the response code if necessary */
  if((result = (line[3] == ' ')) != 0)
    *resp = curlx_sltosi(strtol(line, NULL, 10));

  line += 4;
  len -= 4;

  if(smtpc->state == SMTP_EHLO && len >= 4 && !memcmp(line, "SIZE", 4)) {
    DEBUGF(infof(conn->data, "Server supports SIZE extension.\n"));
    smtpc->size_supported = true;
  }

  if(smtpc->state == SMTP_EHLO && len >= 5 && !memcmp(line, "AUTH ", 5)) {
    line += 5;
    len -= 5;

    for(;;) {
      while(len &&
            (*line == ' ' || *line == '\t' ||
             *line == '\r' || *line == '\n')) {
        line++;
        len--;
      }

      if(!len)
        break;

      for(wordlen = 0; wordlen < len && line[wordlen] != ' ' &&
            line[wordlen] != '\t' && line[wordlen] != '\r' &&
            line[wordlen] != '\n';)
        wordlen++;

      if(wordlen == 5 && !memcmp(line, "LOGIN", 5))
        smtpc->authmechs |= SASL_MECH_LOGIN;
      else if(wordlen == 5 && !memcmp(line, "PLAIN", 5))
        smtpc->authmechs |= SASL_MECH_PLAIN;
      else if(wordlen == 8 && !memcmp(line, "CRAM-MD5", 8))
        smtpc->authmechs |= SASL_MECH_CRAM_MD5;
      else if(wordlen == 10 && !memcmp(line, "DIGEST-MD5", 10))
        smtpc->authmechs |= SASL_MECH_DIGEST_MD5;
      else if(wordlen == 6 && !memcmp(line, "GSSAPI", 6))
        smtpc->authmechs |= SASL_MECH_GSSAPI;
      else if(wordlen == 8 && !memcmp(line, "EXTERNAL", 8))
        smtpc->authmechs |= SASL_MECH_EXTERNAL;
      else if(wordlen == 4 && !memcmp(line, "NTLM", 4))
        smtpc->authmechs |= SASL_MECH_NTLM;

      line += wordlen;
      len -= wordlen;
    }
  }

  return result;
}
Esempio n. 27
0
CURLcode glob_match_url(char **result, char *filename, URLGlob *glob)
{
  char *target;
  size_t allocsize;
  char numbuf[18];
  char *appendthis = NULL;
  size_t appendlen = 0;
  size_t stringlen = 0;

  *result = NULL;

  /* We cannot use the glob_buffer for storage here since the filename may
   * be longer than the URL we use. We allocate a good start size, then
   * we need to realloc in case of need.
   */
  allocsize = strlen(filename) + 1; /* make it at least one byte to store the
                                       trailing zero */
  target = malloc(allocsize);
  if(!target)
    return CURLE_OUT_OF_MEMORY;

  while(*filename) {
    if(*filename == '#' && ISDIGIT(filename[1])) {
      unsigned long i;
      char *ptr = filename;
      unsigned long num = strtoul(&filename[1], &filename, 10);
      URLPattern *pat =NULL;

      if(num < glob->size) {
        num--; /* make it zero based */
        /* find the correct glob entry */
        for(i=0; i<glob->size; i++) {
          if(glob->pattern[i].globindex == (int)num) {
            pat = &glob->pattern[i];
            break;
          }
        }
      }

      if(pat) {
        switch (pat->type) {
        case UPTSet:
          if(pat->content.Set.elements) {
            appendthis = pat->content.Set.elements[pat->content.Set.ptr_s];
            appendlen =
              strlen(pat->content.Set.elements[pat->content.Set.ptr_s]);
          }
          break;
        case UPTCharRange:
          numbuf[0] = pat->content.CharRange.ptr_c;
          numbuf[1] = 0;
          appendthis = numbuf;
          appendlen = 1;
          break;
        case UPTNumRange:
          snprintf(numbuf, sizeof(numbuf), "%0*d",
                   pat->content.NumRange.padlength,
                   pat->content.NumRange.ptr_n);
          appendthis = numbuf;
          appendlen = strlen(numbuf);
          break;
        default:
          fprintf(stderr, "internal error: invalid pattern type (%d)\n",
                  (int)pat->type);
          Curl_safefree(target);
          return CURLE_FAILED_INIT;
        }
      }
      else {
        /* #[num] out of range, use the #[num] in the output */
        filename = ptr;
        appendthis = filename++;
        appendlen = 1;
      }
    }
    else {
      appendthis = filename++;
      appendlen = 1;
    }
    if(appendlen + stringlen >= allocsize) {
      char *newstr;
      /* we append a single byte to allow for the trailing byte to be appended
         at the end of this function outside the while() loop */
      allocsize = (appendlen + stringlen) * 2;
      newstr = realloc(target, allocsize + 1);
      if(!newstr) {
        Curl_safefree(target);
        return CURLE_OUT_OF_MEMORY;
      }
      target = newstr;
    }
    memcpy(&target[stringlen], appendthis, appendlen);
    stringlen += appendlen;
  }
  target[stringlen]= '\0';
  *result = target;
  return CURLE_OK;
}
Esempio n. 28
0
int
rb_scan_args(int argc, const VALUE *argv, const char *fmt, ...)
{
    int i;
    const char *p = fmt;
    VALUE *var;
    va_list vargs;
    int f_var = 0, f_block = 0;
    int n_lead = 0, n_opt = 0, n_trail = 0, n_mand;
    int argi = 0;

    if (ISDIGIT(*p)) {
	n_lead = *p - '0';
	p++;
	if (ISDIGIT(*p)) {
	    n_opt = *p - '0';
	    p++;
	    if (ISDIGIT(*p)) {
		n_trail = *p - '0';
		p++;
		goto block_arg;
	    }
	}
    }
    if (*p == '*') {
	f_var = 1;
	p++;
	if (ISDIGIT(*p)) {
	    n_trail = *p - '0';
	    p++;
	}
    }
  block_arg:
    if (*p == '&') {
	f_block = 1;
	p++;
    }
    if (*p != '\0') {
	rb_fatal("bad scan arg format: %s", fmt);
    }
    n_mand = n_lead + n_trail;

    if (argc < n_mand)
	goto argc_error;

    va_start(vargs, fmt);

    /* capture leading mandatory arguments */
    for (i = n_lead; i-- > 0; ) {
	var = va_arg(vargs, VALUE *);
	if (var) *var = argv[argi];
	argi++;
    }
    /* capture optional arguments */
    for (i = n_opt; i-- > 0; ) {
	var = va_arg(vargs, VALUE *);
	if (argi < argc - n_trail) {
	    if (var) *var = argv[argi];
	    argi++;
	}
	else {
	    if (var) *var = Qnil;
	}
    }
    /* capture variable length arguments */
    if (f_var) {
	int n_var = argc - argi - n_trail;

	var = va_arg(vargs, VALUE *);
	if (0 < n_var) {
	    if (var) *var = rb_ary_new4(n_var, &argv[argi]);
	    argi += n_var;
	}
	else {
	    if (var) *var = rb_ary_new();
	}
    }
    /* capture trailing mandatory arguments */
    for (i = n_trail; i-- > 0; ) {
	var = va_arg(vargs, VALUE *);
	if (var) *var = argv[argi];
	argi++;
    }
    /* capture iterator block */
    if (f_block) {
	var = va_arg(vargs, VALUE *);
	if (rb_block_given_p()) {
	    *var = rb_block_proc();
	}
	else {
	    *var = Qnil;
	}
    }
    va_end(vargs);

    if (argi < argc)
	goto argc_error;

    return argc;

  argc_error:
    if (0 < n_opt)
	rb_raise(rb_eArgError, "wrong number of arguments (%d for %d..%d%s)",
		 argc, n_mand, n_mand + n_opt, f_var ? "+" : "");
    else
	rb_raise(rb_eArgError, "wrong number of arguments (%d for %d%s)",
		 argc, n_mand, f_var ? "+" : "");
}
Esempio n. 29
0
bfd_boolean
bfd_default_scan (const bfd_arch_info_type *info, const char *string)
{
  const char *ptr_src;
  const char *ptr_tst;
  unsigned long number;
  enum bfd_architecture arch;
  const char *printable_name_colon;

  /* Exact match of the architecture name (ARCH_NAME) and also the
     default architecture?  */
  if (strcasecmp (string, info->arch_name) == 0
      && info->the_default)
    return TRUE;

  /* Exact match of the machine name (PRINTABLE_NAME)?  */
  if (strcasecmp (string, info->printable_name) == 0)
    return TRUE;

  /* Given that printable_name contains no colon, attempt to match:
     ARCH_NAME [ ":" ] PRINTABLE_NAME?  */
  printable_name_colon = strchr (info->printable_name, ':');
  if (printable_name_colon == NULL)
    {
      size_t strlen_arch_name = strlen (info->arch_name);
      if (strncasecmp (string, info->arch_name, strlen_arch_name) == 0)
	{
	  if (string[strlen_arch_name] == ':')
	    {
	      if (strcasecmp (string + strlen_arch_name + 1,
			      info->printable_name) == 0)
		return TRUE;
	    }
	  else
	    {
	      if (strcasecmp (string + strlen_arch_name,
			      info->printable_name) == 0)
		return TRUE;
	    }
	}
    }

  /* Given that PRINTABLE_NAME has the form: <arch> ":" <mach>;
     Attempt to match: <arch> <mach>?  */
  if (printable_name_colon != NULL)
    {
      size_t colon_index = printable_name_colon - info->printable_name;
      if (strncasecmp (string, info->printable_name, colon_index) == 0
	  && strcasecmp (string + colon_index,
			 info->printable_name + colon_index + 1) == 0)
	return TRUE;
    }

  /* Given that PRINTABLE_NAME has the form: <arch> ":" <mach>; Do not
     attempt to match just <mach>, it could be ambiguous.  This test
     is left until later.  */

  /* NOTE: The below is retained for compatibility only.  Please do
     not add to this code.  */

  /* See how much of the supplied string matches with the
     architecture, eg the string m68k:68020 would match the 68k entry
     up to the :, then we get left with the machine number.  */

  for (ptr_src = string, ptr_tst = info->arch_name;
       *ptr_src && *ptr_tst;
       ptr_src++, ptr_tst++)
    {
      if (*ptr_src != *ptr_tst)
	break;
    }

  /* Chewed up as much of the architecture as will match, skip any
     colons.  */
  if (*ptr_src == ':')
    ptr_src++;

  if (*ptr_src == 0)
    {
      /* Nothing more, then only keep this one if it is the default
	 machine for this architecture.  */
      return info->the_default;
    }

  number = 0;
  while (ISDIGIT (*ptr_src))
    {
      number = number * 10 + *ptr_src - '0';
      ptr_src++;
    }

  /* NOTE: The below is retained for compatibility only.
     PLEASE DO NOT ADD TO THIS CODE.  */

  switch (number)
    {
      /* FIXME: These are needed to parse IEEE objects.  */
      /* The following seven case's are here only for compatibility with
	 older binutils (at least IEEE objects from binutils 2.9.1 require
	 them).  */
    case bfd_mach_m68000:
    case bfd_mach_m68010:
    case bfd_mach_m68020:
    case bfd_mach_m68030:
    case bfd_mach_m68040:
    case bfd_mach_m68060:
    case bfd_mach_cpu32:
      arch = bfd_arch_m68k;
      break;
    case 68000:
      arch = bfd_arch_m68k;
      number = bfd_mach_m68000;
      break;
    case 68010:
      arch = bfd_arch_m68k;
      number = bfd_mach_m68010;
      break;
    case 68020:
      arch = bfd_arch_m68k;
      number = bfd_mach_m68020;
      break;
    case 68030:
      arch = bfd_arch_m68k;
      number = bfd_mach_m68030;
      break;
    case 68040:
      arch = bfd_arch_m68k;
      number = bfd_mach_m68040;
      break;
    case 68060:
      arch = bfd_arch_m68k;
      number = bfd_mach_m68060;
      break;
    case 68332:
      arch = bfd_arch_m68k;
      number = bfd_mach_cpu32;
      break;
    case 5200:
      arch = bfd_arch_m68k;
      number = bfd_mach_mcf_isa_a_nodiv;
      break;
    case 5206:
      arch = bfd_arch_m68k;
      number = bfd_mach_mcf_isa_a_mac;
      break;
    case 5307:
      arch = bfd_arch_m68k;
      number = bfd_mach_mcf_isa_a_mac;
      break;
    case 5407:
      arch = bfd_arch_m68k;
      number = bfd_mach_mcf_isa_b_nousp_mac;
      break;
    case 5282:
      arch = bfd_arch_m68k;
      number = bfd_mach_mcf_isa_aplus_emac;
      break;

    case 32000:
      arch = bfd_arch_we32k;
      break;

    case 3000:
      arch = bfd_arch_mips;
      number = bfd_mach_mips3000;
      break;

    case 4000:
      arch = bfd_arch_mips;
      number = bfd_mach_mips4000;
      break;

    case 6000:
      arch = bfd_arch_rs6000;
      break;

    case 7410:
      arch = bfd_arch_sh;
      number = bfd_mach_sh_dsp;
      break;

    case 7708:
      arch = bfd_arch_sh;
      number = bfd_mach_sh3;
      break;

    case 7729:
      arch = bfd_arch_sh;
      number = bfd_mach_sh3_dsp;
      break;

    case 7750:
      arch = bfd_arch_sh;
      number = bfd_mach_sh4;
      break;

    default:
      return FALSE;
    }

  if (arch != info->arch)
    return FALSE;

  if (number != info->mach)
    return FALSE;

  return TRUE;
}
Esempio n. 30
0
/* Incomming string format: host[:port][,host[:port]]... */
int ares_set_servers_csv(ares_channel channel,
                         const char* _csv)
{
  int i;
  char* csv = NULL;
  char* ptr;
  char* start_host;
  long port;
  bool found_port;
  int rv = ARES_SUCCESS;
  struct ares_addr_node *servers = NULL;
  struct ares_addr_node *last = NULL;

  if (ares_library_initialized() != ARES_SUCCESS)
    return ARES_ENOTINITIALIZED;

  if (!channel)
    return ARES_ENODATA;

  ares__destroy_servers_state(channel);

  i = strlen(_csv);
  if (i == 0)
     return ARES_SUCCESS; /* blank all servers */

  csv = malloc(i + 2);
  strcpy(csv, _csv);
  if (csv[i-1] != ',') { /* make parsing easier by ensuring ending ',' */
    csv[i] = ',';
    csv[i+1] = 0;
  }

  start_host = csv;
  found_port = false;
  for (ptr = csv; *ptr; ptr++) {
    if (*ptr == ',') {
      char* pp = ptr - 1;
      struct in_addr in4;
      struct ares_in6_addr in6;
      struct ares_addr_node *s = NULL;

      *ptr = 0; /* null terminate host:port string */
      /* Got an entry..see if port was specified. */
      while (pp > start_host) {
        if (*pp == ':')
          break; /* yes */
        if (!ISDIGIT(*pp)) {
          /* Found end of digits before we found :, so wasn't a port */
          pp = ptr;
          break;
        }
        pp--;
      }
      if ((pp != start_host) && ((pp + 1) < ptr)) {
        /* Found it. */
        found_port = true;
        port = strtol(pp + 1, NULL, 10);
        *pp = 0; /* null terminate host */
      }
      /* resolve host, try ipv4 first, rslt is in network byte order */
      rv = ares_inet_pton(AF_INET, start_host, &in4);
      if (!rv) {
        /* Ok, try IPv6 then */
        rv = ares_inet_pton(AF_INET6, start_host, &in6);
        if (!rv) {
          rv = ARES_EBADSTR;
          goto out;
        }
        /* was ipv6, add new server */
        s = malloc(sizeof(*s));
        if (!s) {
          rv = ARES_ENOMEM;
          goto out;
        }
        s->family = AF_INET6;
        memcpy(&s->addr, &in6, sizeof(struct ares_in6_addr));
      }
      else {
        /* was ipv4, add new server */
        s = malloc(sizeof(*s));
        if (!s) {
          rv = ARES_ENOMEM;
          goto out;
        }
        s->family = AF_INET;
        memcpy(&s->addr, &in4, sizeof(struct in_addr));
      }
      if (s) {
        /* TODO:  Add port to ares_addr_node and assign it here. */

        s->next = NULL;
        if (last) {
          last->next = s;
        }
        else {
          servers = s;
          last = s;
        }
      }

      /* Set up for next one */
      found_port = false;
      start_host = ptr + 1;
    }
  }

  rv = ares_set_servers(channel, servers);

  out:
  if (csv)
    free(csv);
  while (servers) {
    struct ares_addr_node *s = servers;
    servers = servers->next;
    free(s);
  }

  return rv;
}