Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright 2009, Google Inc. | 2 * Copyright 2009, Google Inc. |
| 3 * All rights reserved. | 3 * All rights reserved. |
| 4 * | 4 * |
| 5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
| 6 * modification, are permitted provided that the following conditions are | 6 * modification, are permitted provided that the following conditions are |
| 7 * met: | 7 * met: |
| 8 * | 8 * |
| 9 * * Redistributions of source code must retain the above copyright | 9 * * Redistributions of source code must retain the above copyright |
| 10 * notice, this list of conditions and the following disclaimer. | 10 * notice, this list of conditions and the following disclaimer. |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 34 #include "import/cross/tar_generator.h" | 34 #include "import/cross/tar_generator.h" |
| 35 | 35 |
| 36 using std::string; | 36 using std::string; |
| 37 | 37 |
| 38 #if defined(OS_WIN) | 38 #if defined(OS_WIN) |
| 39 #define snprintf _snprintf | 39 #define snprintf _snprintf |
| 40 #endif | 40 #endif |
| 41 | 41 |
| 42 namespace o3d { | 42 namespace o3d { |
| 43 | 43 |
| 44 const int kMaxFilenameSize = 100; | 44 const int kMaxFilenameSizeOldFormat = 100; |
| 45 | 45 |
| 46 const int kFileNameOffset = 0; | 46 const int kFileNameOffset = 0; |
| 47 const int kFileModeOffset = 100; | 47 const int kFileModeOffset = 100; |
| 48 const int kUserIDOffset = 108; | 48 const int kUserIDOffset = 108; |
| 49 const int kGroupIDOffset = 116; | 49 const int kGroupIDOffset = 116; |
| 50 const int kFileSizeOffset = 124; | 50 const int kFileSizeOffset = 124; |
| 51 const int kModifyTimeOffset = 136; | 51 const int kModifyTimeOffset = 136; |
| 52 const int kHeaderCheckSumOffset = 148; | 52 const int kHeaderCheckSumOffset = 148; |
| 53 const int kLinkFlagOffset = 156; | 53 const int kLinkFlagOffset = 156; |
| 54 const int kMagicOffset = 257; | 54 const int kMagicOffset = 257; |
| 55 const int kUserNameOffset = 265; | 55 const int kUserNameOffset = 265; |
| 56 const int kGroupNameOffset = 297; | 56 const int kGroupNameOffset = 297; |
| 57 static const char* kLongLink = "././@LongLink"; | |
|
Chris Rogers
2009/07/21 19:14:28
comment explaining what kLongLink is
| |
| 57 | 58 |
| 58 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 59 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 59 void TarGenerator::AddFile(const String &file_name, size_t file_size) { | 60 bool TarGenerator::AddFile(const String &file_name, size_t file_size) { |
| 60 AddDirectoryEntryIfNeeded(file_name); | 61 if (!AddDirectoryEntryIfNeeded(file_name)) { |
| 61 AddEntry(file_name, file_size, false); | 62 return false; |
| 63 } | |
| 64 return AddEntry(file_name, file_size, false); | |
| 62 } | 65 } |
| 63 | 66 |
| 64 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 67 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 65 void TarGenerator::AddDirectory(const String &file_name) { | 68 bool TarGenerator::AddDirectory(const String &file_name) { |
| 66 AddEntry(file_name, 0, true); | 69 return AddEntry(file_name, 0, true); |
| 67 } | 70 } |
| 68 | 71 |
| 69 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 72 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 70 // We keep a map so we add a particular directory entry only once | 73 // We keep a map so we add a particular directory entry only once |
| 71 void TarGenerator::AddDirectoryEntryIfNeeded(const String &file_name) { | 74 bool TarGenerator::AddDirectoryEntryIfNeeded(const String &file_name) { |
| 72 string::size_type index = file_name.find_last_of('/'); | 75 string::size_type index = file_name.find_last_of('/'); |
| 73 | 76 |
| 74 if (index != string::npos) { | 77 if (index != string::npos) { |
| 75 String dir_name = file_name.substr(0, index + 1); // keep the '/' at end | 78 String dir_name = file_name.substr(0, index + 1); // keep the '/' at end |
| 76 if (!directory_map_[dir_name]) { | 79 if (!directory_map_[dir_name]) { |
| 77 directory_map_[dir_name] = true; | 80 directory_map_[dir_name] = true; |
| 78 AddDirectory(dir_name); | 81 return AddDirectory(dir_name); |
| 79 } | 82 } |
| 80 } | 83 } |
| 84 return true; | |
| 81 } | 85 } |
| 82 | 86 |
| 83 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 87 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 84 void TarGenerator::AddEntry(const String &file_name, | 88 |
| 85 size_t file_size, | 89 |
| 86 bool is_directory) { | 90 void TarGenerator::WriteHeader(const String& file_name, |
| 91 size_t file_size, | |
| 92 char type, | |
| 93 int mode, | |
| 94 int user_id, | |
| 95 int group_id, | |
| 96 int mod_time) { | |
| 87 // first write out last data block from last file (if any) | 97 // first write out last data block from last file (if any) |
| 88 FlushDataBuffer(true); | 98 FlushDataBuffer(true); |
| 89 | 99 |
| 90 // next fill out a tar header | 100 // next fill out a tar header |
| 91 MemoryBuffer<uint8> header(TAR_HEADER_SIZE); // initializes header to zeroes | 101 MemoryBuffer<uint8> header(TAR_HEADER_SIZE); // initializes header to zeroes |
| 92 | 102 |
| 93 // leave room for NULL-termination | 103 // leave room for NULL-termination |
| 94 uint8 *h = header; | 104 uint8 *h = header; |
| 95 char *p = reinterpret_cast<char*>(h); | 105 char *p = reinterpret_cast<char*>(h); |
| 96 | 106 |
| 97 // File name | 107 // File name |
| 98 strncpy(p, file_name.c_str(), kMaxFilenameSize - 1); | 108 strncpy(p, file_name.c_str(), kMaxFilenameSizeOldFormat - 1); |
| 99 | 109 |
| 100 // File mode | 110 // File mode |
| 101 ::snprintf(p + kFileModeOffset, 8, "%07o", is_directory ? 0755 : 0644); | 111 ::snprintf(p + kFileModeOffset, 8, "%07o", mode); |
| 102 | 112 |
| 103 // UserID | 113 // UserID |
| 104 ::snprintf(p + kUserIDOffset, 8, "%07o", 0765); | 114 ::snprintf(p + kUserIDOffset, 8, "%07o", user_id); |
| 105 | 115 |
| 106 // GroupID | 116 // GroupID |
| 107 ::snprintf(p + kGroupIDOffset, 8, "%07o", 0204); | 117 ::snprintf(p + kGroupIDOffset, 8, "%07o", group_id); |
| 108 | 118 |
| 109 // File size | 119 // File size |
| 110 ::snprintf(p + kFileSizeOffset, 12, "%011o", file_size); | 120 ::snprintf(p + kFileSizeOffset, 12, "%011o", file_size); |
| 111 | 121 |
| 112 // Modification time | 122 // Modification time |
| 113 // TODO: write the correct current time here... | 123 // TODO: write the correct current time here... |
| 114 ::snprintf(p + kModifyTimeOffset, 12, "%07o", 011131753141); | 124 ::snprintf(p + kModifyTimeOffset, 12, "%07o", mod_time); |
| 115 | 125 |
| 116 // Initialize Header checksum so check sum can be computed | 126 // Initialize Header checksum so check sum can be computed |
| 117 // by ComputeCheckSum() which will fill in the value here | 127 // by ComputeCheckSum() which will fill in the value here |
| 118 ::memset(p + kHeaderCheckSumOffset, 32, 8); | 128 ::memset(p + kHeaderCheckSumOffset, 32, 8); |
| 119 | 129 |
| 120 // We only support ordinary files and directories, which is fine | 130 // We only support ordinary files and directories, which is fine |
| 121 // for our use case | 131 // for our use case |
|
Chris Rogers
2009/07/21 19:14:28
maybe should adjust comment to say this can indica
| |
| 122 int link_flag = is_directory ? '5' : '0'; | 132 p[kLinkFlagOffset] = type; |
| 123 p[kLinkFlagOffset] = link_flag; | |
| 124 | 133 |
| 125 // Magic offset | 134 // Magic offset |
| 126 ::snprintf(p + kMagicOffset, 8, "ustar "); | 135 ::snprintf(p + kMagicOffset, 8, "ustar "); |
| 127 | 136 |
| 128 // User name | 137 // User name |
| 129 ::snprintf(p + kUserNameOffset, 32, "guest"); | 138 ::snprintf(p + kUserNameOffset, 32, "guest"); |
| 130 | 139 |
| 131 // Group name | 140 // Group name |
| 132 ::snprintf(p + kGroupNameOffset, 32, "staff"); | 141 ::snprintf(p + kGroupNameOffset, 32, "staff"); |
| 133 | 142 |
| 134 | |
| 135 // This has to be done at the end | 143 // This has to be done at the end |
| 136 ComputeCheckSum(header); | 144 ComputeCheckSum(header); |
| 137 | 145 |
| 138 if (callback_client_) { | 146 if (callback_client_) { |
| 139 MemoryReadStream stream(header, TAR_HEADER_SIZE); | 147 MemoryReadStream stream(header, TAR_HEADER_SIZE); |
| 140 callback_client_->ProcessBytes(&stream, TAR_HEADER_SIZE); | 148 callback_client_->ProcessBytes(&stream, TAR_HEADER_SIZE); |
| 141 } | 149 } |
| 142 } | 150 } |
| 143 | 151 |
| 152 | |
| 153 bool TarGenerator::AddEntry(const String &file_name, | |
| 154 size_t file_size, | |
| 155 bool is_directory) { | |
| 156 // If filename is longer 99 chars, use the GNU format to write out a longer | |
| 157 // filename. | |
| 158 if (file_name.size() >= kMaxFilenameSizeOldFormat) { | |
| 159 WriteHeader(kLongLink, | |
| 160 file_name.size(), | |
| 161 'L', | |
| 162 0, | |
| 163 0, | |
| 164 0, | |
| 165 0); | |
| 166 | |
| 167 MemoryReadStream stream( | |
| 168 reinterpret_cast<const uint8*>(file_name.c_str()), file_name.size()); | |
| 169 AddFileBytes(&stream, file_name.size()); | |
| 170 } | |
| 171 | |
| 172 WriteHeader(file_name, | |
| 173 file_size, | |
| 174 is_directory ? '5' : '0', | |
| 175 is_directory ? 0755 : 0644, | |
| 176 0765, | |
| 177 0204, | |
| 178 011131753141); | |
| 179 | |
| 180 return true; | |
| 181 } | |
| 182 | |
| 144 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 183 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 145 void TarGenerator::ComputeCheckSum(uint8 *header) { | 184 void TarGenerator::ComputeCheckSum(uint8 *header) { |
| 146 unsigned int checksum = 0; | 185 unsigned int checksum = 0; |
| 147 for (int i = 0; i < TAR_HEADER_SIZE; ++i) { | 186 for (int i = 0; i < TAR_HEADER_SIZE; ++i) { |
| 148 checksum += header[i]; | 187 checksum += header[i]; |
| 149 } | 188 } |
| 150 snprintf(reinterpret_cast<char*>(header + kHeaderCheckSumOffset), | 189 snprintf(reinterpret_cast<char*>(header + kHeaderCheckSumOffset), |
| 151 8, "%06o\0\0", checksum); | 190 8, "%06o\0\0", checksum); |
| 152 } | 191 } |
| 153 | 192 |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 190 data_buffer_stream_.Seek(0); | 229 data_buffer_stream_.Seek(0); |
| 191 } | 230 } |
| 192 } | 231 } |
| 193 | 232 |
| 194 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 233 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 195 void TarGenerator::Finalize() { | 234 void TarGenerator::Finalize() { |
| 196 FlushDataBuffer(true); | 235 FlushDataBuffer(true); |
| 197 } | 236 } |
| 198 | 237 |
| 199 } // namespace o3d | 238 } // namespace o3d |
| OLD | NEW |