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 #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
00158 typename S::size_type last_pos =
00159 value.find_first_not_of(separator, 0);
00160
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
00166 ret.push_back(value.substr(last_pos, pos - last_pos));
00167
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
00212 typename S::size_type last_pos = 0;
00213
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
00219 if (pos == std::string::npos)
00220
00221 ret.push_back(value.substr(last_pos, pos));
00222 else
00223
00224 ret.push_back(value.substr(last_pos, pos - last_pos));
00225
00226
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
00375 stat (const char *file,
00376 bool link = false);
00377
00383 stat (std::string const& file,
00384 bool link = false);
00385
00392 stat (std::string const& file,
00393 int fd);
00394
00399 stat (int fd);
00400
00402 virtual ~stat ();
00403
00409 void check () const
00410 {
00411 if (this->errorno)
00412 {
00413 if (!this->file.empty())
00414 throw error(this->file, FILE, std::strerror(this->errorno));
00415 else
00416 {
00417 std::ostringstream str;
00418 str << "fd " << fd;
00419 throw error(str.str(), FD, std::strerror(this->errorno));
00420 }
00421 }
00422 }
00423
00429 struct ::stat const& get_detail()
00430 { return this->status; }
00431
00436 dev_t
00437 device () const
00438 { check(); return status.st_dev; }
00439
00444 ino_t
00445 inode () const
00446 { check(); return status.st_ino; }
00447
00452 mode_t
00453 mode () const
00454 { check(); return status.st_mode; }
00455
00460 nlink_t
00461 links () const
00462 { check(); return status.st_nlink; }
00463
00468 uid_t
00469 uid () const
00470 { check(); return status.st_uid; }
00471
00476 gid_t
00477 gid () const
00478 { check(); return status.st_gid; }
00479
00484 off_t
00485 size () const
00486 { check(); return status.st_size; }
00487
00492 blksize_t
00493 blocksize () const
00494 { check(); return status.st_blksize; }
00495
00500 blkcnt_t
00501 blocks () const
00502 { check(); return status.st_blocks; }
00503
00508 time_t
00509 atime () const
00510 { check(); return status.st_atime; }
00511
00516 time_t
00517 mtime () const
00518 { check(); return status.st_mtime; }
00519
00524 time_t
00525 ctime () const
00526 { check(); return status.st_ctime; }
00527
00532 inline bool
00533 is_regular () const;
00534
00539 inline bool
00540 is_directory () const;
00541
00546 inline bool
00547 is_character () const;
00548
00553 inline bool
00554 is_block () const;
00555
00560 inline bool
00561 is_fifo () const;
00562
00567 inline bool
00568 is_link () const;
00569
00574 inline bool
00575 is_socket () const;
00576
00582 inline bool check_mode (mode_bits mask) const;
00583
00584 private:
00585
00587 std::string file;
00589 int fd;
00591 int errorno;
00593 struct ::stat status;
00594 };
00595
00602 stat::mode_bits
00603 inline operator | (stat::mode_bits const& lhs,
00604 stat::mode_bits const& rhs)
00605 {
00606 return static_cast<stat::mode_bits>
00607 (static_cast<int>(lhs) | static_cast<int>(rhs));
00608 }
00609
00616 stat::mode_bits
00617 inline operator | (mode_t const& lhs,
00618 stat::mode_bits const& rhs)
00619 {
00620 return static_cast<stat::mode_bits>
00621 (lhs | static_cast<int>(rhs));
00622 }
00623
00630 stat::mode_bits
00631 inline operator | (stat::mode_bits const& lhs,
00632 mode_t const& rhs)
00633 {
00634 return static_cast<stat::mode_bits>
00635 (static_cast<int>(lhs) | rhs);
00636 }
00637
00644 stat::mode_bits
00645 inline operator & (stat::mode_bits const& lhs,
00646 stat::mode_bits const& rhs)
00647 {
00648 return static_cast<stat::mode_bits>
00649 (static_cast<int>(lhs) & static_cast<int>(rhs));
00650 }
00651
00658 stat::mode_bits
00659 inline operator & (mode_t const& lhs,
00660 stat::mode_bits const& rhs)
00661 {
00662 return static_cast<stat::mode_bits>
00663 (lhs & static_cast<int>(rhs));
00664 }
00665
00672 stat::mode_bits
00673 inline operator & (stat::mode_bits const& lhs,
00674 mode_t const& rhs)
00675 {
00676 return static_cast<stat::mode_bits>
00677 (static_cast<int>(lhs) & rhs);
00678 }
00679
00680 inline bool
00681 stat::is_regular () const
00682 { return check_mode(FILE_TYPE_REGULAR & FILE_TYPE_MASK); }
00683
00684 inline bool
00685 stat::is_directory () const
00686 { return check_mode(FILE_TYPE_DIRECTORY & FILE_TYPE_MASK); }
00687
00688 inline bool
00689 stat::is_character () const
00690 { return check_mode(FILE_TYPE_CHARACTER & FILE_TYPE_MASK); }
00691
00692 inline bool
00693 stat::is_block () const
00694 { return check_mode(FILE_TYPE_BLOCK & FILE_TYPE_MASK); }
00695
00696 inline bool
00697 stat::is_fifo () const
00698 { return check_mode(FILE_TYPE_FIFO & FILE_TYPE_MASK); }
00699
00700 inline bool
00701 stat::is_link () const
00702 { return check_mode(FILE_TYPE_LINK & FILE_TYPE_MASK); }
00703
00704 inline bool
00705 stat::is_socket () const
00706 { return check_mode(FILE_TYPE_SOCKET & FILE_TYPE_MASK); }
00707
00708 inline bool
00709 stat::check_mode (mode_bits mask) const
00710 {
00711 check();
00712 return (static_cast<stat::mode_bits>(status.st_mode) & mask) == mask;
00713 }
00714
00718 class passwd : public ::passwd
00719 {
00720 public:
00722 typedef std::vector<char> buffer_type;
00723
00725 passwd ();
00726
00732 passwd (uid_t uid);
00733
00739 passwd (const char *name);
00740
00746 passwd (std::string const& name);
00747
00752 void
00753 clear ();
00754
00760 void
00761 query_uid (uid_t uid);
00762
00768 void
00769 query_name (const char *name);
00770
00776 void
00777 query_name (std::string const& name);
00778
00782 bool
00783 operator ! () const;
00784
00785 private:
00787 buffer_type buffer;
00789 bool valid;
00790 };
00791
00795 class group : public ::group
00796 {
00797 public:
00799 typedef std::vector<char> buffer_type;
00800
00802 group ();
00803
00809 group (gid_t gid);
00810
00816 group (const char *name);
00817
00823 group (std::string const& name);
00824
00829 void
00830 clear ();
00831
00837 void
00838 query_gid (gid_t gid);
00839
00845 void
00846 query_name (const char *name);
00847
00853 void
00854 query_name (std::string const& name);
00855
00859 bool
00860 operator ! () const;
00861
00862 private:
00864 buffer_type buffer;
00866 bool valid;
00867 };
00868
00869 }
00870
00871 #endif
00872
00873
00874
00875
00876
00877