/*
 * Decide what type of # directive this line is.
 */
int deftype (char *line, struct filepointer *filep, struct inclist *file_red,
             struct inclist *file, int parse_it)
{
    register char *p;
    char *directive, savechar;
    register int ret;

    /* Parse the directive... */
    directive = line + 1;
    while (*directive == ' ' || *directive == '\t')
        directive++;

    p = directive;
    while (*p >= 'a' && *p <= 'z')
        p++;
    savechar = *p;
    *p = '\0';
    ret = match (directive, directives);
    *p = savechar;

    /*
     If we don't recognize this compiler directive or we happen to just
     be gobbling up text while waiting for an #endif or #elif or #else
     in the case of an #elif we must check the zero_value and return an
     ELIF or an ELIFFALSE.
     */

    if (ret == ELIF && !parse_it)
    {
        while (*p == ' ' || *p == '\t')
            p++;
        /* parse an expression. */
        debug (0, ("%s, line %d: #elif %s ",
                   file->i_file, filep->f_line, p));
        ret = zero_value (p, filep, file_red);
        if (ret != IF)
        {
            debug (0, ("false...\n"));
            if (ret == IFFALSE)
                return (ELIFFALSE);
            else
                return (ELIFGUESSFALSE);
        }
        else
        {
            debug (0, ("true...\n"));
            return (ELIF);
        }
    }

    if (ret < 0 || !parse_it)
        return (ret);

    /* now decide how to parse the directive, and do it. */
    while (*p == ' ' || *p == '\t')
        p++;
    switch (ret)
    {
    case IF:
        /* parse an expression. */
        ret = zero_value (p, filep, file_red);
        debug (0, ("%s, line %d: %s #if %s\n",
                   file->i_file, filep->f_line, ret ? "false" : "true", p));
        break;
    case IFDEF:
    case IFNDEF:
        debug (0, ("%s, line %d: #%s %s\n",
                   file->i_file, filep->f_line, directives[ret], p));
    case UNDEF:
        /* separate the name of a single symbol. */
        while (isalnum (*p) || *p == '_')
            *line++ = *p++;
        *line = '\0';
        break;
    case INCLUDE:
        debug (2, ("%s, line %d: #include %s\n",
                   file->i_file, filep->f_line, p));

        /* Support ANSI macro substitution */
        {
            struct symtab **sym = isdefined (p, file_red, NULL);

            while (sym)
            {
                p = (char *)(*sym)->s_value;
                debug (3, ("%s : #includes SYMBOL %s = %s\n",
                           file->i_incstring,
                           (*sym)->s_name,
                           (*sym)->s_value));
                /* mark file as having included a 'soft include' */
                file->i_flags |= INCLUDED_SYM;
                sym = isdefined (p, file_red, NULL);
            }
        }

        /* Separate the name of the include file. */
        while (*p && *p != '"' && *p != '<')
            p++;
        if (!*p)
            return (-2);
        if (*p++ == '"')
        {
            ret = INCLUDEDOT;
            while (*p && *p != '"')
                *line++ = *p++;
        }
        else
            while (*p && *p != '>')
                *line++ = *p++;
        *line = '\0';
        break;
    case DEFINE:
        /* copy the definition back to the beginning of the line. */
        strcpy (line, p);
        break;
    case ELSE:
    case ENDIF:
    case ELIF:
    case PRAGMA:
    case ERROR:
    case IDENT:
    case SCCS:
    case EJECT:
    case WARNING:
        debug (0, ("%s, line %d: #%s\n",
                   file->i_file, filep->f_line, directives[ret]));
        /* nothing to do. */
        break;
    }
    return (ret);
}
Beispiel #2
0
/*
 * Decide what type of # directive this line is.
 */
int deftype (char *line, struct filepointer *filep, struct inclist *file_red, struct inclist *file, int parse_it, struct symhash *symbols)
{
    char   *p;
    char    *directive, savechar;
    int    ret;

    /*
     * Parse the directive...
     */
    directive=line+1;
    while (*directive == ' ' || *directive == '\t')
        directive++;

    p = directive;
    while (*p >= 'a' && *p <= 'z')
        p++;
    savechar = *p;
    *p = '\0';
    ret = match(directive, directives);
    *p = savechar;

    /* If we don't recognize this compiler directive or we happen to just
     * be gobbling up text while waiting for an #endif or #elif or #else
     * in the case of an #elif we must check the zero_value and return an
     * ELIF or an ELIFFALSE.
     */

    if (ret == ELIF && !parse_it)
    {
        while (*p == ' ' || *p == '\t')
            p++;
        /*
         * parse an expression.
         */
        debug(0,("%s, line %d: #elif %s ",
           file->i_file, filep->f_line, p));
        ret = zero_value(p, filep, file_red, symbols);
        if (ret != IF)
        {
          debug(0,("false...\n"));
          if (ret == IFFALSE)
              return ELIFFALSE;
          else
              return ELIFGUESSFALSE;
          }
        else
        {
          debug(0,("true...\n"));
          return ELIF;
        }
    }

    if (ret < 0 || ! parse_it)
        return ret;

    /*
     * now decide how to parse the directive, and do it.
     */
    while (*p == ' ' || *p == '\t')
        p++;
    switch (ret) {
    case IF:
        /*
         * parse an expression.
         */
        ret = zero_value(p, filep, file_red, symbols);
        debug(0,("%s, line %d: %s #if %s\n",
             file->i_file, filep->f_line, ret?"false":"true", p));
        break;
    case IFDEF:
    case IFNDEF:
        debug(0,("%s, line %d: #%s %s\n",
            file->i_file, filep->f_line, directives[ret], p));
        //fall-through
    case UNDEF:
        /*
         * separate the name of a single symbol.
         */
        while (isalnum((unsigned char)*p) || *p == '_')
            *line++ = *p++;
        *line = '\0';
        break;
    case INCLUDE:
        debug(2,("%s, line %d: #include %s\n",
            file->i_file, filep->f_line, p));

        /* Support ANSI macro substitution */
        {
            char *sym = hash_lookup(p, symbols);
            while (sym)
            {
                p = sym;
                debug(3,("%s : #includes SYMBOL %s\n",
                            file->i_incstring,
                            sym));
                /* mark file as having included a 'soft include' */
                file->i_included_sym = TRUE;
                sym = hash_lookup(p, symbols);
            }
        }

        /*
         * Separate the name of the include file.
         */
        while (*p && *p != '"' && *p != '<')
            p++;
        if (! *p)
            return -2;
        if (*p++ == '"') {
            ret = INCLUDEDOT;
            while (*p && *p != '"')
                *line++ = *p++;
        } else
            while (*p && *p != '>')
                *line++ = *p++;
        *line = '\0';
        break;
    case DEFINE:
        /*
         * copy the definition back to the beginning of the line.
         */
        memmove (line, p, strlen(p));
        break;
    case ELSE:
    case ENDIF:
    case ELIF:
    case PRAGMA:
    case ERROR:
    case IDENT:
    case SCCS:
    case EJECT:
        debug(0,("%s, line %d: #%s\n",
            file->i_file, filep->f_line, directives[ret]));
        /*
         * nothing to do.
         */
        break;
    }
    return ret;
}
Beispiel #3
0
bool handler__set(globals_t * vars, char **argv, unsigned argc)
{
    unsigned block, seconds = 1;
    char *delay = NULL;
    char *end;
    bool cont = false;
    struct setting {
        char *matchids;
        char *value;
        unsigned seconds;
    } *settings = NULL;

    assert(argc != 0);
    assert(argv != NULL);
    assert(vars != NULL);


    if (argc < 2) {
        show_error("expected an argument, type `help set` for details.\n");
        return false;
    }

    /* supporting `set` for bytearray will cause annoying syntax problems... */
    if ((vars->options.scan_data_type == BYTEARRAY)
       ||(vars->options.scan_data_type == STRING))
    {
        show_error("`set` is not supported for bytearray or string, use `write` instead.\n");
        return false;
    }

    /* check if there are any matches */
    if (vars->num_matches == 0) {
        show_error("no matches are known.\n");
        return false;
    }

    /* --- parse arguments into settings structs --- */

    settings = calloca(argc - 1, sizeof(struct setting));

    /* parse every block into a settings struct */
    for (block = 0; block < argc - 1; block++) {

        /* first seperate the block into matches and value, which are separated by '=' */
        if ((settings[block].value = strchr(argv[block + 1], '=')) == NULL) {

            /* no '=' found, whole string must be the value */
            settings[block].value = argv[block + 1];
        } else {
            /* there is a '=', value+1 points to value string. */

            /* use strndupa() to copy the matchids into a new buffer */
            settings[block].matchids =
                strndupa(argv[block + 1],
                         (size_t) (settings[block].value++ - argv[block + 1]));
        }

        /* value points to the value string, possibly with a delay suffix */

        /* matchids points to the match-ids (possibly multiple) or NULL */

        /* now check for a delay suffix (meaning continuous mode), eg 0xff/10 */
        if ((delay = strchr(settings[block].value, '/')) != NULL) {
            char *end = NULL;

            /* parse delay count */
            settings[block].seconds = strtoul(delay + 1, &end, 10);

            if (*(delay + 1) == '\0') {
                /* empty delay count, eg: 12=32/ */
                show_error("you specified an empty delay count, `%s`, see `help set`.\n", settings[block].value);
                return false;
            } else if (*end != '\0') {
                /* parse failed before end, probably trailing garbage, eg 34=9/16foo */
                show_error("trailing garbage after delay count, `%s`.\n", settings[block].value);
                return false;
            } else if (settings[block].seconds == 0) {
                /* 10=24/0 disables continous mode */
                show_info("you specified a zero delay, disabling continuous mode.\n");
            } else {
                /* valid delay count seen and understood */
                show_info("setting %s every %u seconds until interrupted...\n", settings[block].matchids ? settings[block].  matchids : "all", settings[block].seconds);

                /* continuous mode on */
                cont = true;
            }

            /* remove any delay suffix from the value */
            settings[block].value =
                strndupa(settings[block].value,
                         (size_t) (delay - settings[block].value));
        }                       /* if (strchr('/')) */
    }                           /* for(block...) */

    /* --- setup a longjmp to handle interrupt --- */
    if (INTERRUPTABLE()) {
        
        /* control returns here when interrupted */
// settings is allocated with alloca, do not free it
//        free(settings);
        detach(vars->target);
        ENDINTERRUPTABLE();
        return true;
    }

    /* --- execute the parsed setting structs --- */

    while (true) {
        uservalue_t userval;

        /* for every settings struct */
        for (block = 0; block < argc - 1; block++) {

            /* check if this block has anything to do this iteration */
            if (seconds != 1) {
                /* not the first iteration (all blocks get executed first iteration) */

                /* if settings.seconds is zero, then this block is only executed once */
                /* if seconds % settings.seconds is zero, then this block must be executed */
                if (settings[block].seconds == 0
                    || (seconds % settings[block].seconds) != 0)
                    continue;
            }

            /* convert value */
            if (!parse_uservalue_number(settings[block].value, &userval)) {
                show_error("bad number `%s` provided\n", settings[block].value);
                goto fail;
            }

            /* check if specific match(s) were specified */
            if (settings[block].matchids != NULL) {
                char *id, *lmatches = NULL;
                unsigned num = 0;

                /* create local copy of the matchids for strtok() to modify */
                lmatches = strdupa(settings[block].matchids);

                /* now seperate each match, spearated by commas */
                while ((id = strtok(lmatches, ",")) != NULL) {
                    match_location loc;

                    /* set to NULL for strtok() */
                    lmatches = NULL;

                    /* parse this id */
                    num = strtoul(id, &end, 0x00);

                    /* check that succeeded */
                    if (*id == '\0' || *end != '\0') {
                        show_error("could not parse match id `%s`\n", id);
                        goto fail;
                    }

                    /* check this is a valid match-id */
                    loc = nth_match(vars->matches, num);
                    if (loc.swath) {
                        value_t v;
                        value_t old;
                        void *address = remote_address_of_nth_element(loc.swath, loc.index /* ,MATCHES_AND_VALUES */);

                        /* copy val onto v */
                        /* XXX: valcmp? make sure the sizes match */
                        old = data_to_val(loc.swath, loc.index /* ,MATCHES_AND_VALUES */);
                        zero_value(&v);
                        v.flags = old.flags = loc.swath->data[loc.index].match_info;
                        uservalue2value(&v, &userval);
                        
                        show_info("setting *%p to %#"PRIx64"...\n", address, v.int64_value);

                        /* set the value specified */
                        fix_endianness(vars, &v);
                        if (setaddr(vars->target, address, &v) == false) {
                            show_error("failed to set a value.\n");
                            goto fail;
                        }

                    } else {
                        /* match-id > than number of matches */
                        show_error("found an invalid match-id `%s`\n", id);
                        goto fail;
                    }
                }
            } else {
                
                matches_and_old_values_swath *reading_swath_index = (matches_and_old_values_swath *)vars->matches->swaths;
                int reading_iterator = 0;

                /* user wants to set all matches */
                while (reading_swath_index->first_byte_in_child) {

                    /* Only actual matches are considered */
                    if (flags_to_max_width_in_bytes(reading_swath_index->data[reading_iterator].match_info) > 0)
                    {
                        void *address = remote_address_of_nth_element(reading_swath_index, reading_iterator /* ,MATCHES_AND_VALUES */);

                        /* XXX: as above : make sure the sizes match */
                                    
                        value_t old = data_to_val(reading_swath_index, reading_iterator /* ,MATCHES_AND_VALUES */);
                        value_t v;
                        zero_value(&v);
                        v.flags = old.flags = reading_swath_index->data[reading_iterator].match_info;
                        uservalue2value(&v, &userval);

                        show_info("setting *%p to %#"PRIx64"...\n", address, v.int64_value);

                        fix_endianness(vars, &v);
                        if (setaddr(vars->target, address, &v) == false) {
                            show_error("failed to set a value.\n");
                            goto fail;
                        }
                    }
                     
                     /* Go on to the next one... */
                    ++reading_iterator;
                    if (reading_iterator >= reading_swath_index->number_of_bytes)
                    {
                        reading_swath_index = local_address_beyond_last_element(reading_swath_index /* ,MATCHES_AND_VALUES */);
                        reading_iterator = 0;
                    }
                }
            }                   /* if (matchid != NULL) else ... */
        }                       /* for(block) */

        if (cont) {
            sleep(1);
        } else {
            break;
        }

        seconds++;
    }                           /* while(true) */

    ENDINTERRUPTABLE();
    return true;

fail:
    ENDINTERRUPTABLE();
    return false;
    
}