Overview
| Comment: | add in a bunch of missing pqclears, because i am a *retard*, and wipe out a fuckton of memory leaks |
|---|---|
| Downloads: | Tarball | ZIP archive | SQL archive |
| Timelines: | family | ancestors | descendants | both | trunk |
| Files: | files | file ages | folders |
| SHA3-256: |
a4e71fdfda530542a5efa3090ac16dcb |
| User & Date: | lexi on 2021-01-28 02:44:55 |
| Original Comment: | add in a bunch of missing pqclears, because i am a *retards*, and wipe out a fuckton of memory leaks |
| Other Links: | manifest | tags |
Context
|
2021-01-28
| ||
| 02:50 | fix more dumb leaks check-in: 4ce1aab090 user: lexi tags: trunk | |
| 02:44 | add in a bunch of missing pqclears, because i am a *retard*, and wipe out a fuckton of memory leaks check-in: a4e71fdfda user: lexi tags: trunk | |
| 00:51 | wrote mimelib, continued iterating on litepub support; tweets can now be imported into honk check-in: c774e2c5a9 user: lexi tags: trunk | |
Changes
Modified api/lp/outbox.t from [7ed4c4752c] to [748fc8c886].
24 24 var time: lib.store.timepoint 25 25 if at:cmp('top') then 26 26 time = lib.osclock.time(nil) 27 27 else 28 28 var tp, ok = lib.math.decparse(at) 29 29 if ok then time = tp end 30 30 end 31 - lib.io.fmt('from-time: %llu\n', time) 32 31 var posts = co.srv:post_enum_author_uid(uid, lib.store.range { 33 32 mode = 1; -- time -> idx 34 33 from_time = time; 35 34 to_idx = 65; 36 35 }) 37 36 var oldest = time 38 37 json:lpush',"partOf":"https://':ppush(co.srv.cfg.domain):ppush(path) 39 38 :lpush'","type":"CollectionPage","orderedItems":[' 40 39 if posts.sz > 0 then defer posts:free() 41 40 for i=0, lib.math.smallest(posts.sz,64) do 42 41 if i~=0 then json:lpush',' end 43 42 json:ppush(lib.api.lp.tweet(co,posts(i).ptr,true)) 44 43 oldest = lib.math.smallest(posts(i)().posted, oldest) 44 + posts(i):free() 45 45 end 46 46 end 47 47 json:lpush'],"totalItems":':ipush(posts.sz) 48 48 if oldest ~= time and oldest > 0 and posts.sz > 64 then 49 49 json:lpush',"next":"https://':ppush(co.srv.cfg.domain):ppush(path) 50 50 :lpush'?at=':ipush(oldest-1):lpush'"' 51 51 end
Modified backend/pgsql.t from [d6c61590d0] to [8e095d7d59].
954 954 -- only to the connecting parsav instance, stored in memory, and dropped 955 955 -- as soon as the connection session ends. 956 956 957 957 local tempviews = sqlsquash(lib.util.ingest 'backend/schema/pgsql-views.sql') 958 958 local prep = { quote 959 959 var res = lib.pq.PQexec([con], tempviews) 960 960 if lib.pq.PQresultStatus(res) == lib.pq.PGRES_COMMAND_OK then 961 - lib.dbg('uploading pgsql session views') 961 + lib.dbg('uploaded pgsql session views') 962 + lib.pq.PQclear(res) 962 963 else 963 964 lib.bail('backend pgsql - failed to upload session views: \n', lib.pq.PQresultErrorMessage(res)) 964 965 end 965 966 end } 966 967 967 968 for k,q in pairs(queries) do 968 969 local qt = sqlsquash(q.sql) ................................................................................ 1026 1027 [#args], params, params_sz, params_ft, 1) 1027 1028 if res == nil then 1028 1029 lib.bail(['grievous error occurred executing '..k..' against database']) 1029 1030 elseif lib.pq.PQresultStatus(res) ~= okconst then 1030 1031 lib.bail(['PGSQL database procedure '..k..' failed\n'], 1031 1032 lib.pq.PQresultErrorMessage(res)) 1032 1033 end 1033 - 1034 - var ct = lib.pq.PQntuples(res) 1035 - if ct == 0 then 1036 - lib.pq.PQclear(res) 1037 - return pqr {0, nil} 1038 - else 1039 - return pqr {ct, res} 1034 + escape 1035 + if q.cmd then 1036 + emit quote lib.pq.PQclear(res) end 1037 + else emit quote 1038 + var ct = lib.pq.PQntuples(res) 1039 + if ct == 0 then 1040 + lib.pq.PQclear(res) 1041 + return pqr {0, nil} 1042 + else 1043 + return pqr {ct, res} 1044 + end 1045 + end end 1040 1046 end 1041 1047 end 1042 1048 q.exec.name = 'pgsql.' .. k .. '.exec' 1043 1049 end 1044 1050 1045 1051 local terra row_to_artifact(res: &pqr, i: intptr): lib.mem.ptr(lib.store.artifact) 1046 1052 var id = res:int(uint64,i,0) ................................................................................ 1242 1248 local getpow = terra( 1243 1249 src: &lib.store.source, 1244 1250 uid: uint64 1245 1251 ): lib.store.powerset 1246 1252 var powers = lib.store.rights_default().powers 1247 1253 var map = array([privmap]) 1248 1254 var r = queries.actor_powers_fetch.exec(src, uid) 1255 + defer r:free() 1249 1256 1250 1257 for i=0, r.sz do 1251 1258 for j=0, [map.type.N] do 1252 1259 var pn = r:_string(i,0) 1253 1260 if map[j].name:cmp(pn) then 1254 1261 if r:bool(i,1) 1255 1262 then powers = powers + map[j].val ................................................................................ 1261 1268 1262 1269 return powers 1263 1270 end 1264 1271 1265 1272 1266 1273 local txdo = terra(src: &lib.store.source) 1267 1274 var res = lib.pq.PQexec([&lib.pq.PGconn](src.handle), 'begin') 1275 + var r: bool 1268 1276 if lib.pq.PQresultStatus(res) == lib.pq.PGRES_COMMAND_OK then 1269 1277 lib.dbg('beginning pgsql transaction') 1270 - return true 1278 + r = true 1271 1279 else 1272 1280 lib.warn('backend pgsql - failed to begin transaction: \n', lib.pq.PQresultErrorMessage(res)) 1273 - return false 1281 + r = false 1274 1282 end 1283 + lib.pq.PQclear(res) 1284 + return r 1275 1285 end 1276 1286 1277 1287 local txdone = terra(src: &lib.store.source) 1278 1288 var res = lib.pq.PQexec([&lib.pq.PGconn](src.handle), 'end') 1289 + var r: bool 1279 1290 if lib.pq.PQresultStatus(res) == lib.pq.PGRES_COMMAND_OK then 1280 1291 lib.dbg('completing pgsql transaction') 1281 - return true 1292 + r = true 1282 1293 else 1283 1294 lib.warn('backend pgsql - failed to complete transaction: \n', lib.pq.PQresultErrorMessage(res)) 1284 - return false 1295 + r = false 1285 1296 end 1297 + lib.pq.PQclear(res) 1298 + return r 1286 1299 end 1287 1300 1288 1301 local b = `lib.store.backend { 1289 1302 id = "pgsql"; 1290 1303 open = [terra(src: &lib.store.source): &opaque 1291 1304 lib.report('connecting to postgres database: ', src.string.ptr) 1292 1305 var [con] = lib.pq.PQconnectdb(src.string.ptr) ................................................................................ 1348 1361 key: binblob 1349 1362 ): {} 1350 1363 queries.server_setup_self.exec(src,domain,key,lib.osclock.time(nil)) 1351 1364 end]; 1352 1365 1353 1366 dbsetup = [terra(src: &lib.store.source): bool 1354 1367 var res = lib.pq.PQexec([&lib.pq.PGconn](src.handle), schema) 1368 + var r = true 1355 1369 if lib.pq.PQresultStatus(res) == lib.pq.PGRES_COMMAND_OK then 1356 1370 lib.report('successfully instantiated schema in database') 1357 - return true 1358 1371 else 1359 1372 lib.warn('backend pgsql - failed to initialize database: \n', lib.pq.PQresultErrorMessage(res)) 1360 - return false 1373 + r = false 1361 1374 end 1375 + lib.pq.PQclear(res) 1376 + return r 1362 1377 end]; 1363 1378 1364 1379 obliterate_everything = [terra(src: &lib.store.source): bool 1365 1380 var res = lib.pq.PQexec([&lib.pq.PGconn](src.handle), obliterator) 1381 + var r = true 1366 1382 if lib.pq.PQresultStatus(res) == lib.pq.PGRES_COMMAND_OK then 1367 1383 lib.report('successfully wiped out everything parsav-related in database') 1368 - return true 1369 1384 else 1370 1385 lib.warn('backend pgsql - failed to obliterate database: \n', lib.pq.PQresultErrorMessage(res)) 1371 1386 return false 1372 1387 end 1388 + lib.pq.PQclear(res) 1389 + return r 1373 1390 end]; 1374 1391 1375 - conf_get = [terra(src: &lib.store.source, key: pstring) 1392 + conf_get = [terra(src: &lib.store.source, pool: &lib.mem.pool, key: pstring) 1376 1393 var r = queries.conf_get.exec(src, key) 1377 1394 if r.sz == 0 then return [lib.mem.ptr(int8)] { ptr = nil, ct = 0 } else 1378 1395 defer r:free() 1379 - return r:String(0,0) 1396 + return r:_string(0,0):pdup(pool) 1380 1397 end 1381 1398 end]; 1382 1399 conf_set = [terra(src: &lib.store.source, key: pstring, val: pstring) 1383 - queries.conf_set.exec(src, key, val):free() end]; 1400 + queries.conf_set.exec(src, key, val) end]; 1384 1401 conf_reset = [terra(src: &lib.store.source, key: rawstring) 1385 - queries.conf_reset.exec(src, key):free() end]; 1402 + queries.conf_reset.exec(src, key) end]; 1386 1403 1387 1404 actor_fetch_uid = [terra(src: &lib.store.source, uid: uint64) 1388 1405 var r = queries.actor_fetch_uid.exec(src, uid) 1389 1406 if r.sz == 0 then 1390 1407 return [lib.mem.ptr(lib.store.actor)] { ct = 0, ptr = nil } 1391 1408 else defer r:free() 1392 1409 var a = row_to_actor(&r, 0) ................................................................................ 1511 1528 ::fail::return 0, 0, pstring.null() 1512 1529 end]; 1513 1530 1514 1531 1515 1532 actor_stats = [terra(src: &lib.store.source, uid: uint64) 1516 1533 var r = queries.actor_stats.exec(src, uid) 1517 1534 if r.sz == 0 then lib.bail('error fetching actor stats!') end 1535 + defer r:free() 1518 1536 var s: lib.store.actor_stats 1519 1537 s.posts = r:int(uint64, 0, 0) 1520 1538 s.follows = r:int(uint64, 0, 1) 1521 1539 s.followers = r:int(uint64, 0, 2) 1522 1540 s.mutuals = r:int(uint64, 0, 3) 1523 1541 return s 1524 1542 end]; ................................................................................ 1587 1605 1588 1606 post_fetch = [terra( 1589 1607 src: &lib.store.source, 1590 1608 post: uint64 1591 1609 ): lib.mem.ptr(lib.store.post) 1592 1610 var r = queries.post_fetch.exec(src, post) 1593 1611 if r.sz == 0 then return [lib.mem.ptr(lib.store.post)].null() end 1612 + defer r:free() 1594 1613 var p = row_to_post(&r, 0) 1595 1614 p.ptr.source = src 1596 1615 return p 1597 1616 end]; 1598 1617 1599 1618 post_act_cancel = [terra( 1600 1619 src: &lib.store.source, ................................................................................ 1646 1665 r = queries.timeline_instance_fetch.exec(src,A,B,C,D) 1647 1666 1648 1667 var ret: lib.mem.ptr(lib.mem.ptr(lib.store.post)) ret:init(r.sz) 1649 1668 for i=0,r.sz do 1650 1669 ret.ptr[i] = row_to_post(&r, i) -- MUST FREE ALL 1651 1670 ret.ptr[i].ptr.source = src 1652 1671 end 1672 + r:free() 1653 1673 1654 1674 return ret 1655 1675 end]; 1656 1676 1657 1677 timeline_circle_fetch = [terra( 1658 1678 src: &lib.store.source, 1659 1679 cid: uint64, ................................................................................ 1664 1684 r = queries.timeline_circle_fetch.exec(src,cid,A,B,C,D) 1665 1685 1666 1686 var ret: lib.mem.ptr(lib.mem.ptr(lib.store.post)) ret:init(r.sz) 1667 1687 for i=0,r.sz do 1668 1688 ret.ptr[i] = row_to_post(&r, i) -- MUST FREE ALL 1669 1689 ret.ptr[i].ptr.source = src 1670 1690 end 1691 + r:free() 1671 1692 1672 1693 return ret 1673 1694 end]; 1674 1695 1675 1696 timeline_actor_fetch_uid = [terra( 1676 1697 src: &lib.store.source, 1677 1698 uid: uint64, ................................................................................ 1682 1703 r = queries.timeline_actor_fetch.exec(src,uid,A,B,C,D) 1683 1704 1684 1705 var ret: lib.mem.ptr(lib.mem.ptr(lib.store.post)) ret:init(r.sz) 1685 1706 for i=0,r.sz do 1686 1707 ret.ptr[i] = row_to_post(&r, i) -- MUST FREE ALL 1687 1708 ret.ptr[i].ptr.source = src 1688 1709 end 1710 + r:free() 1689 1711 1690 1712 return ret 1691 1713 end]; 1692 1714 1693 1715 post_enum_author_uid = [terra( 1694 1716 src: &lib.store.source, 1695 1717 uid: uint64, ................................................................................ 1700 1722 r = queries.post_enum_author_uid.exec(src,A,B,C,D,uid) 1701 1723 1702 1724 var ret: lib.mem.ptr(lib.mem.ptr(lib.store.post)) ret:init(r.sz) 1703 1725 for i=0,r.sz do 1704 1726 ret.ptr[i] = row_to_post(&r, i) -- MUST FREE ALL 1705 1727 ret.ptr[i].ptr.source = src 1706 1728 end 1729 + r:free() 1707 1730 1708 1731 return ret 1709 1732 end]; 1710 1733 1711 1734 actor_powers_fetch = getpow; 1712 1735 actor_save = [terra( 1713 1736 src: &lib.store.source, ................................................................................ 1732 1755 ac.id = r:int(uint64,0,0) 1733 1756 1734 1757 -- check against default rights, insert records for wherever powers differ 1735 1758 lib.dbg('created new actor, establishing powers') 1736 1759 privupdate(src,ac) 1737 1760 1738 1761 lib.dbg('powers established') 1762 + r:free() 1739 1763 return ac.id 1740 1764 end]; 1741 1765 1742 1766 actor_rel_create = [terra( 1743 1767 src: &lib.store.source, 1744 1768 kind: uint16, 1745 1769 relator: uint64, ................................................................................ 1818 1842 1819 1843 auth_fetch_aid = [terra( 1820 1844 src: &lib.store.source, 1821 1845 aid: uint64 1822 1846 ): lib.mem.ptr(lib.store.auth) 1823 1847 var r = queries.auth_fetch_aid.exec(src,aid) 1824 1848 if r.sz == 0 then return [lib.mem.ptr(lib.store.auth)].null() end 1849 + defer r:free() 1825 1850 var kind = r:_string(0, 2) 1826 1851 var comment = r:_string(0, 3) 1827 1852 var a = [ lib.str.encapsulate(lib.store.auth, { 1828 1853 kind = {`kind.ptr, `kind.ct+1}; 1829 1854 comment = {`comment.ptr, `comment.ct+1}; 1830 1855 }) ] 1831 1856 a.ptr.aid = r:int(uint64, 0, 0) ................................................................................ 1840 1865 1841 1866 auth_enum_uid = [terra( 1842 1867 src: &lib.store.source, 1843 1868 uid: uint64 1844 1869 ): lib.mem.lstptr(lib.store.auth) 1845 1870 var r = queries.auth_enum_uid.exec(src,uid) 1846 1871 if r.sz == 0 then return [lib.mem.lstptr(lib.store.auth)].null() end 1872 + defer r:free() 1847 1873 var ret = lib.mem.heapa([lib.mem.ptr(lib.store.auth)], r.sz) 1848 1874 for i=0, r.sz do 1849 1875 var kind = r:_string(i, 1) 1850 1876 var comment = r:_string(i, 2) 1851 1877 var a = [ lib.str.encapsulate(lib.store.auth, { 1852 1878 kind = {`kind.ptr, `kind.ct+1}; 1853 1879 comment = {`comment.ptr, `comment.ct+1}; ................................................................................ 2004 2030 2005 2031 artifact_enum_uid = [terra( 2006 2032 src: &lib.store.source, 2007 2033 uid: uint64, 2008 2034 folder: pstring 2009 2035 ) 2010 2036 var res = queries.artifact_enum_uid.exec(src,uid,folder) 2011 - if res.sz > 0 then 2037 + if res.sz > 0 then defer res:free() 2012 2038 var m = lib.mem.heapa([lib.mem.ptr(lib.store.artifact)], res.sz) 2013 2039 for i=0,res.sz do 2014 2040 m.ptr[i] = row_to_artifact(&res, i) 2015 2041 m(i).ptr.owner = uid 2016 2042 end 2017 2043 return m 2018 2044 else return [lib.mem.lstptr(lib.store.artifact)].null() end ................................................................................ 2160 2186 actor_conf_str_enum = nil; 2161 2187 actor_conf_str_get = [terra( 2162 2188 src: &lib.store.source, 2163 2189 pool: &lib.mem.pool, 2164 2190 uid: uint64, 2165 2191 key: pstring 2166 2192 ): pstring 2167 - var r = queries.actor_conf_str_get.exec(src, uid, key) 2168 - if r.sz > 0 then 2169 - return r:_string(0,0):pdup(pool) 2170 - else return pstring.null() end 2171 - end]; 2193 + var r = queries.actor_conf_str_get.exec(src, uid, key) 2194 + if r.sz > 0 then defer r:free() 2195 + return r:_string(0,0):pdup(pool) 2196 + else return pstring.null() end 2197 + end]; 2172 2198 actor_conf_str_set = [terra(src: &lib.store.source, uid: uint64, key: pstring, value: pstring): {} 2173 - queries.actor_conf_str_set.exec(src,uid,key,value) end]; 2199 + queries.actor_conf_str_set.exec(src,uid,key,value) end]; 2174 2200 actor_conf_str_reset = [terra(src: &lib.store.source, uid: uint64, key: pstring): {} 2175 - queries.actor_conf_str_reset.exec(src,uid,key) end]; 2201 + queries.actor_conf_str_reset.exec(src,uid,key) end]; 2176 2202 2177 2203 actor_conf_int_enum = nil; 2178 2204 actor_conf_int_get = [terra(src: &lib.store.source, uid: uint64, key: pstring) 2179 2205 var r = queries.actor_conf_int_get.exec(src, uid, key) 2180 2206 if r.sz > 0 then 2181 2207 var ret = r:int(uint64,0,0) 2182 2208 r:free()
Modified convo.t from [ff68c1adfe] to [5c6e342d23].
14 14 method: lib.http.method.t 15 15 live_last: lib.store.timepoint 16 16 uploads: lib.mem.vec(lib.http.upload) 17 17 body: pstring 18 18 -- cache 19 19 ui_hue: uint16 20 20 navbar: pstring 21 - actorcache: lib.mem.cache(lib.mem.ptr(lib.store.actor),32) -- naive cache to avoid unnecessary queries 21 + actorcache: lib.mem.cache(lib.mem.ptr(lib.store.actor),32,true) -- naive cache to avoid unnecessary queries 22 22 -- private 23 23 varbuf: pstring 24 24 vbofs: &int8 25 25 } 26 26 27 27 struct convo.page { 28 28 title: pstring
Modified mem.t from [d10508934e] to [8aa8839430].
15 15 local p = m.ptr(ty:astype()) 16 16 return `p { 17 17 ptr = [&ty:astype()](m.heapa_raw(sizeof(ty) * sz)); 18 18 ct = sz; 19 19 } 20 20 end) 21 21 22 -function m.cache(ty,sz) 22 +function m.cache(ty,sz,autofree) 23 23 sz = sz or 32 24 24 local struct c { 25 25 store: ty[sz] 26 26 top: intptr 27 27 cur: intptr 28 28 } 29 29 c.name = string.format('cache<%s,%u>', tostring(ty), sz) ................................................................................ 33 33 end 34 34 self.store[self.cur] = v 35 35 self.top = lib.math.biggest(self.top, self.cur + 1) 36 36 self.cur = (self.cur + 1) % sz 37 37 return v 38 38 end 39 39 c.metamethods.__apply = terra(self: &c, idx: intptr) return &self.store[idx] end 40 - if ty.ptr_basetype then 40 + if autofree then 41 41 terra c:free() 42 42 for i=0,self.top do self.store[i]:free() end 43 43 end 44 44 end 45 45 return c 46 46 end 47 47
Modified mgtool.t from [aa223ca2fb] to [f2643e6a8b].
54 54 55 55 all: bool 56 56 src: &lib.store.source 57 57 srv: &lib.srv.overlord 58 58 59 59 sid: uint64 60 60 iname: rawstring 61 + 62 + cfgpool: lib.mem.pool 61 63 } 62 64 idelegate.metamethods.__methodmissing = macro(function(meth, self, ...) 63 65 local expr = {...} 64 66 local rt 65 67 66 68 for _,f in pairs(lib.store.backend.entries) do 67 69 local fn = f.field or f[1] ................................................................................ 74 76 if self.all or (self.srv ~= nil and self.srv.sources.ct == 1) 75 77 then r=self.srv:[meth]([expr]) 76 78 elseif self.src ~= nil then r=self.src:[meth]([expr]) 77 79 else lib.bail('no data source specified') 78 80 end 79 81 in r end 80 82 end) 83 + 84 +terra idelegate:conf(key: lib.str.t) 85 + return self:conf_get(&self.cfgpool, key) 86 +end 81 87 82 88 terra idelegate:ipc_send(cmd: lib.ipc.cmd.t, operand: uint64) 83 89 var emp = self.emperor 84 90 var acks: lib.mem.ptr(lib.ipc.ack) 85 91 if self.sid == 0 and self.iname == nil then 86 92 if not self.all and emp:countpeers() > 1 then 87 93 lib.bail('either specify the instance to control or pass --all to control all instances') ................................................................................ 155 161 [lib.init] 156 162 157 163 var srv: lib.srv.overlord 158 164 var dlg = idelegate { 159 165 emperor = &emp, srv = &srv; 160 166 src = nil, sid = 0, iname = nil, all = false; 161 167 } 168 + dlg.cfgpool:init(128) 162 169 163 170 var mode: ctloptions 164 171 mode:parse(argc,argv) defer mode:free() 165 172 if mode.version then version() return 0 end 166 173 if mode.help then 167 174 [ lib.emit(false, 1, 'usage: ', `argv[0], ' ', ctloptions.helptxt.flags, ' <cmd> [<args>…]', ctloptions.helptxt.opts, cmdhelp(ctlcmds)) ] 168 175 return 0 ................................................................................ 378 385 if lib.str.cmp(mode.arglist(0),'mkroot') == 0 then 379 386 var cfmode: pbasic cfmode:parse(mode.arglist.ct, &mode.arglist(0)) 380 387 if cfmode.help then 381 388 [ lib.emit(false, 1, 'usage: ', `argv[0], ' mkroot ', cfmode.type.helptxt.flags, ' <handle>', cfmode.type.helptxt.opts) ] 382 389 return 1 383 390 end 384 391 if cfmode.arglist.ct == 1 then 385 - var am = dlg:conf_get('credential-store') 392 + var am = dlg:conf('credential-store') 386 393 var mg: bool 387 394 if (not am) or am:cmp('managed') then 388 395 mg = true 389 396 elseif am:cmp('unmanaged') then 390 397 lib.warn('credential store is unmanaged; you will need to create credentials for the new root user manually!') 391 398 mg = false 392 399 else lib.bail('unknown credential store mode "',{am.ptr,am.ct},'"; should be either "managed" or "unmanaged"') end
Modified mime.t from [8a0a5cf230] to [16ec90c72f].
56 56 if type(ty.id) == 'string' then ty.id = {ty.id} end 57 57 for i, mime in ipairs(ty.id) do 58 58 idcache[mime] = ty 59 59 end 60 60 61 61 local op = lib.http.mime[typecode] 62 62 if op == nil then op = lib.http.mime.none end 63 - print(typecode,op) 64 63 65 64 ty.offset = #typestore 66 65 typestore[#typestore + 1] = `mime { 67 66 key = typecode; 68 67 canonical = [ty.id[1]]; 69 68 safe = [not ty.unsafe]; 70 69 ext = [ty.ext or `pstr{nil,0}]; ................................................................................ 96 95 type = mime; 97 96 types = knowntypes; 98 97 tbl = idcache; 99 98 typedex = typedex; 100 99 lookup = terra(m: pstr): &mime 101 100 for i=0, [#typemap_l] do 102 101 if m:cmp(typemap[i].string) then 103 - lib.io.fmt('returning type %s %u\n', typemap[i].type.key, typemap[i].type.output) 104 102 return typemap[i].type 105 103 end 106 104 end 107 105 return nil 108 106 end; 109 107 }
Modified parsav.t from [3c7c1240d3] to [584b173afe].
640 640 elseif d.cmd == lib.ipc.cmd.enumerate then 641 641 if srv.id ~= nil then 642 642 lib.str.ncpy(&a.iname[0], srv.id, [(`a.iname).tree.type.N]) 643 643 else a.iname[0] = 0 end 644 644 elseif d.cmd == lib.ipc.cmd.chnoise then 645 645 lib.noise.level = d.operand 646 646 elseif d.cmd == lib.ipc.cmd.cfgrefresh then 647 - srv.cfg:free() 647 + srv.cfg:purge() 648 648 srv.cfg:load() 649 649 end 650 650 d:ack(&lib.ipc.global_emperor, &a) 651 651 end 652 652 end 653 653 srv:shutdown() 654 654
Modified route.t from [1bb0eb41f3] to [5d2607bf9b].
517 517 return quote 518 518 var [me] 519 519 [check] 520 520 in [me] end 521 521 end)()] 522 522 if privs:sz() > 0 then 523 523 lib.dbg('installing credential restrictions') 524 - lib.io.fmt('on priv %llu\n',aid) 525 524 co.srv:auth_privs_set(aid, privs) 526 525 end 527 526 528 527 lib.dbg('setting netmask restrictions') 529 528 var nm = co:pgetv('netmask') 530 529 end 531 530 co:reroute('?') ................................................................................ 905 904 end 906 905 end 907 906 908 907 909 908 terra http.local_avatar(co: &lib.srv.convo, handle: lib.mem.ptr(int8)) 910 909 -- TODO retrieve user avatars 911 910 var usr = co.srv:actor_fetch_xid(handle) 912 - if not usr then 913 - goto default end 914 - if usr(0).origin == 0 then 915 - if usr(0).avatarid == 0 then goto default end 916 - var avi, mime = co.srv:artifact_load(usr(0).avatarid) 917 - if not avi then goto default end 918 - defer avi:free() defer mime:free() 919 - co:bytestream(mime,avi) 920 - else 921 - co:reroute(usr(0).avatar) 922 - end 923 - do return end 911 + if not usr then goto default end 912 + do defer usr:free() 913 + if usr(0).origin == 0 then 914 + if usr(0).avatarid == 0 then goto default end 915 + var avi, mime = co.srv:artifact_load(usr(0).avatarid) 916 + if not avi then goto default end 917 + defer avi:free() defer mime:free() 918 + co:bytestream(mime,avi) 919 + else 920 + co:reroute(usr(0).avatar) 921 + end 922 + return end 924 923 ::default:: co:reroute('/s/default-avatar.webp') 925 924 end 926 925 927 926 terra http.file_serve_raw(co: &lib.srv.convo, id: lib.mem.ptr(int8)) 928 927 var id, idok = lib.math.shorthand.parse(id.ptr, id.ct) 929 928 if not idok then goto e404 end 930 929 var data, mime = co.srv:artifact_load(id)
Modified session.t from [c79e9ffb10] to [15e824caf3].
22 22 [lib.mem.ptr(uint8)] {ptr = [&uint8](secret.ptr), ct = secret.ct}, 23 23 [lib.mem.ptr( int8)] {ptr = out, ct = len}, 24 24 &hash[0]) 25 25 ptr = ptr + lib.math.shorthand.gen(lib.math.truncate64(hash, [hash.type.N]), ptr) 26 26 return ptr - out 27 27 end 28 28 29 -terra m.cookie_interpret(secret: lib.mem.ptr(int8), c: lib.mem.ptr(int8), now: uint64) -- returns either 0,0 or a valid {authid, timepoint} 30 - var authid_sz = lib.str.cspan(c.ptr, lib.str.lit '.', c.ct) 29 +terra m.cookie_interpret(secret: lib.mem.ptr(int8), c: lib.mem.ptr(int8), now: uint64) 30 + -- returns either 0,0 or a valid {authid, timepoint} 31 + var authid_sz = lib.str.cspan(c.ptr, '.', c.ct) 31 32 if authid_sz == 0 then return 0,0 end 32 33 if authid_sz + 1 > c.ct then return 0,0 end 33 - var time_sz = lib.str.cspan(c.ptr+authid_sz+1, lib.str.lit '.', c.ct - (authid_sz+1)) 34 + var time_sz = lib.str.cspan(c.ptr+authid_sz+1, '.', c.ct - (authid_sz+1)) 34 35 if time_sz == 0 then return 0,0 end 35 36 if (authid_sz + time_sz + 2) > c.ct then return 0,0 end 36 37 var hash_sz = c.ct - (authid_sz + time_sz + 2) 37 38 38 39 var knownhash: uint8[lib.crypt.algsz.sha256] 39 40 lib.crypt.hmac(lib.crypt.alg.sha256, 40 41 [lib.mem.ptr(uint8)] {ptr = [&uint8](secret.ptr), ct = secret.ct},
Modified srv.t from [dafa2dc374] to [1938b717c7].
1 1 -- vim: ft=terra 2 2 local util = lib.util 3 3 local secmode = lib.enum { 'public', 'private', 'lockdown', 'isolate' } 4 4 local pstring = lib.mem.ptr(int8) 5 5 6 6 local struct srv 7 7 local struct cfgcache { 8 + _pool: lib.mem.pool 8 9 secret: pstring 9 10 pol_sec: secmode.t 10 11 pol_reg: bool 11 12 pol_autoherald: bool 12 13 credmgd: bool 13 14 maxupsz: intptr 14 15 poolinitsz: intptr ................................................................................ 30 31 webmgr: lib.net.mg_mgr 31 32 webcon: &lib.net.mg_connection 32 33 cfg: cfgcache 33 34 id: rawstring 34 35 pool: lib.mem.pool 35 36 } 36 37 37 -terra cfgcache:free() -- :/ TODO replace with pool 38 - self.secret:free() 39 - self.instance:free() 40 - self.domain:free() 41 - self.ui_cue_staff:free() 42 - self.ui_cue_founder:free() 43 - self.usrdef_pol_follow:free() 44 - self.usrdef_pol_follow_req:free() 38 +terra cfgcache:purge() 39 + self._pool:clear() 40 +end 41 + 42 +terra cfgcache:free() 43 + self._pool:free() 45 44 end 46 45 47 46 terra srv:post_enum_author_uid(uid: uint64, r: lib.store.range): lib.mem.vec(lib.mem.ptr(lib.store.post)) 48 47 var all: lib.mem.vec(lib.mem.ptr(lib.store.post)) all:init(64) 49 48 for i=0,self.sources.ct do var src = self.sources.ptr + i 50 49 if src.handle ~= nil and src.backend.timeline_instance_fetch ~= nil then 51 50 var lst = src:post_enum_author_uid(uid,r) ................................................................................ 375 374 co:complain(400,'bad request','unrecognized content-type') 376 375 goto fail 377 376 end 378 377 var boundary = pstring {ptr=p+9,ct=ctt.ct - ((p - ctt.ptr) + 9)} 379 378 co.method = lib.http.method.post_file 380 379 co.uploads:init(8) 381 380 382 - var bsr = (lib.str.acc{}):compose('\r\n--',boundary,'\r\n'):finalize() 381 + var bsr = co:qstr('\r\n--',boundary,'\r\n') 383 382 384 383 var upmap = lib.str.splitmap(co.body,bsr,8) 385 384 -- first entry may not be preceded by header-break 386 385 if lib.str.find(upmap(0), pstring { 387 386 ptr = bsr.ptr + 2, ct = bsr.ct - 2 388 387 }):ref() then 389 388 upmap(0).ptr = upmap(0).ptr + (bsr.ct - 2) ................................................................................ 451 450 nextup.field = fld 452 451 nextup.filename = file 453 452 end 454 453 end 455 454 end 456 455 end 457 456 end 458 - bsr:free() 459 457 upmap:free() 460 458 end 461 459 end 462 460 end 463 461 464 - var mtt = lib.http.mime._str(co.reqtype) 465 - lib.dbg('routing with negotiated type of ', {mtt.ptr,mtt.ct}) 466 462 route.dispatch_http(&co, uri) 467 463 468 464 ::fail:: 469 465 if co.uploads.run > 0 then 470 466 for i=0,co.uploads.sz do 471 467 co.uploads(i).filename:free() 472 468 co.uploads(i).field:free() ................................................................................ 654 650 -- 655 651 -- return 0 656 652 --end 657 653 658 654 terra cfgcache.methods.load :: {&cfgcache} -> {} 659 655 terra cfgcache:init(o: &srv) 660 656 self.overlord = o 657 + self._pool:init(256) 661 658 self:load() 662 659 end 663 660 664 661 terra srv:setup(befile: rawstring) 665 662 cfg(self, befile) 666 663 var success = false 667 664 if self.sources.ct == 0 then lib.bail('no data sources specified') end ................................................................................ 675 672 end 676 673 end 677 674 678 675 terra srv:start(iname: rawstring) 679 676 self:conprep(lib.store.prepmode.full) 680 677 self.cfg:init(self) 681 678 self.pool:init(self.cfg.poolinitsz) 682 - var dbbind = self:conf_get('bind') 679 + var dbbind = self:conf_get(&self.pool, 'bind') 683 680 if iname == nil then iname = lib.proc.getenv('parsav_instance') end 684 681 if iname == nil then 685 682 self.id = self.cfg.instance.ptr; 686 683 -- let this leak -- it'll be needed for the lifetime of the process anyway 687 684 else self.id = iname end 688 685 689 686 if iname ~= nil then ................................................................................ 698 695 bind = dbbind.ptr 699 696 else bind = '[::1]:10917' end 700 697 701 698 lib.report('binding to ', bind) 702 699 lib.net.mg_mgr_init(&self.webmgr) 703 700 self.webcon = lib.net.mg_http_listen(&self.webmgr, bind, handle.http, self) 704 701 705 - if dbbind.ptr ~= nil then dbbind:free() end 702 + --if dbbind.ptr ~= nil then dbbind:free() end 706 703 end 707 704 708 705 terra srv:poll() 709 706 lib.net.mg_mgr_poll(&self.webmgr,300) 710 707 end 711 708 712 709 terra srv:shutdown() ................................................................................ 715 712 lib.report('closing data source ', src.id.ptr, '(', src.backend.id, ')') 716 713 src:close() 717 714 end 718 715 self.sources:free() 719 716 self.pool:free() 720 717 end 721 718 722 -terra cfgcache:cfint(name: rawstring, default: intptr) 723 - var str = self.overlord:conf_get(name) 719 +terra cfgcache:cfstr(name: pstring) 720 + return self.overlord:conf_get(&self._pool, name) 721 +end 722 + 723 +terra cfgcache:cfint(name: pstring, default: intptr) 724 + var f = self._pool:frame() 725 + var str = self:cfstr(name) 726 + defer self._pool:reset(f) 724 727 if str.ptr ~= nil then 725 728 var i,ok = lib.math.decparse(str) 726 729 if ok then default = i else 727 - lib.warn('invalid configuration setting ',name,'="',{str.ptr,str.ct},'", expected integer; using default value instead') 730 + lib.warn('invalid configuration setting ',{name.ptr,name.ct},'="',{str.ptr,str.ct},'", expected integer; using default value instead') 728 731 end 729 - str:free() 730 732 end 731 733 return default 732 734 end 733 735 734 -terra cfgcache:cffsz(name: rawstring, default: intptr) 735 - var str = self.overlord:conf_get(name) 736 +terra cfgcache:cffsz(name: pstring, default: intptr) 737 + var f = self._pool:frame() 738 + var str = self:cfstr(name) 739 + defer self._pool:reset(f) 736 740 if str:ref() then 737 741 var sz, ok = lib.math.fsz_parse(str) 738 742 if ok then default = sz else 739 - lib.warn('invalid configuration setting ',name,'="',{str.ptr,str.ct},'", expected byte length; using default value instead') 743 + lib.warn('invalid configuration setting ',{name.ptr,name.ct},'="',{str.ptr,str.ct},'", expected byte length; using default value instead') 740 744 end 741 - str:free() 742 745 end 743 746 return default 744 747 end 745 748 746 -terra cfgcache:cfbool(name: rawstring, default: bool) 747 - var str = self.overlord:conf_get(name) 749 +terra cfgcache:cfbool(name: pstring, default: bool) 750 + var f = self._pool:frame() 751 + var str = self:cfstr(name) 752 + defer self._pool:reset(f) 748 753 if str.ptr ~= nil then 749 754 if str:cmp('true') or str:cmp('on') or 750 755 str:cmp('yes') or str:cmp('1') then 751 756 default = true 752 757 elseif str:cmp('false') or str:cmp('off') or 753 758 str:cmp('no') or str:cmp('0') then 754 759 default = false 755 760 else 756 - lib.warn('invalid configuration setting ',name,'="',{str.ptr,str.ct},'", expected boolean; using default value instead') 761 + lib.warn('invalid configuration setting ',{name.ptr,name.ct},'="',{str.ptr,str.ct},'", expected boolean; using default value instead') 757 762 end 758 - str:free() 759 763 end 760 764 return default 761 765 end 762 766 763 767 terra cfgcache:load() 764 - self.instance = self.overlord:conf_get('instance-name') 765 - self.domain = self.overlord:conf_get('domain') 766 - self.secret = self.overlord:conf_get('server-secret') 768 + 769 + self.instance = self:cfstr('instance-name') 770 + self.domain = self:cfstr('domain') 771 + self.secret = self:cfstr('server-secret') 767 772 768 773 self.pol_reg = self:cfbool('policy-self-register', false) 769 774 self.pol_autoherald = self:cfbool('policy-self-herald', true) 770 775 771 776 do self.credmgd = false 772 - var sreg = self.overlord:conf_get('credential-store') 777 + var fr = self._pool:frame() 778 + var sreg = self:cfstr('credential-store') 773 779 if sreg:ref() then 774 780 if lib.str.cmp(sreg.ptr, 'managed') == 0 775 781 then self.credmgd = true 776 782 else self.credmgd = false 777 783 end 778 - sreg:free() 784 + self._pool:reset(fr) 779 785 end end 780 786 781 787 self.maxupsz = self:cffsz('maximum-artifact-size', [1024 * 100]) -- 100 kilobyte default 782 788 self.poolinitsz = self:cffsz('server-pool-size-initial', [1024 * 10]) -- 10 kilobyte default 783 789 784 790 self.pol_sec = secmode.lockdown 785 - var smode = self.overlord:conf_get('policy-security') 791 + do var fr = self._pool:frame() 792 + var smode = self:cfstr('policy-security') 786 793 if smode.ptr ~= nil then 787 794 if lib.str.cmp(smode.ptr, 'public') == 0 then 788 795 self.pol_sec = secmode.public 789 796 elseif lib.str.cmp(smode.ptr, 'private') == 0 then 790 797 self.pol_sec = secmode.private 791 798 elseif lib.str.cmp(smode.ptr, 'lockdown') == 0 then 792 799 self.pol_sec = secmode.lockdown 793 800 elseif lib.str.cmp(smode.ptr, 'isolate') == 0 then 794 801 self.pol_sec = secmode.isolate 795 802 end 796 - smode:free() 797 - end 803 + self._pool:reset(fr) 804 + end end 798 805 799 806 self.ui_hue = self:cfint('ui-accent',config.default_ui_accent) 800 807 self.nranks = self:cfint('user-ranks',10) 801 808 self.maxinvites = self:cfint('max-invites',64) 802 809 803 - var webmaster = self.overlord:conf_get('master') 804 - if webmaster:ref() then defer webmaster:free() 810 + do var fr = self._pool:frame() 811 + var webmaster = self:cfstr('master') 812 + defer self._pool:reset(fr) 813 + if webmaster:ref() then 805 814 var wma = self.overlord:actor_fetch_xid(webmaster) 806 815 if not wma then 807 816 lib.warn('the webmaster specified in the configuration store does not seem to exist or is not known to this instance; preceding as if no master defined. if the master is a remote user, you can rectify this with the `actor "',{webmaster.ptr,webmaster.ct},'" instantiate` and `conf refresh` commands') 808 817 else 809 818 self.master = wma(0).id 810 819 wma:free() 811 820 end 812 - end 821 + end end 813 822 814 - self.ui_cue_staff = self.overlord:conf_get('ui-profile-cue-staff') 815 - self.ui_cue_founder = self.overlord:conf_get('ui-profile-cue-master') 823 + self.ui_cue_staff = self:cfstr('ui-profile-cue-staff') 824 + self.ui_cue_founder = self:cfstr('ui-profile-cue-master') 816 825 817 - self.usrdef_pol_follow = self.overlord:conf_get('user-default-acl-follow') 818 - self.usrdef_pol_follow_req = self.overlord:conf_get('user-default-acl-follow-req') 826 + self.usrdef_pol_follow = self:cfstr('user-default-acl-follow') 827 + self.usrdef_pol_follow_req = self:cfstr('user-default-acl-follow-req') 819 828 end 820 829 821 830 return { 822 831 overlord = srv; 823 832 convo = convo; 824 833 route = route; 825 834 secmode = secmode; 826 835 }
Modified store.t from [6e43eba049] to [54bd5bc381].
372 372 -- these two functions are special, in that they should be called 373 373 -- directly on a specific backend, rather than passed down to the 374 374 -- backends by the server; that is pathological behavior that will 375 375 -- not have the desired effect 376 376 377 377 server_setup_self: {&m.source, rawstring, lib.mem.ptr(uint8)} -> {} 378 378 379 - conf_get: {&m.source, lib.str.t} -> lib.mem.ptr(int8) 379 + conf_get: {&m.source, &lib.mem.pool, lib.str.t} -> lib.mem.ptr(int8) 380 380 conf_set: {&m.source, lib.str.t, lib.str.t} -> {} 381 381 conf_reset: {&m.source, rawstring} -> {} 382 382 383 383 actor_create: {&m.source, &m.actor} -> uint64 384 384 actor_save: {&m.source, &m.actor} -> {} 385 385 actor_save_privs: {&m.source, &m.actor} -> {} 386 386 actor_purge_uid: {&m.source, uint64} -> {}