// Implement the 'x' operation. This function extracts files back to the file // system. static void doExtract(StringRef Name, object::Archive::child_iterator I) { // Retain the original mode. sys::fs::perms Mode = I->getAccessMode(); SmallString<128> Storage = Name; int FD; failIfError( sys::fs::openFileForWrite(Storage.c_str(), FD, sys::fs::F_None, Mode), Storage.c_str()); { raw_fd_ostream file(FD, false); // Get the data and its length StringRef Data = I->getBuffer(); // Write the data. file.write(Data.data(), Data.size()); } // If we're supposed to retain the original modification times, etc. do so // now. if (OriginalDates) failIfError( sys::fs::setLastModificationAndAccessTime(FD, I->getLastModified())); if (close(FD)) fail("Could not close the file"); }
// Implement the 't' operation. This function prints out just // the file names of each of the members. However, if verbose mode is requested // ('v' modifier) then the file type, permission mode, user, group, size, and // modification time are also printed. static void doDisplayTable(StringRef Name, object::Archive::child_iterator I) { if (Verbose) { sys::fs::perms Mode = I->getAccessMode(); printMode((Mode >> 6) & 007); printMode((Mode >> 3) & 007); printMode(Mode & 007); outs() << ' ' << I->getUID(); outs() << '/' << I->getGID(); outs() << ' ' << format("%6llu", I->getSize()); outs() << ' ' << I->getLastModified().str(); outs() << ' '; } outs() << Name << "\n"; }
// Implements the 'p' operation. This function traverses the archive // looking for members that match the path list. static void doPrint(StringRef Name, object::Archive::child_iterator I) { if (Verbose) outs() << "Printing " << Name << "\n"; StringRef Data = I->getBuffer(); outs().write(Data.data(), Data.size()); }
void addMember(std::vector<NewArchiveIterator> &Members, object::Archive::child_iterator I, StringRef Name, int Pos = -1) { if (Thin && !I->getParent()->isThin()) fail("Cannot convert a regular archive to a thin one"); NewArchiveIterator NI(I, Name); if (Pos == -1) Members.push_back(NI); else Members[Pos] = NI; }
static InsertAction computeInsertAction(ArchiveOperation Operation, object::Archive::child_iterator I, StringRef Name, std::vector<std::string>::iterator &Pos) { if (Operation == QuickAppend || Members.empty()) return IA_AddOldMember; std::vector<std::string>::iterator MI = std::find_if( Members.begin(), Members.end(), [Name](StringRef Path) { return Name == sys::path::filename(Path); }); if (MI == Members.end()) return IA_AddOldMember; Pos = MI; if (Operation == Delete) return IA_Delete; if (Operation == Move) return IA_MoveOldMember; if (Operation == ReplaceOrInsert) { StringRef PosName = sys::path::filename(RelPos); if (!OnlyUpdate) { if (PosName.empty()) return IA_AddNewMeber; return IA_MoveNewMember; } // We could try to optimize this to a fstat, but it is not a common // operation. sys::fs::file_status Status; failIfError(sys::fs::status(*MI, Status), *MI); if (Status.getLastModificationTime() < I->getLastModified()) { if (PosName.empty()) return IA_AddOldMember; return IA_MoveOldMember; } if (PosName.empty()) return IA_AddNewMeber; return IA_MoveNewMember; } llvm_unreachable("No such operation"); }