int Device::GetInterfaceStringIndex(usb::DeviceDescriptorPtr desc, u8 number) { static const u16 DT_INTERFACE = 4; ByteArray descData = desc->GetDescriptor(); HexDump("descriptor", descData); size_t offset = 0; while(offset < descData.size()) { u8 len = descData.at(offset + 0); u8 type = descData.at(offset + 1); if (len < 2) throw std::runtime_error("invalid descriptor length"); if (type == DT_INTERFACE && len >= 9 && descData.at(offset + 2) == number) return descData.at(offset + 8); offset += len; } throw std::runtime_error("no interface descriptor found"); }
static inline GccArguments::Lang guessLang(const Path &fullPath) { ByteArray compiler = fullPath.fileName(); ByteArray c; int dash = compiler.lastIndexOf('-'); if (dash >= 0) { c = ByteArray(compiler.constData() + dash + 1, compiler.size() - dash - 1); } else { c = ByteArray(compiler.constData(), compiler.size()); } if (c.size() != compiler.size()) { bool isVersion = true; for (int i=0; i<c.size(); ++i) { if ((c.at(i) < '0' || c.at(i) > '9') && c.at(i) != '.') { isVersion = false; break; } } if (isVersion) { dash = compiler.lastIndexOf('-', dash - 1); if (dash >= 0) { c = compiler.mid(dash + 1, compiler.size() - c.size() - 2 - dash); } else { c = compiler.left(dash); } } } GccArguments::Lang lang = GccArguments::NoLang; if (c.startsWith("g++") || c.startsWith("c++")) { lang = GccArguments::CPlusPlus; } else if (c.startsWith("gcc") || c.startsWith("cc")) { lang = GccArguments::C; } return lang; }
Path Process::findCommand(const ByteArray& command) { if (command.isEmpty() || command.at(0) == '/') return command; const char* path = getenv("PATH"); if (!path) return Path(); bool ok; const List<ByteArray> paths = ByteArray(path).split(':'); for (List<ByteArray>::const_iterator it = paths.begin(); it != paths.end(); ++it) { const Path ret = Path::resolved(command, *it, &ok); if (ok && !access(ret.nullTerminated(), R_OK | X_OK)) return ret; } return Path(); }
bool TarReader::readHeader(Ref<ArchiveEntry> *nextEntry) { if (!data_) data_ = ByteArray::create(512); *nextEntry = ArchiveEntry::create(); ByteArray *data = data_; ArchiveEntry *entry = *nextEntry; if (source_->readAll(data) < data->count()) return false; i_ += data->count(); bool eoi = true; for (int i = 0; i < data->count(); ++i) { if (data->byteAt(i) != 0) { eoi = false; break; } } if (eoi) return false; bool ustarMagic = false; bool gnuMagic = false; bool readAgain = true; while (readAgain) { readAgain = false; String magic; data->scanString(&magic, "", 257, 263); ustarMagic = (magic == "ustar"); gnuMagic = (magic == "ustar "); unsigned checksum, probesum; data->scanNumber(&checksum, 8, 148, 156); entry->type_ = data->at(156); if (entry->path_ == "") data->scanString(&entry->path_, "", 0, 100); if (entry->linkPath_ == "") data->scanString(&entry->linkPath_, "", 157, 257); probesum = tarHeaderSum(data); if (checksum != probesum) throw BrokenArchive(i_ - data->count(), Format("Checksum mismatch (%% != %%), path = \"%%\"") << oct(checksum, 6) << oct(probesum, 6) << entry->path()); if (gnuMagic) { while ((entry->type_ == 'K' || entry->type_ == 'L') /*&& entry->path_ == "././@LongLink"*/) { data->scanNumber(&entry->size_, 8, 124, 136); String longPath = source_->readAll(entry->size_); if (longPath->count() < entry->size_) throw BrokenArchive(i_, "Expected GNU @LongLink data"); i_ += entry->size_; if (entry->size() % 512 != 0) { i_ += source_->skip(512 - entry->size() % 512); } if (longPath->byteAt(longPath->count() - 1) == 0) longPath->truncate(longPath->count() - 1); if (entry->type_ == 'K') entry->linkPath_ = longPath; else if (entry->type_ == 'L') entry->path_ = longPath; if (source_->readAll(data) < data->count()) throw BrokenArchive(i_, "Expected GNU @LongLink header"); i_ += data->count(); entry->type_ = data->at(156); readAgain = true; } } } if (ustarMagic || gnuMagic) { String prefix; data->scanString(&entry->userName_, "", 265, 297); data->scanString(&entry->groupName_, "", 297, 329); if (!gnuMagic) { data->scanString(&prefix, "", 345, 500); if (prefix != "") entry->path_ = prefix + "/" + entry->path_; } } data->scanNumber(&entry->mode_, 8, 100, 108); data->scanNumber(&entry->userId_, 8, 108, 116); data->scanNumber(&entry->groupId_, 8, 116, 124); data->scanNumber(&entry->size_, 8, 124, 136); data->scanNumber(&entry->lastModified_, 8, 136, 148); if (entry->type() == 0 && entry->path()->count() > 0) { if (entry->path()->at(entry->path()->count() - 1) == '/') entry->type_ = ArchiveEntry::Directory; } entry->offset_ = i_; return true; }