librostlab 1.0.20
Loading...
Searching...
No Matches
cxxgrp.h
Go to the documentation of this file.
1/*
2 Copyright (C) 2011 Laszlo Kajan, Technical University of Munich, Germany
3
4 This file is part of librostlab.
5
6 librostlab is free software: you can redistribute it and/or modify
7 it under the terms of the GNU Lesser General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU Lesser General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
18*/
19#ifndef ROSTLAB_CXXGRP
20#define ROSTLAB_CXXGRP 1
21
22#include <boost/format.hpp>
23#include <errno.h>
24#include <grp.h>
25#include <string>
26#include <string.h>
27#include <sys/types.h>
28#include <vector>
29
31
32namespace bo = boost;
33
34namespace rostlab {
35
37{
38 std::string gr_name; /* group name */
39 std::string gr_passwd; /* group password */
40 gid_t gr_gid; /* group ID */
41 std::vector<std::string> gr_mem; /* group members */
42
43 inline cxx_group(){};
44 inline cxx_group( const std::string& __gr_name );
45 inline cxx_group( const std::string& __gr_name, const std::string& __gr_passwd, gid_t __gr_gid, const std::vector<std::string>& __gr_mem ) :
46 gr_name(__gr_name), gr_passwd(__gr_passwd), gr_gid(__gr_gid), gr_mem(__gr_mem) {};
47 inline cxx_group( const std::string& __gr_name, const std::string& __gr_passwd, gid_t __gr_gid, char** __gr_mem ) :
48 gr_name(__gr_name), gr_passwd(__gr_passwd), gr_gid(__gr_gid) { while(*__gr_mem) gr_mem.push_back( *__gr_mem++ ); };
49};
50
51class gid_not_found_error : public runtime_error { public: gid_not_found_error( const std::string& what ) : runtime_error(what) {} };
52class gname_not_found_error : public runtime_error { public: gname_not_found_error( const std::string& what ) : runtime_error(what) {} };
53
54// namespace functions
55inline std::string getgrgid_r( gid_t __gid );
56inline std::string getgrgid_r( gid_t __gid, cxx_group& __group );
57inline gid_t getgrnam_r( const std::string& __gname );
58inline gid_t getgrnam_r( const std::string& __gname, struct cxx_group& __group );
59
60
61inline cxx_group::cxx_group( const std::string& __gr_name )
62{
63 rostlab::getgrnam_r( __gr_name, *this );
64};
65
66inline std::string getgrgid_r( gid_t __gid, cxx_group& __group )
67{
68 struct group gbuf;
69 struct group *gbufp;
70
71 size_t buflen = sysconf( _SC_GETGR_R_SIZE_MAX );
72 char* buf = static_cast<char *>( malloc(buflen) ); if(!buf) throw runtime_error( bo::str( bo::format("failed to allocate %d bytes") % buflen ) );
73
74 try{
75 int _errno;
76 do {
77 _errno = ::getgrgid_r( __gid, &gbuf, buf, buflen, &gbufp );
78 if( _errno == ERANGE ) // too small buffer
79 {
80 buflen *= 2;
81 buf = static_cast<char *>( realloc( buf, buflen ) ); if(!buf) throw runtime_error( bo::str( bo::format("failed to allocate %d bytes") % buflen ) );
82 }
83 else if( _errno ) throw runtime_error( bo::str( bo::format("failed to getgrgid_r '%d': %s") % __gid % strerror( errno ) ) );
84 } while( _errno );
85
86 if( gbufp == NULL ) throw gid_not_found_error( bo::str( bo::format("gid '%d' not found") % __gid ) );
87
88 __group = cxx_group( gbuf.gr_name, gbuf.gr_passwd, gbuf.gr_gid, gbuf.gr_mem );
89 }
90 catch(...)
91 {
92 free(buf);
93 throw;
94 }
95 free(buf); buf = NULL;
96
97 return __group.gr_name;
98}
99
100inline std::string getgrgid_r( gid_t __gid )
101{
102 struct cxx_group grp;
103 return getgrgid_r( __gid, grp );
104}
105
106
107inline gid_t getgrnam_r( const std::string& __gname, struct cxx_group& __group )
108{
109 struct group gbuf;
110 struct group *gbufp;
111
112 size_t buflen = sysconf( _SC_GETGR_R_SIZE_MAX );
113 char* buf = static_cast<char *>( malloc(buflen) ); if(!buf) throw runtime_error( bo::str( bo::format("failed to allocate %d bytes") % buflen ) );
114
115 try{
116 int _errno;
117 do {
118 _errno = ::getgrnam_r( __gname.c_str(), &gbuf, buf, buflen, &gbufp );
119 if( _errno == ERANGE ) // too small buffer
120 {
121 buflen *= 2;
122 buf = static_cast<char *>( realloc( buf, buflen ) ); if(!buf) throw runtime_error( bo::str( bo::format("failed to allocate %d bytes") % buflen ) );
123 }
124 else if( _errno ) throw runtime_error( bo::str( bo::format("failed to getgrnam_r '%s': %s") % __gname % strerror( errno ) ) );
125 } while( _errno );
126
127 if( gbufp == NULL ) throw gname_not_found_error( bo::str( bo::format("gname '%s' not found") % __gname ) );
128
129 __group = cxx_group( gbuf.gr_name, gbuf.gr_passwd, gbuf.gr_gid, gbuf.gr_mem );
130 }
131 catch(...)
132 {
133 free(buf);
134 throw;
135 }
136 free(buf); buf = NULL;
137
138 return gbuf.gr_gid;
139}
140
141
142inline gid_t getgrnam_r( const std::string& __gname )
143{
144 struct cxx_group grp;
145 return getgrnam_r( __gname, grp );
146}
147
148}; // namespace rostlab
149
150#endif // ROSTLAB_CXXGRP
151// vim:et:ai:ts=2:
gid_not_found_error(const std::string &what)
Definition cxxgrp.h:51
gname_not_found_error(const std::string &what)
Definition cxxgrp.h:52
std::string getgrgid_r(gid_t __gid)
Definition cxxgrp.h:100
gid_t getgrnam_r(const std::string &__gname)
Definition cxxgrp.h:142
std::vector< std::string > gr_mem
Definition cxxgrp.h:41
std::string gr_name
Definition cxxgrp.h:38
std::string gr_passwd
Definition cxxgrp.h:39
cxx_group(const std::string &__gr_name, const std::string &__gr_passwd, gid_t __gr_gid, char **__gr_mem)
Definition cxxgrp.h:47
cxx_group(const std::string &__gr_name, const std::string &__gr_passwd, gid_t __gr_gid, const std::vector< std::string > &__gr_mem)
Definition cxxgrp.h:45