sbuild
1.5.4
|
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 #include <cstring> 00030 00031 #include <sys/types.h> 00032 #include <sys/stat.h> 00033 #include <pwd.h> 00034 #include <grp.h> 00035 #include <unistd.h> 00036 00037 namespace sbuild 00038 { 00039 00047 std::string 00048 basename (std::string name); 00049 00057 std::string 00058 dirname (std::string name); 00059 00067 std::string 00068 normalname (std::string name); 00069 00077 bool 00078 is_absname (std::string const& name); 00079 00088 bool 00089 is_valid_sessionname (std::string const& name); 00090 00100 bool 00101 is_valid_filename (std::string const& name, 00102 bool lsb_mode = true); 00103 00110 std::string 00111 getcwd (); 00112 00113 00121 std::string 00122 unique_identifier (); 00123 00132 std::string 00133 string_list_to_string (string_list const& list, 00134 std::string const& separator); 00135 00150 template <typename S> 00151 std::vector<S> 00152 split_string (S const& value, 00153 S const& separator) 00154 { 00155 std::vector<S> ret; 00156 00157 // Skip any separators at the start 00158 typename S::size_type last_pos = 00159 value.find_first_not_of(separator, 0); 00160 // Find first separator. 00161 typename S::size_type pos = value.find_first_of(separator, last_pos); 00162 00163 while (pos !=S::npos || last_pos != S::npos) 00164 { 00165 // Add to list 00166 ret.push_back(value.substr(last_pos, pos - last_pos)); 00167 // Find next 00168 last_pos = value.find_first_not_of(separator, pos); 00169 pos = value.find_first_of(separator, last_pos); 00170 } 00171 00172 return ret; 00173 } 00174 00186 std::vector<std::string> 00187 split_string (std::string const& value, 00188 std::string const& separator); 00189 00204 template <typename S> 00205 std::vector<S> 00206 split_string_strict (S const& value, 00207 S const& separator) 00208 { 00209 std::vector<S> ret; 00210 00211 // Skip any separators at the start 00212 typename S::size_type last_pos = 0; 00213 // Find first separator. 00214 typename S::size_type pos = value.find_first_of(separator, last_pos); 00215 00216 while (pos !=S::npos || last_pos != S::npos) 00217 { 00218 // Add to list 00219 if (pos == std::string::npos) 00220 // Entire string from last_pos 00221 ret.push_back(value.substr(last_pos, pos)); 00222 else 00223 // Between pos and last_pos 00224 ret.push_back(value.substr(last_pos, pos - last_pos)); 00225 00226 // Find next 00227 last_pos = pos + separator.length(); 00228 pos = value.find_first_of(separator, last_pos); 00229 } 00230 00231 return ret; 00232 } 00233 00245 std::vector<std::string> 00246 split_string_strict (std::string const& value, 00247 std::string const& separator); 00248 00258 std::wstring 00259 widen_string (std::string const& str, 00260 std::locale locale); 00261 00271 std::string 00272 narrow_string (std::wstring const& str, 00273 std::locale locale); 00274 00285 std::string 00286 find_program_in_path (std::string const& program, 00287 std::string const& path, 00288 std::string const& prefix); 00289 00298 char ** 00299 string_list_to_strv (string_list const& str); 00300 00308 void 00309 strv_delete (char **strv); 00310 00321 int 00322 exec (std::string const& file, 00323 string_list const& command, 00324 environment const& env); 00325 00329 class stat 00330 { 00331 public: 00333 enum error_code 00334 { 00335 FILE, 00336 FD 00337 }; 00338 00340 enum mode_bits 00341 { 00342 FILE_TYPE_MASK = S_IFMT, 00343 FILE_TYPE_SOCKET = S_IFSOCK, 00344 FILE_TYPE_LINK = S_IFLNK, 00345 FILE_TYPE_REGULAR = S_IFREG, 00346 FILE_TYPE_BLOCK = S_IFBLK, 00347 FILE_TYPE_DIRECTORY = S_IFDIR, 00348 FILE_TYPE_CHARACTER = S_IFCHR, 00349 FILE_TYPE_FIFO = S_IFIFO, 00350 PERM_SETUID = S_ISUID, 00351 PERM_SETGIT = S_ISGID, 00352 PERM_STICKY = S_ISVTX, 00353 PERM_USER_MASK = S_IRWXU, 00354 PERM_USER_READ = S_IRUSR, 00355 PERM_USER_WRITE = S_IWUSR, 00356 PERM_USER_EXECUTE = S_IXUSR, 00357 PERM_GROUP_MASK = S_IRWXG, 00358 PERM_GROUP_READ = S_IRGRP, 00359 PERM_GROUP_WRITE = S_IWGRP, 00360 PERM_GROUP_EXECUTE = S_IXGRP, 00361 PERM_OTHER_MASK = S_IRWXO, 00362 PERM_OTHER_READ = S_IROTH, 00363 PERM_OTHER_WRITE = S_IWOTH, 00364 PERM_OTHER_EXECUTE = S_IXOTH 00365 }; 00366 00368 typedef custom_error<error_code> error; 00369 00374 stat (const char *file); 00375 00380 stat (std::string const& file); 00381 00388 stat (std::string const& file, 00389 int fd); 00390 00395 stat (int fd); 00396 00398 virtual ~stat (); 00399 00405 void check () const 00406 { 00407 if (this->errorno) 00408 { 00409 if (!this->file.empty()) 00410 throw error(this->file, FILE, std::strerror(this->errorno)); 00411 else 00412 { 00413 std::ostringstream str; 00414 str << "fd " << fd; 00415 throw error(str.str(), FD, std::strerror(this->errorno)); 00416 } 00417 } 00418 } 00419 00425 struct ::stat const& get_detail() 00426 { return this->status; } 00427 00432 dev_t 00433 device () const 00434 { check(); return status.st_dev; } 00435 00440 ino_t 00441 inode () const 00442 { check(); return status.st_ino; } 00443 00448 mode_t 00449 mode () const 00450 { check(); return status.st_mode; } 00451 00456 nlink_t 00457 links () const 00458 { check(); return status.st_nlink; } 00459 00464 uid_t 00465 uid () const 00466 { check(); return status.st_uid; } 00467 00472 gid_t 00473 gid () const 00474 { check(); return status.st_gid; } 00475 00480 off_t 00481 size () const 00482 { check(); return status.st_size; } 00483 00488 blksize_t 00489 blocksize () const 00490 { check(); return status.st_blksize; } 00491 00496 blkcnt_t 00497 blocks () const 00498 { check(); return status.st_blocks; } 00499 00504 time_t 00505 atime () const 00506 { check(); return status.st_atime; } 00507 00512 time_t 00513 mtime () const 00514 { check(); return status.st_mtime; } 00515 00520 time_t 00521 ctime () const 00522 { check(); return status.st_ctime; } 00523 00528 inline bool 00529 is_regular () const; 00530 00535 inline bool 00536 is_directory () const; 00537 00542 inline bool 00543 is_character () const; 00544 00549 inline bool 00550 is_block () const; 00551 00556 inline bool 00557 is_fifo () const; 00558 00563 inline bool 00564 is_link () const; 00565 00570 inline bool 00571 is_socket () const; 00572 00578 inline bool check_mode (mode_bits mask) const; 00579 00580 private: 00581 00583 std::string file; 00585 int fd; 00587 int errorno; 00589 struct ::stat status; 00590 }; 00591 00598 stat::mode_bits 00599 inline operator | (stat::mode_bits const& lhs, 00600 stat::mode_bits const& rhs) 00601 { 00602 return static_cast<stat::mode_bits> 00603 (static_cast<int>(lhs) | static_cast<int>(rhs)); 00604 } 00605 00612 stat::mode_bits 00613 inline operator | (mode_t const& lhs, 00614 stat::mode_bits const& rhs) 00615 { 00616 return static_cast<stat::mode_bits> 00617 (lhs | static_cast<int>(rhs)); 00618 } 00619 00626 stat::mode_bits 00627 inline operator | (stat::mode_bits const& lhs, 00628 mode_t const& rhs) 00629 { 00630 return static_cast<stat::mode_bits> 00631 (static_cast<int>(lhs) | rhs); 00632 } 00633 00640 stat::mode_bits 00641 inline operator & (stat::mode_bits const& lhs, 00642 stat::mode_bits const& rhs) 00643 { 00644 return static_cast<stat::mode_bits> 00645 (static_cast<int>(lhs) & static_cast<int>(rhs)); 00646 } 00647 00654 stat::mode_bits 00655 inline operator & (mode_t const& lhs, 00656 stat::mode_bits const& rhs) 00657 { 00658 return static_cast<stat::mode_bits> 00659 (lhs & static_cast<int>(rhs)); 00660 } 00661 00668 stat::mode_bits 00669 inline operator & (stat::mode_bits const& lhs, 00670 mode_t const& rhs) 00671 { 00672 return static_cast<stat::mode_bits> 00673 (static_cast<int>(lhs) & rhs); 00674 } 00675 00676 inline bool 00677 stat::is_regular () const 00678 { return check_mode(FILE_TYPE_REGULAR & FILE_TYPE_MASK); } 00679 00680 inline bool 00681 stat::is_directory () const 00682 { return check_mode(FILE_TYPE_DIRECTORY & FILE_TYPE_MASK); } 00683 00684 inline bool 00685 stat::is_character () const 00686 { return check_mode(FILE_TYPE_CHARACTER & FILE_TYPE_MASK); } 00687 00688 inline bool 00689 stat::is_block () const 00690 { return check_mode(FILE_TYPE_BLOCK & FILE_TYPE_MASK); } 00691 00692 inline bool 00693 stat::is_fifo () const 00694 { return check_mode(FILE_TYPE_FIFO & FILE_TYPE_MASK); } 00695 00696 inline bool 00697 stat::is_link () const 00698 { return check_mode(FILE_TYPE_LINK & FILE_TYPE_MASK); } 00699 00700 inline bool 00701 stat::is_socket () const 00702 { return check_mode(FILE_TYPE_SOCKET & FILE_TYPE_MASK); } 00703 00704 inline bool 00705 stat::check_mode (mode_bits mask) const 00706 { 00707 check(); 00708 return (static_cast<stat::mode_bits>(status.st_mode) & mask) == mask; 00709 } 00710 00714 class passwd : public ::passwd 00715 { 00716 public: 00718 typedef std::vector<char> buffer_type; 00719 00721 passwd (); 00722 00728 passwd (uid_t uid); 00729 00735 passwd (const char *name); 00736 00742 passwd (std::string const& name); 00743 00748 void 00749 clear (); 00750 00756 void 00757 query_uid (uid_t uid); 00758 00764 void 00765 query_name (const char *name); 00766 00772 void 00773 query_name (std::string const& name); 00774 00778 bool 00779 operator ! () const; 00780 00781 private: 00783 buffer_type buffer; 00785 bool valid; 00786 }; 00787 00791 class group : public ::group 00792 { 00793 public: 00795 typedef std::vector<char> buffer_type; 00796 00798 group (); 00799 00805 group (gid_t gid); 00806 00812 group (const char *name); 00813 00819 group (std::string const& name); 00820 00825 void 00826 clear (); 00827 00833 void 00834 query_gid (gid_t gid); 00835 00841 void 00842 query_name (const char *name); 00843 00849 void 00850 query_name (std::string const& name); 00851 00855 bool 00856 operator ! () const; 00857 00858 private: 00860 buffer_type buffer; 00862 bool valid; 00863 }; 00864 00865 } 00866 00867 #endif /* SBUILD_UTIL_H */ 00868 00869 /* 00870 * Local Variables: 00871 * mode:C++ 00872 * End: 00873 */