--
-- $Id: DET_nntp.sql,v 1.2 2007/03/28 10:48:51 source Exp $
--
-- This file is part of the OpenLink Software Virtuoso Open-Source (VOS)
-- project.
--
-- Copyright (C) 1998-2006 OpenLink Software
--
-- This project is free software; you can redistribute it and/or modify it
-- under the terms of the GNU General Public License as published by the
-- Free Software Foundation; only version 2 of the License, dated June 1991.
--
-- This program is distributed in the hope that it will be useful, but
-- WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-- General Public License for more details.
--
-- You should have received a copy of the GNU General Public License along
-- with this program; if not, write to the Free Software Foundation, Inc.,
-- 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
--
--
use DB
;
create function "nntp_FIXNAME" (in mailname any) returns varchar
{
return
replace (
replace (
replace (
replace (
replace (
replace (
replace (
replace (mailname, '/', '_'), '\\', '_'), ':', '_'), '+', '_'), '\"', '_'), '[', '_'), ']', '_'), '\'', '_');
}
;
create procedure "nntp_PARSE_SERVER_NAME"(in fullname varchar, out server varchar, out port integer)
{
declare pos integer;
pos := strrchr(fullname, '_');
server := subseq(fullname, 0, pos);
port := atoi(subseq(fullname, pos + 1));
}
;
create function "nntpf_display_message_text2"(in _text varchar, in ct varchar := 'text/plain', in ses any)
{
_text := nntpf_replace_at (_text);
if (ct = 'text/plain')
http ('<pre class="artbody"> <br/>', ses);
else
http ('<div class="artbody">', ses);
http (_text, ses);
if (ct = 'text/plain')
http ('</pre>', ses);
else
http ('</div>', ses);
}
;
create function "nntp_COMPOSE_HTML_NAME" (in title varchar, in id varchar) returns varchar
{
if (title is null or title = '')
return "nntp_FIXNAME"(sprintf('%s', id));
return "nntp_FIXNAME"(sprintf('%s %s', title, id));
}
;
create function "nntp_COMPOSE_COMMENTS_NAME" (in title varchar, in id varchar) returns varchar
{
if (title is null or title = '')
return "nntp_FIXNAME"(sprintf('%s Comments', id));
return "nntp_FIXNAME"(sprintf('%s %s Comments', title, id));
}
;
create procedure "nntp_PARSE_HTML_NAME" (in fullname varchar, out title varchar, out id varchar)
{
declare pos integer;
pos := strrchr(fullname, ' ');
if (pos is NULL)
id := fullname;
else
{
title := subseq(fullname, 0, pos);
id := subseq(fullname, pos + 1);
}
}
;
create procedure "nntp_PARSE_COMMENTS_NAME" (in fullname varchar, out title varchar, out id varchar)
{
declare pos integer;
declare real_part, comment_part varchar;
pos := strrchr(fullname, ' ');
comment_part := subseq(fullname, pos + 1);
if (comment_part = 'Comments')
{
real_part := subseq(fullname, 0, pos);
pos := strrchr(real_part, ' ');
if (pos is NULL)
id := real_part;
else
{
title := subseq(real_part, 0, pos);
id := subseq(real_part, pos + 1);
}
}
}
;
create function "nntp_CHANNEL_DESC_NAMES" () returns any
{
return vector ('atom.xml', 'foaf.xml', 'index.ocs', 'index.opml', 'index.rdf', 'rss.xml', 'xbel.xml');
}
;
create function "nntp_ACCESS_PARAMS" (in detcol_id any, out access varchar, out gid integer, out uid integer)
{
declare access_tmp varchar;
whenever not found goto ret;
access := '100000000NN';
gid := http_nogroup_gid ();
uid := http_nobody_uid ();
if (isinteger (detcol_id))
{
select COL_PERMS, COL_GROUP, COL_OWNER into access_tmp, gid, uid from WS.WS.SYS_DAV_COL where COL_ID = detcol_id;
}
access[0] := access_tmp[0];
access[1] := access_tmp[1];
-- access[3] := access_tmp[3];
ret:
;
}
;
--| This matches DAV_AUTHENTICATE (in id any, in what char(1), in req varchar, in a_uname varchar, in a_pwd varchar, in a_uid integer := null)
--| The difference is that the DET function should not check whether the pair of name and password is valid; the auth_uid is not a null already.
create function "nntp_DAV_AUTHENTICATE" (in id any, in what char(1), in req varchar, in auth_uname varchar, in auth_pwd varchar, in auth_uid integer)
{
-- dbg_obj_princ ('nntp_DAV_AUTHENTICATE (', id, what, req, auth_uname, auth_pwd, auth_uid, http_dav_uid(), ')');
if (auth_uid < 0)
return -12;
if (not ('110' like req))
{
--dbg_obj_princ ('a_uid2 is ', auth_uid, ', id[3] is ', id[3], ' mismatch');
return -13;
}
if ((auth_uid <> id[3]) and (auth_uid <> http_dav_uid()))
{
--dbg_obj_princ ('a_uid is ', auth_uid, ', id[3] is ', id[3], ' mismatch');
return -13;
}
return auth_uid;
}
;
--| This exactly matches DAV_AUTHENTICATE_HTTP (in id any, in what char(1), in req varchar, in can_write_http integer, inout a_lines any, inout a_uname varchar, inout a_pwd varchar, inout a_uid integer, inout a_gid integer, inout _perms varchar) returns integer
--| The function should fully check access because DAV_AUTHENTICATE_HTTP do nothing with auth data either before or after calling this DET function.
--| Unlike DAV_AUTHENTICATE, user name passed to DAV_AUTHENTICATE_HTTP header may not match real DAV user.
--| If DET call is successful, DAV_AUTHENTICATE_HTTP checks whether the user have read permission on mount point collection.
--| Thus even if DET function allows anonymous access, the whole request may fail if mountpoint is not readable by public.
create function "nntp_DAV_AUTHENTICATE_HTTP" (in id any, in what char(1), in req varchar, in can_write_http integer, inout a_lines any, inout a_uname varchar, inout a_pwd varchar, inout a_uid integer, inout a_gid integer, inout _perms varchar) returns integer
{
declare rc integer;
declare puid, pgid, ruid, rgid integer;
declare u_password, pperms varchar;
-- anon are never allowed for mails! declare allow_anon integer;
if (length (req) <> 3)
return -15;
whenever not found goto nf_col_or_res;
if ((what <> 'R') and (what <> 'C'))
return -14;
-- allow_anon := WS.WS.PERM_COMP (substring (cast (pperms as varchar), 7, 3), req);
if (a_uid is null)
{
-- if ((not allow_anon) or ('' <> WS.WS.FINDPARAM (a_lines, 'Authorization:')))
rc := WS.WS.GET_DAV_AUTH (a_lines, 0, can_write_http, a_uname, u_password, a_uid, a_gid, _perms);
if (rc < 0)
return rc;
}
if (isinteger (a_uid))
{
if (a_uid < 0)
return a_uid;
if (a_uid = 1) -- Anonymous FTP
{
a_uid := http_nobody_uid ();
a_gid := http_nogroup_gid ();
}
}
if ((a_uid <> id[3]) and (a_uid <> http_dav_uid()))
{
-- dbg_obj_princ ('a_uid is ', a_uid, ', id[3] is ', id[3], ' mismatch');
return -13;
}
if (not ('100' like req))
return -13;
return a_uid;
nf_col_or_res:
return -1;
}
;
--| This matches DAV_GET_PARENT (in id any, in st char(1), in path varchar) returns any
create function "nntp_DAV_GET_PARENT" (in id any, in st char(1), in path varchar) returns any
{
-- dbg_obj_princ ('nntp_DAV_GET_PARENT (', id, st, path, ')');
return -20;
}
;
--| When DAV_COL_CREATE_INT calls DET function, authentication, check for lock and check for overwrite are passed, uid and gid are translated from strings to IDs.
--| Check for overwrite, but the deletion of previously existing collection should be made by DET function.
create function "nntp_DAV_COL_CREATE" (in detcol_id any, in path_parts any, in permissions varchar, in uid integer, in gid integer, in auth_uid integer) returns any
{
-- dbg_obj_princ ('nntp_DAV_COL_CREATE (', detcol_id, path_parts, permissions, uid, gid, auth_uid, ')');
return -20;
}
;
--| It looks like that this is redundant and should be removed at all.
create function "nntp_DAV_COL_MOUNT" (in detcol_id any, in path_parts any, in full_mount_path varchar, in mount_det varchar, in permissions varchar, in uid integer, in gid integer, in auth_uid integer) returns any
{
-- dbg_obj_princ ('nntp_DAV_COL_MOUNT (', detcol_id, path_parts, full_mount_path, mount_det, permissions, uid, gid, auth_uid, ')');
return -20;
}
;
--| It looks like that this is redundant and should be removed at all.
create function "nntp_DAV_COL_MOUNT_HERE" (in parent_id any, in full_mount_path varchar, in permissions varchar, in uid integer, in gid integer, in auth_uid integer) returns any
{
-- dbg_obj_princ ('nntp_DAV_COL_MOUNT_HERE (', parent_id, full_mount_path, permissions, uid, gid, auth_uid, ')');
return -20;
}
;
--| When DAV_DELETE_INT calls DET function, authentication and check for lock are passed.
create function "nntp_DAV_DELETE" (in detcol_id any, in path_parts any, in what char(1), in silent integer, in auth_uid integer) returns integer
{
-- dbg_obj_princ ('nntp_DAV_DELETE (', detcol_id, path_parts, what, silent, auth_uid, ')');
return -20;
}
;
--| When DAV_RES_UPLOAD_STRSES_INT calls DET function, authentication and check for locks are performed before the call.
--| There's a special problem, known as 'Transaction deadlock after reading from HTTP session'.
--| The DET function should do only one INSERT of the 'content' into the table and do it as late as possible.
--| The function should return -29 if deadlocked or otherwise broken after reading blob from HTTP.
create function "nntp_DAV_RES_UPLOAD" (in detcol_id any, in path_parts any, inout content any, in type varchar, in permissions varchar, in uid integer, in gid integer, in auth_uid integer) returns any
{
-- dbg_obj_princ ('nntp_DAV_RES_UPLOAD (', detcol_id, path_parts, ', [content], ', content, type, permissions, uid, gid, auth_uid, ')');
return -20;
}
;
--| When DAV_PROP_REMOVE_INT calls DET function, authentication and check for locks are performed before the call.
--| The check whether it's a system name or not is _not_ permitted.
create function "nntp_DAV_PROP_REMOVE" (in id any, in what char(0), in propname varchar, in silent integer, in auth_uid integer) returns integer
{
-- dbg_obj_princ ('nntp_DAV_PROP_REMOVE (', id, what, propname, silent, auth_uid, ')');
return -20;
}
;
--| When DAV_PROP_SET_INT calls DET function, authentication and check for locks are performed before the call.
--| The check whether it's a system property or not is _not_ permitted and the function should return -16 for live system properties.
create function "nntp_DAV_PROP_SET" (in id any, in what char(0), in propname varchar, in propvalue any, in overwrite integer, in auth_uid integer) returns any
{
-- dbg_obj_princ ('nntp_DAV_PROP_SET (', id, what, propname, propvalue, overwrite, auth_uid, ')');
if (propname[0] = 58)
{
return -16;
}
return -20;
}
;
--| When DAV_PROP_GET_INT calls DET function, authentication and check whether it's a system property are performed before the call.
create function "nntp_DAV_PROP_GET" (in id any, in what char(0), in propname varchar, in auth_uid integer)
{
-- dbg_obj_princ ('nntp_DAV_PROP_GET (', id, what, propname, auth_uid, ')');
return -11;
}
;
--| When DAV_PROP_LIST_INT calls DET function, authentication is performed before the call.
--| The returned list should contain only user properties.
create function "nntp_DAV_PROP_LIST" (in id any, in what char(0), in propmask varchar, in auth_uid integer)
{
-- dbg_obj_princ ('nntp_DAV_PROP_LIST (', id, what, propmask, auth_uid, ')');
return vector ();
}
;
--| When DAV_PROP_GET_INT or DAV_DIR_LIST_INT calls DET function, authentication is performed before the call.
create function "nntp_DAV_DIR_SINGLE" (in id any, in what char(0), in path any, in auth_uid integer) returns any
{
declare mnamefmt varchar;
declare folder_id, server_id varchar;
declare fullpath, rightcol, resname varchar;
declare maxrcvdate datetime;
declare colname varchar;
--dbg_obj_princ ('nntp_DAV_DIR_SINGLE (', id, what, path, auth_uid, ')');
server_id := cast(id[4] as varchar);
folder_id := cast(id[5] as varchar);
fullpath := '';
rightcol := NULL;
if (atoi(folder_id) = 0)
{
maxrcvdate := (select FTHR_DATE from DB.DBA.NNFE_THR where FTHR_MESS_ID = folder_id);
while (folder_id is not null)
{
colname := (select "nntp_COMPOSE_COMMENTS_NAME"(FTHR_SUBJ, FTHR_MESS_ID)
from DB.DBA.NNFE_THR where FTHR_MESS_ID = folder_id);
if (DAV_HIDE_ERROR (colname) is null)
return -1;
if (rightcol is null)
rightcol := colname;
fullpath := colname || '/' || fullpath;
folder_id := coalesce ((select FTHR_REFER from DB.DBA.NNFE_THR where FTHR_MESS_ID = folder_id));
}
folder_id := cast((select FTHR_GROUP from DB.DBA.NNFE_THR where FTHR_MESS_ID = id[5]) as varchar);
}
if ((server_id = '0' or server_id is null) and folder_id is not null)
{
server_id := folder_id;
folder_id := null;
}
if (folder_id is not null)
{
if (maxrcvdate is null)
maxrcvdate := (select NG_UP_TIME from DB.DBA.NEWS_GROUPS where NG_GROUP = folder_id);
colname := (select "nntp_FIXNAME"(NG_NAME) from DB.DBA.NEWS_GROUPS where NG_GROUP = atoi(folder_id));
if (DAV_HIDE_ERROR (colname) is null)
return -1;
if (rightcol is null)
rightcol := colname;
fullpath := colname || '/' || fullpath;
}
if (server_id is not null)
{
if (maxrcvdate is null)
maxrcvdate := coalesce ((select max(NG_UP_TIME) from DB.DBA.NEWS_GROUPS where NG_SERVER = atoi(folder_id)),
cast ('1980-01-01' as datetime) );
colname := (select "nntp_FIXNAME" (concat(NS_SERVER, ':', cast(NS_PORT as varchar)))
from DB.DBA.NEWS_SERVERS where NS_ID = atoi(server_id));
if (DAV_HIDE_ERROR (colname) is null)
return -1;
if (rightcol is null)
rightcol := colname;
fullpath := colname || '/' || fullpath;
}
fullpath := DAV_CONCAT_PATH (DAV_SEARCH_PATH (id[1], 'C'), fullpath);
if ('C' = what)
{
if (id[6] >= 0)
return -1;
return vector (fullpath, 'C', 0, maxrcvdate,
id, '100000000NN', 0, id[3], maxrcvdate, 'dav/unix-directory', rightcol );
}
for select "nntp_COMPOSE_HTML_NAME"(FTHR_SUBJ, FTHR_MESS_ID) as orig_mname,
FTHR_MESS_ID as m_id, FTHR_DATE
from DB.DBA.NNFE_THR
where FTHR_MESS_ID = id[6]
do
{
return vector (fullpath || orig_mname, 'R', 1024, FTHR_DATE,
id,
'100000000NN', 0, id[3], FTHR_DATE, 'text/plain', orig_mname);
}
return -1;
}
;
--| When DAV_PROP_GET_INT or DAV_DIR_LIST_INT calls DET function, authentication is performed before the call.
create function "nntp_DAV_DIR_LIST" (in detcol_id any, in path_parts any, in detcol_path varchar, in name_mask varchar, in recursive integer, in auth_uid integer) returns any
{
--dbg_obj_princ ('nntp_DAV_DIR_LIST (', detcol_id, path_parts, detcol_path, name_mask, recursive, auth_uid, ')');
declare mgroup_id, muser_id integer;
declare mfolder_id, mserver_id varchar;
declare top_davpath varchar;
declare res, grand_res any;
declare top_id, descnames any;
declare reslen integer;
declare what char (1);
declare access varchar;
declare ownergid, owner_uid, dn_ctr, dn_count integer;
"nntp_ACCESS_PARAMS" (detcol_id, access, ownergid, owner_uid);
if ((0 = length (path_parts)) or ('' = path_parts[length (path_parts) - 1]))
what := 'C';
else
what := 'R';
mgroup_id := 0;
mserver_id := NULL;
mfolder_id := NULL;
grand_res := vector();
if ('C' = what and 1 = length(path_parts))
top_id := vector (UNAME'nntp', detcol_id, mgroup_id, owner_uid, null, null, -1); -- may be a fake id because top_id[4] may be NULL
else
top_id := "nntp_DAV_SEARCH_ID_IMPL" (detcol_id, path_parts, what, mgroup_id, muser_id, mserver_id, mfolder_id);
if (DAV_HIDE_ERROR (top_id) is null)
return vector();
top_davpath := DAV_CONCAT_PATH (detcol_path, path_parts);
if ('R' = what)
return vector ("nntp_DAV_DIR_SINGLE" (top_id, what, top_davpath, auth_uid));
res := vector();
reslen := 0;
if ('C' = what and 1 = length(path_parts))
{
for select "nntp_FIXNAME" (concat(NS_SERVER, ':', cast(NS_PORT as varchar))) as orig_name, cast(NS_ID as varchar) as f_id
from DB.DBA.NEWS_SERVERS
order by 1, 2
do
{
declare maxrcvdate datetime;
maxrcvdate := coalesce((select max(NG_UP_TIME)
from DB.DBA.NEWS_GROUPS
where
NG_SERVER = atoi(f_id)),
cast('1980-01-01' as datetime));
res := vector_concat (res, vector (vector (DAV_CONCAT_PATH (top_davpath, orig_name) || '/', 'C', 0, maxrcvdate,
vector (UNAME'nntp', detcol_id, mgroup_id, owner_uid, mserver_id, f_id, -1),
'100000000NN', ownergid, owner_uid, maxrcvdate, 'dav/unix-directory', orig_name) ) );
}
grand_res := res;
}
if ('C' = what and length(path_parts) = 2)
{
for select "nntp_FIXNAME" (NG_NAME) as orig_name, NG_UP_TIME as maxrcvdate, cast(NG_GROUP as varchar) as f_id
from DB.DBA.NEWS_GROUPS
where NG_SERVER = top_id[5]
order by 1, 2
do
{
res := vector_concat (res, vector (vector (DAV_CONCAT_PATH (top_davpath, orig_name) || '/', 'C', 0, maxrcvdate,
vector (UNAME'nntp', detcol_id, mgroup_id, owner_uid, mserver_id, f_id, -1),
'100000000NN', ownergid, owner_uid, maxrcvdate, 'dav/unix-directory', orig_name) ) );
}
grand_res := res;
}
if ('C' = what and length(path_parts) > 2)
{
for select distinct FTHR_REFER as f_ref
from DB.DBA.NNFE_THR
where FTHR_GROUP = atoi(top_id[5]) and FTHR_REFER is not null
do
{
for select "nntp_COMPOSE_COMMENTS_NAME"(FTHR_SUBJ, FTHR_MESS_ID) as orig_name, FTHR_MESS_ID as f_id, FTHR_DATE
from DB.DBA.NNFE_THR
where f_ref = FTHR_MESS_ID and FTHR_TOP = 1 and FTHR_SUBJ like name_mask
order by 1, 2
do
{
res := vector_concat(res, vector (vector (DAV_CONCAT_PATH (top_davpath, orig_name) || '/', 'C', 0, FTHR_DATE,
vector (UNAME'nntp', detcol_id, mgroup_id, owner_uid, mserver_id, f_id, -1),
'100000000NN', ownergid, owner_uid, FTHR_DATE, 'dav/unix-directory', orig_name) ) );
reslen := reslen + 1;
}
}
for select distinct FTHR_MESS_ID as f_ref2
from DB.DBA.NNFE_THR
where FTHR_REFER = top_id[5]
do
{
for select "nntp_COMPOSE_COMMENTS_NAME"(FTHR_SUBJ, FTHR_MESS_ID) as orig_name,
FTHR_MESS_ID as f_id, FTHR_DATE
from DB.DBA.NNFE_THR
where f_ref2 = FTHR_MESS_ID
and FTHR_SUBJ like name_mask
order by 1, 2
do
{
res := vector_concat(res, vector (vector (DAV_CONCAT_PATH (top_davpath, orig_name) || '/', 'C', 0, FTHR_DATE,
vector (UNAME'nntp', detcol_id, mgroup_id, owner_uid, mserver_id, f_id, -1),
'100000000NN', ownergid, owner_uid, FTHR_DATE, 'dav/unix-directory', orig_name) ) );
reslen := reslen + 1;
}
}
grand_res := res;
reslen := 0;
res := vector();
for select "nntp_COMPOSE_HTML_NAME"(FTHR_SUBJ, FTHR_MESS_ID) as orig_mname,
FTHR_MESS_ID as m_id, FTHR_DATE
from DB.DBA.NNFE_THR
where ((FTHR_GROUP = atoi(top_id[5]) and FTHR_TOP=1) or FTHR_REFER = top_id[5])
and FTHR_SUBJ like name_mask
order by 1, 2
do
{
res := vector_concat (res, vector (vector (DAV_CONCAT_PATH (top_davpath, orig_mname), 'R', 1024, FTHR_DATE,
vector (UNAME'nntp', detcol_id, mgroup_id, owner_uid, mserver_id, top_id[5], m_id),
'100000000NN', ownergid, owner_uid, FTHR_DATE, 'text/plain', orig_mname) ) );
reslen := reslen + 1;
}
grand_res := vector_concat (grand_res, res);
}
finalize_res:
return grand_res;
}
;
--| When DAV_DIR_FILTER_INT calls DET function, authentication is performed before the call and compilation is initialized.
create function "nntp_DAV_DIR_FILTER" (in detcol_id any, in path_parts any, in detcol_path any, inout compilation any, in recursive integer, in auth_uid integer) returns any
{
-- dbg_obj_princ ('nntp_DAV_DIR_FILTER (', detcol_id, path_parts, detcol_path, compilation, recursive, auth_uid, ')');
return vector();
}
;
create function "nntp_DAV_SEARCH_ID_IMPL" (in detcol_id any, in path_parts any, in what char(1), inout group_id integer, inout muser_id integer, inout mserver_id varchar, inout mfolder_id varchar) returns any
{
declare colpath, merged_fnameext, orig_fnameext varchar;
declare orig_id varchar;
declare ctr, len integer;
declare hitlist any;
declare access varchar;
declare ownergid, owner_uid integer;
--dbg_obj_princ ('nntp_DAV_SEARCH_ID_IMPL (', detcol_id, path_parts, what, group_id, muser_id, mfolder_id, ')');
"nntp_ACCESS_PARAMS" (detcol_id, access, ownergid, owner_uid);
if (0 = length(path_parts))
{
if ('C' <> what)
{
return -1;
}
return vector (UNAME'nntp', detcol_id, group_id, owner_uid, mserver_id, mfolder_id, -1);
}
if ('' = path_parts[length(path_parts) - 1])
{
if ('C' <> what)
{
return -1;
}
}
else
{
if ('R' <> what)
{
return -1;
}
}
len := length (path_parts) - 1;
ctr := 0;
while (ctr < len)
{
if (ctr = 0)
{
hitlist := vector ();
for select NS_ID
from DB.DBA.NEWS_SERVERS
where "nntp_FIXNAME"(concat(NS_SERVER, ':', cast(NS_PORT as varchar))) = path_parts[ctr]
do
{
hitlist := vector_concat (hitlist, vector (NS_ID));
}
if (length (hitlist) <> 1)
return -1;
mfolder_id := cast(hitlist[0] as varchar);
if (len > 1)
mserver_id := cast(hitlist[0] as varchar);
}
if (ctr = 1)
{
hitlist := vector ();
for select NG_GROUP
from DB.DBA.NEWS_GROUPS
where "nntp_FIXNAME"(NG_NAME) = path_parts[ctr]
do
{
hitlist := vector_concat (hitlist, vector (NG_GROUP));
}
if (length (hitlist) <> 1)
return -1;
mfolder_id := cast(hitlist[0] as varchar);
}
if (ctr > 1)
{
hitlist := vector ();
for select FTHR_MESS_ID from DB.DBA.NNFE_THR
where "nntp_COMPOSE_COMMENTS_NAME"(FTHR_SUBJ, FTHR_MESS_ID) = path_parts[ctr]
do
{
hitlist := vector_concat (hitlist, vector (FTHR_MESS_ID));
}
if (length (hitlist) <> 1)
return -1;
mfolder_id := cast(hitlist[0] as varchar);
}
ctr := ctr + 1;
}
if ('C' = what)
return vector (UNAME'nntp', detcol_id, group_id, owner_uid, mserver_id, mfolder_id, -1);
len := length (path_parts);
while (ctr < len)
{
hitlist := vector ();
for select FTHR_MESS_ID
from DB.DBA.NNFE_THR
where (FTHR_GROUP = atoi(mfolder_id) or (FTHR_REFER = mfolder_id)) and
("nntp_COMPOSE_HTML_NAME" (FTHR_SUBJ, FTHR_MESS_ID) = path_parts[ctr])
do
{
hitlist := vector_concat (hitlist, vector (FTHR_MESS_ID));
}
if (length (hitlist) <> 1)
return -1;
ctr := ctr + 1;
}
return vector (UNAME'nntp', detcol_id, group_id, owner_uid, mserver_id, mfolder_id, hitlist[0]);
}
;
--| When DAV_PROP_GET_INT or DAV_DIR_LIST_INT calls DET function, authentication is performed before the call.
create function "nntp_DAV_SEARCH_ID" (in detcol_id any, in path_parts any, in what char(1)) returns any
{
declare mgroup_id, muser_id integer;
declare mfolder_id, mserver_id varchar;
--dbg_obj_princ ('nntp_DAV_SEARCH_ID (', detcol_id, path_parts, what, ')');
return "nntp_DAV_SEARCH_ID_IMPL" (detcol_id, path_parts, what, mgroup_id, muser_id, mserver_id, mfolder_id);
}
;
--| When DAV_SEARCH_PATH_INT calls DET function, authentication is performed before the call.
create function "nntp_DAV_SEARCH_PATH" (in id any, in what char(1)) returns any
{
--dbg_obj_princ ('nntp_DAV_SEARCH_PATH (', id, what, ')');
return NULL;
}
;
--| When DAV_COPY_INT calls DET function, authentication and check for locks are performed before the call, but no check for existing/overwrite.
create function "nntp_DAV_RES_UPLOAD_COPY" (in detcol_id any, in path_parts any, in source_id any, in what char(1), in overwrite_flags integer, in permissions varchar, in uid integer, in gid integer, in auth_uid integer) returns any
{
-- dbg_obj_princ ('nntp_DAV_RES_UPLOAD_COPY (', detcol_id, path_parts, source_id, what, overwrite_flags, permissions, uid, gid, auth_uid, ')');
return -20;
}
;
--| When DAV_COPY_INT calls DET function, authentication and check for locks are performed before the call, but no check for existing/overwrite.
create function "nntp_DAV_RES_UPLOAD_MOVE" (in detcol_id any, in path_parts any, in source_id any, in what char(1), in overwrite_flags integer, in auth_uid integer) returns any
{
-- dbg_obj_princ ('nntp_DAV_RES_UPLOAD_MOVE (', detcol_id, path_parts, source_id, what, overwrite_flags, auth_uid, ')');
return -20;
}
;
--| When DAV_RES_CONTENT or DAV_RES_COPY_INT or DAV_RES_MOVE_INT calls DET function, authentication is made.
--| If content_mode is 1 then content is a valid output stream before the call.
create function "nntp_DAV_RES_CONTENT" (in id any, inout content any, out type varchar, in content_mode integer) returns integer
{
--dbg_obj_princ ('nntp_DAV_RES_CONTENT (', id, ', [content], [type], ', content_mode, ')');
declare str_out any;
str_out := string_output();
content := '';
if (id[6] is not null)
{
type := 'text/plain';
declare _date, _from, _subj, _grps, _print_body, d_name varchar;
declare _body, _head, parsed_message any;
declare idx integer;
set isolation='committed';
select NM_HEAD, blob_to_string (NM_BODY)
into parsed_message, _body
from DB.DBA.NEWS_MSG
where NM_ID = id[6];
for (select NM_GROUP
from DB.DBA.NEWS_MULTI_MSG
where NM_KEY_ID = id[6]) do
{
if (ns_rest_rate_read (NM_GROUP) > 0)
{
content := '<h3>Excessive read detected, please try again later.</h3>';
return 0;
}
}
if (__tag (parsed_message) <> 193)
parsed_message := mime_tree (_body);
_head := parsed_message[0];
_subj := coalesce (get_keyword_ucase ('Subject', _head), '');
_from := coalesce (get_keyword_ucase ('From', _head), '');
_grps := coalesce (get_keyword_ucase ('Newsgroups', _head), '');
_date := coalesce (get_keyword_ucase ('Date', _head), '');
nntpf_decode_subj (_subj);
nntpf_decode_subj (_from);
_from := nntpf_replace_at (_from);
http ('<div class="artheaders">', str_out);
http (sprintf ('<span class="header">From:</span>%V<br/>', _from), str_out);
http (sprintf ('<span class="header">Subject:</span>%s<br/>', _subj), str_out);
http (sprintf ('<span class="header">Newsgroups:</span>%s<br/>', _grps), str_out);
http (sprintf ('<span class="header">Date:</span>%s<br/>', _date), str_out);
http ('</div><br/>', str_out);
--if (parsed_message[2] <> 0)
-- return nntpf_display_article_multi_part (parsed_message, _body, id, sid);
--nntpf_display_message_reply (sid, id);
_print_body := subseq (_body, parsed_message[1][0], parsed_message[1][1]);
if (length (_print_body) > 3)
_print_body := subseq (_print_body, 0, (length (_print_body) - 3));
-- CLEAR THIS
parsed_message := nntpf_get_mess_attachments (_print_body, 0);
_print_body := parsed_message[0];
"nntpf_display_message_text2" (_print_body, get_keyword_ucase ('Content-Type', _head), str_out);
http ('<br/>', str_out);
idx := 1;
while (idx < length (parsed_message))
{
d_name := parsed_message[idx];
http (sprintf ('Download attachment : <a href="http://%s/INLINEFILE/%s?VSP=/nntpf/attachment.vsp&id=%U&part=%i&fn=%s"> %s </a><br/>',
nntpf_get_host (vector ()),
d_name,
encode_base64 (id),
idx,
d_name,
d_name), str_out);
if (d_name like '%.jpg' or d_name like '%.gif')
{
http (sprintf ('<img alt="attachment" src="http://%s/INLINEFILE/%s?VSP=/nntpf/attachment.vsp&id=%U&part=%i&fn=%s">',
nntpf_get_host (vector()),
d_name,
encode_base64 (id),
idx,
d_name), str_out);
http ('<br/><br/><br/>', str_out);
}
idx := idx + 1;
}
}
content := string_output_string(str_out);
return 0;
}
;
--| This adds an extra access path to the existing resource or collection.
create function "nntp_DAV_SYMLINK" (in detcol_id any, in path_parts any, in source_id any, in what char(1), in overwrite integer, in uid integer, in gid integer, in auth_uid integer) returns any
{
-- dbg_obj_princ ('nntp_DAV_SYMLINK (', detcol_id, path_parts, source_id, overwrite, uid, gid, auth_uid, ')');
return -20;
}
;
--| This gets a list of resources and/or collections as it is returned by DAV_DIR_LIST and and writes the list of quads (old_id, 'what', old_full_path, dereferenced_id, dereferenced_full_path).
create function "nntp_DAV_DEREFERENCE_LIST" (in detcol_id any, inout report_array any) returns any
{
-- dbg_obj_princ ('nntp_DAV_DEREFERENCE_LIST (', detcol_id, report_array, ')');
return -20;
}
;
--| This gets one of reference quads returned by ..._DAV_REREFERENCE_LIST() and returns a record (new_full_path, new_dereferenced_full_path, name_may_vary).
create function "nntp_DAV_RESOLVE_PATH" (in detcol_id any, inout reference_item any, inout old_base varchar, inout new_base varchar) returns any
{
-- dbg_obj_princ ('nntp_DAV_RESOLVE_PATH (', detcol_id, reference_item, old_base, new_base, ')');
return -20;
}
;
--| There's no API function to lock for a while (do we need such?) The "LOCK" DAV method checks that all parameters are valid but does not check for existing locks.
create function "nntp_DAV_LOCK" (in path any, in id any, in type char(1), inout locktype varchar, inout scope varchar, in token varchar, inout owner_name varchar, inout owned_tokens varchar, in depth varchar, in timeout_sec integer, in auth_uid integer) returns any
{
-- dbg_obj_princ ('nntp_DAV_LOCK (', id, type, locktype, scope, token, owner_name, owned_tokens, depth, timeout_sec, owner_name, auth_uid, ')');
return -20;
}
;
--| There's no API function to unlock for a while (do we need such?) The "UNLOCK" DAV method checks that all parameters are valid but does not check for existing locks.
create function "nntp_DAV_UNLOCK" (in id any, in type char(1), in token varchar, in auth_uid integer)
{
-- dbg_obj_princ ('nntp_DAV_UNLOCK (', id, type, token, auth_uid, ')');
return -27;
}
;
--| The caller does not check if id is valid.
--| This returns -1 if id is not valid, 0 if all existing locks are listed in owned_tokens whitespace-delimited list, 1 for soft 2 for hard lock.
create function "nntp_DAV_IS_LOCKED" (inout id any, inout type char(1), in owned_tokens varchar) returns integer
{
-- dbg_obj_princ ('nntp_DAV_IS_LOCKED (', id, type, owned_tokens, ')');
return 0;
}
;
--| The caller does not check if id is valid.
--| This returns -1 if id is not valid, list of tuples (LOCK_TYPE, LOCK_SCOPE, LOCK_TOKEN, LOCK_TIMEOUT, LOCK_OWNER, LOCK_OWNER_INFO) otherwise.
create function "nntp_DAV_LIST_LOCKS" (in id any, in type char(1), in recursive integer) returns any
{
-- dbg_obj_princ ('nntp_DAV_LIST_LOCKS" (', id, type, recursive);
return vector ();
}
;