sbuild
1.4.26
|
00001 /* Copyright © 2005-2007 Roger Leigh <rleigh@debian.org> 00002 * 00003 * schroot is free software: you can redistribute it and/or modify it 00004 * under the terms of the GNU General Public License as published by 00005 * the Free Software Foundation, either version 3 of the License, or 00006 * (at your option) any later version. 00007 * 00008 * schroot is distributed in the hope that it will be useful, but 00009 * WITHOUT ANY WARRANTY; without even the implied warranty of 00010 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00011 * General Public License for more details. 00012 * 00013 * You should have received a copy of the GNU General Public License 00014 * along with this program. If not, see 00015 * <http://www.gnu.org/licenses/>. 00016 * 00017 *********************************************************************/ 00018 00019 #ifndef SBUILD_UTIL_H 00020 #define SBUILD_UTIL_H 00021 00022 #include <sbuild/sbuild-environment.h> 00023 #include <sbuild/sbuild-error.h> 00024 #include <sbuild/sbuild-regex.h> 00025 #include <sbuild/sbuild-types.h> 00026 00027 #include <string> 00028 #include <cerrno> 00029 00030 #include <sys/types.h> 00031 #include <sys/stat.h> 00032 #include <pwd.h> 00033 #include <grp.h> 00034 #include <unistd.h> 00035 00036 namespace sbuild 00037 { 00038 00046 std::string 00047 basename (std::string name); 00048 00056 std::string 00057 dirname (std::string name); 00058 00066 std::string 00067 normalname (std::string name); 00068 00076 bool 00077 is_absname (std::string const& name); 00078 00087 bool 00088 is_valid_sessionname (std::string const& name); 00089 00099 bool 00100 is_valid_filename (std::string const& name, 00101 bool lsb_mode = true); 00102 00109 std::string 00110 getcwd (); 00111 00112 00120 std::string 00121 unique_identifier (); 00122 00131 std::string 00132 string_list_to_string (string_list const& list, 00133 std::string const& separator); 00134 00149 template <typename S> 00150 std::vector<S> 00151 split_string (S const& value, 00152 S const& separator) 00153 { 00154 std::vector<S> ret; 00155 00156 // Skip any separators at the start 00157 typename S::size_type last_pos = 00158 value.find_first_not_of(separator, 0); 00159 // Find first separator. 00160 typename S::size_type pos = value.find_first_of(separator, last_pos); 00161 00162 while (pos !=S::npos || last_pos != S::npos) 00163 { 00164 // Add to list 00165 ret.push_back(value.substr(last_pos, pos - last_pos)); 00166 // Find next 00167 last_pos = value.find_first_not_of(separator, pos); 00168 pos = value.find_first_of(separator, last_pos); 00169 } 00170 00171 return ret; 00172 } 00173 00185 std::vector<std::string> 00186 split_string (std::string const& value, 00187 std::string const& separator); 00188 00203 template <typename S> 00204 std::vector<S> 00205 split_string_strict (S const& value, 00206 S const& separator) 00207 { 00208 std::vector<S> ret; 00209 00210 // Skip any separators at the start 00211 typename S::size_type last_pos = 0; 00212 // Find first separator. 00213 typename S::size_type pos = value.find_first_of(separator, last_pos); 00214 00215 while (pos !=S::npos || last_pos != S::npos) 00216 { 00217 // Add to list 00218 if (pos == std::string::npos) 00219 // Entire string from last_pos 00220 ret.push_back(value.substr(last_pos, pos)); 00221 else 00222 // Between pos and last_pos 00223 ret.push_back(value.substr(last_pos, pos - last_pos)); 00224 00225 // Find next 00226 last_pos = pos + separator.length(); 00227 pos = value.find_first_of(separator, last_pos); 00228 } 00229 00230 return ret; 00231 } 00232 00244 std::vector<std::string> 00245 split_string_strict (std::string const& value, 00246 std::string const& separator); 00247 00257 std::wstring 00258 widen_string (std::string const& str, 00259 std::locale locale); 00260 00270 std::string 00271 narrow_string (std::wstring const& str, 00272 std::locale locale); 00273 00284 std::string 00285 find_program_in_path (std::string const& program, 00286 std::string const& path, 00287 std::string const& prefix); 00288 00297 char ** 00298 string_list_to_strv (string_list const& str); 00299 00307 void 00308 strv_delete (char **strv); 00309 00320 int 00321 exec (std::string const& file, 00322 string_list const& command, 00323 environment const& env); 00324 00328 class stat 00329 { 00330 public: 00332 enum error_code 00333 { 00334 FILE, 00335 FD 00336 }; 00337 00339 enum mode_bits 00340 { 00341 FILE_TYPE_MASK = S_IFMT, 00342 FILE_TYPE_SOCKET = S_IFSOCK, 00343 FILE_TYPE_LINK = S_IFLNK, 00344 FILE_TYPE_REGULAR = S_IFREG, 00345 FILE_TYPE_BLOCK = S_IFBLK, 00346 FILE_TYPE_DIRECTORY = S_IFDIR, 00347 FILE_TYPE_CHARACTER = S_IFCHR, 00348 FILE_TYPE_FIFO = S_IFIFO, 00349 PERM_SETUID = S_ISUID, 00350 PERM_SETGIT = S_ISGID, 00351 PERM_STICKY = S_ISVTX, 00352 PERM_USER_MASK = S_IRWXU, 00353 PERM_USER_READ = S_IRUSR, 00354 PERM_USER_WRITE = S_IWUSR, 00355 PERM_USER_EXECUTE = S_IXUSR, 00356 PERM_GROUP_MASK = S_IRWXG, 00357 PERM_GROUP_READ = S_IRGRP, 00358 PERM_GROUP_WRITE = S_IWGRP, 00359 PERM_GROUP_EXECUTE = S_IXGRP, 00360 PERM_OTHER_MASK = S_IRWXO, 00361 PERM_OTHER_READ = S_IROTH, 00362 PERM_OTHER_WRITE = S_IWOTH, 00363 PERM_OTHER_EXECUTE = S_IXOTH 00364 }; 00365 00367 typedef custom_error<error_code> error; 00368 00373 stat (const char *file); 00374 00379 stat (std::string const& file); 00380 00387 stat (std::string const& file, 00388 int fd); 00389 00394 stat (int fd); 00395 00397 virtual ~stat (); 00398 00404 void check () const 00405 { 00406 if (this->errorno) 00407 { 00408 if (!this->file.empty()) 00409 throw error(this->file, FILE, strerror(this->errorno)); 00410 else 00411 { 00412 std::ostringstream str; 00413 str << "fd " << fd; 00414 throw error(str.str(), FD, strerror(this->errorno)); 00415 } 00416 } 00417 } 00418 00424 struct ::stat const& get_detail() 00425 { return this->status; } 00426 00431 dev_t 00432 device () const 00433 { check(); return status.st_dev; } 00434 00439 ino_t 00440 inode () const 00441 { check(); return status.st_ino; } 00442 00447 mode_t 00448 mode () const 00449 { check(); return status.st_mode; } 00450 00455 nlink_t 00456 links () const 00457 { check(); return status.st_nlink; } 00458 00463 uid_t 00464 uid () const 00465 { check(); return status.st_uid; } 00466 00471 gid_t 00472 gid () const 00473 { check(); return status.st_gid; } 00474 00479 off_t 00480 size () const 00481 { check(); return status.st_size; } 00482 00487 blksize_t 00488 blocksize () const 00489 { check(); return status.st_blksize; } 00490 00495 blkcnt_t 00496 blocks () const 00497 { check(); return status.st_blocks; } 00498 00503 time_t 00504 atime () const 00505 { check(); return status.st_atime; } 00506 00511 time_t 00512 mtime () const 00513 { check(); return status.st_mtime; } 00514 00519 time_t 00520 ctime () const 00521 { check(); return status.st_ctime; } 00522 00527 inline bool 00528 is_regular () const; 00529 00534 inline bool 00535 is_directory () const; 00536 00541 inline bool 00542 is_character () const; 00543 00548 inline bool 00549 is_block () const; 00550 00555 inline bool 00556 is_fifo () const; 00557 00562 inline bool 00563 is_link () const; 00564 00569 inline bool 00570 is_socket () const; 00571 00577 inline bool check_mode (mode_bits mask) const; 00578 00579 private: 00580 00582 std::string file; 00584 int fd; 00586 int errorno; 00588 struct ::stat status; 00589 }; 00590 00597 stat::mode_bits 00598 inline operator | (stat::mode_bits const& lhs, 00599 stat::mode_bits const& rhs) 00600 { 00601 return static_cast<stat::mode_bits> 00602 (static_cast<int>(lhs) | static_cast<int>(rhs)); 00603 } 00604 00611 stat::mode_bits 00612 inline operator | (mode_t const& lhs, 00613 stat::mode_bits const& rhs) 00614 { 00615 return static_cast<stat::mode_bits> 00616 (lhs | static_cast<int>(rhs)); 00617 } 00618 00625 stat::mode_bits 00626 inline operator | (stat::mode_bits const& lhs, 00627 mode_t const& rhs) 00628 { 00629 return static_cast<stat::mode_bits> 00630 (static_cast<int>(lhs) | rhs); 00631 } 00632 00639 stat::mode_bits 00640 inline operator & (stat::mode_bits const& lhs, 00641 stat::mode_bits const& rhs) 00642 { 00643 return static_cast<stat::mode_bits> 00644 (static_cast<int>(lhs) & static_cast<int>(rhs)); 00645 } 00646 00653 stat::mode_bits 00654 inline operator & (mode_t const& lhs, 00655 stat::mode_bits const& rhs) 00656 { 00657 return static_cast<stat::mode_bits> 00658 (lhs & static_cast<int>(rhs)); 00659 } 00660 00667 stat::mode_bits 00668 inline operator & (stat::mode_bits const& lhs, 00669 mode_t const& rhs) 00670 { 00671 return static_cast<stat::mode_bits> 00672 (static_cast<int>(lhs) & rhs); 00673 } 00674 00675 inline bool 00676 stat::is_regular () const 00677 { return check_mode(FILE_TYPE_REGULAR & FILE_TYPE_MASK); } 00678 00679 inline bool 00680 stat::is_directory () const 00681 { return check_mode(FILE_TYPE_DIRECTORY & FILE_TYPE_MASK); } 00682 00683 inline bool 00684 stat::is_character () const 00685 { return check_mode(FILE_TYPE_CHARACTER & FILE_TYPE_MASK); } 00686 00687 inline bool 00688 stat::is_block () const 00689 { return check_mode(FILE_TYPE_BLOCK & FILE_TYPE_MASK); } 00690 00691 inline bool 00692 stat::is_fifo () const 00693 { return check_mode(FILE_TYPE_FIFO & FILE_TYPE_MASK); } 00694 00695 inline bool 00696 stat::is_link () const 00697 { return check_mode(FILE_TYPE_LINK & FILE_TYPE_MASK); } 00698 00699 inline bool 00700 stat::is_socket () const 00701 { return check_mode(FILE_TYPE_SOCKET & FILE_TYPE_MASK); } 00702 00703 inline bool 00704 stat::check_mode (mode_bits mask) const 00705 { 00706 check(); 00707 return (static_cast<stat::mode_bits>(status.st_mode) & mask) == mask; 00708 } 00709 00713 class passwd : public ::passwd 00714 { 00715 public: 00717 typedef std::vector<char> buffer_type; 00718 00720 passwd (); 00721 00727 passwd (uid_t uid); 00728 00734 passwd (const char *name); 00735 00741 passwd (std::string const& name); 00742 00747 void 00748 clear (); 00749 00755 void 00756 query_uid (uid_t uid); 00757 00763 void 00764 query_name (const char *name); 00765 00771 void 00772 query_name (std::string const& name); 00773 00777 bool 00778 operator ! () const; 00779 00780 private: 00782 buffer_type buffer; 00784 bool valid; 00785 }; 00786 00790 class group : public ::group 00791 { 00792 public: 00794 typedef std::vector<char> buffer_type; 00795 00797 group (); 00798 00804 group (gid_t gid); 00805 00811 group (const char *name); 00812 00818 group (std::string const& name); 00819 00824 void 00825 clear (); 00826 00832 void 00833 query_gid (gid_t gid); 00834 00840 void 00841 query_name (const char *name); 00842 00848 void 00849 query_name (std::string const& name); 00850 00854 bool 00855 operator ! () const; 00856 00857 private: 00859 buffer_type buffer; 00861 bool valid; 00862 }; 00863 00864 } 00865 00866 #endif /* SBUILD_UTIL_H */ 00867 00868 /* 00869 * Local Variables: 00870 * mode:C++ 00871 * End: 00872 */