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
00047 std::string
00048 basename (std::string name,
00049 char separator = '/');
00050
00059 std::string
00060 dirname (std::string name,
00061 char separator = '/');
00062
00071 std::string
00072 normalname (std::string name,
00073 char separator = '/');
00074
00082 bool
00083 is_absname (std::string const& name);
00084
00094 bool
00095 is_valid_filename (std::string const& name,
00096 bool lsb_mode = true);
00097
00104 std::string
00105 getcwd ();
00106
00107
00115 std::string
00116 unique_identifier ();
00117
00126 std::string
00127 string_list_to_string (string_list const& list,
00128 std::string const& separator);
00129
00144 template <typename S>
00145 std::vector<S>
00146 split_string (S const& value,
00147 S const& separator)
00148 {
00149 std::vector<S> ret;
00150
00151
00152 typename S::size_type last_pos =
00153 value.find_first_not_of(separator, 0);
00154
00155 typename S::size_type pos = value.find_first_of(separator, last_pos);
00156
00157 while (pos !=S::npos || last_pos != S::npos)
00158 {
00159
00160 ret.push_back(value.substr(last_pos, pos - last_pos));
00161
00162 last_pos = value.find_first_not_of(separator, pos);
00163 pos = value.find_first_of(separator, last_pos);
00164 }
00165
00166 return ret;
00167 }
00168
00169
00170 std::vector<std::string>
00171 split_string (std::string const& value,
00172 std::string const& separator);
00173
00188 template <typename S>
00189 std::vector<S>
00190 split_string_strict (S const& value,
00191 S const& separator)
00192 {
00193 std::vector<S> ret;
00194
00195
00196 typename S::size_type last_pos = 0;
00197
00198 typename S::size_type pos = value.find_first_of(separator, last_pos);
00199
00200 while (pos !=S::npos || last_pos != S::npos)
00201 {
00202
00203 if (pos == std::string::npos)
00204
00205 ret.push_back(value.substr(last_pos, pos));
00206 else
00207
00208 ret.push_back(value.substr(last_pos, pos - last_pos));
00209
00210
00211 last_pos = pos + separator.length();
00212 pos = value.find_first_of(separator, last_pos);
00213 }
00214
00215 return ret;
00216 }
00217
00218
00219 std::vector<std::string>
00220 split_string_strict (std::string const& value,
00221 std::string const& separator);
00222
00232 std::wstring
00233 widen_string (std::string const& str,
00234 std::locale locale);
00235
00245 std::string
00246 narrow_string (std::wstring const& str,
00247 std::locale locale);
00248
00259 std::string
00260 find_program_in_path (std::string const& program,
00261 std::string const& path,
00262 std::string const& prefix);
00263
00271 char **
00272 string_list_to_strv (string_list const& str);
00273
00281 void
00282 strv_delete (char **strv);
00283
00294 int
00295 exec (std::string const& file,
00296 string_list const& command,
00297 environment const& env);
00298
00302 class stat
00303 {
00304 public:
00306 enum error_code
00307 {
00308 FILE,
00309 FD
00310 };
00311
00313 enum mode_bits
00314 {
00315 FILE_TYPE_MASK = S_IFMT,
00316 FILE_TYPE_SOCKET = S_IFSOCK,
00317 FILE_TYPE_LINK = S_IFLNK,
00318 FILE_TYPE_REGULAR = S_IFREG,
00319 FILE_TYPE_BLOCK = S_IFBLK,
00320 FILE_TYPE_DIRECTORY = S_IFDIR,
00321 FILE_TYPE_CHARACTER = S_IFCHR,
00322 FILE_TYPE_FIFO = S_IFIFO,
00323 PERM_SETUID = S_ISUID,
00324 PERM_SETGIT = S_ISGID,
00325 PERM_STICKY = S_ISVTX,
00326 PERM_USER_MASK = S_IRWXU,
00327 PERM_USER_READ = S_IRUSR,
00328 PERM_USER_WRITE = S_IWUSR,
00329 PERM_USER_EXECUTE = S_IXUSR,
00330 PERM_GROUP_MASK = S_IRWXG,
00331 PERM_GROUP_READ = S_IRGRP,
00332 PERM_GROUP_WRITE = S_IWGRP,
00333 PERM_GROUP_EXECUTE = S_IXGRP,
00334 PERM_OTHER_MASK = S_IRWXO,
00335 PERM_OTHER_READ = S_IROTH,
00336 PERM_OTHER_WRITE = S_IWOTH,
00337 PERM_OTHER_EXECUTE = S_IXOTH
00338 };
00339
00341 typedef custom_error<error_code> error;
00342
00347 stat (const char *file);
00348
00353 stat (std::string const& file);
00354
00361 stat (std::string const& file,
00362 int fd);
00363
00368 stat (int fd);
00369
00371 virtual ~stat ();
00372
00378 void check () const
00379 {
00380 if (this->errorno)
00381 {
00382 if (!this->file.empty())
00383 throw error(this->file, FILE, strerror(this->errorno));
00384 else
00385 {
00386 std::ostringstream str;
00387 str << "fd " << fd;
00388 throw error(str.str(), FD, strerror(this->errorno));
00389 }
00390 }
00391 }
00392
00398 struct ::stat const& get_detail()
00399 { return this->status; }
00400
00405 dev_t
00406 device () const
00407 { check(); return status.st_dev; }
00408
00413 ino_t
00414 inode () const
00415 { check(); return status.st_ino; }
00416
00421 mode_t
00422 mode () const
00423 { check(); return status.st_mode; }
00424
00429 nlink_t
00430 links () const
00431 { check(); return status.st_nlink; }
00432
00437 uid_t
00438 uid () const
00439 { check(); return status.st_uid; }
00440
00445 gid_t
00446 gid () const
00447 { check(); return status.st_gid; }
00448
00453 off_t
00454 size () const
00455 { check(); return status.st_size; }
00456
00461 blksize_t
00462 blocksize () const
00463 { check(); return status.st_blksize; }
00464
00469 blkcnt_t
00470 blocks () const
00471 { check(); return status.st_blocks; }
00472
00477 time_t
00478 atime () const
00479 { check(); return status.st_atime; }
00480
00485 time_t
00486 mtime () const
00487 { check(); return status.st_mtime; }
00488
00493 time_t
00494 ctime () const
00495 { check(); return status.st_ctime; }
00496
00501 inline bool
00502 is_regular () const;
00503
00508 inline bool
00509 is_directory () const;
00510
00515 inline bool
00516 is_character () const;
00517
00522 inline bool
00523 is_block () const;
00524
00529 inline bool
00530 is_fifo () const;
00531
00536 inline bool
00537 is_link () const;
00538
00543 inline bool
00544 is_socket () const;
00545
00551 inline bool check_mode (mode_bits mask) const;
00552
00553 private:
00554
00556 std::string file;
00558 int fd;
00560 int errorno;
00562 struct ::stat status;
00563 };
00564
00571 stat::mode_bits
00572 inline operator | (stat::mode_bits const& lhs,
00573 stat::mode_bits const& rhs)
00574 {
00575 return static_cast<stat::mode_bits>
00576 (static_cast<int>(lhs) | static_cast<int>(rhs));
00577 }
00578
00585 stat::mode_bits
00586 inline operator | (mode_t const& lhs,
00587 stat::mode_bits const& rhs)
00588 {
00589 return static_cast<stat::mode_bits>
00590 (lhs | static_cast<int>(rhs));
00591 }
00592
00599 stat::mode_bits
00600 inline operator | (stat::mode_bits const& lhs,
00601 mode_t const& rhs)
00602 {
00603 return static_cast<stat::mode_bits>
00604 (static_cast<int>(lhs) | rhs);
00605 }
00606
00613 stat::mode_bits
00614 inline operator & (stat::mode_bits const& lhs,
00615 stat::mode_bits const& rhs)
00616 {
00617 return static_cast<stat::mode_bits>
00618 (static_cast<int>(lhs) & static_cast<int>(rhs));
00619 }
00620
00627 stat::mode_bits
00628 inline operator & (mode_t const& lhs,
00629 stat::mode_bits const& rhs)
00630 {
00631 return static_cast<stat::mode_bits>
00632 (lhs & static_cast<int>(rhs));
00633 }
00634
00641 stat::mode_bits
00642 inline operator & (stat::mode_bits const& lhs,
00643 mode_t const& rhs)
00644 {
00645 return static_cast<stat::mode_bits>
00646 (static_cast<int>(lhs) & rhs);
00647 }
00648
00649 inline bool
00650 stat::is_regular () const
00651 { return check_mode(FILE_TYPE_REGULAR & FILE_TYPE_MASK); }
00652
00653 inline bool
00654 stat::is_directory () const
00655 { return check_mode(FILE_TYPE_DIRECTORY & FILE_TYPE_MASK); }
00656
00657 inline bool
00658 stat::is_character () const
00659 { return check_mode(FILE_TYPE_CHARACTER & FILE_TYPE_MASK); }
00660
00661 inline bool
00662 stat::is_block () const
00663 { return check_mode(FILE_TYPE_BLOCK & FILE_TYPE_MASK); }
00664
00665 inline bool
00666 stat::is_fifo () const
00667 { return check_mode(FILE_TYPE_FIFO & FILE_TYPE_MASK); }
00668
00669 inline bool
00670 stat::is_link () const
00671 { return check_mode(FILE_TYPE_LINK & FILE_TYPE_MASK); }
00672
00673 inline bool
00674 stat::is_socket () const
00675 { return check_mode(FILE_TYPE_SOCKET & FILE_TYPE_MASK); }
00676
00677 inline bool
00678 stat::check_mode (mode_bits mask) const
00679 {
00680 check();
00681 return (static_cast<stat::mode_bits>(status.st_mode) & mask) == mask;
00682 }
00683
00687 class passwd : public ::passwd
00688 {
00689 public:
00690 typedef std::vector<char> buffer_type;
00691
00692 passwd ();
00693
00694 passwd (uid_t uid);
00695
00696 passwd (const char *name);
00697
00698 passwd (std::string const& name);
00699
00700 void
00701 clear ();
00702
00703 void
00704 query_uid (uid_t uid);
00705
00706 void
00707 query_name (const char *name);
00708
00709 void
00710 query_name (std::string const& name);
00711
00712 bool
00713 operator ! () const;
00714
00715 private:
00716 buffer_type buffer;
00717 bool valid;
00718 };
00719
00723 class group : public ::group
00724 {
00725 public:
00726 typedef std::vector<char> buffer_type;
00727
00728 group ();
00729
00730 group (gid_t gid);
00731
00732 group (const char *name);
00733
00734 group (std::string const& name);
00735
00736 void
00737 clear ();
00738
00739 void
00740 query_gid (gid_t gid);
00741
00742 void
00743 query_name (const char *name);
00744
00745 void
00746 query_name (std::string const& name);
00747
00748 bool
00749 operator ! () const;
00750
00751 private:
00752 buffer_type buffer;
00753 bool valid;
00754 };
00755
00756 }
00757
00758 #endif
00759
00760
00761
00762
00763
00764