1 -- SQL-UNIX-API (prototype)
2 -- Copyright © 2014 František Kučera (frantovo.cz)
4 -- This program is free software: you can redistribute it and/or modify
5 -- it under the terms of the GNU General Public License as published by
6 -- the Free Software Foundation, either version 3 of the License, or
7 -- (at your option) any later version.
9 -- This program is distributed in the hope that it will be useful,
10 -- but WITHOUT ANY WARRANTY; without even the implied warranty of
11 -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 -- GNU General Public License for more details.
14 -- You should have received a copy of the GNU General Public License
15 -- along with this program. If not, see <http://www.gnu.org/licenses/>.
19 -- CREATE SCHEMA unix_sql_api;
21 SET search_path TO unix_sql_api;
24 -- fstab: --------------------------------------------------------------------
26 DROP VIEW IF EXISTS fstab;
27 DROP FUNCTION IF EXISTS fstab();
28 DROP TYPE IF EXISTS unix_sql_api_fstab;
30 CREATE TYPE unix_sql_api_fstab AS (
42 CREATE OR REPLACE FUNCTION fstab()
43 RETURNS SETOF unix_sql_api_fstab AS $$
47 open(FSTAB, "<", "/etc/fstab") or die $!;
50 if (/^([^\s#]+)\s+([^\s]+)\s+([^\s]+)\s+([^\s]+)\s+(\d+)\s+(\d+)\s*$/) {
53 my $device_spec_value;
55 if ($1 =~ /([^=]+)=(.*)/) {
56 ($device_spec_type, $device_spec_value) = ($1, $2);
62 device_type => $device_spec_type,
63 device_value => $device_spec_value,
66 types => [split(",", $3)],
67 options => [split(",", $4)],
77 CREATE OR REPLACE VIEW fstab AS
82 -- user groups: --------------------------------------------------------------
84 DROP VIEW IF EXISTS users_groups;
86 DROP VIEW IF EXISTS groups;
87 DROP FUNCTION IF EXISTS groups();
88 DROP TYPE IF EXISTS unix_sql_api_groups;
90 CREATE TYPE unix_sql_api_groups AS (
96 CREATE OR REPLACE FUNCTION groups()
97 RETURNS SETOF unix_sql_api_groups STABLE AS $$
104 while (my $group = getgrent()) {
107 name => $group->name,
108 members => [@{$group->members}]
116 CREATE OR REPLACE VIEW groups AS
117 SELECT * FROM groups()
119 COMMENT ON COLUMN groups.members IS 'does not contain users who have this group as primary one – see view: users_groups';
122 -- users: --------------------------------------------------------------------
124 DROP VIEW IF EXISTS users;
125 DROP FUNCTION IF EXISTS users();
126 DROP TYPE IF EXISTS unix_sql_api_users;
128 CREATE TYPE unix_sql_api_users AS (
139 CREATE OR REPLACE FUNCTION users()
140 RETURNS SETOF unix_sql_api_users STABLE AS $$
144 use encoding "UTF-8";
148 while (my $user = getpwent()) {
153 # comment => $user->comment,
154 gecos => [split(",", $user->gecos)],
156 shell => $user->shell,
157 # expire => $user->expire
165 CREATE OR REPLACE VIEW users AS
166 SELECT * FROM users()
170 -- users_groups: -------------------------------------------------------------
172 CREATE OR REPLACE VIEW users_groups AS
180 JOIN groups AS g ON (u.gid = g.id)
189 unnest(members) AS user,
192 JOIN users AS u ON (u.name = g.user)
194 COMMENT ON COLUMN users_groups.initial IS 'whether this group is the „initial login group“ of given user (the primary group)';
197 -- processes: ----------------------------------------------------------------
199 DROP VIEW IF EXISTS processes;
200 DROP FUNCTION IF EXISTS processes();
201 DROP TYPE IF EXISTS unix_sql_api_processes;
203 CREATE TYPE unix_sql_api_processes AS (
211 CREATE OR REPLACE FUNCTION processes()
212 RETURNS SETOF unix_sql_api_processes STABLE AS $$
216 # There is a library…
217 # aptitude install libproc-processtable-perl
218 # use Proc::ProcessTable::Process;
219 # But there can be found:
220 # /* replace all '\0' with spaces (except for the last one */
221 # for (cur = cmndline_text; cur < cmndline_text + cmndline_off - 1; cur++) {
225 # which wipes boundaries between arguments (that can also contain spaces)
226 # So wait until the patch https://rt.cpan.org/Public/Bug/Display.html?id=52442 will be integrated
230 opendir(DIR, $dir) or die $!;
231 while (readdir(DIR)) {
234 my @process_dir_stat = stat("$dir/$pid") or next;
235 my $uid = $process_dir_stat[4];
237 open(CMDLINE, "<$dir/$pid/cmdline");
239 my @cmdline = split("\x00", <CMDLINE>);
244 command => shift(@cmdline),
245 arguments => [@cmdline],
246 working_dir => readlink("$dir/$pid/cwd")
254 CREATE OR REPLACE VIEW processes AS
255 SELECT * FROM processes()