Esempio n. 1
0
void TransportSSH::send(const std::string& source)
{
    std::vector<std::string> sourcelist;
    std::vector<std::string>::const_iterator source_iter;

    if (_uri._host == "")
        throw std::string (STRING_TRANSPORT_SSH_URI);

    // cmd line is: scp [-p port] [user@]host:path
    if (_uri._port != "")
    {
        _arguments.push_back ("-P");
        _arguments.push_back (_uri._port);
    }

    if (is_filelist (source))
    {
        expand_braces (source, _uri._data, sourcelist);
        // Is there more than one source?
        // Then path has to end with a '/'
        if (sourcelist.size () > 1 && !_uri.is_directory ())
            throw format (STRING_TRANSPORT_URI_NODIR, _uri);

        for (source_iter = sourcelist.begin (); source_iter != sourcelist.end (); ++source_iter) {
            _arguments.push_back (*source_iter);
        }
    }
    else
    {
        _arguments.push_back (source);
    }

    if (_uri._user != "")
    {
        _arguments.push_back (_uri._user + "@" + _uri._host + ":" + escape (_uri._path, ' '));
    }
    else
    {
        _arguments.push_back (_uri._host + ":" + escape (_uri._path, ' '));
    }

    if (execute ())
        throw std::string (STRING_TRANSPORT_SSH_FAIL);
}
Esempio n. 2
0
/// Perform brace expansion.
static expand_error_t expand_braces(const wcstring &instr, expand_flags_t flags,
                                      std::vector<completion_t> *out, parse_error_list_t *errors) {
    bool syntax_error = false;
    int brace_count = 0;

    const wchar_t *brace_begin = NULL, *brace_end = NULL;
    const wchar_t *last_sep = NULL;

    const wchar_t *item_begin;
    size_t length_preceding_braces, length_following_braces, tot_len;

    const wchar_t *const in = instr.c_str();

    // Locate the first non-nested brace pair.
    for (const wchar_t *pos = in; (*pos) && !syntax_error; pos++) {
        switch (*pos) {
            case BRACE_BEGIN: {
                if (brace_count == 0) brace_begin = pos;
                brace_count++;
                break;
            }
            case BRACE_END: {
                brace_count--;
                if (brace_count < 0) {
                    syntax_error = true;
                } else if (brace_count == 0) {
                    brace_end = pos;
                }
                break;
            }
            case BRACE_SEP: {
                if (brace_count == 1) last_sep = pos;
                break;
            }
            default: {
                break;  // we ignore all other characters here
            }
        }
    }

    if (brace_count > 0) {
        if (!(flags & EXPAND_FOR_COMPLETIONS)) {
            syntax_error = true;
        } else {
            // The user hasn't typed an end brace yet; make one up and append it, then expand
            // that.
            wcstring mod;
            if (last_sep) {
                mod.append(in, brace_begin - in + 1);
                mod.append(last_sep + 1);
                mod.push_back(BRACE_END);
            } else {
                mod.append(in);
                mod.push_back(BRACE_END);
            }

            // Note: this code looks very fishy, apparently it has never worked.
            return expand_braces(mod, 1, out, errors);
        }
    }

    // Expand a literal "{}" to itself because it is useless otherwise,
    // and this eases e.g. `find -exec {}`. See #1109.
    if (brace_begin + 1 == brace_end) {
        wcstring newstr = instr;
        newstr.at(brace_begin - in) = L'{';
        newstr.at(brace_end - in) = L'}';
        return expand_braces(newstr, flags, out, errors);
    }

    if (syntax_error) {
        append_syntax_error(errors, SOURCE_LOCATION_UNKNOWN, _(L"Mismatched braces"));
        return EXPAND_ERROR;
    }

    if (brace_begin == NULL) {
        append_completion(out, instr);
        return EXPAND_OK;
    }

    length_preceding_braces = (brace_begin - in);
    length_following_braces = wcslen(brace_end) - 1;
    tot_len = length_preceding_braces + length_following_braces;
    item_begin = brace_begin + 1;
    for (const wchar_t *pos = (brace_begin + 1); true; pos++) {
        if (brace_count == 0 && ((*pos == BRACE_SEP) || (pos == brace_end))) {
            assert(pos >= item_begin);
            size_t item_len = pos - item_begin;
            wcstring item = wcstring(item_begin, item_len);
            item = trim(item, (const wchar_t[]) { BRACE_SPACE, L'\0' });
            for (auto &c : item) {
                if (c == BRACE_SPACE) {
                    c = ' ';
                }
            }

            wcstring whole_item;
            whole_item.reserve(tot_len + item_len + 2);
            whole_item.append(in, length_preceding_braces);
            whole_item.append(item.begin(), item.end());
            whole_item.append(brace_end + 1);
            expand_braces(whole_item, flags, out, errors);

            item_begin = pos + 1;
            if (pos == brace_end) break;
        }