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-passwd.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 // Password file functions.  (Why not?)
45 
46 static octave_value
mk_pw_map(const octave::sys::password & pw)47 mk_pw_map (const octave::sys::password& pw)
48 {
49   octave_value retval;
50 
51   if (pw)
52     {
53       octave_scalar_map m;
54 
55       m.assign ("name", pw.name ());
56       m.assign ("passwd", pw.passwd ());
57       m.assign ("uid", static_cast<double> (pw.uid ()));
58       m.assign ("gid", static_cast<double> (pw.gid ()));
59       m.assign ("gecos", pw.gecos ());
60       m.assign ("dir", pw.dir ());
61       m.assign ("shell", pw.shell ());
62 
63       return octave_value (m);
64     }
65   else
66     return octave_value (0);
67 }
68 
69 DEFUN (getpwent, args, ,
70        doc: /* -*- texinfo -*-
71 @deftypefn {} {@var{pw_struct} =} getpwent ()
72 Return a structure containing an entry from the password database,
73 opening it if necessary.
74 
75 Once the end of the data has been reached, @code{getpwent} returns 0.
76 @seealso{setpwent, endpwent}
77 @end deftypefn */)
78 {
79   if (args.length () != 0)
80     print_usage ();
81 
82   std::string msg;
83 
84   // octave::sys::password::getpwent may set msg.
85   octave_value val = mk_pw_map (octave::sys::password::getpwent (msg));
86 
87   return ovl (val, msg);
88 }
89 
90 DEFUN (getpwuid, args, ,
91        doc: /* -*- texinfo -*-
92 @deftypefn {} {@var{pw_struct} =} getpwuid (@var{uid}).
93 Return a structure containing the first entry from the password database
94 with the user ID @var{uid}.
95 
96 If the user ID does not exist in the database, @code{getpwuid} returns 0.
97 @seealso{getpwnam}
98 @end deftypefn */)
99 {
100   if (args.length () != 1)
101     print_usage ();
102 
103   double dval = args(0).double_value ();
104 
105   if (octave::math::x_nint (dval) != dval)
106     error ("getpwuid: UID must be an integer");
107 
108   uid_t uid = static_cast<uid_t> (dval);
109 
110   std::string msg;
111 
112   // octave::sys::password::getpwuid may set msg.
113   octave_value val = mk_pw_map (octave::sys::password::getpwuid (uid, msg));
114 
115   return ovl (val, msg);
116 }
117 
118 DEFUN (getpwnam, args, ,
119        doc: /* -*- texinfo -*-
120 @deftypefn {} {@var{pw_struct} =} getpwnam (@var{name})
121 Return a structure containing the first entry from the password database
122 with the user name @var{name}.
123 
124 If the user name does not exist in the database, @code{getpwname} returns 0.
125 @seealso{getpwuid}
126 @end deftypefn */)
127 {
128   if (args.length () != 1)
129     print_usage ();
130 
131   std::string s = args(0).string_value ();
132 
133   std::string msg;
134 
135   // octave::sys::password::getpwnam may set msg.
136   octave_value val = mk_pw_map (octave::sys::password::getpwnam (s, msg));
137 
138   return ovl (val, msg);
139 }
140 
141 DEFUN (setpwent, args, ,
142        doc: /* -*- texinfo -*-
143 @deftypefn {} {} setpwent ()
144 Return the internal pointer to the beginning of the password database.
145 @seealso{getpwent, endpwent}
146 @end deftypefn */)
147 {
148   if (args.length () != 0)
149     print_usage ();
150 
151   std::string msg;
152 
153   // octave::sys::password::setpwent may set msg.
154   int status = octave::sys::password::setpwent (msg);
155 
156   return ovl (static_cast<double> (status), msg);
157 }
158 
159 DEFUN (endpwent, args, ,
160        doc: /* -*- texinfo -*-
161 @deftypefn {} {} endpwent ()
162 Close the password database.
163 @seealso{getpwent, setpwent}
164 @end deftypefn */)
165 {
166   if (args.length () != 0)
167     print_usage ();
168 
169   std::string msg;
170 
171   // octave::sys::password::endpwent may set msg.
172   int status = octave::sys::password::endpwent (msg);
173 
174   return ovl (static_cast<double> (status), msg);
175 }
176