sbuild 1.4.23
sbuild-util.h
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 
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     // Skip any separators at the start
00157     typename S::size_type last_pos =
00158       value.find_first_not_of(separator, 0);
00159     // Find first separator.
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         // Add to list
00165         ret.push_back(value.substr(last_pos, pos - last_pos));
00166         // Find next
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     // Skip any separators at the start
00211     typename S::size_type last_pos = 0;
00212     // Find first separator.
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         // Add to list
00218         if (pos == std::string::npos)
00219           // Entire string from last_pos
00220           ret.push_back(value.substr(last_pos, pos));
00221         else
00222           // Between pos and last_pos
00223           ret.push_back(value.substr(last_pos, pos - last_pos));
00224 
00225         // Find next
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 /* SBUILD_UTIL_H */
00867 
00868 /*
00869  * Local Variables:
00870  * mode:C++
00871  * End:
00872  */