prototyp/prototyp.sql
author František Kučera <franta-hg@frantovo.cz>
Tue, 02 Sep 2014 10:25:23 +0200
changeset 13 552252ca87db
parent 12 c6688467d03c
permissions -rw-r--r--
prototyp: align code
franta-hg@6
     1
-- SQL-UNIX-API (prototype)
franta-hg@6
     2
-- Copyright © 2014 František Kučera (frantovo.cz)
franta-hg@6
     3
-- 
franta-hg@6
     4
-- This program is free software: you can redistribute it and/or modify
franta-hg@6
     5
-- it under the terms of the GNU General Public License as published by
franta-hg@6
     6
-- the Free Software Foundation, either version 3 of the License, or
franta-hg@6
     7
-- (at your option) any later version.
franta-hg@6
     8
-- 
franta-hg@6
     9
-- This program is distributed in the hope that it will be useful,
franta-hg@6
    10
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
franta-hg@6
    11
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
franta-hg@6
    12
-- GNU General Public License for more details.
franta-hg@6
    13
-- 
franta-hg@6
    14
-- You should have received a copy of the GNU General Public License
franta-hg@6
    15
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
franta-hg@6
    16
franta-hg@6
    17
franta-hg@6
    18
franta-hg@2
    19
-- CREATE SCHEMA unix_sql_api;
franta-hg@2
    20
franta-hg@2
    21
SET search_path TO unix_sql_api;
franta-hg@2
    22
franta-hg@3
    23
franta-hg@3
    24
-- fstab: --------------------------------------------------------------------
franta-hg@3
    25
franta-hg@2
    26
DROP VIEW IF EXISTS fstab;
franta-hg@2
    27
DROP FUNCTION IF EXISTS fstab();
franta-hg@2
    28
DROP TYPE IF EXISTS unix_sql_api_fstab;
franta-hg@2
    29
franta-hg@2
    30
CREATE TYPE unix_sql_api_fstab AS (
franta-hg@13
    31
	device         VARCHAR,
franta-hg@13
    32
	device_type    VARCHAR,
franta-hg@13
    33
	device_value   VARCHAR,
franta-hg@13
    34
	mount_point    VARCHAR,
franta-hg@13
    35
	type           VARCHAR,
franta-hg@13
    36
	types          VARCHAR[],
franta-hg@13
    37
	options        VARCHAR[],
franta-hg@13
    38
	dump           INTEGER,
franta-hg@13
    39
	pass           INTEGER
franta-hg@2
    40
);
franta-hg@2
    41
franta-hg@2
    42
CREATE OR REPLACE FUNCTION fstab()
franta-hg@2
    43
RETURNS SETOF unix_sql_api_fstab AS $$
franta-hg@2
    44
	use strict;
franta-hg@2
    45
	use warnings;
franta-hg@2
    46
	
franta-hg@2
    47
	open(FSTAB, "<", "/etc/fstab") or die $!;
franta-hg@2
    48
	
franta-hg@2
    49
	while (<FSTAB>) {
franta-hg@2
    50
		if (/^([^\s#]+)\s+([^\s]+)\s+([^\s]+)\s+([^\s]+)\s+(\d+)\s+(\d+)\s*$/) {
franta-hg@2
    51
			
franta-hg@2
    52
			my $device_spec_type;
franta-hg@2
    53
			my $device_spec_value;
franta-hg@2
    54
			{
franta-hg@2
    55
				if ($1 =~ /([^=]+)=(.*)/) {
franta-hg@2
    56
					($device_spec_type, $device_spec_value) = ($1, $2);
franta-hg@2
    57
				}
franta-hg@2
    58
			}
franta-hg@2
    59
			
franta-hg@2
    60
			return_next({
franta-hg@2
    61
				device => $1,
franta-hg@2
    62
				device_type => $device_spec_type,
franta-hg@2
    63
				device_value => $device_spec_value,
franta-hg@2
    64
				mount_point => $2,
franta-hg@2
    65
				type => $3,
franta-hg@2
    66
				types => [split(",", $3)],
franta-hg@2
    67
				options => [split(",", $4)],
franta-hg@2
    68
				dump => $5,
franta-hg@2
    69
				pass => $6
franta-hg@2
    70
			});
franta-hg@2
    71
		}
franta-hg@2
    72
	}
franta-hg@2
    73
	
franta-hg@2
    74
	return undef;
franta-hg@2
    75
$$ LANGUAGE plperlu;
franta-hg@2
    76
franta-hg@2
    77
CREATE OR REPLACE VIEW fstab AS
franta-hg@2
    78
	SELECT * FROM fstab()
franta-hg@3
    79
;
franta-hg@3
    80
franta-hg@3
    81
franta-hg@3
    82
-- user groups: --------------------------------------------------------------
franta-hg@3
    83
franta-hg@8
    84
DROP VIEW IF EXISTS users_groups;
franta-hg@8
    85
franta-hg@4
    86
DROP VIEW IF EXISTS groups;
franta-hg@4
    87
DROP FUNCTION IF EXISTS groups();
franta-hg@4
    88
DROP TYPE IF EXISTS unix_sql_api_groups;
franta-hg@3
    89
franta-hg@4
    90
CREATE TYPE unix_sql_api_groups AS (
franta-hg@13
    91
	id        INTEGER,
franta-hg@13
    92
	name      VARCHAR,
franta-hg@13
    93
	members   VARCHAR[]
franta-hg@3
    94
);
franta-hg@3
    95
franta-hg@4
    96
CREATE OR REPLACE FUNCTION groups()
franta-hg@8
    97
RETURNS SETOF unix_sql_api_groups STABLE AS $$
franta-hg@3
    98
	use strict;
franta-hg@3
    99
	use warnings;
franta-hg@5
   100
franta-hg@3
   101
	use User::grent;
franta-hg@8
   102
	
franta-hg@9
   103
	setgrent();
franta-hg@5
   104
	while (my $group = getgrent()) {
franta-hg@3
   105
		return_next({
franta-hg@3
   106
			id => $group->gid,
franta-hg@3
   107
			name => $group->name,
franta-hg@3
   108
			members => [@{$group->members}]
franta-hg@3
   109
		});
franta-hg@3
   110
	}
franta-hg@9
   111
	endgrent();
franta-hg@5
   112
	
franta-hg@3
   113
	return undef;
franta-hg@3
   114
$$ LANGUAGE plperlu;
franta-hg@3
   115
franta-hg@4
   116
CREATE OR REPLACE VIEW groups AS
franta-hg@4
   117
	SELECT * FROM groups()
franta-hg@3
   118
;
franta-hg@9
   119
COMMENT ON COLUMN groups.members IS 'does not contain users who have this group as primary one – see view: users_groups';
franta-hg@3
   120
franta-hg@5
   121
franta-hg@8
   122
-- users: --------------------------------------------------------------------
franta-hg@5
   123
franta-hg@5
   124
DROP VIEW IF EXISTS users;
franta-hg@5
   125
DROP FUNCTION IF EXISTS users();
franta-hg@5
   126
DROP TYPE IF EXISTS unix_sql_api_users;
franta-hg@5
   127
franta-hg@5
   128
CREATE TYPE unix_sql_api_users AS (
franta-hg@13
   129
	id           INTEGER,
franta-hg@13
   130
	gid          INTEGER,
franta-hg@13
   131
	name         VARCHAR,
franta-hg@13
   132
	-- comment   VARCHAR,
franta-hg@13
   133
	gecos        VARCHAR[],
franta-hg@13
   134
	home         VARCHAR,
franta-hg@13
   135
	shell        VARCHAR
franta-hg@13
   136
	-- expire    VARCHAR
franta-hg@5
   137
);
franta-hg@5
   138
franta-hg@5
   139
CREATE OR REPLACE FUNCTION users()
franta-hg@8
   140
RETURNS SETOF unix_sql_api_users STABLE AS $$
franta-hg@5
   141
	use strict;
franta-hg@5
   142
	use warnings;
franta-hg@5
   143
	
franta-hg@7
   144
	use encoding "UTF-8";
franta-hg@5
   145
	use User::pwent;
franta-hg@5
   146
	
franta-hg@9
   147
	setpwent();
franta-hg@5
   148
	while (my $user = getpwent()) {
franta-hg@5
   149
		return_next({
franta-hg@5
   150
			id => $user->uid,
franta-hg@5
   151
			gid => $user->gid,
franta-hg@5
   152
			name => $user->name,
franta-hg@5
   153
			# comment => $user->comment,
franta-hg@7
   154
			gecos => [split(",", $user->gecos)],
franta-hg@5
   155
			home => $user->dir,
franta-hg@5
   156
			shell => $user->shell,
franta-hg@5
   157
			# expire => $user->expire
franta-hg@5
   158
		});
franta-hg@5
   159
	}
franta-hg@9
   160
	endpwent();
franta-hg@8
   161
	
franta-hg@5
   162
	return undef;
franta-hg@5
   163
$$ LANGUAGE plperlu;
franta-hg@5
   164
franta-hg@5
   165
CREATE OR REPLACE VIEW users AS
franta-hg@5
   166
	SELECT * FROM users()
franta-hg@5
   167
;
franta-hg@5
   168
franta-hg@8
   169
franta-hg@8
   170
-- users_groups: -------------------------------------------------------------
franta-hg@8
   171
franta-hg@9
   172
CREATE OR REPLACE VIEW users_groups AS
franta-hg@8
   173
	SELECT
franta-hg@13
   174
		u.id     AS uid,
franta-hg@13
   175
		u.gid    AS gid,
franta-hg@13
   176
		u.name   AS user,
franta-hg@13
   177
		g.name   AS group,
franta-hg@13
   178
		true     AS initial
franta-hg@13
   179
	FROM users AS u
franta-hg@13
   180
	JOIN groups AS g ON (u.gid = g.id)
franta-hg@9
   181
	UNION
franta-hg@8
   182
	SELECT
franta-hg@13
   183
		u.id     AS uid,
franta-hg@13
   184
		g.*,
franta-hg@13
   185
		false    AS initial
franta-hg@8
   186
	FROM
franta-hg@8
   187
		(SELECT
franta-hg@13
   188
			id                AS gid,
franta-hg@13
   189
			unnest(members)   AS user,
franta-hg@13
   190
			name              AS group
franta-hg@13
   191
		FROM groups) AS g
franta-hg@13
   192
	JOIN users AS u ON (u.name = g.user)
franta-hg@8
   193
;
franta-hg@9
   194
COMMENT ON COLUMN users_groups.initial IS 'whether this group is the „initial login group“ of given user (the primary group)';
franta-hg@8
   195
franta-hg@10
   196
franta-hg@10
   197
-- processes: ----------------------------------------------------------------
franta-hg@10
   198
franta-hg@10
   199
DROP VIEW IF EXISTS processes;
franta-hg@10
   200
DROP FUNCTION IF EXISTS processes();
franta-hg@10
   201
DROP TYPE IF EXISTS unix_sql_api_processes;
franta-hg@10
   202
franta-hg@10
   203
CREATE TYPE unix_sql_api_processes AS (
franta-hg@13
   204
	id            INTEGER,
franta-hg@13
   205
	owner         INTEGER,
franta-hg@13
   206
	command       VARCHAR,
franta-hg@13
   207
	arguments     VARCHAR[],
franta-hg@13
   208
	working_dir   VARCHAR
franta-hg@10
   209
);
franta-hg@10
   210
franta-hg@10
   211
CREATE OR REPLACE FUNCTION processes()
franta-hg@10
   212
RETURNS SETOF unix_sql_api_processes STABLE AS $$
franta-hg@10
   213
	use strict;
franta-hg@10
   214
	use warnings;
franta-hg@10
   215
	
franta-hg@12
   216
	# There is a library…
franta-hg@11
   217
	# aptitude install libproc-processtable-perl
franta-hg@12
   218
	# use Proc::ProcessTable::Process;
franta-hg@12
   219
	# But there can be found:
franta-hg@12
   220
	# /* replace all '\0' with spaces (except for the last one */
franta-hg@12
   221
	# for (cur = cmndline_text; cur < cmndline_text + cmndline_off - 1; cur++) {
franta-hg@12
   222
	# if (*cur == '\0')
franta-hg@12
   223
	# 	*cur = ' ';
franta-hg@12
   224
	# }
franta-hg@12
   225
	# which wipes boundaries between arguments (that can also contain spaces)
franta-hg@12
   226
	# So wait until the patch https://rt.cpan.org/Public/Bug/Display.html?id=52442 will be integrated
franta-hg@10
   227
	
franta-hg@11
   228
	my $dir = "/proc";
franta-hg@11
   229
	
franta-hg@11
   230
	opendir(DIR, $dir) or die $!;
franta-hg@11
   231
	while (readdir(DIR)) {
franta-hg@11
   232
		if (/\d+/) {
franta-hg@11
   233
			my $pid = $_;
franta-hg@11
   234
			my @process_dir_stat = stat("$dir/$pid") or next;
franta-hg@11
   235
			my $uid = $process_dir_stat[4];
franta-hg@11
   236
			
franta-hg@11
   237
			open(CMDLINE, "<$dir/$pid/cmdline");
franta-hg@11
   238
			binmode CMDLINE;
franta-hg@12
   239
			my @cmdline = split("\x00", <CMDLINE>);
franta-hg@11
   240
			
franta-hg@11
   241
			return_next({
franta-hg@11
   242
				id => $pid,
franta-hg@11
   243
				owner => $uid,
franta-hg@12
   244
				command => shift(@cmdline),
franta-hg@12
   245
				arguments => [@cmdline],
franta-hg@11
   246
				working_dir => readlink("$dir/$pid/cwd")
franta-hg@11
   247
			});
franta-hg@11
   248
		}
franta-hg@11
   249
	}
franta-hg@10
   250
	
franta-hg@10
   251
	return undef;
franta-hg@10
   252
$$ LANGUAGE plperlu;
franta-hg@10
   253
franta-hg@10
   254
CREATE OR REPLACE VIEW processes AS
franta-hg@10
   255
	SELECT * FROM processes()
franta-hg@10
   256
;
franta-hg@10
   257