sbuild  1.7.1
util.h
1 /* Copyright © 2005-2013 Roger Leigh <rleigh@debian.org>
2  *
3  * schroot is free software: you can redistribute it and/or modify it
4  * under the terms of the GNU General Public License as published by
5  * the Free Software Foundation, either version 3 of the License, or
6  * (at your option) any later version.
7  *
8  * schroot is distributed in the hope that it will be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11  * General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program. If not, see
15  * <http://www.gnu.org/licenses/>.
16  *
17  *********************************************************************/
18 
19 #ifndef SBUILD_UTIL_H
20 #define SBUILD_UTIL_H
21 
22 #include <sbuild/environment.h>
23 #include <sbuild/error.h>
24 #include <sbuild/regex.h>
25 #include <sbuild/types.h>
26 
27 #include <string>
28 #include <cerrno>
29 #include <cstring>
30 
31 #include <sys/types.h>
32 #include <sys/stat.h>
33 #include <pwd.h>
34 #include <grp.h>
35 #include <unistd.h>
36 #include <typeinfo>
37 
38 #ifdef __GNUG__
39 #include <cxxabi.h>
40 #endif
41 
42 namespace sbuild
43 {
44 
52  std::string
53  basename (std::string name);
54 
62  std::string
63  dirname (std::string name);
64 
72  std::string
73  normalname (std::string name);
74 
82  bool
83  is_absname (const std::string& name);
84 
93  bool
94  is_valid_sessionname (const std::string& name);
95 
105  bool
106  is_valid_filename (const std::string& name,
107  bool lsb_mode = true);
108 
115  std::string
116  getcwd ();
117 
118 
124  std::string
126 
135  std::string
136  string_list_to_string (const string_list& list,
137  const std::string& separator);
138 
153  template <typename S>
154  std::vector<S>
155  split_string (S const& value,
156  S const& separator)
157  {
158  std::vector<S> ret;
159 
160  // Skip any separators at the start
161  typename S::size_type last_pos =
162  value.find_first_not_of(separator, 0);
163  // Find first separator.
164  typename S::size_type pos = value.find_first_of(separator, last_pos);
165 
166  while (pos !=S::npos || last_pos != S::npos)
167  {
168  // Add to list
169  ret.push_back(value.substr(last_pos, pos - last_pos));
170  // Find next
171  last_pos = value.find_first_not_of(separator, pos);
172  pos = value.find_first_of(separator, last_pos);
173  }
174 
175  return ret;
176  }
177 
189  std::vector<std::string>
190  split_string (const std::string& value,
191  const std::string& separator);
192 
207  template <typename S>
208  std::vector<S>
209  split_string_strict (S const& value,
210  S const& separator)
211  {
212  std::vector<S> ret;
213 
214  // Skip any separators at the start
215  typename S::size_type last_pos = 0;
216  // Find first separator.
217  typename S::size_type pos = value.find_first_of(separator, last_pos);
218 
219  while (pos !=S::npos || last_pos != S::npos)
220  {
221  // Add to list
222  if (pos == std::string::npos)
223  // Entire string from last_pos
224  ret.push_back(value.substr(last_pos, pos));
225  else
226  // Between pos and last_pos
227  ret.push_back(value.substr(last_pos, pos - last_pos));
228 
229  // Find next
230  last_pos = pos + separator.length();
231  pos = value.find_first_of(separator, last_pos);
232  }
233 
234  return ret;
235  }
236 
248  std::vector<std::string>
249  split_string_strict (const std::string& value,
250  const std::string& separator);
251 
261  std::wstring
262  widen_string (const std::string& str,
263  std::locale locale);
264 
274  std::string
275  narrow_string (const std::wstring& str,
276  std::locale locale);
277 
288  std::string
289  find_program_in_path (const std::string& program,
290  const std::string& path,
291  const std::string& prefix);
292 
301  char **
302  string_list_to_strv (const string_list& str);
303 
311  void
312  strv_delete (char **strv);
313 
324  int
325  exec (const std::string& file,
326  const string_list& command,
327  const environment& env);
328 
332  template <typename T>
333  std::string
335  {
336  std::string name;
337 
338  const std::type_info& info = typeid(T);
339 
340 #ifdef __GNUG__
341  int status;
342  char *demangled = abi::__cxa_demangle(info.name(), 0, 0, &status);
343  if (status)
344  name = info.name();
345  else
346  name = demangled;
347  free(demangled);
348 #else
349  name = info.name();
350 #endif
351 
352  return name;
353  }
354 
358  class stat
359  {
360  public:
363  {
365  FD
366  };
367 
370  {
371  FILE_TYPE_MASK = S_IFMT,
372  FILE_TYPE_SOCKET = S_IFSOCK,
373  FILE_TYPE_LINK = S_IFLNK,
374  FILE_TYPE_REGULAR = S_IFREG,
375  FILE_TYPE_BLOCK = S_IFBLK,
378  FILE_TYPE_FIFO = S_IFIFO,
379  PERM_SETUID = S_ISUID,
380  PERM_SETGIT = S_ISGID,
381  PERM_STICKY = S_ISVTX,
382  PERM_USER_MASK = S_IRWXU,
383  PERM_USER_READ = S_IRUSR,
384  PERM_USER_WRITE = S_IWUSR,
385  PERM_USER_EXECUTE = S_IXUSR,
386  PERM_GROUP_MASK = S_IRWXG,
387  PERM_GROUP_READ = S_IRGRP,
388  PERM_GROUP_WRITE = S_IWGRP,
389  PERM_GROUP_EXECUTE = S_IXGRP,
390  PERM_OTHER_MASK = S_IRWXO,
391  PERM_OTHER_READ = S_IROTH,
392  PERM_OTHER_WRITE = S_IWOTH,
394  };
395 
398 
404  stat (const char *file,
405  bool link = false);
406 
412  stat (const std::string& file,
413  bool link = false);
414 
421  stat (const std::string& file,
422  int fd);
423 
428  stat (int fd);
429 
431  virtual ~stat ();
432 
438  void check () const
439  {
440  if (this->errorno)
441  {
442  if (!this->file.empty())
443  throw error(this->file, FILE, std::strerror(this->errorno));
444  else
445  {
446  std::ostringstream str;
447  str << "fd " << fd;
448  throw error(str.str(), FD, std::strerror(this->errorno));
449  }
450  }
451  }
452 
458  const struct ::stat& get_detail()
459  { return this->status; }
460 
465  dev_t
466  device () const
467  { check(); return status.st_dev; }
468 
473  ino_t
474  inode () const
475  { check(); return status.st_ino; }
476 
481  mode_t
482  mode () const
483  { check(); return status.st_mode; }
484 
489  nlink_t
490  links () const
491  { check(); return status.st_nlink; }
492 
497  uid_t
498  uid () const
499  { check(); return status.st_uid; }
500 
505  gid_t
506  gid () const
507  { check(); return status.st_gid; }
508 
513  off_t
514  size () const
515  { check(); return status.st_size; }
516 
521  blksize_t
522  blocksize () const
523  { check(); return status.st_blksize; }
524 
529  blkcnt_t
530  blocks () const
531  { check(); return status.st_blocks; }
532 
537  time_t
538  atime () const
539  { check(); return status.st_atime; }
540 
545  time_t
546  mtime () const
547  { check(); return status.st_mtime; }
548 
553  time_t
554  ctime () const
555  { check(); return status.st_ctime; }
556 
561  inline bool
562  is_regular () const;
563 
568  inline bool
569  is_directory () const;
570 
575  inline bool
576  is_character () const;
577 
582  inline bool
583  is_block () const;
584 
589  inline bool
590  is_fifo () const;
591 
596  inline bool
597  is_link () const;
598 
603  inline bool
604  is_socket () const;
605 
611  inline bool check_mode (mode_bits mask) const;
612 
613  private:
614 
616  std::string file;
618  int fd;
620  int errorno;
622  struct ::stat status;
623  };
624 
632  inline operator | (const stat::mode_bits& lhs,
633  const stat::mode_bits& rhs)
634  {
635  return static_cast<stat::mode_bits>
636  (static_cast<int>(lhs) | static_cast<int>(rhs));
637  }
638 
646  inline operator | (const mode_t& lhs,
647  const stat::mode_bits& rhs)
648  {
649  return static_cast<stat::mode_bits>
650  (lhs | static_cast<int>(rhs));
651  }
652 
660  inline operator | (const stat::mode_bits& lhs,
661  const mode_t& rhs)
662  {
663  return static_cast<stat::mode_bits>
664  (static_cast<int>(lhs) | rhs);
665  }
666 
674  inline operator & (const stat::mode_bits& lhs,
675  const stat::mode_bits& rhs)
676  {
677  return static_cast<stat::mode_bits>
678  (static_cast<int>(lhs) & static_cast<int>(rhs));
679  }
680 
688  inline operator & (const mode_t& lhs,
689  const stat::mode_bits& rhs)
690  {
691  return static_cast<stat::mode_bits>
692  (lhs & static_cast<int>(rhs));
693  }
694 
702  inline operator & (const stat::mode_bits& lhs,
703  const mode_t& rhs)
704  {
705  return static_cast<stat::mode_bits>
706  (static_cast<int>(lhs) & rhs);
707  }
708 
709  inline bool
712 
713  inline bool
716 
717  inline bool
720 
721  inline bool
722  stat::is_block () const
724 
725  inline bool
726  stat::is_fifo () const
728 
729  inline bool
730  stat::is_link () const
732 
733  inline bool
736 
737  inline bool
739  {
740  check();
741  return (static_cast<stat::mode_bits>(status.st_mode) & mask) == mask;
742  }
743 
747  class passwd : public ::passwd
748  {
749  public:
751  typedef std::vector<char> buffer_type;
752 
754  passwd ();
755 
761  passwd (uid_t uid);
762 
768  passwd (const char *name);
769 
775  passwd (const std::string& name);
776 
781  void
782  clear ();
783 
789  void
790  query_uid (uid_t uid);
791 
797  void
798  query_name (const char *name);
799 
805  void
806  query_name (const std::string& name);
807 
811  bool
812  operator ! () const;
813 
814  private:
818  bool valid;
819  };
820 
824  class group : public ::group
825  {
826  public:
828  typedef std::vector<char> buffer_type;
829 
831  group ();
832 
838  group (gid_t gid);
839 
845  group (const char *name);
846 
852  group (const std::string& name);
853 
858  void
859  clear ();
860 
866  void
867  query_gid (gid_t gid);
868 
874  void
875  query_name (const char *name);
876 
882  void
883  query_name (const std::string& name);
884 
888  bool
889  operator ! () const;
890 
891  private:
895  bool valid;
896  };
897 
898 }
899 
900 #endif /* SBUILD_UTIL_H */
901 
902 /*
903  * Local Variables:
904  * mode:C++
905  * End:
906  */