sbuild  1.5.3
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 #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     // Skip any separators at the start
00158     typename S::size_type last_pos =
00159       value.find_first_not_of(separator, 0);
00160     // Find first separator.
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         // Add to list
00166         ret.push_back(value.substr(last_pos, pos - last_pos));
00167         // Find next
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     // Skip any separators at the start
00212     typename S::size_type last_pos = 0;
00213     // Find first separator.
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         // Add to list
00219         if (pos == std::string::npos)
00220           // Entire string from last_pos
00221           ret.push_back(value.substr(last_pos, pos));
00222         else
00223           // Between pos and last_pos
00224           ret.push_back(value.substr(last_pos, pos - last_pos));
00225 
00226         // Find next
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 
00374     stat (const char *file);
00375 
00380     stat (std::string const& file);
00381 
00388     stat (std::string const& file,
00389           int                fd);
00390 
00395     stat (int fd);
00396 
00398     virtual ~stat ();
00399 
00405     void check () const
00406     {
00407       if (this->errorno)
00408         {
00409           if (!this->file.empty())
00410             throw error(this->file, FILE, std::strerror(this->errorno));
00411           else
00412             {
00413               std::ostringstream str;
00414               str << "fd " << fd;
00415               throw error(str.str(), FD, std::strerror(this->errorno));
00416             }
00417         }
00418     }
00419 
00425     struct ::stat const& get_detail()
00426     { return this->status; }
00427 
00432     dev_t
00433     device () const
00434     { check(); return status.st_dev; }
00435 
00440     ino_t
00441     inode () const
00442     { check(); return status.st_ino; }
00443 
00448     mode_t
00449     mode () const
00450     { check(); return status.st_mode; }
00451 
00456     nlink_t
00457     links () const
00458     { check(); return status.st_nlink; }
00459 
00464     uid_t
00465     uid () const
00466     { check(); return status.st_uid; }
00467 
00472     gid_t
00473     gid () const
00474     { check(); return status.st_gid; }
00475 
00480     off_t
00481     size () const
00482     { check(); return status.st_size; }
00483 
00488     blksize_t
00489     blocksize () const
00490     { check(); return status.st_blksize; }
00491 
00496     blkcnt_t
00497     blocks () const
00498     { check(); return status.st_blocks; }
00499 
00504     time_t
00505     atime () const
00506     { check(); return status.st_atime; }
00507 
00512     time_t
00513     mtime () const
00514     { check(); return status.st_mtime; }
00515 
00520     time_t
00521     ctime () const
00522     { check(); return status.st_ctime; }
00523 
00528     inline bool
00529     is_regular () const;
00530 
00535     inline bool
00536     is_directory () const;
00537 
00542     inline bool
00543     is_character () const;
00544 
00549     inline bool
00550     is_block () const;
00551 
00556     inline bool
00557     is_fifo () const;
00558 
00563     inline bool
00564     is_link () const;
00565 
00570     inline bool
00571     is_socket () const;
00572 
00578     inline bool check_mode (mode_bits mask) const;
00579 
00580   private:
00581 
00583     std::string file;
00585     int fd;
00587     int errorno;
00589     struct ::stat status;
00590   };
00591 
00598   stat::mode_bits
00599   inline operator | (stat::mode_bits const& lhs,
00600                      stat::mode_bits const& rhs)
00601   {
00602     return static_cast<stat::mode_bits>
00603       (static_cast<int>(lhs) | static_cast<int>(rhs));
00604   }
00605 
00612   stat::mode_bits
00613   inline operator | (mode_t const&          lhs,
00614                      stat::mode_bits const& rhs)
00615   {
00616     return static_cast<stat::mode_bits>
00617       (lhs | static_cast<int>(rhs));
00618   }
00619 
00626   stat::mode_bits
00627   inline operator | (stat::mode_bits const& lhs,
00628                      mode_t const&          rhs)
00629   {
00630     return static_cast<stat::mode_bits>
00631       (static_cast<int>(lhs) | rhs);
00632   }
00633 
00640   stat::mode_bits
00641   inline operator & (stat::mode_bits const& lhs,
00642                      stat::mode_bits const& rhs)
00643   {
00644     return static_cast<stat::mode_bits>
00645       (static_cast<int>(lhs) & static_cast<int>(rhs));
00646   }
00647 
00654   stat::mode_bits
00655   inline operator & (mode_t const&          lhs,
00656                      stat::mode_bits const& rhs)
00657   {
00658     return static_cast<stat::mode_bits>
00659       (lhs & static_cast<int>(rhs));
00660   }
00661 
00668   stat::mode_bits
00669   inline operator & (stat::mode_bits const& lhs,
00670                      mode_t const&          rhs)
00671   {
00672     return static_cast<stat::mode_bits>
00673       (static_cast<int>(lhs) & rhs);
00674   }
00675 
00676   inline bool
00677   stat::is_regular () const
00678   { return check_mode(FILE_TYPE_REGULAR & FILE_TYPE_MASK); }
00679 
00680   inline bool
00681   stat::is_directory () const
00682   { return check_mode(FILE_TYPE_DIRECTORY & FILE_TYPE_MASK); }
00683 
00684   inline bool
00685   stat::is_character () const
00686   { return check_mode(FILE_TYPE_CHARACTER & FILE_TYPE_MASK); }
00687 
00688   inline bool
00689   stat::is_block () const
00690   { return check_mode(FILE_TYPE_BLOCK & FILE_TYPE_MASK); }
00691 
00692   inline bool
00693   stat::is_fifo () const
00694   { return check_mode(FILE_TYPE_FIFO & FILE_TYPE_MASK); }
00695 
00696   inline bool
00697   stat::is_link () const
00698   { return check_mode(FILE_TYPE_LINK & FILE_TYPE_MASK); }
00699 
00700   inline bool
00701   stat::is_socket () const
00702   { return check_mode(FILE_TYPE_SOCKET & FILE_TYPE_MASK); }
00703 
00704   inline bool
00705   stat::check_mode (mode_bits mask) const
00706   {
00707     check();
00708     return (static_cast<stat::mode_bits>(status.st_mode) & mask) == mask;
00709   }
00710 
00714   class passwd : public ::passwd
00715   {
00716   public:
00718     typedef std::vector<char> buffer_type;
00719 
00721     passwd ();
00722 
00728     passwd (uid_t uid);
00729 
00735     passwd (const char *name);
00736 
00742     passwd (std::string const& name);
00743 
00748     void
00749     clear ();
00750 
00756     void
00757     query_uid (uid_t uid);
00758 
00764     void
00765     query_name (const char *name);
00766 
00772     void
00773     query_name (std::string const& name);
00774 
00778     bool
00779     operator ! () const;
00780 
00781   private:
00783     buffer_type buffer;
00785     bool        valid;
00786   };
00787 
00791   class group : public ::group
00792   {
00793   public:
00795     typedef std::vector<char> buffer_type;
00796 
00798     group ();
00799 
00805     group (gid_t gid);
00806 
00812     group (const char *name);
00813 
00819     group (std::string const& name);
00820 
00825     void
00826     clear ();
00827 
00833     void
00834     query_gid (gid_t gid);
00835 
00841     void
00842     query_name (const char *name);
00843 
00849     void
00850     query_name (std::string const& name);
00851 
00855     bool
00856     operator ! () const;
00857 
00858   private:
00860     buffer_type buffer;
00862     bool        valid;
00863   };
00864 
00865 }
00866 
00867 #endif /* SBUILD_UTIL_H */
00868 
00869 /*
00870  * Local Variables:
00871  * mode:C++
00872  * End:
00873  */