// 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"; }
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"); }