1 ////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (C) 1996-2021 The Octave Project Developers
4 //
5 // See the file COPYRIGHT.md in the top-level directory of this
6 // distribution or <https://octave.org/copyright/>.
7 //
8 // This file is part of Octave.
9 //
10 // Octave is free software: you can redistribute it and/or modify it
11 // under the terms of the GNU General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // Octave is distributed in the hope that it will be useful, but
16 // WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 // GNU General Public License for more details.
19 //
20 // You should have received a copy of the GNU General Public License
21 // along with Octave; see the file COPYING.  If not, see
22 // <https://www.gnu.org/licenses/>.
23 //
24 ////////////////////////////////////////////////////////////////////////
25 
26 #if defined (HAVE_CONFIG_H)
27 #  include "config.h"
28 #endif
29 
30 #include <string>
31 
32 #include <sys/types.h>
33 
34 #include "oct-group.h"
35 
36 #include "defun.h"
37 #include "error.h"
38 #include "errwarn.h"
39 #include "oct-map.h"
40 #include "ov.h"
41 #include "ovl.h"
42 #include "utils.h"
43 
44 // Group file functions.  (Why not?)
45 
46 static octave_value
mk_gr_map(const octave::sys::group & gr)47 mk_gr_map (const octave::sys::group& gr)
48 {
49   if (gr)
50     {
51       octave_scalar_map m;
52 
53       m.assign ("name", gr.name ());
54       m.assign ("passwd", gr.passwd ());
55       m.assign ("gid", static_cast<double> (gr.gid ()));
56       m.assign ("mem", octave_value (gr.mem ()));
57 
58       return octave_value (m);
59     }
60   else
61     return octave_value (0);
62 }
63 
64 DEFUN (getgrent, args, ,
65        doc: /* -*- texinfo -*-
66 @deftypefn {} {@var{grp_struct} =} getgrent ()
67 Return an entry from the group database, opening it if necessary.
68 
69 Once the end of data has been reached, @code{getgrent} returns 0.
70 @seealso{setgrent, endgrent}
71 @end deftypefn */)
72 {
73   if (args.length () != 0)
74     print_usage ();
75 
76   std::string msg;
77 
78   // octave::sys::group::getgrent may set msg.
79   octave_value val = mk_gr_map (octave::sys::group::getgrent (msg));
80 
81   return ovl (val, msg);
82 }
83 
84 DEFUN (getgrgid, args, ,
85        doc: /* -*- texinfo -*-
86 @deftypefn {} {@var{grp_struct} =} getgrgid (@var{gid}).
87 Return the first entry from the group database with the group ID
88 @var{gid}.
89 
90 If the group ID does not exist in the database, @code{getgrgid} returns 0.
91 @seealso{getgrnam}
92 @end deftypefn */)
93 {
94   if (args.length () != 1)
95     print_usage ();
96 
97   double dval = args(0).double_value ();
98 
99   if (octave::math::x_nint (dval) != dval)
100     error ("getgrgid: GID must be an integer");
101 
102   gid_t gid = static_cast<gid_t> (dval);
103 
104   std::string msg;
105 
106   // octave::sys::group::getgrgid may set msg.
107   octave_value val = mk_gr_map (octave::sys::group::getgrgid (gid, msg));
108 
109   return ovl (val, msg);
110 }
111 
112 DEFUN (getgrnam, args, ,
113        doc: /* -*- texinfo -*-
114 @deftypefn {} {@var{grp_struct} =} getgrnam (@var{name})
115 Return the first entry from the group database with the group name
116 @var{name}.
117 
118 If the group name does not exist in the database, @code{getgrnam} returns 0.
119 @seealso{getgrgid}
120 @end deftypefn */)
121 {
122   if (args.length () != 1)
123     print_usage ();
124 
125   std::string s = args(0).string_value ();
126 
127   std::string msg;
128 
129   // octave::sys::group::getgrnam may set msg.
130   octave_value val = mk_gr_map (octave::sys::group::getgrnam (s.c_str (), msg));
131 
132   return ovl (val, msg);
133 }
134 
135 DEFUN (setgrent, args, ,
136        doc: /* -*- texinfo -*-
137 @deftypefn {} {} setgrent ()
138 Return the internal pointer to the beginning of the group database.
139 @seealso{getgrent, endgrent}
140 @end deftypefn */)
141 {
142   if (args.length () != 0)
143     print_usage ();
144 
145   std::string msg;
146 
147   // octave::sys::group::setgrent may set msg.
148   int status = octave::sys::group::setgrent (msg);
149 
150   return ovl (static_cast<double> (status), msg);
151 }
152 
153 DEFUN (endgrent, args, ,
154        doc: /* -*- texinfo -*-
155 @deftypefn {} {} endgrent ()
156 Close the group database.
157 @seealso{getgrent, setgrent}
158 @end deftypefn */)
159 {
160   if (args.length () != 0)
161     print_usage ();
162 
163   std::string msg;
164 
165   // octave::sys::group::endgrent may set msg.
166   int status = octave::sys::group::endgrent (msg);
167 
168   return ovl (static_cast<double> (status), msg);
169 }
170