Пример #1
0
void taskmain(int argc, char *argv[])
{
    dbg_set_log(stderr);
    int i = 0;

    bstring arguments = bfromcstr(argv[0]);

    for(i = 1; i < argc; i++) {
        bstring a = bfromcstr(argv[i]);

        // compensate for quotes getting taken off by the shell
        // TODO: also need to escape " to bring back that
        if(bstrchr(a, ' ') != -1) {
            bcatcstr(arguments, " \"");
            bconcat(arguments, a);
            bcatcstr(arguments, "\"");
        } else {
            bcatcstr(arguments, " ");
            bconcat(arguments, a);
        }

        bdestroy(a);
    }

    debug("RUNNING: %s", bdata(arguments));
    taskexitall(Command_run(arguments));
}
Пример #2
0
static const unsigned char *
bstrstr(const unsigned char *s1, size_t l1, const unsigned char *s2, size_t l2) {
    /* find first occurrence of s2[] in s1[] for length l1*/
    const unsigned char *ss1 = s1;
    const unsigned char *ss2 = s2;
    /* handle special case */
    if(l1 == 0)
        return (NULL);
    if(l2 == 0)
        return s1;

    /* match prefix */
    for (; (s1 = bstrchr(s1, *s2, (uintptr_t)ss1-(uintptr_t)s1+(uintptr_t)l1)) != NULL &&
             (uintptr_t)ss1-(uintptr_t)s1+(uintptr_t)l1 != 0; ++s1) {

        /* match rest of prefix */
        const unsigned char *sc1, *sc2;
        for (sc1 = s1, sc2 = s2; ;)
            if (++sc2 >= ss2+l2)
                return s1;
            else if (*++sc1 != *sc2)
                break;
    }
    return NULL;
}
Пример #3
0
Dir *Dir_create(const char *base, const char *prefix, const char *index_file, const char *default_ctype)
{
    Dir *dir = calloc(sizeof(Dir), 1);
    check_mem(dir);

    dir->base = bfromcstr(base);
    check(blength(dir->base) < MAX_DIR_PATH, "Base directory is too long, must be less than %d", MAX_DIR_PATH);

    // dir can come from the routing table so it could have a pattern in it, strip that off
    bstring pattern = bfromcstr(prefix);
    int first_paren = bstrchr(pattern, '(');
    dir->prefix = first_paren >= 0 ? bHead(pattern, first_paren) : bstrcpy(pattern);
    bdestroy(pattern);

    check(blength(dir->prefix) < MAX_DIR_PATH, "Prefix is too long, must be less than %d", MAX_DIR_PATH);

    check(bchar(dir->prefix, 0) == '/' && bchar(dir->prefix, blength(dir->prefix)-1) == '/',
                "Dir route prefix (%s) must start with / and end with / or else you break the internet.", prefix);

    dir->index_file = bfromcstr(index_file);
    dir->default_ctype = bfromcstr(default_ctype);

    dir->fr_cache = Cache_create(FR_CACHE_SIZE, filerecord_cache_lookup,
                                 filerecord_cache_evict);
    check(dir->fr_cache, "Failed to create FileRecord cache");

    return dir;

error:
    if(dir)
        free(dir);

    return NULL;
}
Пример #4
0
struct bstr bstr_getline(struct bstr str, struct bstr *rest)
{
    int pos = bstrchr(str, '\n');
    if (pos < 0)
        pos = str.len;
    if (rest)
        *rest = bstr_cut(str, pos + 1);
    return bstr_splice(str, 0, pos + 1);
}
Пример #5
0
struct bstr bstr_splitchar(struct bstr str, struct bstr *rest, const char c)
{
    int pos = bstrchr(str, c);
    if (pos < 0)
        pos = str.len;
    if (rest)
        *rest = bstr_cut(str, pos + 1);
    return bstr_splice(str, 0, pos + 1);
}
Пример #6
0
Файл: cue.c Проект: ThreeGe/mpv
static char *read_quoted(void *talloc_ctx, struct bstr *data)
{
    *data = bstr_lstrip(*data);
    if (!eat_char(data, '"'))
        return NULL;
    int end = bstrchr(*data, '"');
    if (end < 0)
        return NULL;
    struct bstr res = bstr_splice(*data, 0, end);
    *data = bstr_cut(*data, end + 1);
    return bstrto0(talloc_ctx, res);
}
Пример #7
0
static void header_done_cb(void *data, const char *at, size_t length)
{
    (void)at;
    (void)length;

    Request *req = (Request *)data;

    // extract content_len
    const char *clen = bdata(Request_get(req, &HTTP_CONTENT_LENGTH));
    if(clen) req->parser.content_len = atoi(clen);

    // extract host header
    req->host = Request_get(req, &HTTP_HOST);
    int colon = bstrchr(req->host, ':');
    if(req->host) {
        req->host_name = colon > 0 ? bHead(req->host, colon) : bstrcpy(req->host);
    }
}
Пример #8
0
// Returns 0 if a valid option/file is available, <0 on error, 1 on end of args.
static int split_opt_silent(struct parse_state *p)
{
    assert(!p->error);

    if (p->argc < 1)
        return 1;

    p->mp_opt = NULL;
    p->arg = bstr0(p->argv[0]);
    p->param = bstr0(NULL);

    p->argc--;
    p->argv++;

    if (p->no_more_opts || !bstr_startswith0(p->arg, "-") || p->arg.len == 1)
        return 0;

    if (bstrcmp0(p->arg, "--") == 0) {
        p->no_more_opts = true;
        return split_opt_silent(p);
    }

    bool old_syntax = !bstr_startswith0(p->arg, "--");
    if (old_syntax) {
        p->arg = bstr_cut(p->arg, 1);
    } else {
        p->arg = bstr_cut(p->arg, 2);
        int idx = bstrchr(p->arg, '=');
        if (idx > 0) {
            p->param = bstr_cut(p->arg, idx + 1);
            p->arg = bstr_splice(p->arg, 0, idx);
        }
    }

    p->mp_opt = m_config_get_option(p->config, p->arg);
    if (!p->mp_opt) {
        // Automagic "no-" arguments: "--no-bla" turns into "--bla=no".
        if (!bstr_startswith0(p->arg, "no-"))
            return -1;

        struct bstr s = bstr_cut(p->arg, 3);
        p->mp_opt = m_config_get_option(p->config, s);
        if (!p->mp_opt || p->mp_opt->type != &m_option_type_flag)
            return -1;
        // Avoid allowing "--no-no-bla".
        if (bstr_startswith(bstr0(p->mp_opt->name), bstr0("no-")))
            return -1;
        // Flag options never have parameters.
        old_syntax = false;
        if (p->param.len)
            return -2;
        p->arg = s;
        p->param = bstr0("no");
    }

    if (bstr_endswith0(p->arg, "-clr"))
        old_syntax = false;

    if (old_syntax && !(p->mp_opt->type->flags & M_OPT_TYPE_OLD_SYNTAX_NO_PARAM))
    {
        if (p->argc < 1)
            return -3;
        p->param = bstr0(p->argv[0]);
        p->argc--;
        p->argv++;
    }

    return 0;
}
Пример #9
0
/* ----------------------------------------------------------
 * FUNCTION     : parse_line
 * DESCRIPTION  : This function will process a line of data
 *              : from a configuration file.
 * INPUT        : 0 - Line (bstring)
 * ---------------------------------------------------------- */
void parse_line (bstring line)
{
    bstring param, value;
    struct bstrList *list;
    int i;

    /* Check to see if this line has something to read. */
    if (line->data[0] == '\0' || line->data[0] == '#')
       return;

    /* Check to see if this line has a comment in it. */
    if ((list = bsplit(line, '#')) != NULL) {
        if ((bassign(line, list->entry[0])) == -1) {
            log_message("warning:  'bassign' in function 'parse_line' failed.");
        }
        if (list != NULL)
            bstrListDestroy(list);
    }

    /* Seperate line into a parameter and a value. */
    if ((i = bstrchr(line, ' ')) == BSTR_ERR)
        return;
    if ((param = bmidstr(line, 0, i)) == NULL)
        return;
    if ((value = bmidstr(line, i + 1, line->slen - i)) == NULL)
        return;

    /* Normalize Strings */
    if ((btolower(param)) != 0)
        log_message("warning:  'btolower' in function 'parse_line' failed.");
    if ((bltrim(value)) != 0)
        log_message("warning:  'bltrim' in function 'parse_line' failed.");
    if ((brtrim(value)) != 0)
        log_message("warning:  'brtrim' in function 'parse_line' failed.");

    /* Do something based upon value. */
    if ((biseqcstr(param, "daemon")) == 1) {
        /* DAEMON */
        if (!gc.daemon_mode) {
            if (value->data[0] == '1')
                gc.daemon_mode = 1;
            else
                gc.daemon_mode = 0;
        }

    } else if ((biseqcstr(param, "pid_file")) == 1) {
            /* PID FILE */
        gc.pid_file = bstrcpy(value);

    } else if ((biseqcstr(param, "sig_file")) == 1) {
        /* SIGNATURE FILE */
        gc.sig_file = bstrcpy(value);
   
    } else if ((biseqcstr(param, "mac_file")) == 1) {
        /* MAC / VENDOR RESOLUTION FILE */
        gc.mac_file = bstrcpy(value);

    } else if ((biseqcstr(param, "output")) == 1) {
        /* OUTPUT */
        conf_module_plugin(value, &activate_output_plugin);

    } else if ((biseqcstr(param, "user")) == 1) {
        /* USER */
        gc.priv_user = bstrcpy(value);

    } else if ((biseqcstr(param, "group")) == 1) {
        /* GROUP */
        gc.priv_group = bstrcpy(value);

    } else if ((biseqcstr(param, "interface")) == 1) {
        /* INTERFACE */
        gc.dev = bstr2cstr(value, '-');

    } else if ((biseqcstr(param, "filter")) == 1) {
        /* FILTER */
        gc.pcap_filter = bstr2cstr(value, '-');

    } else if ((biseqcstr(param, "network")) == 1) {
        /* NETWORK */
        parse_networks(bdata(value));

    }

    verbose_message("config - PARAM:  |%s| / VALUE:  |%s|", bdata(param), bdata(value));

    /* Clean Up */
    if (param != NULL)
        bdestroy(param);
    if (value != NULL)
        bdestroy(value);
}
Пример #10
0
int m_config_parse(m_config_t *config, const char *location, bstr data,
                   char *initial_section, int flags)
{
    m_profile_t *profile = m_config_add_profile(config, initial_section);
    void *tmp = talloc_new(NULL);
    int line_no = 0;
    int errors = 0;

    bstr_eatstart0(&data, "\xEF\xBB\xBF"); // skip BOM

    while (data.len) {
        talloc_free_children(tmp);
        bool ok = false;

        line_no++;
        char loc[512];
        snprintf(loc, sizeof(loc), "%s:%d:", location, line_no);

        bstr line = bstr_strip_linebreaks(bstr_getline(data, &data));
        if (!skip_ws(&line))
            continue;

        // Profile declaration
        if (bstr_eatstart0(&line, "[")) {
            bstr profilename;
            if (!bstr_split_tok(line, "]", &profilename, &line)) {
                MP_ERR(config, "%s missing closing ]\n", loc);
                goto error;
            }
            if (skip_ws(&line)) {
                MP_ERR(config, "%s unparseable extra characters: '%.*s'\n",
                       loc, BSTR_P(line));
                goto error;
            }
            profile = m_config_add_profile(config, bstrto0(tmp, profilename));
            continue;
        }

        bstr_eatstart0(&line, "--");

        bstr option = line;
        while (line.len && (mp_isalnum(line.start[0]) || line.start[0] == '_' ||
                            line.start[0] == '-'))
            line = bstr_cut(line, 1);
        option.len = option.len - line.len;
        skip_ws(&line);

        bstr value = {0};
        if (bstr_eatstart0(&line, "=")) {
            skip_ws(&line);
            if (line.len && (line.start[0] == '"' || line.start[0] == '\'')) {
                // Simple quoting, like "value"
                char term[2] = {line.start[0], 0};
                line = bstr_cut(line, 1);
                if (!bstr_split_tok(line, term, &value, &line)) {
                    MP_ERR(config, "%s unterminated quote\n", loc);
                    goto error;
                }
            } else if (bstr_eatstart0(&line, "%")) {
                // Quoting with length, like %5%value
                bstr rest;
                long long len = bstrtoll(line, &rest, 10);
                if (rest.len == line.len || !bstr_eatstart0(&rest, "%") ||
                    len > rest.len)
                {
                    MP_ERR(config, "%s fixed-length quoting expected - put "
                           "\"quotes\" around the option value if you did not "
                           "intend to use this, but your option value starts "
                           "with '%%'\n", loc);
                    goto error;
                }
                value = bstr_splice(rest, 0, len);
                line = bstr_cut(rest, len);
            } else {
                // No quoting; take everything until the comment or end of line
                int end = bstrchr(line, '#');
                value = bstr_strip(end < 0 ? line : bstr_splice(line, 0, end));
                line.len = 0;
            }
        }
        if (skip_ws(&line)) {
            MP_ERR(config, "%s unparseable extra characters: '%.*s'\n",
                   loc, BSTR_P(line));
            goto error;
        }

        int res;
        if (profile) {
            if (bstr_equals0(option, "profile-desc")) {
                m_profile_set_desc(profile, value);
                res = 0;
            } else {
                res = m_config_set_profile_option(config, profile, option, value);
            }
        } else {
            res = m_config_set_option_ext(config, option, value, flags);
        }
        if (res < 0) {
            MP_ERR(config, "%s setting option %.*s='%.*s' failed.\n",
                   loc, BSTR_P(option), BSTR_P(value));
            goto error;
        }

        ok = true;
    error:
        if (!ok)
            errors++;
        if (errors > 16) {
            MP_ERR(config, "%s: too many errors, stopping.\n", location);
            break;
        }
    }

    talloc_free(tmp);
    return 1;
}
Пример #11
0
FileRecord *Dir_resolve_file(Dir *dir, bstring pattern, bstring path)
{
    FileRecord *file = NULL;
    bstring target = NULL;
    bstring prefix = NULL;

    check(Dir_lazy_normalize_base(dir) == 0, "Failed to normalize base path when requesting %s",
            bdata(path));

    file = FileRecord_cache_check(dir, path);

    if(file) {
        // TODO: double check this gives the right users count
        file->users++;
        return file;
    }
    
    int paren = bstrchr(pattern, '(');
    prefix = (paren > 0) ? bHead(pattern, paren) : bstrcpy(pattern);

    check(bchar(prefix, 0) == '/', "Route '%s' pointing to directory must have pattern with leading '/'", bdata(pattern));
    check(blength(prefix) < MAX_DIR_PATH, "Prefix is too long, must be less than %d", MAX_DIR_PATH);

    debug("Building target from base: %s pattern: %s prefix: %s path: %s index_file: %s", 
            bdata(dir->normalized_base),
            bdata(pattern),
            bdata(prefix),
            bdata(path),
            bdata(dir->index_file));

    if(bchar(path, blength(path) - 1) == '/') {
        // a directory so figureo out the index file
        target = bformat("%s%s%s",
                         bdata(dir->normalized_base),
                         path->data + blength(prefix) - 1,
                         bdata(dir->index_file));
    } else if(biseq(prefix, path)) {
        target = bformat("%s%s", bdata(dir->normalized_base), bdata(path));

    } else {
        target = bformat("%s%s", bdata(dir->normalized_base), path->data + blength(prefix) - 1);
    }

    check(target, "Couldn't construct target path for %s", bdata(path));

    check_debug(normalize_path(target) == 0,
            "Failed to normalize target path: %s", bdata(target));
   
    check_debug(bstrncmp(target, dir->normalized_base, blength(dir->normalized_base)) == 0, 
            "Request for path %s does not start with %s base after normalizing.", 
            bdata(target), bdata(dir->base));

    // the FileRecord now owns the target
    file = Dir_find_file(target, dir->default_ctype);
    check_debug(file, "Error opening file: %s", bdata(target));

    // Increment the user count because we're adding it to the cache
    file->users++;
    file->request_path = bstrcpy(path);
    Cache_add(dir->fr_cache, file);


    return file;

error:
    bdestroy(target);
    FileRecord_release(file);
    return NULL;
}
Пример #12
0
static struct bstr read_quoted(struct bstr *data)
{
    *data = bstr_lstrip(*data);
    if (!eat_char(data, '"'))
        return (struct bstr) {0};
    int end = bstrchr(*data, '"');
    if (end < 0)
        return (struct bstr) {0};
    struct bstr res = bstr_splice(*data, 0, end);
    *data = bstr_cut(*data, end + 1);
    return res;
}

// Read a 2 digit unsigned decimal integer.
// Return -1 on failure.
static int read_int_2(struct bstr *data)
{
    *data = bstr_lstrip(*data);
    if (data->len && data->start[0] == '-')
        return -1;
    struct bstr s = *data;
    int res = (int)bstrtoll(s, &s, 10);
    if (data->len == s.len || data->len - s.len > 2)
        return -1;
    *data = s;
    return res;
}

static double read_time(struct bstr *data)
{
    struct bstr s = *data;
    bool ok = true;
    double t1 = read_int_2(&s);
    ok = eat_char(&s, ':') && ok;
    double t2 = read_int_2(&s);
    ok = eat_char(&s, ':') && ok;
    double t3 = read_int_2(&s);
    ok = ok && t1 >= 0 && t2 >= 0 && t3 >= 0;
    return ok ? t1 * 60.0 + t2 + t3 * SECS_PER_CUE_FRAME : 0;
}

static struct bstr skip_utf8_bom(struct bstr data)
{
    return bstr_startswith0(data, "\xEF\xBB\xBF") ? bstr_cut(data, 3) : data;
}

// Check if the text in data is most likely CUE data. This is used by the
// demuxer code to check the file type.
// data is the start of the probed file, possibly cut off at a random point.
bool mp_probe_cue(struct bstr data)
{
    bool valid = false;
    data = skip_utf8_bom(data);
    for (;;) {
        enum cue_command cmd = read_cmd(&data, NULL);
        // End reached. Since the line was most likely cut off, don't use the
        // result of the last parsing call.
        if (data.len == 0)
            break;
        if (cmd == CUE_ERROR)
            return false;
        if (cmd != CUE_EMPTY)
            valid = true;
    }
    return valid;
}
Пример #13
0
static int
parse_server_xport_option(allium_ptcfg *cfg, const bstring arg_str)
{
	struct allium_ptcfg_method_s *m;
	struct allium_ptcfg_xport_opt_s *opt;
	bstring transport;
	bstring key;
	bstring value;
	int i, j;

	assert(cfg);
	assert(arg_str);

	if (0 == blength(arg_str))
		return (-1);

	/*
	 * Figure out what transport this argument is for.  We don't need to
	 * unescape method names as they conform to "[a-zA-Z_][a-zA-Z0-9_]*"
	 */
	i = bstrchr(arg_str, ':');
	if (BSTR_ERR == i)
		return (-1);

	transport = bmidstr(arg_str, 0, i);
	if (NULL == transport)
		return (-1);

	m = get_method(cfg, bdata(transport));
	bdestroy(transport);    /* Done with the transport at this point */
	if (NULL == m)
		return (-1);

	/*
	 * Figure out what key the transport is expecting the value for.
	 *
	 * XXX: If people want to use the escaped characters in their keys they
	 * get what they deserve (Note this as a gotcha and fix it when people
	 * cry about it).
	 */
	j = bstrchrp(arg_str, '=', i);
	if (BSTR_ERR == j)
		return (-1);

	key = bmidstr(arg_str, i + 1, j - i - 1);
	if (NULL == key)
		return (-1);

	opt = get_xport_opt(m, key);
	if ((NULL != opt) || (0 == blength(key))) {
		/* We don't support redefining existing key/value pairs */
		bdestroy(key);
		return (-1);
	}

	/* Parse the value, unescaping as needed */
	value = bmidstr(arg_str, j + 1, blength(arg_str) - j - 1);
	if (NULL == value) {
		bdestroy(key);
		return (-1);
	}
	unescape_opt_value(value);

	/* Stash it away so people can get to it */
	opt = calloc(1, sizeof(*opt));
	if (NULL == opt) {
		bdestroy(key);
		bdestroy_safe(value);
		return (-1);
	}
	opt->key = key;
	opt->value = value;
	opt->next = m->xport_opts;
	m->xport_opts = opt;

	return (0);
}