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
00088 bool
00089 is_valid_filename (std::string const& name,
00090 bool lsb_mode = true);
00091
00098 std::string
00099 getcwd ();
00100
00101
00109 std::string
00110 unique_identifier ();
00111
00120 std::string
00121 string_list_to_string (string_list const& list,
00122 std::string const& separator);
00123
00138 template <typename S>
00139 std::vector<S>
00140 split_string (S const& value,
00141 S const& separator)
00142 {
00143 std::vector<S> ret;
00144
00145
00146 typename S::size_type last_pos =
00147 value.find_first_not_of(separator, 0);
00148
00149 typename S::size_type pos = value.find_first_of(separator, last_pos);
00150
00151 while (pos !=S::npos || last_pos != S::npos)
00152 {
00153
00154 ret.push_back(value.substr(last_pos, pos - last_pos));
00155
00156 last_pos = value.find_first_not_of(separator, pos);
00157 pos = value.find_first_of(separator, last_pos);
00158 }
00159
00160 return ret;
00161 }
00162
00163
00164 std::vector<std::string>
00165 split_string (std::string const& value,
00166 std::string const& separator);
00167
00182 template <typename S>
00183 std::vector<S>
00184 split_string_strict (S const& value,
00185 S const& separator)
00186 {
00187 std::vector<S> ret;
00188
00189
00190 typename S::size_type last_pos = 0;
00191
00192 typename S::size_type pos = value.find_first_of(separator, last_pos);
00193
00194 while (pos !=S::npos || last_pos != S::npos)
00195 {
00196
00197 if (pos == std::string::npos)
00198
00199 ret.push_back(value.substr(last_pos, pos));
00200 else
00201
00202 ret.push_back(value.substr(last_pos, pos - last_pos));
00203
00204
00205 last_pos = pos + separator.length();
00206 pos = value.find_first_of(separator, last_pos);
00207 }
00208
00209 return ret;
00210 }
00211
00212
00213 std::vector<std::string>
00214 split_string_strict (std::string const& value,
00215 std::string const& separator);
00216
00226 std::wstring
00227 widen_string (std::string const& str,
00228 std::locale locale);
00229
00239 std::string
00240 narrow_string (std::wstring const& str,
00241 std::locale locale);
00242
00253 std::string
00254 find_program_in_path (std::string const& program,
00255 std::string const& path,
00256 std::string const& prefix);
00257
00265 char **
00266 string_list_to_strv (string_list const& str);
00267
00275 void
00276 strv_delete (char **strv);
00277
00288 int
00289 exec (std::string const& file,
00290 string_list const& command,
00291 environment const& env);
00292
00296 class stat
00297 {
00298 public:
00300 enum error_code
00301 {
00302 FILE,
00303 FD
00304 };
00305
00307 enum mode_bits
00308 {
00309 FILE_TYPE_MASK = S_IFMT,
00310 FILE_TYPE_SOCKET = S_IFSOCK,
00311 FILE_TYPE_LINK = S_IFLNK,
00312 FILE_TYPE_REGULAR = S_IFREG,
00313 FILE_TYPE_BLOCK = S_IFBLK,
00314 FILE_TYPE_DIRECTORY = S_IFDIR,
00315 FILE_TYPE_CHARACTER = S_IFCHR,
00316 FILE_TYPE_FIFO = S_IFIFO,
00317 PERM_SETUID = S_ISUID,
00318 PERM_SETGIT = S_ISGID,
00319 PERM_STICKY = S_ISVTX,
00320 PERM_USER_MASK = S_IRWXU,
00321 PERM_USER_READ = S_IRUSR,
00322 PERM_USER_WRITE = S_IWUSR,
00323 PERM_USER_EXECUTE = S_IXUSR,
00324 PERM_GROUP_MASK = S_IRWXG,
00325 PERM_GROUP_READ = S_IRGRP,
00326 PERM_GROUP_WRITE = S_IWGRP,
00327 PERM_GROUP_EXECUTE = S_IXGRP,
00328 PERM_OTHER_MASK = S_IRWXO,
00329 PERM_OTHER_READ = S_IROTH,
00330 PERM_OTHER_WRITE = S_IWOTH,
00331 PERM_OTHER_EXECUTE = S_IXOTH
00332 };
00333
00335 typedef custom_error<error_code> error;
00336
00341 stat (const char *file);
00342
00347 stat (std::string const& file);
00348
00355 stat (std::string const& file,
00356 int fd);
00357
00362 stat (int fd);
00363
00365 virtual ~stat ();
00366
00372 void check () const
00373 {
00374 if (this->errorno)
00375 {
00376 if (!this->file.empty())
00377 throw error(this->file, FILE, strerror(this->errorno));
00378 else
00379 {
00380 std::ostringstream str;
00381 str << "fd " << fd;
00382 throw error(str.str(), FD, strerror(this->errorno));
00383 }
00384 }
00385 }
00386
00392 struct ::stat const& get_detail()
00393 { return this->status; }
00394
00399 dev_t
00400 device () const
00401 { check(); return status.st_dev; }
00402
00407 ino_t
00408 inode () const
00409 { check(); return status.st_ino; }
00410
00415 mode_t
00416 mode () const
00417 { check(); return status.st_mode; }
00418
00423 nlink_t
00424 links () const
00425 { check(); return status.st_nlink; }
00426
00431 uid_t
00432 uid () const
00433 { check(); return status.st_uid; }
00434
00439 gid_t
00440 gid () const
00441 { check(); return status.st_gid; }
00442
00447 off_t
00448 size () const
00449 { check(); return status.st_size; }
00450
00455 blksize_t
00456 blocksize () const
00457 { check(); return status.st_blksize; }
00458
00463 blkcnt_t
00464 blocks () const
00465 { check(); return status.st_blocks; }
00466
00471 time_t
00472 atime () const
00473 { check(); return status.st_atime; }
00474
00479 time_t
00480 mtime () const
00481 { check(); return status.st_mtime; }
00482
00487 time_t
00488 ctime () const
00489 { check(); return status.st_ctime; }
00490
00495 inline bool
00496 is_regular () const;
00497
00502 inline bool
00503 is_directory () const;
00504
00509 inline bool
00510 is_character () const;
00511
00516 inline bool
00517 is_block () const;
00518
00523 inline bool
00524 is_fifo () const;
00525
00530 inline bool
00531 is_link () const;
00532
00537 inline bool
00538 is_socket () const;
00539
00545 inline bool check_mode (mode_bits mask) const;
00546
00547 private:
00548
00550 std::string file;
00552 int fd;
00554 int errorno;
00556 struct ::stat status;
00557 };
00558
00565 stat::mode_bits
00566 inline operator | (stat::mode_bits const& lhs,
00567 stat::mode_bits const& rhs)
00568 {
00569 return static_cast<stat::mode_bits>
00570 (static_cast<int>(lhs) | static_cast<int>(rhs));
00571 }
00572
00579 stat::mode_bits
00580 inline operator | (mode_t const& lhs,
00581 stat::mode_bits const& rhs)
00582 {
00583 return static_cast<stat::mode_bits>
00584 (lhs | static_cast<int>(rhs));
00585 }
00586
00593 stat::mode_bits
00594 inline operator | (stat::mode_bits const& lhs,
00595 mode_t const& rhs)
00596 {
00597 return static_cast<stat::mode_bits>
00598 (static_cast<int>(lhs) | rhs);
00599 }
00600
00607 stat::mode_bits
00608 inline operator & (stat::mode_bits const& lhs,
00609 stat::mode_bits const& rhs)
00610 {
00611 return static_cast<stat::mode_bits>
00612 (static_cast<int>(lhs) & static_cast<int>(rhs));
00613 }
00614
00621 stat::mode_bits
00622 inline operator & (mode_t const& lhs,
00623 stat::mode_bits const& rhs)
00624 {
00625 return static_cast<stat::mode_bits>
00626 (lhs & static_cast<int>(rhs));
00627 }
00628
00635 stat::mode_bits
00636 inline operator & (stat::mode_bits const& lhs,
00637 mode_t const& rhs)
00638 {
00639 return static_cast<stat::mode_bits>
00640 (static_cast<int>(lhs) & rhs);
00641 }
00642
00643 inline bool
00644 stat::is_regular () const
00645 { return check_mode(FILE_TYPE_REGULAR & FILE_TYPE_MASK); }
00646
00647 inline bool
00648 stat::is_directory () const
00649 { return check_mode(FILE_TYPE_DIRECTORY & FILE_TYPE_MASK); }
00650
00651 inline bool
00652 stat::is_character () const
00653 { return check_mode(FILE_TYPE_CHARACTER & FILE_TYPE_MASK); }
00654
00655 inline bool
00656 stat::is_block () const
00657 { return check_mode(FILE_TYPE_BLOCK & FILE_TYPE_MASK); }
00658
00659 inline bool
00660 stat::is_fifo () const
00661 { return check_mode(FILE_TYPE_FIFO & FILE_TYPE_MASK); }
00662
00663 inline bool
00664 stat::is_link () const
00665 { return check_mode(FILE_TYPE_LINK & FILE_TYPE_MASK); }
00666
00667 inline bool
00668 stat::is_socket () const
00669 { return check_mode(FILE_TYPE_SOCKET & FILE_TYPE_MASK); }
00670
00671 inline bool
00672 stat::check_mode (mode_bits mask) const
00673 {
00674 check();
00675 return (static_cast<stat::mode_bits>(status.st_mode) & mask) == mask;
00676 }
00677
00681 class passwd : public ::passwd
00682 {
00683 public:
00684 typedef std::vector<char> buffer_type;
00685
00686 passwd ();
00687
00688 passwd (uid_t uid);
00689
00690 passwd (const char *name);
00691
00692 passwd (std::string const& name);
00693
00694 void
00695 clear ();
00696
00697 void
00698 query_uid (uid_t uid);
00699
00700 void
00701 query_name (const char *name);
00702
00703 void
00704 query_name (std::string const& name);
00705
00706 bool
00707 operator ! () const;
00708
00709 private:
00710 buffer_type buffer;
00711 bool valid;
00712 };
00713
00717 class group : public ::group
00718 {
00719 public:
00720 typedef std::vector<char> buffer_type;
00721
00722 group ();
00723
00724 group (gid_t gid);
00725
00726 group (const char *name);
00727
00728 group (std::string const& name);
00729
00730 void
00731 clear ();
00732
00733 void
00734 query_gid (gid_t gid);
00735
00736 void
00737 query_name (const char *name);
00738
00739 void
00740 query_name (std::string const& name);
00741
00742 bool
00743 operator ! () const;
00744
00745 private:
00746 buffer_type buffer;
00747 bool valid;
00748 };
00749
00750 }
00751
00752 #endif
00753
00754
00755
00756
00757
00758