00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
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
00157 typename S::size_type last_pos =
00158 value.find_first_not_of(separator, 0);
00159
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
00165 ret.push_back(value.substr(last_pos, pos - last_pos));
00166
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
00211 typename S::size_type last_pos = 0;
00212
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
00218 if (pos == std::string::npos)
00219
00220 ret.push_back(value.substr(last_pos, pos));
00221 else
00222
00223 ret.push_back(value.substr(last_pos, pos - last_pos));
00224
00225
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
00867
00868
00869
00870
00871
00872