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 
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 /* SBUILD_UTIL_H */
00872 
00873 /*
00874  * Local Variables:
00875  * mode:C++
00876  * End:
00877  */