static void
analyze_backticks(void)
{
    int myline = *ratslexer.lex_lineno;
    int column = *ratslexer.lex_column;

    if (ratslexer.lang == LANG_C)  
        return;
  
    /* we're just gobbling up whatever is in the backticks and
     * ignoring them for now.
     */

    scan_tokens(gobble_backtick, NULL);

    switch (ratslexer.lang)
    {
        case LANG_PYTHON:
            log_pythonbacktick(myline, column, Medium);
            break;
        case LANG_PHP:    
            log_phpbacktick(myline, column,Medium);
            break;
        case LANG_PERL:
            log_perlbacktick(myline, column,Medium);
            break;
	    case LANG_RUBY:
            log_rubybacktick(myline, column,Medium);
            break;
    }
}
static
void scan_arguments(void)
{
    int         i;
    argscan_t   data;

    data.tail = (argument_t *)NULL;
    data.current = (argument_t *)NULL;
    for (i = 0;  i < DEPTH_COUNT;  i++)
        data.depths[i] = depths[i];

    scan_tokens(check_argument, (void *)&data);
}
/*
 * XXX: This function can be cleaned up to prevent more false positives.
 *      Currently running lex.yy.c through this yields false positives due to
 *      pointer initializers, i.e. char *foo = bar[15]; - MMessier, 09-May-2001
 */
static
void analyze_variable(int token)
{
    charscan_t  data;

    /* If we're processing arguments right now, we don't want to check for
     * stack variables because they're not really stack variables
     */
    if (current_frame != (rats_stack_t *)NULL && current_frame->next != (rats_stack_t *)NULL)
        return;
    if (depths[DEPTH_PARENTHESIS] || depths[DEPTH_BRACKET])
        return;

    data.column = *ratslexer.lex_column;
    data.lineno = *ratslexer.lex_lineno;
    data.initial_type = token;
    data.last_token = token;
    data.depth = depths[DEPTH_BRACE];
    data.skip = 0;
    scan_tokens(check_buffer, (void *)&data);
}
Ejemplo n.º 4
0
bool protocol_stats_merge_line(genhash_t *merger, char *line) {
    int nline;
    token_t tokens[MAX_TOKENS];
    int ntokens;
    char *name;
    int name_len;


    cb_assert(merger != NULL);
    cb_assert(line != NULL);

    nline = strlen(line); /* Ex: "STATS uptime 123455" */
    if (nline <= 0 ||
        nline >= MERGE_BUF_SIZE) {
        return false;
    }

    ntokens = scan_tokens(line, tokens, MAX_TOKENS, NULL);

    if (ntokens != 4) { /* 3 + 1 for the terminal token. */
        return false;
    }

    name = tokens[NAME_TOKEN].value;
    name_len = tokens[NAME_TOKEN].length;
    if (name == NULL ||
        name_len <= 0 ||
        tokens[VALUE_TOKEN].value == NULL ||
        tokens[VALUE_TOKEN].length <= 0 ||
        tokens[VALUE_TOKEN].length >= MERGE_BUF_SIZE) {
        return false;
    }

    return protocol_stats_merge_name_val(merger,
                                         tokens[PREFIX_TOKEN].value,
                                         tokens[PREFIX_TOKEN].length,
                                         name, name_len,
                                         tokens[VALUE_TOKEN].value,
                                         tokens[VALUE_TOKEN].length);
}
Ejemplo n.º 5
0
void cproxy_process_a2a_downstream(conn *c, char *line) {
    assert(c != NULL);
    assert(c->next == NULL);
    assert(c->extra != NULL);
    assert(c->cmd == -1);
    assert(c->item == NULL);
    assert(line != NULL);
    assert(line == c->rcurr);
    assert(IS_ASCII(c->protocol));
    assert(IS_PROXY(c->protocol));

    if (settings.verbose > 1)
        fprintf(stderr, "<%d cproxy_process_a2a_downstream %s\n",
                c->sfd, line);

    downstream *d = c->extra;

    assert(d != NULL);
    assert(d->ptd != NULL);
    assert(d->ptd->proxy != NULL);

    if (strncmp(line, "VALUE ", 6) == 0) {
        token_t      tokens[MAX_TOKENS];
        size_t       ntokens;
        unsigned int flags;
        int          clen = 0;
        int          vlen;
        uint64_t     cas = CPROXY_NOT_CAS;

        ntokens = scan_tokens(line, tokens, MAX_TOKENS, &clen);
        if (ntokens >= 5 && // Accounts for extra termimation token.
            ntokens <= 6 &&
            tokens[KEY_TOKEN].length <= KEY_MAX_LENGTH &&
            safe_strtoul(tokens[2].value, (uint32_t *) &flags) &&
            safe_strtoul(tokens[3].value, (uint32_t *) &vlen)) {
            char  *key  = tokens[KEY_TOKEN].value;
            size_t nkey = tokens[KEY_TOKEN].length;

            item *it = item_alloc(key, nkey, flags, 0, vlen + 2);
            if (it != NULL) {
                if (ntokens == 5 ||
                    safe_strtoull(tokens[4].value, &cas)) {
                    ITEM_set_cas(it, cas);

                    c->item = it;
                    c->ritem = ITEM_data(it);
                    c->rlbytes = it->nbytes;
                    c->cmd = -1;

                    conn_set_state(c, conn_nread);

                    return; // Success.
                } else {
                    if (settings.verbose > 1)
                        fprintf(stderr, "cproxy could not parse cas\n");
                }
            } else {
                if (settings.verbose > 1)
                    fprintf(stderr, "cproxy could not item_alloc size %u\n",
                            vlen + 2);
            }

            if (it != NULL)
                item_remove(it);
            it = NULL;

            c->sbytes = vlen + 2; // Number of bytes to swallow.

            conn_set_state(c, conn_swallow);

            // Note, eventually, we'll see an END later.
        } else {
            // We don't know how much to swallow, so close the downstream.
            // The conn_closing should release the downstream,
            // which should write a suffix/error to the upstream.
            //
            conn_set_state(c, conn_closing);
        }
    } else if (strncmp(line, "END", 3) == 0) {
        conn_set_state(c, conn_pause);
    } else if (strncmp(line, "OK", 2) == 0) {
        conn_set_state(c, conn_pause);

        // TODO: Handle flush_all's expiration parameter against
        // the front_cache.
        //
        // TODO: We flush the front_cache too often, inefficiently
        // on every downstream flush_all OK response, rather than
        // on just the last flush_all OK response.
        //
        conn *uc = d->upstream_conn;
        if (uc != NULL &&
            uc->cmd_curr == PROTOCOL_BINARY_CMD_FLUSH) {
            mcache_flush_all(&d->ptd->proxy->front_cache, 0);
        }
    } else if (strncmp(line, "STAT ", 5) == 0 ||
               strncmp(line, "ITEM ", 5) == 0 ||
               strncmp(line, "PREFIX ", 7) == 0) {
        assert(d->merger != NULL);

        conn *uc = d->upstream_conn;
        if (uc != NULL) {
            assert(uc->next == NULL);

            if (protocol_stats_merge_line(d->merger, line) == false) {
                // Forward the line as-is if we couldn't merge it.
                //
                int nline = strlen(line);

                item *it = item_alloc("s", 1, 0, 0, nline + 2);
                if (it != NULL) {
                    strncpy(ITEM_data(it), line, nline);
                    strncpy(ITEM_data(it) + nline, "\r\n", 2);

                    if (add_conn_item(uc, it)) {
                        add_iov(uc, ITEM_data(it), nline + 2);

                        it = NULL;
                    }

                    if (it != NULL)
                        item_remove(it);
                }
            }
        }

        conn_set_state(c, conn_new_cmd);
    } else {
        conn_set_state(c, conn_pause);

        // The upstream conn might be NULL when closed already
        // or while handling a noreply.
        //
        conn *uc = d->upstream_conn;
        if (uc != NULL) {
            assert(uc->next == NULL);

            out_string(uc, line);

            if (!update_event(uc, EV_WRITE | EV_PERSIST)) {
                if (settings.verbose > 1)
                    fprintf(stderr,
                            "Can't update upstream write event\n");

                d->ptd->stats.stats.err_oom++;
                cproxy_close_conn(uc);
            }

            cproxy_del_front_cache_key_ascii_response(d, line,
                                                      uc->cmd_start);
        }
    }
}
Ejemplo n.º 6
0
/* Forward a simple one-liner command downstream.
 * For example, get, incr/decr, delete, etc.
 * The response, though, might be a simple line or
 * multiple VALUE+END lines.
 */
bool cproxy_forward_a2a_simple_downstream(downstream *d,
                                          char *command, conn *uc) {
    assert(d != NULL);
    assert(d->ptd != NULL);
    assert(d->ptd->proxy != NULL);
    assert(d->downstream_conns != NULL);
    assert(command != NULL);
    assert(uc != NULL);
    assert(uc->item == NULL);
    assert(uc->cmd_curr != -1);
    assert(d->multiget == NULL);
    assert(d->merger == NULL);

    // Handles get and gets.
    //
    if (uc->cmd_curr == PROTOCOL_BINARY_CMD_GET) {
        // Only use front_cache for 'get', not for 'gets'.
        //
        mcache *front_cache =
            (command[3] == ' ') ? &d->ptd->proxy->front_cache : NULL;

        return multiget_ascii_downstream(d, uc,
                                         a2a_multiget_start,
                                         a2a_multiget_skey,
                                         a2a_multiget_end,
                                         front_cache);
    }

    assert(uc->next == NULL);

    if (uc->cmd_curr == PROTOCOL_BINARY_CMD_FLUSH)
        return cproxy_broadcast_a2a_downstream(d, command, uc,
                                               "OK\r\n");

    if (uc->cmd_curr == PROTOCOL_BINARY_CMD_STAT) {
        if (strncmp(command + 5, " reset", 6) == 0)
            return cproxy_broadcast_a2a_downstream(d, command, uc,
                                                   "RESET\r\n");

        if (cproxy_broadcast_a2a_downstream(d, command, uc,
                                            "END\r\n")) {
            d->merger = genhash_init(512, skeyhash_ops);
            return true;
        } else {
            return false;
        }
    }

    // TODO: Inefficient repeated scan_tokens.
    //
    int      cmd_len = 0;
    token_t  tokens[MAX_TOKENS];
    size_t   ntokens = scan_tokens(command, tokens, MAX_TOKENS, &cmd_len);
    char    *key     = tokens[KEY_TOKEN].value;
    int      key_len = tokens[KEY_TOKEN].length;

    if (ntokens <= 1) { // This was checked long ago, while parsing
        assert(false);  // the upstream conn.
        return false;
    }

    // Assuming we're already connected to downstream.
    //
    bool self = false;

    conn *c = cproxy_find_downstream_conn(d, key, key_len,
                                          &self);
    if (c != NULL) {
        if (self) {
            // TODO: This optimization could be done much earlier,
            // even before the upstream conn was assigned
            // to a downstream.
            //
            cproxy_optimize_to_self(d, uc, command);
            process_command(uc, command);
            return true;
        }

        if (cproxy_prep_conn_for_write(c)) {
            assert(c->state == conn_pause);

            out_string(c, command);

            if (settings.verbose > 1)
                fprintf(stderr, "forwarding to %d, noreply %d\n",
                        c->sfd, uc->noreply);

            if (update_event(c, EV_WRITE | EV_PERSIST)) {
                d->downstream_used_start = 1;
                d->downstream_used       = 1;

                if (cproxy_dettach_if_noreply(d, uc) == false) {
                    cproxy_start_downstream_timeout(d, c);
                } else {
                    c->write_and_go = conn_pause;

                    // Do mcache_delete() here only during a noreply,
                    // otherwise for with-reply requests, we could
                    // be in a race with other clients repopulating
                    // the front_cache.  For with-reply requests, we
                    // clear the front_cache when we get a success reply.
                    //
                    mcache_delete(&d->ptd->proxy->front_cache, key, key_len);
                }

                return true;
            }

            if (settings.verbose > 1)
                fprintf(stderr, "Couldn't update cproxy write event\n");

            d->ptd->stats.stats.err_oom++;
            cproxy_close_conn(c);
        } else {
            d->ptd->stats.stats.err_downstream_write_prep++;
            cproxy_close_conn(c);
        }
    }

    return false;
}
Ejemplo n.º 7
0
void cproxy_process_upstream_ascii(conn *c, char *line) {
    assert(c != NULL);
    assert(c->next == NULL);
    assert(c->extra != NULL);
    assert(c->cmd == -1);
    assert(c->item == NULL);
    assert(line != NULL);
    assert(line == c->rcurr);
    assert(IS_ASCII(c->protocol));
    assert(IS_PROXY(c->protocol));

    if (settings.verbose > 2) {
        moxi_log_write("<%d cproxy_process_upstream_ascii %s\n",
                       c->sfd, line);
    }

    // Snapshot rcurr, because the caller, try_read_command(), changes it.
    //
    c->cmd_curr       = -1;
    c->cmd_start      = c->rcurr;
    c->cmd_start_time = msec_current_time;
    c->cmd_retries    = 0;

    proxy_td *ptd = c->extra;
    assert(ptd != NULL);

    /* For commands set/add/replace, we build an item and read the data
     * directly into it, then continue in nread_complete().
     */
    if (!cproxy_prep_conn_for_write(c)) {
        ptd->stats.stats.err_upstream_write_prep++;
        conn_set_state(c, conn_closing);
        return;
    }

    bool mcmux_command = false;
    bool self_command = false;

    /* Check for proxy pattern - A:host:port or B:host:port */
    if (true == settings.enable_mcmux_mode &&
            ((*line == 'A' || *line == 'B') && *(line + 1) == ':')) {
        mcmux_command = true;
    } else if (true == settings.enable_mcmux_mode) {
        self_command = true;
    }

    c->peer_protocol = 0;
    c->peer_host = NULL;
    c->peer_port = 0;

    if (mcmux_command) {
        char *peer_port = NULL;
        int i = 0;

        c->peer_protocol = (*line == 'A') ?
                           proxy_downstream_ascii_prot :
                           proxy_downstream_binary_prot;
        line += 2;
        c->peer_host = line;

        while (*line != ' ' && *line != '\0' &&
                *line != ':' && ++i < MAX_HOSTNAME_LEN) {
            line++;
        }

        if (*line == '\0' || line - c->peer_host <= 0) {
            out_string(c, "ERROR");
            moxi_log_write("Malformed request line");
            return;
        }
        *line = '\0';
        line++;
        peer_port = line;
        i = 0;

        while (*line != ' ' && *line != '\0' && ++i <= MAX_PORT_LEN) {
            line++;
        }

        if (*line == '\0' || line - peer_port <= 0) {
            out_string(c, "ERROR");
            moxi_log_write("Malformed request line");
            return;
        }

        c->peer_port = atoi(peer_port);

        *line++ = '\0';
        c->cmd_start = line;
    }

    int     cmd_len = 0;
    token_t tokens[MAX_TOKENS];
    size_t  ntokens = scan_tokens(line, tokens, MAX_TOKENS, &cmd_len);
    char   *cmd     = tokens[COMMAND_TOKEN].value;
    int     cmdx    = -1;
    int     cmd_st  = STATS_CMD_TYPE_REGULAR;
    int     comm;

#define SEEN(cmd_id, is_cas, cmd_len)                           \
    cmd_st = c->noreply ?                                       \
        STATS_CMD_TYPE_QUIET : STATS_CMD_TYPE_REGULAR;          \
    ptd->stats.stats_cmd[cmd_st][cmd_id].seen++;                \
    ptd->stats.stats_cmd[cmd_st][cmd_id].read_bytes += cmd_len; \
    if (is_cas) {                                               \
        ptd->stats.stats_cmd[cmd_st][cmd_id].cas++;             \
    }

    if (ntokens >= 3 &&
            (false == self_command) &&
            (strncmp(cmd, "get", 3) == 0)) {
        if (cmd[3] == 'l') {
            c->cmd_curr = PROTOCOL_BINARY_CMD_GETL;
        } else if (ntokens == 3) {
            // Single-key get/gets optimization.
            //
            c->cmd_curr = PROTOCOL_BINARY_CMD_GETK;
        } else {
            c->cmd_curr = PROTOCOL_BINARY_CMD_GETKQ;
        }

        // Handles get and gets.
        //
        cproxy_pause_upstream_for_downstream(ptd, c);

        // The cmd_len from scan_tokens might not include
        // all the keys, so cmd_len might not == strlen(command).
        // Handle read_bytes during multiget broadcast.
        //
        if (cmd[3] == 'l') {
            SEEN(STATS_CMD_GETL, true, 0);
        } else {
            SEEN(STATS_CMD_GET, cmd[3] == 's', 0);
        }

    } else if ((ntokens == 6 || ntokens == 7) &&
               (false == self_command) &&
               ((strncmp(cmd, "add", 3) == 0 &&
                 (comm = NREAD_ADD) &&
                 (cmdx = STATS_CMD_ADD) &&
                 (c->cmd_curr = PROTOCOL_BINARY_CMD_ADD)) ||
                (strncmp(cmd, "set", 3) == 0 &&
                 (comm = NREAD_SET) &&
                 (cmdx = STATS_CMD_SET) &&
                 (c->cmd_curr = PROTOCOL_BINARY_CMD_SET)) ||
                (strncmp(cmd, "replace", 7) == 0 &&
                 (comm = NREAD_REPLACE) &&
                 (cmdx = STATS_CMD_REPLACE) &&
                 (c->cmd_curr = PROTOCOL_BINARY_CMD_REPLACE)) ||
                (strncmp(cmd, "prepend", 7) == 0 &&
                 (comm = NREAD_PREPEND) &&
                 (cmdx = STATS_CMD_PREPEND) &&
                 (c->cmd_curr = PROTOCOL_BINARY_CMD_PREPEND)) ||
                (strncmp(cmd, "append", 6) == 0 &&
                 (comm = NREAD_APPEND) &&
                 (cmdx = STATS_CMD_APPEND) &&
                 (c->cmd_curr = PROTOCOL_BINARY_CMD_APPEND)))) {
        assert(c->item == NULL);
        c->item = NULL;

        process_update_command(c, tokens, ntokens, comm, false);

        if (cmdx >= 0) {
            item *it = c->item;
            if (it != NULL) {
                SEEN(cmdx, false, cmd_len + it->nbytes);
            } else {
                SEEN(cmdx, false, cmd_len);
                ptd->stats.stats_cmd[cmd_st][cmdx].misses++;
            }
        }

    } else if ((ntokens == 7 || ntokens == 8) &&
               (false == self_command) &&
               (strncmp(cmd, "cas", 3) == 0 &&
                (comm = NREAD_CAS) &&
                (c->cmd_curr = PROTOCOL_BINARY_CMD_SET))) {
        assert(c->item == NULL);
        c->item = NULL;

        process_update_command(c, tokens, ntokens, comm, true);

        item *it = c->item;
        if (it != NULL) {
            SEEN(STATS_CMD_CAS, true, cmd_len + it->nbytes);
        } else {
            SEEN(STATS_CMD_CAS, true, cmd_len);
            ptd->stats.stats_cmd[cmd_st][STATS_CMD_CAS].misses++;
        }

    } else if ((ntokens == 4 || ntokens == 5) &&
               (false == self_command) &&
               (strncmp(cmd, "incr", 4) == 0) &&
               (c->cmd_curr = PROTOCOL_BINARY_CMD_INCREMENT)) {
        set_noreply_maybe(c, tokens, ntokens);
        cproxy_pause_upstream_for_downstream(ptd, c);

        SEEN(STATS_CMD_INCR, false, cmd_len);

    } else if ((ntokens == 4 || ntokens == 5) &&
               (false == self_command) &&
               (strncmp(cmd, "decr", 4) == 0) &&
               (c->cmd_curr = PROTOCOL_BINARY_CMD_DECREMENT)) {
        set_noreply_maybe(c, tokens, ntokens);
        cproxy_pause_upstream_for_downstream(ptd, c);

        SEEN(STATS_CMD_DECR, false, cmd_len);

    } else if (ntokens >= 3 && ntokens <= 4 &&
               (false == self_command) &&
               (strncmp(cmd, "delete", 6) == 0) &&
               (c->cmd_curr = PROTOCOL_BINARY_CMD_DELETE)) {
        set_noreply_maybe(c, tokens, ntokens);
        cproxy_pause_upstream_for_downstream(ptd, c);

        SEEN(STATS_CMD_DELETE, false, cmd_len);

    } else if (ntokens >= 2 && ntokens <= 4 &&
               (false == self_command) &&
               (strncmp(cmd, "flush_all", 9) == 0) &&
               (c->cmd_curr = PROTOCOL_BINARY_CMD_FLUSH)) {
        set_noreply_maybe(c, tokens, ntokens);
        cproxy_pause_upstream_for_downstream(ptd, c);

        SEEN(STATS_CMD_FLUSH_ALL, false, cmd_len);

    } else if (ntokens >= 3 && ntokens <= 4 &&
               (strncmp(cmd, "stats proxy", 10) == 0)) {

        process_stats_proxy_command(c, tokens, ntokens);

        SEEN(STATS_CMD_STATS, false, cmd_len);

    } else if (ntokens == 3 &&
               (false == self_command) &&
               (strcmp(cmd, "stats reset") == 0) &&
               (c->cmd_curr = PROTOCOL_BINARY_CMD_STAT)) {
        cproxy_pause_upstream_for_downstream(ptd, c);

        SEEN(STATS_CMD_STATS_RESET, false, cmd_len);

    } else if (ntokens == 2 &&
               (false == self_command) &&
               (strcmp(cmd, "stats") == 0) &&
               (c->cmd_curr = PROTOCOL_BINARY_CMD_STAT)) {
        // Even though we've coded to handle advanced stats
        // like stats cachedump, prevent those here to avoid
        // locking downstream servers.
        //
        cproxy_pause_upstream_for_downstream(ptd, c);

        SEEN(STATS_CMD_STATS, false, cmd_len);

    } else if (ntokens == 2 &&
               (true == mcmux_command) &&
               (strncmp(cmd, "version", 7) == 0) &&
               (c->cmd_curr = PROTOCOL_BINARY_CMD_VERSION)) {
        /* downstream version command */
        cproxy_pause_upstream_for_downstream(ptd, c);

        SEEN(STATS_CMD_VERSION, false, cmd_len);

    } else if (ntokens == 2 &&
               (strncmp(cmd, "version", 7) == 0)) {
        out_string(c, "VERSION " VERSION);

        SEEN(STATS_CMD_VERSION, false, cmd_len);

    } else if ((ntokens == 3 || ntokens == 4) &&
               (strncmp(cmd, "verbosity", 9) == 0)) {
        process_verbosity_command(c, tokens, ntokens);

        SEEN(STATS_CMD_VERBOSITY, false, cmd_len);

    } else if (ntokens == 2 &&
               (strncmp(cmd, "quit", 4) == 0)) {
        conn_set_state(c, conn_closing);

        SEEN(STATS_CMD_QUIT, false, cmd_len);

    } else if (ntokens == 4 &&
               (strncmp(cmd, "unl", 3) == 0) &&
               (false == self_command) &&
               (c->cmd_curr = PROTOCOL_BINARY_CMD_UNL)) {
        cproxy_pause_upstream_for_downstream(ptd, c);
        SEEN(STATS_CMD_UNL, false, cmd_len);
    } else {
        out_string(c, "ERROR");

        SEEN(STATS_CMD_ERROR, false, cmd_len);
    }
}
void process_file(char *filename, int forcelang)
{
    FILE *fd = NULL;
    int             i;
    accumulator_t * acc;
#ifdef _MSC_VER
    struct _stat fstat;
#else
	struct stat fstat;
#endif

    /* 
     * We need to determine the filetype first.
     * If it's a real file, process normally.  
     * If it's a directory and the recursion flag is set, iterate through the
     * files in the directory and run process_file on them.
     */

    if (!strcmp(filename, "<stdin>"))
    {
      fd=stdin;
    } else {
    
      if(lstat(filename,&fstat)==-1) 
      {
        fprintf(stderr,"An error occurred. The file '%s' does not appear to exist\n", filename);
      return;
      }
#ifndef _MSC_VER
      /* Symbolic link check */
      if(S_ISLNK(fstat.st_mode)) {
        if(flags & FOLLOW_SYMLINK) {
	  char *symname;
	  symname=calloc(PATH_MAX,1);
	  if(readlink(filename,symname,PATH_MAX)==-1) {
	    return;
	  }
	  process_file(symname,forcelang);
        }
        return;
      }
#endif
      if(S_ISDIR(fstat.st_mode)) {
        /* Need to error catch here.*/
        if( flags & RECURSIVE_FILE_SCAN ) {
	  process_directory(filename,forcelang);
	  return;
        }
     }
    
     if (!S_ISREG(fstat.st_mode))
     {
       printf("NOT REGULAR FILE\n");
       return;
     } 

   }
 

   if(!fd && (fd=fopen(filename,"r")) == (FILE *)NULL) {
      return;
   }

    /* (Re-)Initialize state */
    if(!determine_language(filename, fd, forcelang)) {
      fclose(fd);
      return;
    }

    *ratslexer.lex_lineno = 1;
    last_text_line = 0;
    current_file = strdup(filename);
    for (i = 0;  i < DEPTH_COUNT;  depths[i++] = 0);

    /* Process the file */

   if (!(flags & NO_STATUS))
   {
     if ((flags & HTML_OUTPUT))
     {
       printf("Analyzing <b>%s</b><br>\n", filename);
     } else if (flags & XML_OUTPUT) {
       printf("<analyzed>%s</analyzed>\n", filename);
     } else {
       printf("Analyzing %s\n", filename);
     }
   }

    scan_tokens((processorfn_t)NULL, NULL);
    process_toctou();
    

    total_lines += *ratslexer.lex_lineno;
    /* Cleanup */
    current_ignore = (ignore_t *)NULL;
    while ((acc = accumulators) != (accumulator_t *)NULL)
    {
        if (*(acc->text) != (char *)NULL)
            free(*(acc->text));
        pop_accumulator();
    }
    fclose(fd);
}
Ejemplo n.º 9
0
/* Forward a simple one-liner command downstream.
 * For example, get, incr/decr, delete, etc.
 * The response, though, might be a simple line or
 * multiple VALUE+END lines.
 */
bool cproxy_forward_a2a_simple_downstream(downstream *d,
                                          char *command, conn *uc) {
    cb_assert(d != NULL);
    cb_assert(d->ptd != NULL);
    cb_assert(d->ptd->proxy != NULL);
    cb_assert(d->downstream_conns != NULL);
    cb_assert(command != NULL);
    cb_assert(uc != NULL);
    cb_assert(uc->item == NULL);
    cb_assert(uc->cmd_curr != (protocol_binary_command) -1);
    cb_assert(d->multiget == NULL);
    cb_assert(d->merger == NULL);

    /* Handles get and gets. */

    if (uc->cmd_curr == PROTOCOL_BINARY_CMD_GETK ||
        uc->cmd_curr == PROTOCOL_BINARY_CMD_GETKQ ||
        uc->cmd_curr == PROTOCOL_BINARY_CMD_GETL) {
        /* Only use front_cache for 'get', not for 'gets'. */

        mcache *front_cache =
            (command[3] == ' ') ? &d->ptd->proxy->front_cache : NULL;

        return multiget_ascii_downstream(d, uc,
                                         a2a_multiget_start,
                                         a2a_multiget_skey,
                                         a2a_multiget_end,
                                         front_cache);
    }

    cb_assert(uc->next == NULL);

    if (uc->cmd_curr == PROTOCOL_BINARY_CMD_FLUSH) {
        return cproxy_broadcast_a2a_downstream(d, command, uc,
                                               "OK\r\n");
    }

    if (uc->cmd_curr == PROTOCOL_BINARY_CMD_STAT) {
        if (strncmp(command + 5, " reset", 6) == 0) {
            return cproxy_broadcast_a2a_downstream(d, command, uc,
                                                   "RESET\r\n");
        }

        if (cproxy_broadcast_a2a_downstream(d, command, uc,
                                            "END\r\n")) {
            d->merger = genhash_init(512, skeyhash_ops);
            return true;
        } else {
            return false;
        }
    }

    /* TODO: Inefficient repeated scan_tokens. */

    int      cmd_len = 0;
    token_t  tokens[MAX_TOKENS];
    size_t   ntokens = scan_tokens(command, tokens, MAX_TOKENS, &cmd_len);
    char    *key     = tokens[KEY_TOKEN].value;
    int      key_len = tokens[KEY_TOKEN].length;

    if (ntokens <= 1) { /* This was checked long ago, while parsing */
        cb_assert(false);  /* the upstream conn. */
        return false;
    }

    /* Assuming we're already connected to downstream. */

    if (!strcmp(command, "version")) {
        /* fake key for version command handling */
        key = "v";
        key_len = 1;
    }

    conn *c = cproxy_find_downstream_conn(d, key, key_len, NULL);
    if (c != NULL) {

        if (cproxy_prep_conn_for_write(c)) {
            cb_assert(c->state == conn_pause);

            out_string(c, command);

            if (settings.verbose > 1) {
                moxi_log_write("forwarding to %d, noreply %d\n",
                        c->sfd, uc->noreply);
            }

            if (update_event(c, EV_WRITE | EV_PERSIST)) {
                d->downstream_used_start = 1;
                d->downstream_used       = 1;

                if (cproxy_dettach_if_noreply(d, uc) == false) {
                    cproxy_start_downstream_timeout(d, c);
                } else {
                    c->write_and_go = conn_pause;

                    /* Do mcache_delete() here only during a noreply, */
                    /* otherwise for with-reply requests, we could */
                    /* be in a race with other clients repopulating */
                    /* the front_cache.  For with-reply requests, we */
                    /* clear the front_cache when we get a success reply. */

                    cproxy_front_cache_delete(d->ptd, key, key_len);
                }

                return true;
            }

            if (settings.verbose > 1) {
                moxi_log_write("Couldn't update cproxy write event\n");
            }

            d->ptd->stats.stats.err_oom++;
            cproxy_close_conn(c);
        } else {
            d->ptd->stats.stats.err_downstream_write_prep++;
            cproxy_close_conn(c);
        }
    }

    return false;
}
Ejemplo n.º 10
0
void protocol_stats_foreach_write(const void *key,
                                  const void *value,
                                  void *user_data) {

    char *line = (char *) value;
    conn *uc = (conn *) user_data;
    int nline;
    cb_assert(line != NULL);
    cb_assert(uc != NULL);
    (void)key;

    nline = strlen(line);
    if (nline > 0) {
        item *it;
        if (settings.verbose > 2) {
            moxi_log_write("%d: cproxy_stats writing: %s\n", uc->sfd, line);
        }

        if (IS_BINARY(uc->protocol)) {
            token_t line_tokens[MAX_TOKENS];
            size_t  line_ntokens = scan_tokens(line, line_tokens, MAX_TOKENS, NULL);

            if (line_ntokens == 4) {
                uint16_t key_len  = line_tokens[NAME_TOKEN].length;
                uint32_t data_len = line_tokens[VALUE_TOKEN].length;

                it = item_alloc("s", 1, 0, 0,
                                sizeof(protocol_binary_response_stats) + key_len + data_len);
                if (it != NULL) {
                    protocol_binary_response_stats *header =
                        (protocol_binary_response_stats *) ITEM_data(it);

                    memset(ITEM_data(it), 0, it->nbytes);

                    header->message.header.response.magic = (uint8_t) PROTOCOL_BINARY_RES;
                    header->message.header.response.opcode = uc->binary_header.request.opcode;
                    header->message.header.response.keylen  = (uint16_t) htons(key_len);
                    header->message.header.response.bodylen = htonl(key_len + data_len);
                    header->message.header.response.opaque  = uc->opaque;

                    memcpy((ITEM_data(it)) + sizeof(protocol_binary_response_stats),
                           line_tokens[NAME_TOKEN].value, key_len);
                    memcpy((ITEM_data(it)) + sizeof(protocol_binary_response_stats) + key_len,
                           line_tokens[VALUE_TOKEN].value, data_len);

                    if (add_conn_item(uc, it)) {
                        add_iov(uc, ITEM_data(it), it->nbytes);

                        if (settings.verbose > 2) {
                            moxi_log_write("%d: cproxy_stats writing binary", uc->sfd);
                            cproxy_dump_header(uc->sfd, ITEM_data(it));
                        }

                        return;
                    }

                    item_remove(it);
                }
            }

            return;
        }

        it = item_alloc("s", 1, 0, 0, nline + 2);
        if (it != NULL) {
            strncpy(ITEM_data(it), line, nline);
            strncpy(ITEM_data(it) + nline, "\r\n", 2);

            if (add_conn_item(uc, it)) {
                add_iov(uc, ITEM_data(it), nline + 2);
                return;
            }

            item_remove(it);
        }
    }
}
Ejemplo n.º 11
0
bool protocol_stats_merge_name_val(genhash_t *merger,
                                   char *prefix,
                                   int   prefix_len,
                                   char *name,
                                   int   name_len,
                                   char *val,
                                   int   val_len) {

    char *key;
    int key_len;

    cb_assert(merger);
    cb_assert(name);
    cb_assert(val);

    key = name + name_len - 1;     /* Key part for merge rule lookup. */
    while (key >= name && *key != ':') { /* Scan for last colon. */
        key--;
    }
    if (key < name) {
        key = name;
    }
    key_len = name_len - (key - name);
    if (key_len > 0 && key_len < MERGE_BUF_SIZE) {
        char buf_name[MERGE_BUF_SIZE];
        char buf_key[MERGE_BUF_SIZE];
        char buf_val[MERGE_BUF_SIZE];
        char *prev;
        token_t prev_tokens[MAX_TOKENS];
        size_t prev_ntokens;
        bool ok;

        strncpy(buf_name, name, name_len);
        buf_name[name_len] = '\0';

        prev = (char *) genhash_find(merger, buf_name);
        if (prev == NULL) {
            char *hval = malloc(prefix_len + 1 +
                                name_len + 1 +
                                val_len + 1);
            if (hval != NULL) {
                memcpy(hval, prefix, prefix_len);
                hval[prefix_len] = ' ';

                memcpy(hval + prefix_len + 1, name, name_len);
                hval[prefix_len + 1 + name_len] = ' ';

                memcpy(hval + prefix_len + 1 + name_len + 1, val, val_len);
                hval[prefix_len + 1 + name_len + 1 + val_len] = '\0';

                genhash_update(merger, hval + prefix_len + 1, hval);
            }

            return true;
        }

        strncpy(buf_key, key, key_len);
        buf_key[key_len] = '\0';

        if (strstr(protocol_stats_keys_first, buf_key) != NULL) {
            return true;
        }

        prev_ntokens = scan_tokens(prev, prev_tokens, MAX_TOKENS, NULL);
        if (prev_ntokens != 4) {
            return true;
        }

        strncpy(buf_val, val, val_len);
        buf_val[val_len] = '\0';

        if (strstr(protocol_stats_keys_smallest, buf_key) != NULL) {
            ok = protocol_stats_merge_smallest(prev_tokens[VALUE_TOKEN].value,
                                               prev_tokens[VALUE_TOKEN].length,
                                               buf_val, val_len,
                                               buf_val, MERGE_BUF_SIZE);
        } else {
            ok = protocol_stats_merge_sum(prev_tokens[VALUE_TOKEN].value,
                                          prev_tokens[VALUE_TOKEN].length,
                                          buf_val, val_len,
                                          buf_val, MERGE_BUF_SIZE);
        }

        if (ok) {
            int   vlen = strlen(buf_val);
            char *hval = malloc(prefix_len + 1 +
                                name_len + 1 +
                                vlen + 1);
            if (hval != NULL) {
                memcpy(hval, prefix, prefix_len);
                hval[prefix_len] = ' ';

                memcpy(hval + prefix_len + 1, name, name_len);
                hval[prefix_len + 1 + name_len] = ' ';

                strcpy(hval + prefix_len + 1 + name_len + 1, buf_val);
                hval[prefix_len + 1 + name_len + 1 + vlen] = '\0';

                genhash_update(merger, hval + prefix_len + 1, hval);

                free(prev);
            }
        }

        /* Note, if we couldn't merge, then just keep */
        /* the previous value. */

        return true;
    }

    return false;
}