Overview
| Comment: | add ipc backbone |
|---|---|
| Downloads: | Tarball | ZIP archive | SQL archive |
| Timelines: | family | ancestors | descendants | both | trunk |
| Files: | files | file ages | folders |
| SHA3-256: |
87731d4007d725922fe0a577842d9435 |
| User & Date: | lexi on 2020-12-29 14:35:10 |
| Other Links: | manifest | tags |
Context
|
2020-12-29
| ||
| 14:35 | check in missing file check-in: 5a4f99fb55 user: lexi tags: trunk | |
| 14:35 | add ipc backbone check-in: 87731d4007 user: lexi tags: trunk | |
| 00:57 | add privilege control verbs check-in: a64461061f user: lexi tags: trunk | |
Changes
Modified backend/pgsql.t from [f0f9593494] to [0f1425913d].
215
216
217
218
219
220
221
222
223
224
225
226
227
228
...
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
|
insert into parsav_auth (uid, name, kind, cred) values (
$1::bigint,
(select handle from parsav_actors where id = $1::bigint),
'pw-sha256', $2::bytea
)
]]
};
post_create = {
params = {uint64, rawstring, rawstring, rawstring}, sql = [[
insert into parsav_posts (
author, subject, acl, body,
posted, discovered,
circles, mentions
................................................................................
auth_create_pw = [terra(
src: &lib.store.source,
uid: uint64,
reset: bool,
pw: lib.mem.ptr(int8)
): {}
-- TODO impl reset support
var hash: uint8[lib.crypt.algsz.sha256]
if lib.md.mbedtls_md(lib.md.mbedtls_md_info_from_type(lib.crypt.alg.sha256.id),
[&uint8](pw.ptr), pw.ct, &hash[0]) ~= 0 then
lib.bail('cannot hash password')
end
queries.auth_create_pw.exec(src, uid, [lib.mem.ptr(uint8)] {ptr = &hash[0], ct = [hash.type.N]})
end];
actor_auth_register_uid = nil; -- not necessary for view-based auth
}
return b
|
>
>
>
>
>
>
>
>
<
>
>
>
>
>
>
>
>
>
>
>
>
>
|
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
...
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
|
insert into parsav_auth (uid, name, kind, cred) values ( $1::bigint, (select handle from parsav_actors where id = $1::bigint), 'pw-sha256', $2::bytea ) ]] }; auth_purge_type = { params = {rawstring, uint64, rawstring}, cmd = true, sql = [[ delete from parsav_auth where ((uid = 0 and name = $1::text) or uid = $2::bigint) and kind like $3::text ]] }; post_create = { params = {uint64, rawstring, rawstring, rawstring}, sql = [[ insert into parsav_posts ( author, subject, acl, body, posted, discovered, circles, mentions ................................................................................ auth_create_pw = [terra( src: &lib.store.source, uid: uint64, reset: bool, pw: lib.mem.ptr(int8) ): {} var hash: uint8[lib.crypt.algsz.sha256] if lib.md.mbedtls_md(lib.md.mbedtls_md_info_from_type(lib.crypt.alg.sha256.id), [&uint8](pw.ptr), pw.ct, &hash[0]) ~= 0 then lib.bail('cannot hash password') end if reset then queries.auth_purge_type.exec(src, nil, uid, 'pw-%') end queries.auth_create_pw.exec(src, uid, [lib.mem.ptr(uint8)] {ptr = &hash[0], ct = [hash.type.N]}) end]; auth_purge_pw = [terra(src: &lib.store.source, uid: uint64, handle: rawstring): {} queries.auth_purge_type.exec(src, handle, uid, 'pw-%') end]; auth_purge_otp = [terra(src: &lib.store.source, uid: uint64, handle: rawstring): {} queries.auth_purge_type.exec(src, handle, uid, 'otp-%') end]; auth_purge_trust = [terra(src: &lib.store.source, uid: uint64, handle: rawstring): {} queries.auth_purge_type.exec(src, handle, uid, 'trust') end]; actor_auth_register_uid = nil; -- not necessary for view-based auth } return b |
Modified cmdparse.t from [bfedd61eec] to [49c267b075].
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
..
88
89
90
91
92
93
94
95
96
97
98
99
100
101
|
end
terra options:free() self.arglist:free() end
options.methods.parse = terra([self], [argc], [argv])
[init]
var parseopts = true
var [optstack] = 0
var [subcmd] = [ opts.subcmd or 0 ]
self.arglist = lib.mem.heapa(rawstring, argc)
var finalargc = 0
for [idx]=1,argc do
var [arg] = argv[idx]
if optstack > 0 then optstack = optstack - 1 goto [skip] end
if arg[0] == @'-' and parseopts then
if arg[1] == @'-' then -- long option
if arg[2] == 0 then -- last option
................................................................................
subcmd = subcmd - 1
if subcmd == 0 then parseopts = false end
end
end
::[skip]::
end
[verifiers]
if finalargc == 0 then self.arglist:free()
else self.arglist:resize(finalargc) end
end
options.helptxt = { opts = helpstr, flags = flagstr }
end
return options
end
|
|
>
|
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
..
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
|
end terra options:free() self.arglist:free() end options.methods.parse = terra([self], [argc], [argv]) [init] var parseopts = true var [optstack] = 0 var [subcmd] = [ opts.subcmd or 0 ] self.arglist = lib.mem.heapa(rawstring, argc + 1) var finalargc = 0 for [idx]=1,argc do var [arg] = argv[idx] if optstack > 0 then optstack = optstack - 1 goto [skip] end if arg[0] == @'-' and parseopts then if arg[1] == @'-' then -- long option if arg[2] == 0 then -- last option ................................................................................ subcmd = subcmd - 1 if subcmd == 0 then parseopts = false end end end ::[skip]:: end [verifiers] self.arglist.ptr[finalargc] = nil -- for lazy-ass argv compat if finalargc == 0 then self.arglist:free() else self.arglist:resize(finalargc) end end options.helptxt = { opts = helpstr, flags = flagstr } end return options end |
Modified config.lua from [0c09bec0e6] to [931922a3e1].
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
..
65
66
67
68
69
70
71
72
73
74
75
76
77
78
|
tgthf = u.tobool(default('parsav_arch_armhf',true));
doc = {
online = u.tobool(default('parsav_online_documentation',true));
offline = u.tobool(default('parsav_offline_documentation',true));
};
outform = default('parsav_emit_type', 'o');
endian = default('parsav_arch_endian', 'little');
prefix = default('parsav_install_prefix', './');
build = {
id = u.rndstr(6);
release = u.ingest('release');
when = os.date();
};
feat = {};
debug = u.tobool(default('parsav_enable_debug',true));
................................................................................
}):gsub("^'(.*)'$", '%1')
end
conf.os = default('parsav_host_os', default_os)
conf.tgtos = default('parsav_target_os', default_os)
conf.posix = posixes[conf.os]
conf.exe = u.tobool(default('parsav_link',not conf.tgttrip)) -- turn off for partial builds
conf.prefix_conf = default('parsav_install_prefix_cfg', conf.prefix)
conf.prefix_static = default('parsav_install_prefix_static', nil)
conf.build.origin = coalesce(
os.getenv('parsav_builder'),
string.format('%s@%s', coalesce (
os.getenv('USER'),
u.exec{'whoami'}
), u.exec{'hostname'}) -- whoami and hostname are present on both windows & unix
|
|
>
|
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
..
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
|
tgthf = u.tobool(default('parsav_arch_armhf',true));
doc = {
online = u.tobool(default('parsav_online_documentation',true));
offline = u.tobool(default('parsav_offline_documentation',true));
};
outform = default('parsav_emit_type', 'o');
endian = default('parsav_arch_endian', 'little');
prefix = default('parsav_install_prefix', '.');
build = {
id = u.rndstr(6);
release = u.ingest('release');
when = os.date();
};
feat = {};
debug = u.tobool(default('parsav_enable_debug',true));
................................................................................
}):gsub("^'(.*)'$", '%1')
end
conf.os = default('parsav_host_os', default_os)
conf.tgtos = default('parsav_target_os', default_os)
conf.posix = posixes[conf.os]
conf.exe = u.tobool(default('parsav_link',not conf.tgttrip)) -- turn off for partial builds
conf.prefix_conf = default('parsav_install_prefix_cfg', conf.prefix)
conf.prefix_bin = default('parsav_install_prefix_cfg', conf.prefix)
conf.prefix_static = default('parsav_install_prefix_static', nil)
conf.build.origin = coalesce(
os.getenv('parsav_builder'),
string.format('%s@%s', coalesce (
os.getenv('USER'),
u.exec{'whoami'}
), u.exec{'hostname'}) -- whoami and hostname are present on both windows & unix
|
Modified crypt.t from [9b6529621c] to [f5b057e4fa].
58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
for i=0,sz do dest[i] = [uint8](rnd()) end return sz end end m.random = macro(function(typ, from, to) local ty = typ:astype() return quote var v: ty m.spray([&uint8](&v), sizeof(ty)) v = v % (to - from) + from -- only works with unsigned!! in v end end) |
> > |
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
for i=0,sz do dest[i] = [uint8](rnd()) end return sz end end m.random = macro(function(typ, from, to) local ty = typ:astype() from = from or 0 to = to or ty:max() return quote var v: ty m.spray([&uint8](&v), sizeof(ty)) v = v % (to - from) + from -- only works with unsigned!! in v end end) |
Modified mgtool.t from [54eca1a845] to [c954b701da].
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 ... 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 ... 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 ... 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 ... 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 ... 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 |
local subcmds = {
}
local ctlcmds = {
{ 'start', 'start a new instance of the server' };
{ 'stop', 'stop a running instance' };
{ 'attach', 'capture log output from a running instance' };
{ 'db init <domain>', 'initialize backend databases (or a single specified database) with the necessary schema and structures for the given FQDN' };
{ 'db vacuum', 'delete old remote content from the database' };
{ 'db extract (<artifact>|<post>/<attachment number>)', 'extracts an attachment artifact from the database and prints it to standard out' };
{ 'db excise <artifact>', 'extracts an attachment artifact from the database and prints it to standard out' };
{ 'db obliterate', 'completely purge all parsav-related content and structure from the database, destroying all user content (requires confirmation)' };
{ 'db insert', 'reads a file from standard in and inserts it into the attachment database, printing the resulting ID' };
{ 'mkroot <handle>', 'establish a new root user with the given handle' };
{ 'user <handle> auth <type> new', '(where applicable, managed auth only) create a new authentication token of the given type for a user' };
{ 'user <handle> auth <type> reset', '(where applicable, managed auth only) delete all of a user\'s authentication tokens of the given type and issue a new one' };
{ 'user <handle> auth (<type>|all) purge', 'delete all credentials that would allow this user to log in (where possible)' };
{ 'user <handle> (grant|revoke) (<priv>|all)', 'grant or revoke a specific power to or from a user' };
{ 'user <handle> emasculate', 'strip all administrative powers from a user' };
{ 'user <handle> suspend [<timespec>]', '(e.g. \27[1muser jokester suspend 5d 6h 7m 3s\27[m to suspend "jokester" for five days, six hours, seven minutes, and three seconds) suspend a user'};
{ 'actor <xid> purge-all', 'remove all traces of a user from the database (except local user credentials -- use \27[1mauth all purge\27[m to prevent a user from accessing the instance)' };
{ 'actor <xid> create', 'instantiate a new actor' };
{ 'actor <xid> bestow <epithet>', 'bestow an epithet upon an actor' };
{ 'conf set <setting> <value>', 'add or a change a server configuration parameter to the database' };
{ 'conf get <setting>', 'report the value of a server setting' };
{ 'conf reset <setting>', 'reset a server setting to its default value' };
{ 'conf refresh', 'instruct an instance to refresh its configuration cache' };
{ 'conf chsec', 'reset the server secret, invalidating all authentication cookies' };
{ 'serv dl', 'initiate an update cycle over foreign actors' };
{ 'tl', 'print the current local timeline to standard out' };
{ 'be pgsql setup-auth (managed|unmanaged)', '(PGSQL backends) select the authentication strategy to use' };
}
local ctlcmdhelp = 'commands:\n'
for _, v in ipairs(ctlcmds) do
ctlcmdhelp = ctlcmdhelp .. string.format (
' \27[1m%s\27[m: %s\n', v[1]:gsub('(<%w+>)','\27[36m%1\27[;1m'), v[2]
)
end
local struct idelegate {
all: bool
src: &lib.store.source
srv: &lib.srv.overlord
}
................................................................................
end
lib.dbg('assigning temporary password')
dlg:auth_create_pw(uid, reset, pstr {
ptr = [rawstring](tmppw), ct = 32
})
end
local terra entry_mgtool(argc: int, argv: &rawstring): int
if argc < 1 then lib.bail('bad invocation!') end
lib.noise_init(2)
[lib.init]
var srv: lib.srv.overlord
var dlg = idelegate { srv = &srv, src = nil }
var mode: ctloptions
mode:parse(argc,argv) defer mode:free()
if mode.version then version() return 0 end
if mode.help then
[ lib.emit(false, 1, 'usage: ', `argv[0], ' ', ctloptions.helptxt.flags, ' <cmd> [<args>…]', ctloptions.helptxt.opts, ctlcmdhelp) ]
return 0
end
var cnf: rawstring
if mode.backend_file ~= nil
then cnf = @mode.backend_file
else cnf = lib.proc.getenv('parsav_backend_file')
end
if cnf == nil then cnf = "backend.conf" end
if mode.all then dlg.all = true else
-- iterate through and pick the right backend
end
if mode.arglist.ct == 0 then lib.bail('no command') return 1 end
if lib.str.cmp(mode.arglist(0),'attach') == 0 then
elseif lib.str.cmp(mode.arglist(0),'start') == 0 then
elseif lib.str.cmp(mode.arglist(0),'stop') == 0 then
else
if lib.str.cmp(mode.arglist(0),'db') == 0 then
var dbmode: pbasic dbmode:parse(mode.arglist.ct, &mode.arglist(0))
if dbmode.help then
[ lib.emit(false, 1, 'usage: ', `argv[0], ' db ', dbmode.type.helptxt.flags, ' <cmd> [<args>…]', dbmode.type.helptxt.opts) ]
return 1
end
if dbmode.arglist.ct < 1 then goto cmderr end
srv:setup(cnf)
if lib.str.cmp(dbmode.arglist(0),'init') == 0 and dbmode.arglist.ct == 2 then
lib.report('initializing new database structure for domain ', dbmode.arglist(1))
................................................................................
var confirmstrs = array(
'alpha', 'beta', 'gamma', 'delta', 'epsilon', 'eta', 'nu', 'kappa'
)
var cfmstr: int8[64] cfmstr[0] = 0
var tdx = lib.osclock.time(nil) / 60
for i=0,3 do
if i ~= 0 then lib.str.cat(&cfmstr[0], '-') end
lib.str.cat(&cfmstr[0], confirmstrs[(tdx + 49*i) % [confirmstrs.type.N]])
end
if dbmode.arglist.ct == 1 then
lib.bail('you are attempting to completely obliterate all data! make sure you have selected your target correctly. if you really want to do this, pass the confirmation string ', &cfmstr[0])
elseif dbmode.arglist.ct == 2 then
if lib.str.cmp(dbmode.arglist(1), cfmstr) == 0 then
lib.warn('completely obliterating all data!')
................................................................................
srv:conprep(lib.store.prepmode.conf)
var cfmode: lib.cmdparse {
help = {'h','display this list'};
no_notify = {'n', "don't instruct the server to refresh its configuration cache after making changes; useful for \"transactional\" configuration changes."};
}
cfmode:parse(mode.arglist.ct, &mode.arglist(0))
if cfmode.help then
[ lib.emit(false, 1, 'usage: ', `argv[0], ' conf ', cfmode.type.helptxt.flags, ' <cmd> [<args>…]', cfmode.type.helptxt.opts) ]
return 1
end
if cfmode.arglist.ct < 1 then goto cmderr end
if cfmode.arglist.ct == 1 then
if lib.str.cmp(cfmode.arglist(0),'chsec') == 0 then
var sec: int8[65] gensec(&sec[0])
................................................................................
pwset(dlg, &tmppw, ruid, false)
lib.report('temporary root pw: ', {&tmppw[0], 32})
end
else goto cmderr end
elseif lib.str.cmp(mode.arglist(0),'user') == 0 then
var umode: pbasic umode:parse(mode.arglist.ct, &mode.arglist(0))
if umode.help then
[ lib.emit(false, 1, 'usage: ', `argv[0], ' user ', umode.type.helptxt.flags, ' <handle> <cmd> [<args>…]', umode.type.helptxt.opts) ]
return 1
end
if umode.arglist.ct >= 3 then
var grant = lib.str.cmp(umode.arglist(1),'grant') == 0
var handle = umode.arglist(0)
var usr = dlg:actor_fetch_xid(pstr {ptr=handle, ct=lib.str.sz(handle)})
if not usr then lib.bail('unknown handle') end
if grant or lib.str.cmp(umode.arglist(1),'revoke') == 0 then
var newprivs = usr.ptr.rights.powers
var map = array([lib.store.privmap])
if umode.arglist.ct == 3 and lib.str.cmp(umode.arglist(2),'all') == 0 then
if grant
then newprivs:fill()
else newprivs:clear()
end
................................................................................
end
usr.ptr.rights.powers = newprivs
dlg:actor_save_privs(usr.ptr)
elseif lib.str.cmp(umode.arglist(1),'auth') == 0 and umode.arglist.ct == 4 then
var reset = lib.str.cmp(umode.arglist(3),'reset') == 0
if reset or lib.str.cmp(umode.arglist(3),'new') == 0 then
if lib.str.cmp(umode.arglist(2),'pw') == 0 then
var tmppw: int8[33]
pwset(dlg, &tmppw, usr.ptr.id, reset)
lib.report('new temporary password for ',usr.ptr.handle,': ', {&tmppw[0], 32})
else lib.bail('unknown credential type') end
elseif lib.str.cmp(umode.arglist(3),'purge') == 0 then
else goto cmderr end
else goto cmderr end
else goto cmderr end
elseif lib.str.cmp(mode.arglist(0),'actor') == 0 then
elseif lib.str.cmp(mode.arglist(0),'tl') == 0 then
elseif lib.str.cmp(mode.arglist(0),'serv') == 0 then
else goto cmderr end
|
| | < < < < < < < < < < | < < < < | > | | | > > > > | > > > | | > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > > > > > > > | | > > > > > > | > > > > > > > > < > > > > > > > > > > > > > |
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 .. 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 ... 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 ... 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 ... 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 ... 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 |
local subcmds = {
}
local ctlcmds = {
{ 'start', 'start a new instance of the server' };
{ 'stop', 'stop a running instance' };
{ 'attach', 'capture log output from a running instance' };
{ 'db', 'set up and manage the database' };
{ 'user', 'manage users, privileges, and credentials'};
{ 'mkroot <handle>', 'establish a new root user with the given handle' };
{ 'actor <xid> purge-all', 'remove all traces of a user from the database (except local user credentials -- use \27[1mauth all purge\27[m to prevent a user from accessing the instance)' };
{ 'actor <xid> create', 'instantiate a new actor' };
{ 'actor <xid> bestow <epithet>', 'bestow an epithet upon an actor' };
{ 'conf', 'manage the server configuration'};
{ 'serv dl', 'initiate an update cycle over foreign actors' };
{ 'tl', 'print the current local timeline to standard out' };
{ 'be pgsql setup-auth (managed|unmanaged)', '(PGSQL backends) select the authentication strategy to use' };
}
local cmdhelp = function(tbl)
local str = '\ncommands:\n'
for _, v in ipairs(tbl) do
str = str .. string.format (
' \27[1m%s\27[m: %s\n',
v[1]
:gsub('([%(%)|%[%]])', '\27[34m%1\27[;1m')
:gsub('(<.->)','\27[36m%1\27[;1m'),
v[2]
)
end
return str
end
local struct idelegate {
all: bool
src: &lib.store.source
srv: &lib.srv.overlord
}
................................................................................
end
lib.dbg('assigning temporary password')
dlg:auth_create_pw(uid, reset, pstr {
ptr = [rawstring](tmppw), ct = 32
})
end
local emp = lib.ipc.global_emperor
local terra entry_mgtool(argc: int, argv: &rawstring): int
if argc < 1 then lib.bail('bad invocation!') end
lib.noise.init(2)
[lib.init]
var srv: lib.srv.overlord
var dlg = idelegate { srv = &srv, src = nil }
var mode: ctloptions
mode:parse(argc,argv) defer mode:free()
if mode.version then version() return 0 end
if mode.help then
[ lib.emit(false, 1, 'usage: ', `argv[0], ' ', ctloptions.helptxt.flags, ' <cmd> [<args>…]', ctloptions.helptxt.opts, cmdhelp(ctlcmds)) ]
return 0
end
if mode.quiet then lib.noise.level = 0 end
var cnf: rawstring
if mode.backend_file ~= nil
then cnf = @mode.backend_file
else cnf = lib.proc.getenv('parsav_backend_file')
end
if cnf == nil then cnf = [config.prefix_conf .. "/backend.conf"] end
if mode.all then dlg.all = true else
-- iterate through and pick the right backend
end
if mode.arglist.ct == 0 then lib.bail('no command') return 1 end
if lib.str.cmp(mode.arglist(0),'start') ~= 0 then
-- hack to save us some pain around forking
emp = lib.ipc.emperor.mk(false)
end
defer emp:release()
if lib.str.cmp(mode.arglist(0),'attach') == 0 then
elseif lib.str.cmp(mode.arglist(0),'start') == 0 then
mode.arglist(0) = "-";
var chargv = mode.arglist.ptr
var lsr = lib.ipc.listener.mk()
var chpid = lib.proc.fork()
if chpid == 0 then
lsr:release()
--lib.proc.daemonize(1,0)
lib.io.close(0) lib.io.close(1) lib.io.close(2)
lib.proc.exec([config.prefix_bin .. '/parsavd'], chargv)
lib.proc.execp([config.prefix_bin .. '/parsavd'], chargv)
lib.ipc.notify_parent(lib.ipc.signals.state_fail_find)
lib.bail('cannot find parsav program')
else
lib.report('starting parsav daemon')
while true do
var sig = lsr:block()
if sig.system then lib.dbg('got system signal') end
if sig.from == chpid then
if sig.system and sig.sig == lib.ipc.signals.sys_child then
lib.warn('parsavd failed to start')
return 0
elseif sig.sig == lib.ipc.signals.notify_state_change and
sig.event == lib.ipc.signals.state_success then
lib.report('parsavd successfully started')
return 0
elseif sig.sig == lib.ipc.signals.notify_state_change and
sig.event == lib.ipc.signals.state_fail_find then
lib.bail('parsavd could not be found')
else lib.warn('got unrecognized signal, ignoring')
end
end
end
lsr:release() -- just because i feel distinctly uncomfortable leaving it out
end
elseif lib.str.cmp(mode.arglist(0),'stop') == 0 then
var acks = emp:mallack()
emp:decree(0,nil, lib.ipc.cmd.stop, 0, &acks(0)) -- TODO targeting
for i=0,acks.ct do
if acks(i).success then
lib.io.fmt('instance %llu successfully stepped down\n', acks(i).clid)
else
lib.io.fmt('instance %llu reports failure to halt\n', acks(i).clid)
end
end
acks:free()
else
if lib.str.cmp(mode.arglist(0),'db') == 0 then
var dbmode: pbasic dbmode:parse(mode.arglist.ct, &mode.arglist(0))
if dbmode.help then
[ lib.emit(false, 1, 'usage: ', `argv[0], ' db ', dbmode.type.helptxt.flags, ' <cmd> [<args>…]', dbmode.type.helptxt.opts, cmdhelp {
{ 'db init <domain>', 'initialize backend databases (or a single specified database) with the necessary schema and structures for the given FQDN' };
{ 'db vacuum', 'delete old remote content from the database' };
{ 'db extract (<artifact>|<post>/<attachment number>)', 'extracts an attachment artifact from the database and prints it to standard out' };
{ 'db excise (<artifact>|<post>/<attachment number>)', 'removes an undesirable artifact from the database' };
{ 'db obliterate [<confirmation code>]', 'completely purge all parsav-related content and structure from the database, destroying all user content (requires confirmation)' };
{ 'db insert', 'reads a file from standard in and inserts it into the attachment database, printing the resulting ID' };
}) ]
return 1
end
if dbmode.arglist.ct < 1 then goto cmderr end
srv:setup(cnf)
if lib.str.cmp(dbmode.arglist(0),'init') == 0 and dbmode.arglist.ct == 2 then
lib.report('initializing new database structure for domain ', dbmode.arglist(1))
................................................................................
var confirmstrs = array(
'alpha', 'beta', 'gamma', 'delta', 'epsilon', 'eta', 'nu', 'kappa'
)
var cfmstr: int8[64] cfmstr[0] = 0
var tdx = lib.osclock.time(nil) / 60
for i=0,3 do
if i ~= 0 then lib.str.cat(&cfmstr[0], '-') end
lib.str.cat(&cfmstr[0], confirmstrs[(tdx ^ (173*i)) % [confirmstrs.type.N]])
end
if dbmode.arglist.ct == 1 then
lib.bail('you are attempting to completely obliterate all data! make sure you have selected your target correctly. if you really want to do this, pass the confirmation string ', &cfmstr[0])
elseif dbmode.arglist.ct == 2 then
if lib.str.cmp(dbmode.arglist(1), cfmstr) == 0 then
lib.warn('completely obliterating all data!')
................................................................................
srv:conprep(lib.store.prepmode.conf)
var cfmode: lib.cmdparse {
help = {'h','display this list'};
no_notify = {'n', "don't instruct the server to refresh its configuration cache after making changes; useful for \"transactional\" configuration changes."};
}
cfmode:parse(mode.arglist.ct, &mode.arglist(0))
if cfmode.help then
[ lib.emit(false, 1, 'usage: ', `argv[0], ' conf ', cfmode.type.helptxt.flags, ' <cmd> [<args>…]', cfmode.type.helptxt.opts, cmdhelp {
{ 'conf set <setting> <value>', 'add or a change a server configuration parameter to the database' };
{ 'conf get <setting>', 'report the value of a server setting' };
{ 'conf reset <setting>', 'reset a server setting to its default value' };
{ 'conf refresh', 'instruct an instance to refresh its configuration cache' };
{ 'conf chsec', 'reset the server secret, invalidating all authentication cookies' };
}) ]
return 1
end
if cfmode.arglist.ct < 1 then goto cmderr end
if cfmode.arglist.ct == 1 then
if lib.str.cmp(cfmode.arglist(0),'chsec') == 0 then
var sec: int8[65] gensec(&sec[0])
................................................................................
pwset(dlg, &tmppw, ruid, false)
lib.report('temporary root pw: ', {&tmppw[0], 32})
end
else goto cmderr end
elseif lib.str.cmp(mode.arglist(0),'user') == 0 then
var umode: pbasic umode:parse(mode.arglist.ct, &mode.arglist(0))
if umode.help then
[ lib.emit(false, 1, 'usage: ', `argv[0], ' user ', umode.type.helptxt.flags, ' <handle> <cmd> [<args>…]', umode.type.helptxt.opts, cmdhelp {
{ 'user <handle> auth <type> new', '(where applicable, managed auth only) create a new authentication token of the given type for a user' };
{ 'user <handle> auth <type> reset', '(where applicable, managed auth only) delete all of a user\'s authentication tokens of the given type and issue a new one' };
{ 'user <handle> auth (<type>|all) purge', 'delete all credentials that would allow this user to log in (where possible)' };
{ 'user <handle> (grant|revoke) (<priv>|all)', 'grant or revoke a specific power to or from a user' };
{ 'user <handle> emasculate', 'strip all administrative powers from a user' };
{ 'user <handle> forgive', 'restore all default powers to a user' };
{ 'user <handle> suspend [<timespec>]', '(e.g. \27[1muser jokester suspend 5d 6h 7m 3s\27[m to suspend "jokester" for five days, six hours, seven minutes, and three seconds) suspend a user'};
}) ]
return 1
end
if umode.arglist.ct >= 3 then
var grant = lib.str.cmp(umode.arglist(1),'grant') == 0
var handle = umode.arglist(0)
var usr = dlg:actor_fetch_xid(pstr {ptr=handle, ct=lib.str.sz(handle)})
if grant or lib.str.cmp(umode.arglist(1),'revoke') == 0 then
if not usr then lib.bail('unknown handle') end
var newprivs = usr.ptr.rights.powers
var map = array([lib.store.privmap])
if umode.arglist.ct == 3 and lib.str.cmp(umode.arglist(2),'all') == 0 then
if grant
then newprivs:fill()
else newprivs:clear()
end
................................................................................
end
usr.ptr.rights.powers = newprivs
dlg:actor_save_privs(usr.ptr)
elseif lib.str.cmp(umode.arglist(1),'auth') == 0 and umode.arglist.ct == 4 then
var reset = lib.str.cmp(umode.arglist(3),'reset') == 0
if reset or lib.str.cmp(umode.arglist(3),'new') == 0 then
-- FIXME enable resetting pws for users who have
-- not logged in yet
if not usr then lib.bail('unknown handle') end
if lib.str.cmp(umode.arglist(2),'pw') == 0 then
var tmppw: int8[33]
pwset(dlg, &tmppw, usr.ptr.id, reset)
lib.report('new temporary password for ',usr.ptr.handle,': ', {&tmppw[0], 32})
else lib.bail('unknown credential type') end
elseif lib.str.cmp(umode.arglist(3),'purge') == 0 then
var uid: uint64 = 0
if usr:ref() then uid = usr(0).id end
if lib.str.cmp(umode.arglist(2),'pw') == 0 then
dlg:auth_purge_pw(uid, handle)
elseif lib.str.cmp(umode.arglist(2),'otp') == 0 then
dlg:auth_purge_otp(uid, handle)
elseif lib.str.cmp(umode.arglist(2),'trust') == 0 then
dlg:auth_purge_trust(uid, handle)
else lib.bail('unknown credential type') end
else goto cmderr end
else goto cmderr end
else goto cmderr end
elseif lib.str.cmp(mode.arglist(0),'actor') == 0 then
elseif lib.str.cmp(mode.arglist(0),'tl') == 0 then
elseif lib.str.cmp(mode.arglist(0),'serv') == 0 then
else goto cmderr end
|
Modified parsav.t from [d1470e4b10] to [1565f096a3].
124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 ... 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 ... 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 ... 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 ... 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 ... 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 ... 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 |
local q = quote
var [val]
[exp]
in val end
return q
end);
proc = {
exit = terralib.externfunction('exit', int -> {});
getenv = terralib.externfunction('getenv', rawstring -> rawstring);
};
io = {
send = terralib.externfunction('write', {int, rawstring, intptr} -> ptrdiff);
recv = terralib.externfunction('read', {int, rawstring, intptr} -> ptrdiff);
say = macro(function(msg) return `lib.io.send(2, msg, [#(msg:asvalue())]) end);
fmt = terralib.externfunction('printf',
terralib.types.funcpointer({rawstring},{int},true));
};
str = { sz = terralib.externfunction('strlen', rawstring -> intptr) };
copy = function(tbl)
local new = {}
................................................................................
osclock = terralib.includec 'time.h';
}
if config.posix then
lib.uio = terralib.includec 'sys/uio.h';
lib.emit = lib.emitv -- use more efficient call where available
else lib.emit = lib.emit_unitary end
local starttime = global(lib.osclock.time_t)
local lastnoisetime = global(lib.osclock.time_t)
local noise = global(uint8,1)
local noise_header = function(code,txt,mod)
if mod then
return string.format('\27[%s;1m(%s %s)\27[m ', code,mod,txt)
else
return string.format('\27[%s;1m(%s)\27[m ', code,txt)
end
end
local terra timehdr()
var now = lib.osclock.time(nil)
var diff = now - lastnoisetime
if diff > 30 then -- print cur time
lastnoisetime = now
var curtime: int8[26]
lib.osclock.ctime_r(&now, &curtime[0])
for i=0,26 do if curtime[i] == @'\n' then curtime[i] = 0 break end end -- :/
[ lib.emit(false, 2, '\27[1m[', `&curtime[0], ']\27[;36m\n +00 ') ]
else -- print time since last msg
var dfs = arrayof(int8, 0x30 + diff/10, 0x30 + diff%10, 0x20, 0)
[ lib.emit(false, 2, ' \27[36m+', `&dfs[0]) ]
................................................................................
if level >= 3 and config.debug == false then
return macro(function(...) return {} end)
end
return macro(function(...)
local fn = (...).filename
local ln = tostring((...).linenumber)
local dbgtag = string.format('\27[35m · \27[34m%s:\27[1m%s\27[m\n', fn,ln)
local q = lib.emit(level < 3 and true or dbgtag, 2, noise_header(code,n), ...)
return quote
--lib.io.fmt(['attempting to emit at ' .. fn..':'..ln.. '\n'])
if noise >= level then timehdr(); [q] end end
end);
end
lib.dbg = defrep(3,'debug', '32')
lib.report = defrep(2,'info', '35')
lib.warn = defrep(1,'warn', '33')
lib.bail = macro(function(...)
local q = lib.emit(true, 2, noise_header('31','fatal'), ...)
return quote
timehdr(); [q]
lib.proc.exit(1)
end
end);
lib.stat = terralib.memoize(function(ty)
local n = struct {
ok: bool
union {
................................................................................
lib.pk = lib.loadlib('mbedtls','mbedtls/pk.h')
lib.md = lib.loadlib('mbedtls','mbedtls/md.h')
lib.b64 = lib.loadlib('mbedtls','mbedtls/base64.h')
lib.net = lib.loadlib('mongoose','mongoose.h')
lib.pq = lib.loadlib('libpq','libpq-fe.h')
lib.load {
'mem', 'math', 'str', 'file', 'crypt';
'http', 'html', 'session', 'tpl', 'store';
'smackdown'; -- md-alike parser
}
local be = {}
for _, b in pairs(config.backends) do
................................................................................
}
do
local p = string.format('parsav: %s\nbuilt on %s\n', config.build.str, config.build.when)
terra version() lib.io.send(1, p, [#p]) end
end
terra lib.noise_init(default_level: uint)
starttime = lib.osclock.time(nil)
lastnoisetime = 0
var n = lib.proc.getenv('parsav_noise')
if n ~= nil then
if n[0] >= 0x30 and n[0] <= 0x39 and n[1] == 0 then
noise = n[0] - 0x30
return
end
end
noise = default_level
end
lib.load{'mgtool'}
local options = lib.cmdparse {
version = {'V', 'display information about the binary build and exit'};
verbose = {'v', 'increase logging verbosity', inc=1};
quiet = {'q', 'do not print to standard out'};
help = {'h', 'display this list'};
backend_file = {'B', 'init from specified backend file', consume=1};
static_dir = {'S', 'directory with overrides for static content', consume=1};
builtin_data = {'D', 'do not load static content overrides at runtime under any circumstances'};
instance = {'i', 'set an instance name to make it easier to control multiple daemons', consume = 1};
}
local static_setup = quote end
local mapin = quote end
local odir = symbol(rawstring)
local pathbuf = symbol(lib.str.acc)
................................................................................
end or quote return end
] end
var [pathbuf] defer pathbuf:free()
pathbuf:compose(odir,'/')
[mapin]
end
local terra entry_daemon(argc: int, argv: &rawstring): int
if argc < 1 then lib.bail('bad invocation!') end
lib.noise_init(1)
[lib.init]
-- shut mongoose the fuck up
lib.net.mg_log_set_callback([terra(msg: &opaque, sz: int, u: &opaque) end], nil)
var srv: lib.srv.overlord
do var mode: options
................................................................................
mode:parse(argc,argv) defer mode:free()
static_init(&mode)
if mode.version then version() return 0 end
if mode.help then
[ lib.emit(true, 1, 'usage: ',`argv[0],' ', options.helptxt.flags, ' [<args>…]', options.helptxt.opts) ]
return 0
end
var cnf: rawstring
if mode.backend_file ~= nil
then cnf = @mode.backend_file
else cnf = lib.proc.getenv('parsav_backend_file')
end
if cnf == nil then cnf = [config.prefix_conf .. "backend.conf"] end
srv:setup(cnf)
srv:start(lib.trn(mode.instance ~= nil, @mode.instance, nil))
end
lib.report('listening for requests')
while true do
srv:poll()
end
srv:shutdown()
return 0
end
local bflag = function(long,short)
if short and util.has(buildopts, short) then return true end
if long and util.has(buildopts, long) then return true end
return false
end
|
> > > > > > > > | | < | | | | | | | | > | | | | > | > | > > | | | | | | > > > > > | > | > > > > > < > > > > > > > > > > > > > > > > > > > > < |
124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 ... 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 ... 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 ... 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 ... 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 ... 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 ... 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 |
local q = quote
var [val]
[exp]
in val end
return q
end);
proc = {
fork = terralib.externfunction('fork', {} -> int);
daemonize = terralib.externfunction('daemon', {int,int} -> {});
exit = terralib.externfunction('exit', int -> {});
getenv = terralib.externfunction('getenv', rawstring -> rawstring);
exec = terralib.externfunction('execv', {rawstring,&rawstring} -> int);
execp = terralib.externfunction('execvp', {rawstring,&rawstring} -> int);
};
io = {
send = terralib.externfunction('write', {int, rawstring, intptr} -> ptrdiff);
recv = terralib.externfunction('read', {int, rawstring, intptr} -> ptrdiff);
close = terralib.externfunction('close', {int} -> int);
say = macro(function(msg) return `lib.io.send(2, msg, [#(msg:asvalue())]) end);
fmt = terralib.externfunction('printf',
terralib.types.funcpointer({rawstring},{int},true));
};
str = { sz = terralib.externfunction('strlen', rawstring -> intptr) };
copy = function(tbl)
local new = {}
................................................................................
osclock = terralib.includec 'time.h';
}
if config.posix then
lib.uio = terralib.includec 'sys/uio.h';
lib.emit = lib.emitv -- use more efficient call where available
else lib.emit = lib.emit_unitary end
lib.noise = {
level = global(uint8,1);
starttime = global(lib.osclock.time_t);
lasttime = global(lib.osclock.time_t);
header = function(code,txt,mod)
if mod then
return string.format('\27[%s;1m(%s %s)\27[m ', code,mod,txt)
else
return string.format('\27[%s;1m(%s)\27[m ', code,txt)
end
end;
}
local terra timehdr()
var now = lib.osclock.time(nil)
var diff = now - lib.noise.lasttime
if diff > 30 then -- print cur time
lib.noise.lasttime = now
var curtime: int8[26]
lib.osclock.ctime_r(&now, &curtime[0])
for i=0,26 do if curtime[i] == @'\n' then curtime[i] = 0 break end end -- :/
[ lib.emit(false, 2, '\27[1m[', `&curtime[0], ']\27[;36m\n +00 ') ]
else -- print time since last msg
var dfs = arrayof(int8, 0x30 + diff/10, 0x30 + diff%10, 0x20, 0)
[ lib.emit(false, 2, ' \27[36m+', `&dfs[0]) ]
................................................................................
if level >= 3 and config.debug == false then
return macro(function(...) return {} end)
end
return macro(function(...)
local fn = (...).filename
local ln = tostring((...).linenumber)
local dbgtag = string.format('\27[35m · \27[34m%s:\27[1m%s\27[m\n', fn,ln)
local q = lib.emit(level < 3 and true or dbgtag, 2, lib.noise.header(code,n), ...)
return quote
--lib.io.fmt(['attempting to emit at ' .. fn..':'..ln.. '\n'])
if lib.noise.level >= level then timehdr(); [q] end end
end);
end
local terra final_cleanup :: {} -> {}
lib.dbg = defrep(3,'debug', '32')
lib.report = defrep(2,'info', '35')
lib.warn = defrep(1,'warn', '33')
lib.bail = macro(function(...)
local q = lib.emit(true, 2, lib.noise.header('31','fatal'), ...)
return quote
if lib.noise.level ~= 0 then
timehdr(); [q]
end
final_cleanup()
lib.proc.exit(1)
end
end);
lib.stat = terralib.memoize(function(ty)
local n = struct {
ok: bool
union {
................................................................................
lib.pk = lib.loadlib('mbedtls','mbedtls/pk.h')
lib.md = lib.loadlib('mbedtls','mbedtls/md.h')
lib.b64 = lib.loadlib('mbedtls','mbedtls/base64.h')
lib.net = lib.loadlib('mongoose','mongoose.h')
lib.pq = lib.loadlib('libpq','libpq-fe.h')
lib.load {
'mem', 'math', 'str', 'file', 'crypt', 'ipc';
'http', 'html', 'session', 'tpl', 'store';
'smackdown'; -- md-alike parser
}
local be = {}
for _, b in pairs(config.backends) do
................................................................................
}
do
local p = string.format('parsav: %s\nbuilt on %s\n', config.build.str, config.build.when)
terra version() lib.io.send(1, p, [#p]) end
end
terra lib.noise.init(default_level: uint)
lib.noise.starttime = lib.osclock.time(nil)
lib.noise.lasttime = 0
var n = lib.proc.getenv('parsav_noise')
if n ~= nil then
if n[0] >= 0x30 and n[0] <= 0x39 and n[1] == 0 then
lib.noise.level = n[0] - 0x30
return
end
end
lib.noise.level = default_level
end
lib.load{'mgtool'}
local options = lib.cmdparse {
version = {'V', 'display information about the binary build and exit'};
verbose = {'v', 'increase logging verbosity', inc=1};
quiet = {'q', 'do not print to standard out'};
help = {'h', 'display this list'};
backend_file = {'B', 'init from specified backend file', consume=1};
static_dir = {'S', 'directory with overrides for static content', consume=1};
builtin_data = {'D', 'do not load static content overrides at runtime under any circumstances'};
instance = {'i', 'set an instance name to make it easier to control multiple daemons', consume = 1};
no_ipc = {'I', 'disable IPC'};
}
local static_setup = quote end
local mapin = quote end
local odir = symbol(rawstring)
local pathbuf = symbol(lib.str.acc)
................................................................................
end or quote return end
] end
var [pathbuf] defer pathbuf:free()
pathbuf:compose(odir,'/')
[mapin]
end
terra final_cleanup()
lib.ipc.global_emperor:release()
end
local terra entry_daemon(argc: int, argv: &rawstring): int
if argc < 1 then lib.bail('bad invocation!') end
lib.noise.init(1)
[lib.init]
-- shut mongoose the fuck up
lib.net.mg_log_set_callback([terra(msg: &opaque, sz: int, u: &opaque) end], nil)
var srv: lib.srv.overlord
do var mode: options
................................................................................
mode:parse(argc,argv) defer mode:free()
static_init(&mode)
if mode.version then version() return 0 end
if mode.help then
[ lib.emit(true, 1, 'usage: ',`argv[0],' ', options.helptxt.flags, ' [<args>…]', options.helptxt.opts) ]
return 0
end
if mode.quiet then lib.noise.level = 0 end
var cnf: rawstring
if mode.backend_file ~= nil
then cnf = @mode.backend_file
else cnf = lib.proc.getenv('parsav_backend_file')
end
if cnf == nil then cnf = [config.prefix_conf .. "/backend.conf"] end
srv:setup(cnf)
if argv[0][0] == @'-' and argv[0][1] == 0 then
lib.ipc.notify_parent(lib.ipc.signals.state_success)
argv[0] = 'parsav service daemon'
end
srv:start(lib.trn(mode.instance ~= nil, @mode.instance, nil))
end
lib.ipc.global_emperor = lib.ipc.emperor.mk(true) defer lib.ipc.global_emperor:release()
lib.report('listening for requests')
while lib.ipc.proc_active do
srv:poll()
while true do
var d: lib.ipc.demand
lib.ipc.global_emperor:poll(&d)
var a = lib.ipc.ack {success = true}
if d.cmd == lib.ipc.cmd.none then break
elseif d.cmd == lib.ipc.cmd.stop then
lib.ipc.proc_active = false
elseif d.cmd == lib.ipc.cmd.enumerate then
if srv.id ~= nil then
lib.str.ncpy(&a.iname[0], srv.id, [(`a.iname).tree.type.N])
else a.iname[0] = 0 end
elseif d.cmd == lib.ipc.cmd.chnoise then
lib.noise.level = d.operand
elseif d.cmd == lib.ipc.cmd.cfgrefresh then
srv.cfg:free()
srv.cfg:load()
end
d:ack(&lib.ipc.global_emperor, &a)
end
end
srv:shutdown()
return 0
end
local bflag = function(long,short)
if short and util.has(buildopts, short) then return true end
if long and util.has(buildopts, long) then return true end
return false
end
|
Modified store.t from [3a79c99b1d] to [763fd9ba8a].
266 267 268 269 270 271 272 273 274 275 276 277 278 279 |
actor_conf_str: cnf(rawstring, lib.mem.ptr(int8))
actor_conf_int: cnf(intptr, lib.stat(intptr))
auth_create_pw: {&m.source, uint64, bool, lib.mem.ptr(int8)} -> {}
-- uid: uint64
-- reset: bool (delete other passwords?)
-- pw: pstring
post_save: {&m.source, &m.post} -> {}
post_create: {&m.source, &m.post} -> uint64
post_enum_author_uid: {&m.source, uint64, m.range} -> lib.mem.ptr(lib.mem.ptr(m.post))
convo_fetch_xid: {&m.source,rawstring} -> lib.mem.ptr(m.post)
convo_fetch_uid: {&m.source,uint64} -> lib.mem.ptr(m.post)
|
> > > |
266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 |
actor_conf_str: cnf(rawstring, lib.mem.ptr(int8))
actor_conf_int: cnf(intptr, lib.stat(intptr))
auth_create_pw: {&m.source, uint64, bool, lib.mem.ptr(int8)} -> {}
-- uid: uint64
-- reset: bool (delete other passwords?)
-- pw: pstring
auth_purge_pw: {&m.source, uint64, rawstring} -> {}
auth_purge_otp: {&m.source, uint64, rawstring} -> {}
auth_purge_trust: {&m.source, uint64, rawstring} -> {}
post_save: {&m.source, &m.post} -> {}
post_create: {&m.source, &m.post} -> uint64
post_enum_author_uid: {&m.source, uint64, m.range} -> lib.mem.ptr(lib.mem.ptr(m.post))
convo_fetch_xid: {&m.source,rawstring} -> lib.mem.ptr(m.post)
convo_fetch_uid: {&m.source,uint64} -> lib.mem.ptr(m.post)
|