Commit Diff


commit - 3281ec97b6c959eef4aee8593b1f58a12dbbc56e
commit + fc91d0f1e89a9791833c0937147039f7009ca706
blob - 3e84a31ee7ee6d92626fd8c07440e037e843aaa5
blob + 9a9c3d661b475c86272bad8c4d122c0e8ca9f175
--- README.txt
+++ README.txt
@@ -11,9 +11,9 @@ PmWiki is distributed with the following directories:

   pub/guiedit/    Files for the Edit Form's GUIEdit module

   scripts/        Scripts that are part of PmWiki

   wikilib.d/      Bundled wiki pages, including

-                    * a default Home Page

-                    * PmWiki documentation pages

-                    * some Site-oriented pages

+                  * a default Home Page

+                  * PmWiki documentation pages

+                  * Site-oriented interface and configuration pages

 

 After PmWiki is installed the following directories may also exist:

 

@@ -23,16 +23,19 @@ After PmWiki is installed the following directories ma
 For quick installation advice, see docs/INSTALL.txt.

 

 For more extensive information about installing PmWiki, visit

-  http://pmwiki.org/wiki/PmWiki/Installation

+  https://pmwiki.org/wiki/PmWiki/Installation

 

 For information about running PmWiki in standalone mode without

 requiring a webserver, visit

-  http://pmwiki.org/wiki/Cookbook/Standalone

+  https://pmwiki.org/wiki/Cookbook/Standalone

 

-PmWiki is Copyright 2001-2006 Patrick R. Michaud

+PmWiki is Copyright 2001-2022 Patrick R. Michaud

 pmichaud@pobox.com

-http://www.pmichaud.com/

+https://www.pmichaud.com/

 

+Since 2009, PmWiki has been maintained and updated 

+by Petko Yotov 5ko@5ko.fr, https://www.pmwiki.org/petko

+

 This program 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; either version 2 of the License, or

@@ -45,4 +48,4 @@ GNU General Public License for more details.

 

 The GNU General Public License is distributed with this program

 (see docs/COPYING.txt) and it is also available online at

-http://www.fsf.org/licensing/licenses/gpl.txt .

+https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt .

blob - bc37dceaf3e969016b15d37c9e153b4d389f2c66
blob + 39b3e8253f3e738aa8648d28c61df6e8dd2a74f3
--- docs/DOCUMENTATION.txt
+++ docs/DOCUMENTATION.txt
@@ -6,5 +6,5 @@ the documentation is available through PmWiki itself -
 see the "PmWiki.DocumentationIndex" page on your site.

 

 The documentation is also available online at

-http://www.pmwiki.org/wiki/PmWiki/DocumentationIndex .

+https://www.pmwiki.org/wiki/PmWiki/DocumentationIndex .

 

blob - 41dd12e608a87258a0df253631739e0d89c8f72b
blob + 125adaaaf2a542554acb312b8c3e6a6ac9cb3626
--- docs/INSTALL.txt
+++ docs/INSTALL.txt
@@ -1,7 +1,7 @@
 This is the INSTALL.txt file for PmWiki.  This document provides

 convenient steps so an administrator can have a PmWiki site up and

 running quickly.  More extensive information about installing PmWiki

-is available at http://www.pmwiki.org/wiki/PmWiki/Installation .

+is available at https://www.pmwiki.org/wiki/PmWiki/Installation .

 

 Once your site is up and running you will be able to read the bundled

 documentation pages.

@@ -12,7 +12,7 @@ customized installation:

 1a) Put the software in a location accessible by your webserver.

 

 1b) PmWiki can also be run if no webserver is installed.  See

-    http://pmwiki.org/wiki/Cookbook/Standalone

+    https://pmwiki.org/wiki/Cookbook/Standalone

 

 2) Point your browser to pmwiki.php.

 

blob - d8a70b6d428f0c7b66fffef8a49b2c7fbace5e44
blob + 82ea6ef095ebae8bdd5f7677642e9c11abdb97ef
--- docs/UPGRADE.txt
+++ docs/UPGRADE.txt
@@ -2,12 +2,12 @@ This UPGRADE.txt file is a command-line syntax reminde
 experienced PmWiki administrators.  For full documentation on

 upgrading Pmwiki, see the bundled PmWiki.Upgrades page or visit

 

-  http://www.pmwiki.org/wiki/PmWiki/Upgrades

+  https://www.pmwiki.org/wiki/PmWiki/Upgrades

 

 See also these related pages:

 

-  http://www.pmwiki.org/wiki/PmWiki/BackupAndRestore

-  http://www.pmwiki.org/wiki/PmWiki/Subversion

+  https://www.pmwiki.org/wiki/PmWiki/BackupAndRestore

+  https://www.pmwiki.org/wiki/PmWiki/Subversion

 

 The examples assume your PmWiki site is in a ./pmwiki/

 directory (a directory named "pmwiki" immediately below the

@@ -25,15 +25,15 @@ Or, to keep backups organized by date:

 

 The latest release is available here:

 

-  http://www.pmwiki.org/pub/pmwiki/pmwiki-latest.tgz

-  http://www.pmwiki.org/pub/pmwiki/pmwiki-latest.zip

+  https://www.pmwiki.org/pub/pmwiki/pmwiki-latest.tgz

+  https://www.pmwiki.org/pub/pmwiki/pmwiki-latest.zip

 

 Example download commands:

 

-  wget http://www.pmwiki.org/pub/pmwiki/pmwiki-latest.tgz

-  lftpget http://www.pmwiki.org/pub/pmwiki/pmwiki-latest.tgz

-  links http://www.pmwiki.org/pub/pmwiki/pmwiki-latest.tgz

-  lynx http://www.pmwiki.org/pub/pmwiki/pmwiki-latest.tgz

+  wget https://www.pmwiki.org/pub/pmwiki/pmwiki-latest.tgz

+  lftpget https://www.pmwiki.org/pub/pmwiki/pmwiki-latest.tgz

+  links https://www.pmwiki.org/pub/pmwiki/pmwiki-latest.tgz

+  lynx https://www.pmwiki.org/pub/pmwiki/pmwiki-latest.tgz

 

 Expanding the archive:

 

blob - 5fedcdf2da597d8c339de56196864c6cd8e3fa45
blob + fdc7482af8a707957d907b8d41b8226da58ab29c
--- docs/sample-config.php
+++ docs/sample-config.php
@@ -20,29 +20,29 @@ $WikiTitle = 'PmWiki';
 ##  details about this setting and other ways to create nicer-looking urls.
 # $EnablePathInfo = 1;
 
-## $PageLogoUrl is the URL for a logo image -- you can change this
-## to your own logo if you wish.
+##  $PageLogoUrl is the URL for a logo image -- you can change this
+##  to your own logo if you wish.
 # $PageLogoUrl = "$PubDirUrl/skins/pmwiki/pmwiki-32.gif";
 
-## If you want to have a custom skin, then set $Skin to the name
-## of the directory (in pub/skins/) that contains your skin files.
-## See PmWiki.Skins and Cookbook.Skins.
-# $Skin = 'pmwiki-responsive';
+##  If you want to have a custom skin, then set $Skin to the name
+##  of the directory (in pub/skins/) that contains your skin files.
+##  See PmWiki.Skins and Cookbook.Skins.
+$Skin = 'pmwiki-responsive';
 
-## You'll probably want to set an administrative password that you
-## can use to get into password-protected pages.  Also, by default
-## the "attr" passwords for the PmWiki and Main groups are locked, so
-## an admin password is a good way to unlock those.  See PmWiki.Passwords
-## and PmWiki.PasswordsAdmin.
+##  You'll probably want to set an administrative password that you
+##  can use to get into password-protected pages.  Also, by default
+##  the "attr" passwords for the PmWiki and Main groups are locked, so
+##  an admin password is a good way to unlock those.  See PmWiki.Passwords
+##  and PmWiki.PasswordsAdmin.
 # $DefaultPasswords['admin'] = pmcrypt('secret');
 
-## Unicode (UTF-8) allows the display of all languages and all alphabets.
-## Highly recommended for new wikis.
+##  Unicode (UTF-8) allows the display of all languages and all alphabets.
+##  Highly recommended for new wikis.
 include_once("scripts/xlpage-utf-8.php");
 
-## If you're running a publicly available site and allow anyone to
-## edit without requiring a password, you probably want to put some
-## blocklists in place to avoid wikispam.  See PmWiki.Blocklist.
+##  If you're running a publicly available site and allow anyone to
+##  edit without requiring a password, you probably want to put some
+##  blocklists in place to avoid wikispam.  See PmWiki.Blocklist.
 # $EnableBlocklist = 1;                    # enable manual blocklists
 # $EnableBlocklist = 10;                   # enable automatic blocklists
 
@@ -50,6 +50,17 @@ include_once("scripts/xlpage-utf-8.php");
 ##  to enable these buttons, set $EnableGUIButtons to 1.
 # $EnableGUIButtons = 1;
 
+##  This enables a message if editors have modified a page but try to
+##  move away from the edit form before saving the text.
+$EnableNotSavedWarning = 1; # 1: warn editors; 0: disable warning
+
+##  You can enable syntax highlighting for the documentation and/or
+##  for the edit form. 
+# $EnablePmSyntax = 1; # or 2, see documentation
+
+##  For a basic table of contents, see page PmWiki/TableOfContents
+# $PmTOC['Enable'] = 1;
+
 ##  To enable markup syntax from the Creole common wiki markup language
 ##  (http://www.wikicreole.org/), include it here:
 # include_once("scripts/creole.php");
@@ -93,13 +104,13 @@ $UploadPermAdd = 0; # Recommended for most new install
 ##  revision history.  The default is 3650 (approximately 10 years).
 # $DiffKeepDays=30;                        # keep page history at least 30 days
 
-## By default, viewers are prevented from seeing the existence
-## of read-protected pages in search results and page listings,
-## but this can be slow as PmWiki has to check the permissions
-## of each page.  Setting $EnablePageListProtect to zero will
-## speed things up considerably, but it will also mean that
-## viewers may learn of the existence of read-protected pages.
-## (It does not enable them to access the contents of the pages.)
+##  By default, viewers are prevented from seeing the existence
+##  of read-protected pages in search results and page listings,
+##  but this can be slow as PmWiki has to check the permissions
+##  of each page.  Setting $EnablePageListProtect to zero will
+##  speed things up considerably, but it will also mean that
+##  viewers may learn of the existence of read-protected pages.
+##  (It does not enable them to access the contents of the pages.)
 # $EnablePageListProtect = 0;
 
 ##  The refcount.php script enables ?action=refcount, which helps to
blob - d7c96c3167ac06ce19aa1359c424cc50c99f0a59
blob + 184233ef8de1411b062952ec1d2eaed5c365b5b4
--- pmwiki.php
+++ pmwiki.php
@@ -1,7 +1,7 @@
 <?php
 /*
     PmWiki
-    Copyright 2001-2020 Patrick R. Michaud
+    Copyright 2001-2023 Patrick R. Michaud
     pmichaud@pobox.com
     http://www.pmichaud.com/
 
@@ -26,7 +26,7 @@
     provide explanations (and add comments) that answer them.
     
     Script maintained by Petko YOTOV www.pmwiki.org/petko
-    $Id: pmwiki.php 3643 2020-05-21 14:25:47Z petko $
+    $Id: pmwiki.php 4370 2023-02-12 08:26:08Z petko $
 */
 error_reporting(E_ALL ^ E_NOTICE);
 StopWatch('PmWiki');
@@ -40,10 +40,12 @@ if (ini_get('register_globals')) 
     ${$k}=''; unset(${$k}); 
   }
 $UnsafeGlobals = array_keys($GLOBALS); $GCount=0; $FmtV=array();
-SDV($FarmD,dirname(__FILE__));
-SDV($WorkDir,'wiki.d');
+$FmtV['$TokenName'] = 'pmtoken';
 define('PmWiki',1);
-if (preg_match('/\\w\\w:/', $FarmD)) exit();
+SDV($WorkDir,'wiki.d');
+SDV($FarmD,dirname(__FILE__));
+if (strpos($FarmD, 'phar://')===0) $IsFarmArchive = 1;
+elseif (preg_match('/\\w\\w:/', $FarmD)) exit();
 @include_once("$FarmD/scripts/version.php");
 $GroupPattern = '[[:upper:]][\\w]*(?:-\\w+)*';
 $NamePattern = '[[:upper:]\\d][\\w]*(?:-\\w+)*';
@@ -66,7 +68,7 @@ $TimeISOZFmt = '%Y-%m-%dT%H:%M:%SZ';
 $MessagesFmt = array();
 $BlockMessageFmt = "<h3 class='wikimessage'>$[This post has been blocked by the administrator]</h3>";
 $EditFields = array('text');
-$EditFunctions = array('EditTemplate', 'RestorePage', 'ReplaceOnSave',
+$EditFunctions = array('AutoCheckToken', 'EditTemplate', 'RestorePage', 'ReplaceOnSave',
   'SaveAttributes', 'PostPage', 'PostRecentChanges', 'AutoCreateTargets',
   'PreviewPage');
 $EnablePost = 1;
@@ -77,13 +79,15 @@ $SpaceWikiWords = 0;
 $RCDelimPattern = '  ';
 $RecentChangesFmt = array(
   '$SiteGroup.AllRecentChanges' => 
-    '* [[{$Group}.{$Name}]]  . . . $CurrentTime $[by] $AuthorLink: [=$ChangeSummary=]',
+    '* [[{$Group}.{$Name}]]  . . . $CurrentLocalTime $[by] $AuthorLink: [=$ChangeSummary=]',
   '$Group.RecentChanges' =>
-    '* [[{$Group}/{$Name}]]  . . . $CurrentTime $[by] $AuthorLink: [=$ChangeSummary=]');
+    '* [[{$Group}/{$Name}]]  . . . $CurrentLocalTime $[by] $AuthorLink: [=$ChangeSummary=]');
 $UrlScheme = (@$_SERVER['HTTPS']=='on' || @$_SERVER['SERVER_PORT']==443)
              ? 'https' : 'http';
-$ScriptUrl = $UrlScheme.'://'.$_SERVER['HTTP_HOST'].$_SERVER['SCRIPT_NAME'];
+$ScriptUrl = $UrlScheme.'://'.strval(@$_SERVER['HTTP_HOST']).strval(@$_SERVER['SCRIPT_NAME']);
 $PubDirUrl = preg_replace('#/[^/]*$#', '/pub', $ScriptUrl, 1);
+SDV($FarmPubDirPrefix, 'PmFarmPubDirUrl');
+if (@$IsFarmArchive) SDV($FarmPubDirUrl, "$ScriptUrl/$FarmPubDirPrefix");
 $HTMLVSpace = "<vspace>";
 $HTMLPNewline = '';
 $MarkupFrame = array();
@@ -136,7 +140,7 @@ $FmtPV = array(
   '$Title'        => 'FmtPageTitle(@$page["title"], $name, 0)',
   '$LastModifiedBy' => '@$page["author"]',
   '$LastModifiedHost' => '@$page["host"]',
-  '$LastModified' => 'strftime($GLOBALS["TimeFmt"], $page["time"])',
+  '$LastModified' => 'PSFT($GLOBALS["TimeFmt"], $page["time"])',
   '$LastModifiedSummary' => '@$page["csum"]',
   '$LastModifiedTime' => '$page["time"]',
   '$Description'  => '@$page["description"]',
@@ -145,6 +149,7 @@ $FmtPV = array(
   '$VersionNum'   => '$GLOBALS["VersionNum"]',
   '$Version'      => '$GLOBALS["Version"]',
   '$WikiTitle'    => '$GLOBALS["WikiTitle"]',
+  '$PageLogoUrl'  => 'strval(@$GLOBALS["PageLogoUrl"])',
   '$Author'       => 'NoCache($GLOBALS["Author"])',
   '$AuthId'       => 'NoCache($GLOBALS["AuthId"])',
   '$DefaultGroup' => '$GLOBALS["DefaultGroup"]',
@@ -154,13 +159,17 @@ $FmtPV = array(
   '$PasswdRead'   => 'PasswdVar($pn, "read")',
   '$PasswdEdit'   => 'PasswdVar($pn, "edit")',
   '$PasswdAttr'   => 'PasswdVar($pn, "attr")',
+  '$EnabledIMap'  => 'implode("|", array_keys($GLOBALS["IMap"]))', # PmSyntax
+  '$GroupHomePage' => 'FmtGroupHome($pn,$group,$var)',
+  '$GroupHomePageName' => 'FmtGroupHome($pn,$group,$var)',
+  '$GroupHomePageTitle' => 'FmtGroupHome($pn,$group,$var)',
+  '$GroupHomePageTitlespaced' => 'FmtGroupHome($pn,$group,$var)',
   );
 $SaveProperties = array('title', 'description', 'keywords');
 $PageTextVarPatterns = array(
   'var:'        => '/^(:*[ \\t]*(\\w[-\\w]*)[ \\t]*:[ \\t]?)(.*)($)/m',
   '(:var:...:)' => '/(\\(: *(\\w[-\\w]*) *:(?!\\))\\s?)(.*?)(:\\))/s'
   );
-
 
 $WikiTitle = 'PmWiki';
 $Charset = 'ISO-8859-1';
@@ -168,6 +177,10 @@ $HTTPHeaders = array(
   "Expires: Tue, 01 Jan 2002 00:00:00 GMT",
   "Cache-Control: no-store, no-cache, must-revalidate",
   "Content-type: text/html; charset=ISO-8859-1;");
+$HTTPHeaders['XFO'] = 'X-Frame-Options: SAMEORIGIN';
+$HTTPHeaders['CSP'] = "Content-Security-Policy: frame-ancestors 'self'; base-uri 'self'; object-src 'none';";
+$HTTPHeaders['XSSP'] = 'X-XSS-Protection: 1; mode=block';
+
 $CacheActions = array('browse','diff','print');
 $EnableHTMLCache = 0;
 $NoHTMLCache = 0;
@@ -232,20 +245,35 @@ $Conditions['name'] = 
   "(boolean)MatchPageNames(\$pagename, FixGlob(\$condparm, '$1*.$2'))";
 $Conditions['match'] = 'preg_match("!$condparm!",$pagename)';
 $Conditions['authid'] = 'NoCache(@$GLOBALS["AuthId"] > "")';
-$Conditions['exists'] = "(boolean)ListPages(FixGlob(
-  str_replace(array('[[',']]'), array('', ''), \$condparm) , '$1*.$2'))";
 $Conditions['equal'] = 'CompareArgs($condparm) == 0';
 function CompareArgs($arg) 
   { $arg = ParseArgs($arg); return strcmp(@$arg[''][0], @$arg[''][1]); }
 
 $Conditions['auth'] = 'NoCache(CondAuth($pagename, $condparm))';
 function CondAuth($pagename, $condparm) {
-  global $HandleAuth;
+  global $AuthList, $HandleAuth;
   @list($level, $pn) = explode(' ', $condparm, 2);
+  if (@$level && $level[0] == '@') { # user belongs to @group1,@group2
+    $keys = MatchNames(array_keys((array)@$AuthList), $level, true);
+    foreach($keys as $k) {
+      if (@$AuthList[$k] == 1 && $AuthList["-$k"] != 1) return true;
+    }
+    return false;
+  }
   $pn = ($pn > '') ? MakePageName($pagename, $pn) : $pagename;
   if (@$HandleAuth[$level]>'') $level = $HandleAuth[$level];
   return (boolean)RetrieveAuthPage($pn, $level, false, READPAGE_CURRENT);
 }
+$Conditions['exists'] = 'CondExists($condparm)';
+## This is an optimized version of the earlier conditional
+## especially for pagelists
+function CondExists($condparm, $caseinsensitive = true) {
+  static $ls = false;
+  if (!$ls) $ls = ListPages();
+  $condparm = str_replace(array('[[',']]'), array('', ''), $condparm);
+  $glob = FixGlob($condparm, '$1*.$2');
+  return (boolean)MatchPageNames($ls, $glob, $caseinsensitive);
+}
 
 ## CondExpr handles complex conditions (expressions)
 ## Portions Copyright 2005 by D. Faure (dfaure@cpan.org)
@@ -262,7 +290,12 @@ function CondExpr($pagename, $condname, $condparm) {
     if (preg_match("/^($CondExprOps)$/i", $t)) continue;
     if ($t) $terms[$i] = CondText($pagename, "if $t", 'TRUE') ? '1' : '0';
   }
-  return @eval('return(' . implode(' ', $terms) . ');');
+  
+  ## PITS:01480, (:if [ {$EmptyPV} and ... ]:) 
+  $code = preg_replace('/(^\\s*|(and|x?or|&&|\\|\\||!)\\s+)(?=and|x?or|&&|\\|\\|)/', 
+    '$1 0 ', trim(implode(' ', $terms))); 
+
+  return @eval("return( $code );");
 }
 $Conditions['expr'] = 'CondExpr($pagename, $condname, $condparm)';
 $Conditions['('] = 'CondExpr($pagename, $condname, $condparm)';
@@ -282,7 +315,7 @@ Markup('closeall', '_begin',
   '/^\\(:closeall:\\)$/', "MarkupMarkupClose");
 function MarkupMarkupClose() { return '<:block>' . MarkupClose(); }
 
-$ImgExtPattern="\\.(?:gif|jpg|jpeg|png|svgz?|GIF|JPG|JPEG|PNG|SVGZ?)";
+$ImgExtPattern="\\.(?:gif|jpg|jpeg|a?png|svgz?|GIF|JPG|JPEG|A?PNG|SVGZ?|webp|WEBP)";
 $ImgTagFmt="<img src='\$LinkUrl' alt='\$LinkAlt' title='\$LinkAlt' />";
 
 $BlockMarkups = array(
@@ -303,7 +336,7 @@ foreach(array('http:','https:','mailto:','ftp:','news:
   { $LinkFunctions[$m] = 'LinkIMap';  $IMap[$m]="$m$1"; }
 $LinkFunctions['<:page>'] = 'LinkPage';
 
-$q = preg_replace('/(\\?|%3f)([-\\w]+=)/i', '&$2', @$_SERVER['QUERY_STRING']);
+$q = preg_replace('/(\\?|%3f)([-\\w]+=)/i', '&$2', strval(@$_SERVER['QUERY_STRING']));
 if ($q != @$_SERVER['QUERY_STRING']) {
   unset($_GET);
   parse_str($q, $_GET);
@@ -314,14 +347,14 @@ if (isset($_GET['action'])) $action = $_GET['action'];
 elseif (isset($_POST['action'])) $action = $_POST['action'];
 else $action = 'browse';
 
-$pagename = @$_REQUEST['n'];
-if (!$pagename) $pagename = @$_REQUEST['pagename'];
+$pagename = strval(@$_REQUEST['n']);
+if (!$pagename) $pagename = strval(@$_REQUEST['pagename']);
 if (!$pagename && 
-    preg_match('!^'.preg_quote($_SERVER['SCRIPT_NAME'],'!').'/?([^?]*)!',
-      $_SERVER['REQUEST_URI'],$match))
+    preg_match('!^'.preg_quote(strval(@$_SERVER['SCRIPT_NAME']),'!').'/?([^?]*)!',
+      strval(@$_SERVER['REQUEST_URI']),$match))
   $pagename = urldecode($match[1]);
 if (preg_match('/[\\x80-\\xbf]/',$pagename)) 
-  $pagename=utf8_decode($pagename);
+  $pagename=pm_recode($pagename, 'UTF-8', 'WINDOWS-1252');
 $pagename = preg_replace('![^[:alnum:]\\x80-\\xff]+$!','',$pagename);
 $pagename_unfiltered = $pagename;
 $pagename = preg_replace('![${}\'"\\\\]+!', '', $pagename);
@@ -343,6 +376,44 @@ $DenyHtaccessContent = <<<EOF
 
 EOF;
 
+SDVA($ServeFileExts, array(
+  'gif' => 'image/gif', 'png' => 'image/png', 'svg' => 'image/svg+xml',
+  'README' => 'text/plain', 'txt' => 'text/plain',
+  'css' => 'text/css', 'js' => 'application/javascript', 
+));
+function pm_servefile($basedir, $path, $cachecontrol='no-cache') {
+  global $ServeFileExts;
+  header("X-Sent-Via: pm_servefile");
+  $ext = preg_replace('!^.*[./]!', '', $path);
+  if (!isset($ServeFileExts[$ext]) || preg_match('/[?#${}]|\\.\\./', $path)) {
+    http_response_code(403);
+    die('Forbidden');
+  }
+  $filepath = "$basedir/$path";
+  if(!file_exists($filepath)) {
+    http_response_code(404);
+    die('File not found');
+  }
+  
+  header("Cache-Control: $cachecontrol");
+  header('Expires: ');
+  $filelastmod = gmdate('D, d M Y H:i:s \G\M\T', filemtime($filepath));
+  if (@$_SERVER['HTTP_IF_MODIFIED_SINCE'] == $filelastmod)
+    { http_response_code(304); exit(); }
+  header("Last-Modified: $filelastmod");
+  header("Content-Type: {$ServeFileExts[$ext]}");
+  $length = filesize($filepath);
+  header("Content-Length: $length");
+  readfile($filepath);
+  exit;
+}
+
+if (strpos($pagename, "$FarmPubDirPrefix/")===0) {
+  $path = substr($pagename, strlen("$FarmPubDirPrefix/"));
+  pm_servefile("$FarmD/pub", $path);
+  exit;
+}
+
 if (file_exists("$FarmD/local/farmconfig.php")) 
   include_once("$FarmD/local/farmconfig.php");
 if (IsEnabled($EnableLocalConfig,1)) {
@@ -352,8 +423,9 @@ if (IsEnabled($EnableLocalConfig,1)) {
     include_once('config.php');
 }
 
-SDV($CurrentTime, strftime($TimeFmt, $Now));
-SDV($CurrentTimeISO, strftime($TimeISOFmt, $Now));
+SDV($CurrentTime, PSFT($TimeFmt, $Now));
+SDV($CurrentLocalTime, PSFT("@$TimeISOZFmt", $Now, null, 'GMT'));
+SDV($CurrentTimeISO, PSFT($TimeISOFmt, $Now));
 
 if (IsEnabled($EnableStdConfig,1))
   include_once("$FarmD/scripts/stdconfig.php");
@@ -367,19 +439,61 @@ if (isset($PostConfig) && is_array($PostConfig)) {
   }
 }
 
-function pmsetcookie($name, $val="", $exp=0, $path="", $dom="", $secure=null, $httponly=null) {
-  global $EnableCookieSecure, $EnableCookieHTTPOnly, $SetCookieFunction;
-  if(IsEnabled($SetCookieFunction))
-    return $SetCookieFunction($name, $val, $exp, $path, $dom, $secure, $httponly);
+function pmsetcookie($name, $val="", $exp=0, $path="", $dom="", $secure=null, $httponly=null, $samesite=null) {
+  global $EnableCookieSecure, $EnableCookieHTTPOnly, $SetCookieFunction, $CookieSameSite;
+  if (IsEnabled($SetCookieFunction))
+    return $SetCookieFunction($name, $val, $exp, $path, $dom, $secure, $httponly, $samesite);
   if (is_null($secure))   $secure   = IsEnabled($EnableCookieSecure,   false);
   if (is_null($httponly)) $httponly = IsEnabled($EnableCookieHTTPOnly, false);
-  setcookie($name, $val, $exp, $path, $dom, $secure, $httponly);
+  if (is_null($samesite)) $samesite = IsEnabled($CookieSameSite, 'Lax');
+  
+  if (PHP_VERSION_ID>=70300) {
+    return setcookie($name, $val, array(
+       'expires' => $exp, 
+       'path' => $path, 
+       'domain' => $dom, 
+       'secure' => $secure, 
+       'httponly' => $httponly,
+       'samesite' => $samesite
+    ));
+  }
+  if (!$path) $path = '/';
+  setcookie($name, $val, $exp, "$path; SameSite=$samesite", $dom, $secure, $httponly);
 }
-if (IsEnabled($EnableCookieSecure, false)) 
-    @ini_set('session.cookie_secure', $EnableCookieSecure);
-if (IsEnabled($EnableCookieHTTPOnly, false)) 
-    @ini_set('session.cookie_httponly', $EnableCookieHTTPOnly);
+function pm_session_start($a = array()) {
+  global $EnableCookieSecure, $EnableCookieHTTPOnly, $CookieSameSite;
+  if (function_exists('session_status')) {
+    if (session_status() === PHP_SESSION_ACTIVE) return true;
+  }
+  
+  if (!headers_sent()){
+    $params = session_get_cookie_params();
+    if (isset($EnableCookieSecure) && !isset($a['secure']))
+      $a['secure'] = $EnableCookieSecure;
+    if (isset($EnableCookieHTTPOnly) && !isset($a['httponly']))
+      $a['httponly'] = $EnableCookieHTTPOnly;
+    if (!isset($a['samesite'])) $a['samesite'] = IsEnabled($CookieSameSite, 'Lax');
+    SDVA($a, $params);
+  
+    if (PHP_VERSION_ID < 70300) {
+      if (!$a['path']) $a['path'] = '/';
+      $a['path'] .= "; SameSite={$a['samesite']}";
+      session_set_cookie_params(
+        $a['lifetime'],
+        $a['path'],
+        $a['domain'],
+        $a['secure'],
+        $a['httponly']
+      );
+    }
+    else {
+      session_set_cookie_params($a);
+    }
+  }
+  return @session_start();
+}
 
+
 foreach((array)$InterMapFiles as $f) {
   $f = FmtPageName($f, $pagename);
   if (($v = @file($f))) 
@@ -429,12 +543,14 @@ function HandleDispatch($pagename, $action, $msg=NULL)
 
 ## helper functions
 function stripmagic($x) {
+  if(is_null($x)) return '';
   $fn = 'get_magic_quotes_gpc';
   if (!function_exists($fn)) return $x;
   if (is_array($x)) {
     foreach($x as $k=>$v) $x[$k] = stripmagic($v);
     return $x;
   }
+  $x = strval($x);
   return @$fn() ? stripslashes($x) : $x;
 }
 function pre_r(&$x)
@@ -448,18 +564,26 @@ function PZZ($x,$y='') { return ''; }
 function PRR($x=NULL) 
   { if ($x || is_null($x)) $GLOBALS['RedoMarkupLine']++; return $x; }
 function PUE($x)
-  { return preg_replace_callback('/[\\x80-\\xff \'"<>]/', "cb_pue", $x); }
+  { return $x? preg_replace_callback('/[\\x80-\\xff \'"<>]/', "cb_pue", $x) : ''; }
 function cb_pue($m) { return '%'.dechex(ord($m[0])); }
-function PQA($x) { 
+function PQA($x, $keep=true, $styletoclass=false) {
+  global $EnableUnsafeInlineStyle;
+  if (!@$x) return ''; # PHP 8.1
   $out = '';
+  $s = array();
+  $x = MarkupRestore($x);
   if (preg_match_all('/([a-zA-Z][-\\w]*)\\s*=\\s*("[^"]*"|\'[^\']*\'|\\S*)/',
                      $x, $attr, PREG_SET_ORDER)) {
     foreach($attr as $a) {
       if (preg_match('/^on/i', $a[1])) continue;
       $val = preg_replace('/^([\'"]?)(.*)\\1$/', '$2', $a[2]);
-      $val = str_replace("'", '&#39;', $val);
-      $out .= "{$a[1]}='$val' ";
+      $s[$a[1]] = $val;
     }
+    foreach($s as $key=>$val) {
+      $val = PHSC($val, ENT_QUOTES, null, false);
+      if ($keep) $val = Keep($val);
+      $out .= "$key='$val' ";
+    }
   }
   return $out;
 }
@@ -474,7 +598,7 @@ function NoCache($x = '') { $GLOBALS['NoHTMLCache'] |=
 function ParseArgs($x, $optpat = '(?>(\\w+)[:=])') {
   $z = array();
   preg_match_all("/($optpat|[-+])?(\"[^\"]*\"|'[^']*'|\\S+)/",
-    $x, $terms, PREG_SET_ORDER);
+    strval($x), $terms, PREG_SET_ORDER);
   foreach($terms as $t) {
     $v = preg_replace('/^([\'"])?(.*)\\1$/', '$2', $t[3]);
     if ($t[2]) { $z['#'][] = $t[2]; $z[$t[2]] = $v; }
@@ -488,7 +612,164 @@ function PHSC($x, $flags=ENT_COMPAT, $enc=null, $dbl_e
   if (! is_array($x)) return @htmlspecialchars($x, $flags, $enc, $dbl_enc);
   foreach($x as $k=>$v) $x[$k] = PHSC($v, $flags, $enc, $dbl_enc);
   return $x;
+}
+function PSFT($fmt, $stamp=null, $locale=null, $tz=null) { # strftime() replacement
+  global $Now, $FTimeFmt, $TimeFmt, $EnableFTimeNew;
+  static $cached;
+  if (!@$cached) {
+    SDV($FTimeFmt, $TimeFmt);
+    $cached['dloc'] = setlocale(LC_TIME, 0);
+    $cached['dtz'] = date_default_timezone_get();
+    $cached['dtzo'] = timezone_open($cached['dtz']);
+    $cached['formats'] = array(
+      '%d' => 'd',
+      '%e' => ' j', # day " 1"-"31"
+      '%u' => 'N',
+      '%w' => 'w',
+      '%m' => 'm',
+      '%s' => 'U',
+      '%n' => "\n",
+      '%t' => "\t",
+      '%V' => 'W', # ISO-8601 week number, starts Monday, first week with 4+ weekdays
+      
+      '%H' => 'H',
+      '%I' => 'h', # hour 01-12
+      '%k' => ' G', # hour " 1"-"23"
+      '%l' => ' g', # hour " 1"-"12"
+      '%M' => 'i',
+      '%S' => 's',
+      '%R' => 'H:i',
+      '%T' => 'H:i:s',
+      '%r' => 'h:i:s A',
+      '%D' => 'm/d/y',
+      '%F' => 'Y-m-d',
+      
+      '%G' => 'o', # ISO-8601 year (like %V)
+      '%y' => 'y', # 21
+      '%Y' => 'Y', # 2021
+      
+      '%Z' => 'T', # tz: EST
+      '%z' => 'O', # tz offset: -0500
+    );
+    if (extension_loaded('intl')) {
+      $full = IntlDateFormatter::FULL;
+      $long = IntlDateFormatter::LONG;
+      $short = IntlDateFormatter::SHORT;
+      $none = IntlDateFormatter::NONE;
+      $medium = IntlDateFormatter::MEDIUM;
+      
+      $cached['iformats'] = array(
+        '%a' => array($full, $full, 'EEE'),  # Mon
+        '%A' => array($full, $full, 'EEEE'), # Monday
+        '%h' => array($full, $full, 'MMM'),  # Jan
+        '%b' => array($full, $full, 'MMM'),  # Jan
+        '%B' => array($full, $full, 'MMMM'), # January
+        '%p' => array($full, $full, 'aa'), # AM/PM
+        '%P' => array($full, $full, 'aa'), # am/pm (no lowercase for intl am/pm)
+        '%c' => array($long, $short), # date time
+        '%x' => array($short, $none), # date
+        '%X' => array($none, $medium),# time
+      );
+    }
+    else {
+      $cached['iformats'] = array();
+      $cached['formats'] += array(
+        '%a' => 'D', # Mon
+        '%A' => 'l', # Monday
+        '%h' => 'M', # Jan
+        '%b' => 'M', # Jan
+        '%B' => 'F', # January
+        '%p' => 'a', # AM/PM
+        '%P' => 'A', # am/pm
+        '%c' => 'D M j H:i:s Y', # date time
+        '%x' => 'm/d/y', # date
+        '%X' => 'H:i:s', # time
+      );
+    }
+    $cached['new'] = isset($EnableFTimeNew) 
+      ? $EnableFTimeNew
+      : (PHP_VERSION_ID>=80100);
+  }
+
+  if (@$fmt == '') $fmt = $FTimeFmt;
+  $stamp = is_numeric($stamp)? intval($stamp) : $Now;
+  
+  if(preg_match('/(?<!%)(%L)/', $fmt)) {
+    $gmt = PSFT('@%Y-%m-%dT%H:%M:%SZ', $stamp, null, 'GMT');
+    $fmt = preg_replace('/(?<!%)(%L)/', $gmt, $fmt);
+  }
+
+  if (! $cached['new']) {
+    if (@$locale) 
+      setlocale(LC_TIME, preg_split('/[, ]+/', $locale, -1, PREG_SPLIT_NO_EMPTY));
+    if (@$tz) @date_default_timezone_set($tz);
+    $fmt = str_replace(array('%F', '%s', '%o'), 
+        array('%Y-%m-%d', $stamp, date('S', $stamp)), 
+      $fmt);
+    $ret = strftime($fmt, $stamp);
+    if ($tz) date_default_timezone_set($cached['dtz']);
+    if (@$locale) setlocale(LC_TIME, $cached['dloc']);
+    return $ret;
+  }
+  
+  $timestamp = date_create("@$stamp");
+  if ($tz) {
+    $tzo = @timezone_open($tz);
+    if (!@$tzo) unset($tz);
+  }
+  if (!@$tz) { # need to set it otherwise resets to GMT
+    $tz = $cached['dtz'];
+    $tzo = $cached['dtzo'];
+  }
+  date_timezone_set($timestamp, $tzo);
+  
+  $vars = array(
+    'tz' => $tz,
+    'timestamp' => $timestamp,
+    'formats' =>  $cached['formats'],
+    'iformats' =>  $cached['iformats'],
+  );
+  if ($locale) $vars['locale'] = substr($locale, 0, 5);
+  
+  $cb = new PPRC($vars);
+  $fmt = preg_replace_callback('/(?<!%)(%[a-zA-Z])/', array($cb, 'ftime'), $fmt);
+  return str_replace('%%', '%', $fmt);
 }
+function cb_PSFT($fmt, $vars) {
+  extract($vars); # $timestamp, $tz, $locale, $formats, $iformats
+  
+  if (isset($formats[$fmt])) {
+    $fmt = $timestamp->format($formats[$fmt]);
+    if ($fmt[0]==' ' && strlen($fmt)>2) $fmt = substr($fmt, 1);
+    return $fmt;
+  }
+  if ($fmt=='%o') { # ordinal, PITS:01418
+    if (!@$locale) $locale = 'C';
+    $f = numfmt_create($locale, NumberFormatter::ORDINAL);
+    $o = $f->format($timestamp->format('j'));
+    return preg_replace('/\\d+/', '', $o);
+  }
+  if ($fmt=='%j') return sprintf('%03d',$timestamp->format('z')+1);
+  if ($fmt=='%C') return floor($timestamp->format('Y')/100);
+  if ($fmt=='%g') return sprintf('%02d', $timestamp->format('o') % 100);
+  if ($fmt=='%U') return cb_PSFT_UW($timestamp, $tz, 'Sunday');
+  if ($fmt=='%W') return cb_PSFT_UW($timestamp, $tz, 'Monday');
+
+  if (isset($iformats[$fmt])) {
+    $ifmt = $iformats[$fmt];
+    return datefmt_create(@$locale, $ifmt[0], $ifmt[1], $tz, null, @$ifmt[2])->format($timestamp);
+  }
+  return $fmt;
+}
+function cb_PSFT_UW($timestamp, $tz, $day) { # helper for %U %W
+  $first = strtotime(sprintf("%d-01 $day", $timestamp->format('Y')));
+  $stamp1 = date_create("@$first");
+  date_timezone_set($stamp1, timezone_open($tz));
+  $days = $timestamp->format('z') - $stamp1->format('z');
+  return sprintf('%02d', floor($days/7)+1);
+}
+
+# Only called by old addon|skin|recipe needing update, see pmwiki.org/Troubleshooting
 function PCCF($code, $template = 'default', $args = '$m') {
   global $CallbackFnTemplates, $CallbackFunctions, $PCCFOverrideFunction;
   if ($PCCFOverrideFunction && is_callable($PCCFOverrideFunction))
@@ -505,31 +786,57 @@ function PCCF($code, $template = 'default', $args = '$
   return $CallbackFunctions[$code];
 }
 function PPRE($pat, $rep, $x) {
+  if (! function_exists('create_function')) return $x;
   $lambda = PCCF("return $rep;");
   return preg_replace_callback($pat, $lambda, $x);
 }
 function PPRA($array, $x) {
+  if ($x==='' || is_null($x)) return '';
   foreach((array)$array as $pat => $rep) {
+    # skip broken patterns rather than crash the PHP installation
+    $oldpat = preg_match('!^/.+/[^/]*e[^/]*$!', $pat);
+    if ($oldpat && PHP_VERSION_ID >= 50500) continue;
+    
     $fmt = $x; # for $FmtP
-    if (is_callable($rep) && $rep != '_') $x = preg_replace_callback($pat,$rep,$x);
-    else $x = preg_replace($pat,$rep,$x);# simple text OR called by old addon|skin|recipe needing update, see pmwiki.org/Troubleshooting
+    if (is_callable($rep) && $rep != '_') 
+      $x = preg_replace_callback($pat,$rep,$x);
+    else
+      $x = preg_replace($pat,$rep,$x);# simple text OR called by old addon|skin|recipe needing update, see pmwiki.org/Troubleshooting
   }
   return $x;
 }
+function PRCB($pat, $repl, $subj, $vars=null, $limit=-1, &$count=null, $flags=0) {
+  if (isset($vars)) {
+    $cb = new PPRC($vars, $repl);
+    $repl = array($cb, 'callback');
+  }
+  return preg_replace_callback($pat, $repl, $subj, $limit, $count, $flags);
+}
 ## callback functions
 class PPRC { # PmWiki preg replace callbacks + pass local vars
   var $vars;
-  function __construct($vars = false) {
-    if ($vars && !is_null($vars)) $this->vars = $vars;
+  var $cb;
+  function __construct($vars = null, $cb = null) {
+    if (!is_null($vars)) $this->vars = $vars;
+    if (!is_null($cb)) $this->cb = $cb;
+    
   }
   function pagevar($m) { # called from FmtPageName
     $pagename = $this->vars;
     return PageVar($pagename, $m[1]);
   }
+  function ftime($m) { # called from PSFT
+    $vars = $this->vars;
+    return cb_PSFT($m[0], $vars);
+  }
+  function callback($m) {
+    $cb = $this->cb;
+    return $cb($m, $this->vars);
+  }
 }
 
 # restores kept/protected strings
-function cb_expandkpv($m) { return $GLOBALS['KPV'][$m[1]]; }
+function cb_expandkpv($m) { return @$GLOBALS['KPV'][$m[1]]; }
 
 # make a string upper or lower case in various patterns
 function cb_toupper($m) { return strtoupper($m[1]); }
@@ -544,6 +851,49 @@ function pmcrypt($str, $salt=null) {
   return crypt($str);
 }
 
+# generate or check a random one-time token to prevent CSRF
+function pmtoken($token = null) {
+  global $SessionMaxTokens, $PmTokenFn;
+  if (IsEnabled($PmTokenFn) && function_exists($PmTokenFn))
+    return $PmTokenFn($token);
+  pm_session_start();
+  if (!isset($_SESSION['pmtokens'])) $_SESSION['pmtokens'] = array();
+  if (is_null($token)) { # create a one-time token
+    $len = mt_rand(20,30);
+    $token = "";
+    while(strlen($token)<$len) {
+      $token .= chr(mt_rand(32,126));
+    }
+    if (count($_SESSION['pmtokens']))
+      $id = max(array_keys($_SESSION['pmtokens']))+1;
+    else $id = 0;
+    $_SESSION['pmtokens'][$id] = $token;
+    if (IsEnabled($SessionMaxTokens, 0)) {
+      $max = $SessionMaxTokens;
+      $_SESSION['pmtokens'] = array_slice($_SESSION['pmtokens'], -$max, $max, true);
+    }
+    return "$id:" . md5($token);
+  }
+  # else: check a token, if correct, delete it
+  @list($id, $hash) = explode(':', $token);
+  $id = intval($id);
+  if (isset($_SESSION['pmtokens'][$id]) && $hash == md5($_SESSION['pmtokens'][$id])) {
+    unset($_SESSION['pmtokens'][$id]);
+    return true;
+  }
+  return false;
+}
+
+function PmNonce() {
+  if (function_exists('random_bytes')) {
+    $nonce = bin2hex(random_bytes(5));
+  }
+  else $nonce = mt_rand();
+  return $nonce;
+}
+
+
+
 function StopWatch($x) { 
   global $StopWatch, $EnableStopWatch;
   if (!$EnableStopWatch) return;
@@ -617,16 +967,26 @@ function DRange($when) {
   return array($t0, $t1);
 }
 
+## FmtDateTimeZ converts a GMT datetime like @2022-01-08T10:07:08Z 
+## into a <time> element formatted according to $TimeFmt
+function FmtDateTimeZ($m) {
+  global $TimeFmt, $TimeISOZFmt;
+  $time = strtotime(substr($m[0], 1)); # "@"
+  $iso = PSFT($TimeISOZFmt, $time, null, 'GMT');
+  $text = PSFT($TimeFmt, $time);
+  return "<time datetime='$iso'>$text</time>";
+}
+
 ## DiffTimeCompact subtracts 2 timestamps and outputs a compact
 ## human-readable delay in hours, days, weeks, months or years
 function DiffTimeCompact($time, $time2=null, $precision=1) {
-  if(is_null($time2)) $time2 = $GLOBALS['Now'];
+  if (is_null($time2)) $time2 = $GLOBALS['Now'];
   $suffix = explode(',', XL('h,d,w,m,y'));
   $x = $hours = abs($time2 - $time)/3600;
-  if($x<24) return round($x,$precision).$suffix[0];
-  $x /= 24;   if($x<14) return round($x,$precision).$suffix[1];
-  $x /= 7;    if($x< 9) return round($x,$precision).$suffix[2];
-  $x = $hours/2/365.2425; if($x<24) return round($x,$precision).$suffix[3];
+  if ($x<24) return round($x,$precision).$suffix[0];
+  $x /= 24;   if ($x<14) return round($x,$precision).$suffix[1];
+  $x /= 7;    if ($x< 9) return round($x,$precision).$suffix[2];
+  $x = $hours/2/365.2425; if ($x<24) return round($x,$precision).$suffix[3];
   return round($hours/24/365.2425,$precision).$suffix[4];
 }
 
@@ -634,7 +994,7 @@ function DiffTimeCompact($time, $time2=null, $precisio
 ## with an appropriate suffix.
 ## Note: unreliable filemtime()/stat() over 2GB @ 32bit
 function FileSizeCompact($n, $precision=1) {
-  if(!(float)$n) return 0;
+  if (!(float)$n) return 0;
   $units = 'bkMGTPEZY';
   $b = log((float)$n, 1024);
   $fb = floor($b);
@@ -747,16 +1107,17 @@ function FixGlob($x, $rep = '$1*.$2') {
 ## matching the pattern(s) in $pat.  Patterns can be either
 ## regexes to include ('/'), regexes to exclude ('!'), or
 ## wildcard patterns (all others).
-function MatchPageNames($pagelist, $pat) {
+function MatchPageNames($pagelist, $pat, $caseinsensitive = true) {
   # Note: MatchNames() is the generic function matching patterns,
   # works for attachments and other arrays. We can commit to 
   # keep it generic, even if we someday change MatchPageNames().
-  return MatchNames($pagelist, $pat);
+  return MatchNames($pagelist, $pat, $caseinsensitive);
 }
-function MatchNames($list, $pat) {
+function MatchNames($list, $pat, $caseinsensitive = true) {
   global $Charset, $EnableRangeMatchUTF8;
   # allow range matches in utf8; doesn't work on pmwiki.org and possibly elsewhere
   $pcre8 = (IsEnabled($EnableRangeMatchUTF8,0) && $Charset=='UTF-8')? 'u' : '';
+  $insensitive = $caseinsensitive ? 'i' : '';
   $list = (array)$list;
   foreach((array)$pat as $p) {
     if (count($list) < 1) break;
@@ -771,9 +1132,9 @@ function MatchNames($list, $pat) {
       default:
         list($inclp, $exclp) = GlobToPCRE(str_replace('/', '.', $p));
         if ($exclp) 
-          $list = array_diff($list, preg_grep("/$exclp/i$pcre8", $list));
+          $list = array_diff($list, preg_grep("/$exclp/$insensitive$pcre8", $list));
         if ($inclp)
-          $list = preg_grep("/$inclp/i$pcre8", $list);
+          $list = preg_grep("/$inclp/$insensitive$pcre8", $list);
     }
   }
   return $list;
@@ -809,6 +1170,7 @@ function MakePageName($basepage, $str) {
   global $MakePageNameFunction, $PageNameChars, $PagePathFmt,
     $MakePageNamePatterns, $MakePageNameSplitPattern;
   if (@$MakePageNameFunction) return $MakePageNameFunction($basepage, $str);
+  
   SDV($PageNameChars,'-[:alnum:]');
   SDV($MakePageNamePatterns, array(
     "/'/" => '',                      # strip single-quotes
@@ -886,7 +1248,8 @@ function SetProperty($pagename, $prop, $value, $sep=NU
 ## $PageTextVarPatterns) into a page's $PCache entry, and returns
 ## the property associated with $var.
 function PageTextVar($pagename, $var) {
-  global $PCache, $PageTextVarPatterns, $MaxPageTextVars, $DefaultUnsetPageTextVars, $DefaultEmptyPageTextVars;
+  global $PCache, $PageTextVarPatterns, $MaxPageTextVars,
+    $DefaultUnsetPageTextVars, $DefaultEmptyPageTextVars;
   SDV($MaxPageTextVars, 500);
   static $status;
   if (@$status["$pagename:$var"]++ > $MaxPageTextVars) return '';
@@ -896,13 +1259,15 @@ function PageTextVar($pagename, $var) {
     $page = RetrieveAuthPage($pagename, 'read', false, READPAGE_CURRENT);
     if ($page) {
       foreach((array)$PageTextVarPatterns as $pat) 
-        if (preg_match_all($pat, IsEnabled($pc['=preview'],@$page['text']),
-          $match, PREG_SET_ORDER))
+        if (preg_match_all($pat, IsEnabled($pc['=preview'],strval(@$page['text'])),
+          $match, PREG_SET_ORDER)) {
           foreach($match as $m) {
             $t = preg_replace("/\\{\\$:{$m[2]}\\}/", '', $m[3]);
+            
             $pc["=p_{$m[2]}"] = Qualify($pagename, $t);
           }
-    }
+        }
+      }
   }
   if (! isset($PCache[$pagename]["=p_$var"]) && is_array($DefaultUnsetPageTextVars)) {
     foreach($DefaultUnsetPageTextVars as $k=>$v) {
@@ -913,7 +1278,7 @@ function PageTextVar($pagename, $var) {
     }
     SDV($PCache[$pagename]["=p_$var"], ''); # to avoid re-loop
   }
-  elseif (@$PCache[$pagename]["=p_$var"] == '' && is_array($DefaultEmptyPageTextVars)) {
+  elseif (@$PCache[$pagename]["=p_$var"] === '' && is_array($DefaultEmptyPageTextVars)) {
     foreach($DefaultEmptyPageTextVars as $k=>$v) {
       if (count(MatchNames($var, $k))) {
         $PCache[$pagename]["=p_$var"] = $v;
@@ -922,7 +1287,7 @@ function PageTextVar($pagename, $var) {
     }
     SDV($PCache[$pagename]["=p_$var"], ''); # to avoid re-loop
   }
-  return @$PCache[$pagename]["=p_$var"];
+  return strval(@$PCache[$pagename]["=p_$var"]);
 }
 
 
@@ -942,7 +1307,7 @@ function PageVar($pagename, $var, $pn = '') {
     }
     @list($d, $group, $name) = $match;
     $page = &$PCache[$pn];
-    if (strpos(@$FmtPV[$var], '$authpage') !== false) {
+    if (@$FmtPV[$var] && strpos(@$FmtPV[$var], '$authpage') !== false) {
       if (!isset($page['=auth']['read'])) {
         $x = RetrieveAuthPage($pn, 'read', false, READPAGE_CURRENT);
         if ($x) PCache($pn, $x);
@@ -950,18 +1315,18 @@ function PageVar($pagename, $var, $pn = '') {
       if (@$page['=auth']['read']) $authpage = &$page;
     }
   } else { $group = ''; $name = ''; }
-  if (@$FmtPV[$var]) return eval("return ({$FmtPV[$var]});");
+  if (isset($FmtPV[$var])) return eval("return ({$FmtPV[$var]});");
   if (strncmp($var, '$:', 2)==0) return PageTextVar($pn, substr($var, 2));
   return '';
 }
 
-  
 ## FmtPageName handles $[internationalization] and $Variable 
 ## substitutions in strings based on the $pagename argument.
 function FmtPageName($fmt, $pagename) {
   # Perform $-substitutions on $fmt relative to page given by $pagename
   global $GroupPattern, $NamePattern, $EnablePathInfo, $ScriptUrl,
     $GCount, $UnsafeGlobals, $FmtV, $FmtP, $FmtPV, $PCache, $AsSpacedFunction;
+  if (! @$fmt) { return ''; }
   if (strpos($fmt,'$')===false) return $fmt;
   $fmt = preg_replace_callback('/\\$([A-Z]\\w*Fmt)\\b/','cb_expandglobal',$fmt);
   $fmt = preg_replace_callback('/\\$\\[(?>([^\\]]+))\\]/',"cb_expandxlang",$fmt);
@@ -1025,6 +1390,14 @@ function FmtPageTitle($title, $name, $spaced=0) {
   return ($spaced || $SpaceWikiWords) ? $AsSpacedFunction($name) : $name;
 }
 
+## FmtGroupHome returns the homepage of any page ($Group or $DefaultName)
+function FmtGroupHome($pn,$group,$var) {
+  $gpn = MakePageName($pn, "$group.");
+  $pv = substr($var, 14);
+  if (!$pv) return $gpn;
+  return PageVar($gpn, "\$$pv");
+}
+
 ## FmtTemplateVars uses $vars to replace all occurrences of 
 ## {$$key} in $text with $vars['key'].
 function FmtTemplateVars($text, $vars, $pagename = NULL) {
@@ -1085,11 +1458,43 @@ function XLPage($lang,$p,$nohtml=false) {
 function CmpPageAttr($a, $b) {
   @list($x, $agmt) = explode(':', $a);
   @list($x, $bgmt) = explode(':', $b);
+  $nagmt = intval($agmt);
+  $nbgmt = intval($bgmt);
   if ($agmt != $bgmt) 
-    return ($agmt==0 || $bgmt==0) ? $agmt - $bgmt : $bgmt - $agmt;
+    return ($nagmt==0 || $nbgmt==0) ? $nagmt - $nbgmt : $nbgmt - $nagmt;
   return strcmp($a, $b);
 }
 
+function pm_recode($s,$from,$to) {
+  static $able;
+  if (is_null($able)) {
+    # can we rely on iconv() or on mb_convert_encoding() ?
+    if (function_exists('iconv') && @iconv("UTF-8", "WINDOWS-1252//IGNORE", "te\xd0\xafst")=='test' )
+      $able = 'iconv';
+    elseif (function_exists('mb_convert_encoding') && @mb_convert_encoding("te\xd0\xafst", "WINDOWS-1252", "UTF-8")=="te?st")
+      $able = 'mb';
+    elseif (class_exists('UConverter')) $able = 'uc';
+    else $able = false;
+  }
+  $to = strtoupper($to);
+  $from = strtoupper($from);
+  switch ($able) {
+    case "iconv":
+      return @iconv($from,"$to//IGNORE",$s);
+    case "mb":
+      return @mb_convert_encoding($s,$to,$from);
+    case "uc":
+      if ($to == 'WINDOWS-1252') $to = 'ISO-8859-1';
+      if ($from == 'WINDOWS-1252') $from = 'ISO-8859-1';
+      return @UConverter::transcode($s,$to,$from);
+  }
+  if (function_exists('utf8_decode')) {
+    if ($to=='UTF-8' && $from=='WINDOWS-1252') return @utf8_decode($s);
+    if ($from=='UTF-8' && $to=='WINDOWS-1252') return @utf8_encode($s);
+  }
+  return $s;
+}
+
 ## class PageStore holds objects that store pages via the native
 ## filesystem.
 class PageStore {
@@ -1102,23 +1507,7 @@ class PageStore {
     $GLOBALS['PageExistsCache'] = array();
   }
   function recodefn($s,$from,$to) {
-    static $able;
-    if(is_null($able)) {
-      # can we rely on iconv() or on mb_convert_encoding() ?
-      if (function_exists('iconv') && @iconv("UTF-8", "WINDOWS-1252//IGNORE", "te\xd0\xafst")=='test' )
-        $able = 'iconv';
-      elseif (function_exists('mb_convert_encoding') && @mb_convert_encoding("te\xd0\xafst", "WINDOWS-1252", "UTF-8")=="te?st")
-        $able = 'mb';
-    }
-    switch ($able) {
-      case "iconv":
-        return @iconv($from,"$to//IGNORE",$s);
-      case "mb":
-        return @mb_convert_encoding($s,$to,$from);
-    }
-    if ($to=='UTF-8' && $from=='WINDOWS-1252') return utf8_decode($s);
-    if ($from=='UTF-8' && $to=='WINDOWS-1252') return utf8_encode($s);
-    return $s;
+    return pm_recode($s,$from,$to);
   }
   function pagefile($pagename) {
     global $FarmD;
@@ -1165,7 +1554,7 @@ class PageStore {
         }
         if ($k == 'newline') { $newline = $v; continue; }
         if ($since > 0 && preg_match('/:(\\d+)/', $k, $m) && $m[1] < $since) {
-          if ($ordered) break;
+          if (@$ordered) break;
           continue;
         }
         if ($newline) $v = str_replace($newline, "\n", $v);
@@ -1180,10 +1569,10 @@ class PageStore {
     $page['charset'] = $Charset;
     $page['name'] = $pagename;
     $page['time'] = $Now;
-    $page['host'] = $_SERVER['REMOTE_ADDR'];
-    $page['agent'] = @$_SERVER['HTTP_USER_AGENT'];
-    if(IsEnabled($EnableRevUserAgent, 0)) $page["agent:$Now"] = $page['agent'];
-    $page['rev'] = @$page['rev']+1;
+    $page['host'] = strval(@$_SERVER['REMOTE_ADDR']);
+    $page['agent'] = strval(@$_SERVER['HTTP_USER_AGENT']);
+    if (IsEnabled($EnableRevUserAgent, 0)) $page["agent:$Now"] = $page['agent'];
+    $page['rev'] = intval(@$page['rev'])+1;
     unset($page['version']); unset($page['newline']);
     uksort($page, 'CmpPageAttr');
     $s = false;
@@ -1253,7 +1642,8 @@ class PageStore {
   function recode($pagename, $a) {
     if (!$a) return false;
     global $Charset, $PageRecodeFunction, $DefaultPageCharset, $EnableOldCharset;
-    if (function_exists($PageRecodeFunction)) return $PageRecodeFunction($a);
+    if (@$PageRecodeFunction && function_exists($PageRecodeFunction)) 
+      return $PageRecodeFunction($a);
     if (IsEnabled($EnableOldCharset)) $a['=oldcharset'] = @$a['charset'];
     SDVA($DefaultPageCharset, array(''=>@$Charset)); # pre-2.2.31 RecentChanges
     if (@$DefaultPageCharset[$a['charset']]>'')  # wrong pre-2.2.30 encs. *-2, *-9, *-13
@@ -1261,7 +1651,7 @@ class PageStore {
     if (!$a['charset'] || $Charset==$a['charset']) return $a;
     $from = ($a['charset']=='ISO-8859-1') ? 'WINDOWS-1252' : $a['charset'];
     $to = ($Charset=='ISO-8859-1') ? 'WINDOWS-1252' : $Charset;
-    if($from != $to) {
+    if ($from != $to) {
       foreach($a as $k=>$v) $a[$k] = $this->recodefn($v,$from,$to);
     }
     $a['charset'] = $Charset;
@@ -1276,7 +1666,7 @@ function ReadPage($pagename, $since=0) {
     $page = $dir->read($pagename, $since);
     if ($page) break;
   }
-  if (@!$page) $page['ctime'] = $Now;
+  if (@!$page) $page = array('ctime' => $Now);
   if (@!$page['time']) $page['time'] = $Now;
   return $page;
 }
@@ -1357,12 +1747,15 @@ function Redirect($pagename, $urlfmt='$PageUrl', $redi
 
 function PrintFmt($pagename,$fmt) {
   global $HTTPHeaders,$FmtV;
-  if (is_array($fmt)) 
-    { foreach($fmt as $f) PrintFmt($pagename,$f); return; }
+  if (is_array($fmt)) {
+    foreach($fmt as $f) PrintFmt($pagename,$f); 
+    return;
+  }
   if ($fmt == 'headers:') {
     foreach($HTTPHeaders as $h) (@$sent++) ? @header($h) : header($h);
     return;
   }
+  $fmt = strval($fmt);
   $x = FmtPageName($fmt,$pagename);
   if (strncmp($fmt, 'function:', 9) == 0 &&
       preg_match('/^function:(\S+)\s*(.*)$/s', $x, $match) &&
@@ -1384,22 +1777,26 @@ function PrintFmt($pagename,$fmt) {
   echo $x;
 }
 
-function PrintWikiPage($pagename, $wikilist=NULL, $auth='read') {
+function PrintWikiPage($pagename, $wikilist=NULL, $auth='read', $return=false) {
   if (is_null($wikilist)) $wikilist=$pagename;
   $pagelist = preg_split('/\s+/',$wikilist,-1,PREG_SPLIT_NO_EMPTY);
   foreach($pagelist as $p) {
     if (PageExists($p)) {
       $page = ($auth) ? RetrieveAuthPage($p, $auth, false, READPAGE_CURRENT)
               : ReadPage($p, READPAGE_CURRENT);
-      if ($page['text']) 
-        echo MarkupToHTML($pagename,Qualify($p, $page['text']));
-      return;
+      if (@$page['text']) {
+        $html = MarkupToHTML($pagename,Qualify($p, $page['text']));
+        if ($return) return $html;
+        echo $html;
+      }
+      return '';
     }
   }
+  return '';
 }
 
 function Keep($x, $pool=NULL) {
-  if(is_array($x)) $x = $x[0]; # used in many callbacks
+  if (is_array($x)) $x = $x[0]; # used in many callbacks
   # Keep preserves a string from being processed by wiki markups
   global $BlockPattern, $KeepToken, $KPV, $KPCount;
   $x = preg_replace_callback("/$KeepToken(\\d.*?)$KeepToken/", 'cb_expandkpv', $x);
@@ -1408,6 +1805,9 @@ function Keep($x, $pool=NULL) {
   return $KeepToken.$KPCount.$pool.$KeepToken;
 }
 
+function KeepBlock($x, $pool=NULL) {
+  return '<:block>' . Keep($x, $pool);
+}
 
 ##  MarkupEscape examines markup source and escapes any [@...@]
 ##  and [=...=] sequences using Keep().  MarkupRestore undoes the
@@ -1415,10 +1815,12 @@ function Keep($x, $pool=NULL) {
 function MarkupEscape($text) {
   global $EscapePattern;
   SDV($EscapePattern, '\\[([=@]).*?\\1\\]');
-  return preg_replace_callback("/$EscapePattern/s", "Keep", $text);
+  return preg_replace_callback("/$EscapePattern/s", "Keep", strval($text));
 }
 function MarkupRestore($text) {
   global $KeepToken, $KPV;
+  if (is_null($text)) return '';
+  if (!$text) return $text;
   return preg_replace_callback("/$KeepToken(\\d.*?)$KeepToken/", 'cb_expandkpv', $text);
 }
 
@@ -1459,6 +1861,7 @@ function CondText($pagename,$condspec,$condtext) {
 ##  Returns the text unchanged if no sections are requested,
 ##  or false if a requested beginning anchor isn't in the text.
 function TextSection($text, $sections, $args = NULL) {
+  if (!$text) return false; # PHP 8.1
   $args = (array)$args;
   $npat = '[[:alpha:]][-\\w.]*';
   if (!preg_match("/#($npat)?(\\.\\.)?(#($npat)?)?/", $sections, $match))
@@ -1489,13 +1892,13 @@ function RetrieveAuthSection($pagename, $pagesection, 
   global $RASPageName, $PCache;
   if ($pagesection[0] != '#')
     $list = array(MakePageName($pagename, $pagesection));
-  else if (is_null($list)) $list = array($pagename);
+  elseif (is_null($list)) $list = array($pagename);
   foreach((array)$list as $t) {
     $t = FmtPageName($t, $pagename);
     if (!PageExists($t)) continue;
     $tpage = RetrieveAuthPage($t, $auth, false, READPAGE_CURRENT);
     if (!$tpage) continue;
-    $text = TextSection(IsEnabled($PCache[$t]['=preview'],$tpage['text']),$pagesection);
+    $text = TextSection(IsEnabled($PCache[$t]['=preview'],strval(@$tpage['text'])),$pagesection);
     if ($text !== false) { $RASPageName = $t; return $text; }
   }
   $RASPageName = '';
@@ -1503,7 +1906,7 @@ function RetrieveAuthSection($pagename, $pagesection, 
 }
 
 function IncludeText($pagename, $inclspec) {
-  global $MaxIncludes, $IncludeOpt, $InclCount, $PCache;
+  global $MaxIncludes, $IncludeOpt, $InclCount, $PCache, $IncludedPages;
   SDV($MaxIncludes,50);
   SDVA($IncludeOpt, array('self'=>1));
   if (@$InclCount[$pagename]++>=$MaxIncludes) return Keep($inclspec);
@@ -1516,11 +1919,14 @@ function IncludeText($pagename, $inclspec) {
         $iname = MakePageName($pagename, $v);
         if (!$args['self'] && $iname == $pagename) continue;
         $ipage = RetrieveAuthPage($iname, 'read', false, READPAGE_CURRENT);
-        $itext = IsEnabled($PCache[$iname]['=preview'], @$ipage['text']);
+        if (isset($PCache[$iname]['=preview'])) $itext = $PCache[$iname]['=preview'];
+        elseif (isset($ipage['text'])) $itext = $ipage['text'];
       }
-      $itext = TextSection(@$itext, $v, array('anchors' => 1));
+      if (isset($itext))
+        $itext = TextSection($itext, $v, array('anchors' => 1));
       continue;
     }
+    $itext = strval(@$itext);
     if (preg_match('/^(?:line|para)s?$/', $k)) {
       preg_match('/^(\\d*)(\\.\\.(\\d*))?$/', $v, $match);
       @list($x, $a, $dots, $b) = $match;
@@ -1536,6 +1942,7 @@ function IncludeText($pagename, $inclspec) {
               ? MakePageName($pagename, $args['basepage'])
               : @$iname;
   if ($basepage) $itext = Qualify(@$basepage, @$itext);
+  if (@$itext) @$IncludedPages[$iname]++;
   return FmtTemplateVars(PVSE(@$itext), $args);
 }
 
@@ -1577,13 +1984,13 @@ function Block($b) {
   }
   @list($code, $depth, $icol) = explode(',', $b);
   if (!$code) $depth = 1;
-  if ($depth == 0) $depth = strlen($depth);
-  if ($icol == 0) $icol = strlen($icol);
+  if (!is_numeric($depth)) $depth = @$depth? strlen($depth) : 0; # PHP8.1
+  if (!is_numeric($icol)) $icol = @$icol? strlen($icol) : 0; # PHP8.1
   if ($depth > 0) $depth += @$mf['idep'];
   if ($icol > 0) $mf['is'][$depth] = $icol + @$mf['icol'];
   @$mf['idep'] = @$mf['icol'] = 0;
   while (count($cs)>$depth) 
-    { $c = array_pop($cs); $out .= $BlockMarkups[$c][2]; }
+    { $c = array_pop($cs); $out .= @$BlockMarkups[$c][2]; }
   if (!$code) {
     if (@end($cs) == 'p') { $out .= $HTMLPNewline; $code = 'p'; }
     else if ($depth < 2) { $code = 'p'; $mf['is'][$depth] = 0; }
@@ -1681,16 +2088,19 @@ function LinkIMap($pagename,$imap,$path,$alt,$txt,$fmt
   }
   $FmtV['$LinkUrl'] = PUE(str_replace('$1',$path,$IMap[$imap]));
   $FmtV['$LinkText'] = $txt;
-  $FmtV['$LinkAlt'] = str_replace(array('"',"'"),array('&#34;','&#39;'),$alt);
+  if (@$alt) $FmtV['$LinkAlt'] = Keep(str_replace(array('"',"'"),array('&#34;','&#39;'),$alt));
+  else $FmtV['$LinkAlt'] = '';
   if (!$fmt) 
     $fmt = (isset($IMapLinkFmt[$imap])) ? $IMapLinkFmt[$imap] : $UrlLinkFmt;
-  if(IsEnabled($AddLinkCSS['samedomain'])) {
+  if (IsEnabled($AddLinkCSS['samedomain'])) {
     $parsed_url = parse_url($FmtV['$LinkUrl']);
     $parsed_wiki = parse_url($ScriptUrl);
-    if(! @$parsed_url['host'] || $parsed_url['host'] == $parsed_wiki['host']) {
+    if (! @$parsed_url['host'] || $parsed_url['host'] == $parsed_wiki['host']) {
       $fmt = preg_replace('/(<a[^>]*class=["\'])/', "$1{$AddLinkCSS['samedomain']} ", $fmt);
     }
   }
+  # remove unused title attributes
+  if (!$alt) $fmt = preg_replace('/\\stitle=([\'"])\\$LinkAlt\\1/', '', $fmt);
   return str_replace(array_keys($FmtV),array_values($FmtV),$fmt);
 }
 
@@ -1705,7 +2115,7 @@ function ObfuscateLinkIMap($pagename,$imap,$path,$titl
     "<span class='_pmXmail' title=\"\$LinkAlt\"><span class='_t'>\$LinkText</span><span class='_m'>\$LinkUrl</span></span>"));
   $FmtV['$LinkUrl'] = cb_obfuscate_mail(str_replace('$1',$path,$IMap[$imap]));
   $FmtV['$LinkText'] = cb_obfuscate_mail(preg_replace('/^mailto:/i', '', $txt));
-  if($FmtV['$LinkText'] == preg_replace('/^mailto:/i', '', $FmtV['$LinkUrl'])) $FmtV['$LinkUrl'] = '';
+  if ($FmtV['$LinkText'] == preg_replace('/^mailto:/i', '', $FmtV['$LinkUrl'])) $FmtV['$LinkUrl'] = '';
   else $FmtV['$LinkUrl'] = " -&gt; ".$FmtV['$LinkUrl'];
   $FmtV['$LinkAlt'] = str_replace(array('"',"'"),array('&#34;','&#39;'),cb_obfuscate_mail($title, 0));
   return str_replace(array_keys($FmtV),array_values($FmtV), $IMapLinkFmt['obfuscate-mailto:']);
@@ -1726,9 +2136,10 @@ function cb_obfuscate_mail($x, $wrap=1) {
 function LinkPage($pagename,$imap,$path,$alt,$txt,$fmt=NULL) {
   global $QueryFragPattern, $LinkPageExistsFmt, $LinkPageSelfFmt,
     $LinkPageCreateSpaceFmt, $LinkPageCreateFmt, $LinkTargets,
-    $EnableLinkPageRelative, $EnableLinkPlusTitlespaced, $AddLinkCSS;
-  $alt = str_replace(array('"',"'"),array('&#34;','&#39;'),$alt);
-  $path = preg_replace('/(#[-.:\\w]*)#.*$/', '$1', $path); # PITS:01388
+    $EnableLinkPageRelative, $EnableLinkPlusTitlespaced, $AddLinkCSS,
+    $CategoryGroup, $LinkCategoryFmt;
+  if ($alt) $alt = str_replace(array('"',"'"),array('&#34;','&#39;'),$alt);
+  $path = preg_replace('/(#[-.:\\w]*)#.*$/', '$1', strval($path)); # PITS:01388
   if (is_array($txt)) { # PITS:01392
     $suffix = $txt[1];
     $txt = $txt[0];
@@ -1739,12 +2150,22 @@ function LinkPage($pagename,$imap,$path,$alt,$txt,$fmt
     if ($alt) $alt = " title='$alt'";
     return ($path) ? "<a href='#$path'$alt>".str_replace("$", "&#036;", $txt)."</a>" : '';
   }
+  if (preg_match('/^\\s*!/', $path)) {
+    $is_cat = true;
+    $path = preg_replace('/^\\s*!/', "$CategoryGroup/", $path);
+    $txt = preg_replace('/^\\s*!/', '', $txt);
+  }
   if (!preg_match("/^\\s*([^#?]+)($QueryFragPattern)?$/",$path,$match))
     return '';
   $tgtname = MakePageName($pagename, $match[1]); 
   if (!$tgtname) return '';
-  $qf = @$match[2];
+  $qf = @$match[2]? $match[2] : '';
   @$LinkTargets[$tgtname]++;
+  if (@$is_cat) {
+    $fmt = $LinkCategoryFmt;
+    $c = preg_replace('/^.*\\./', '!', $tgtname);
+    @$LinkTargets[$c]++;
+  }
   if (!$fmt) {
     if (!PageExists($tgtname) && !preg_match('/[&?]action=/', $qf))
       $fmt = preg_match('/\\s/', $txt) 
@@ -1759,12 +2180,14 @@ function LinkPage($pagename,$imap,$path,$alt,$txt,$fmt
   $txt = str_replace("$", "&#036;", $txt);
   if (@$EnableLinkPageRelative)
     $url = preg_replace('!^[a-z]+://[^/]*!i', '', $url);
+  # remove unused title attributes
+  if (!$alt) $fmt = preg_replace('/\\stitle=([\'"])\\$LinkAlt\\1/', '', $fmt);
   $fmt = str_replace(array('$LinkUrl', '$LinkText', '$LinkAlt'),
-                     array($url.PUE($qf), $txt, $alt), $fmt);
-  if(IsEnabled($AddLinkCSS['othergroup'])) {
+                     array($url.PUE($qf), $txt, Keep($alt)), $fmt);
+  if (IsEnabled($AddLinkCSS['othergroup'])) {
     list($cgroup, ) = explode('.', $pagename);
     list($tgroup, ) = explode('.', $tgtname);
-    if($cgroup != $tgroup) 
+    if ($cgroup != $tgroup) 
       $fmt = preg_replace('/(<a[^>]*class=["\'])/', "$1{$AddLinkCSS['othergroup']} ", $fmt);
   }
   return FmtPageName($fmt,$tgtname);
@@ -1773,11 +2196,11 @@ function LinkPage($pagename,$imap,$path,$alt,$txt,$fmt
 function MakeLink($pagename,$tgt,$txt=NULL,$suffix=NULL,$fmt=NULL) {
   global $LinkPattern,$LinkFunctions,$UrlExcludeChars,$ImgExtPattern,$ImgTagFmt,
     $LinkTitleFunction;
-  if(preg_match("/^(.*)(?:\"(.*)\")\\s*$/",$tgt,$x)) list(,$tgt,$title) = $x;
+  if (preg_match("/^(.*)(?:\"(.*)\")\\s*$/",$tgt,$x)) list(,$tgt,$title) = $x;
   $t = preg_replace('/[()]/','',trim($tgt));
   $t = preg_replace('/<[^>]*>/','',$t);
   $t = trim(MarkupRestore($t));
-  $txtr = trim(MarkupRestore($txt));
+  $txtr = trim(MarkupRestore(strval($txt)));
   
   preg_match("/^($LinkPattern)?(.+)$/",$t,$m);
   if (!@$m[1]) $m[1]='<:page>';
@@ -1803,8 +2226,8 @@ function MakeLink($pagename,$tgt,$txt=NULL,$suffix=NUL
   return preg_replace('/(<[^>]+)\\stitle=(""|\'\')/', '$1', $out);
 }
 
-function Markup($id, $when, $pat=NULL, $rep=NULL, $tracelev=0) {
-  global $MarkupTable, $EnableMarkupDiag;
+function Markup($id, $when, $pat=NULL, $rep=NULL) {
+  global $MarkupTable, $EnableMarkupDiag, $ObsoleteMarkups;
   unset($GLOBALS['MarkupRules']);
   if (preg_match('/^([<>])?(.+)$/', $when, $m)) {
     $MarkupTable[$id]['cmd'] = $when;
@@ -1818,29 +2241,63 @@ function Markup($id, $when, $pat=NULL, $rep=NULL, $tra
     }
   }
   if ($pat && !isset($MarkupTable[$id]['pat'])) {
+    $oldpat = preg_match('!(^/.+/[^/]*)e([^/]*)$!', $pat, $mm);
+    if ($oldpat && PHP_VERSION_ID >= 50500) {
+      # disable old markup for recent PHP versions
+      $trace = TraceMarkup($id, true);
+      $rep = 'ObsoleteMarkup';
+      $pat = $mm[1].$mm[2];
+    }    
     $MarkupTable[$id]['pat'] = $pat;
     $MarkupTable[$id]['rep'] = $rep;
+    
+    if (IsEnabled($EnableMarkupDiag, 0) || isset($ObsoleteMarkups[$id])) {
+      $MarkupTable[$id]['dbg'] = isset($ObsoleteMarkups[$id])
+        ? $ObsoleteMarkups[$id]
+        : TraceMarkup($id, false);
+    }
+  }
+}
 
-    $oldpat = preg_match('!/[^/]*e[^/]*$!', $pat);
-    if (IsEnabled($EnableMarkupDiag, 0) || $oldpat) {
-      $exmark = $oldpat ? '!' : ' ';
-      if (function_exists('debug_backtrace')) {
-        $dbg = debug_backtrace();
-        $dbginfo = $dbg[$tracelev];
-        $MarkupTable[$id]['dbg'] = "$exmark file: {$dbginfo['file']}, "
-          . "line: {$dbginfo['line']}, pat: {$dbginfo['args'][2]}";
-      }
-      else 
-        $MarkupTable[$id]['dbg'] = "$exmark id: '$id', pat: '$pat'";
+function Markup_e($id, $when, $pat, $rep, $template = 'markup_e') {
+  if (!is_callable($rep)) {
+    if (PHP_VERSION_ID < 70200 || isset($GLOBALS['PCCFOverrideFunction']))
+      $rep = PCCF($rep, $template);
+    else {
+      TraceMarkup($id, true);
+      $rep = 'ObsoleteMarkup';
     }
   }
+  Markup($id, $when, $pat, $rep, 1);
 }
 
-function Markup_e($id, $when, $pat, $rep, $template = 'markup_e') {
-  if (!is_callable($rep)) $rep = PCCF($rep, $template);
-  Markup($id, $when, $pat, $rep, 1);
+function TraceMarkup($id, $obsolete = false) {
+  global $ObsoleteMarkups;
+  $trace = debug_backtrace();
+  foreach($trace as $t) {
+    if (! preg_match('/^Markup(_e)?$/i', $t['function'])) continue;
+    if ($t['args'][0] !== $id) continue;
+    $excl = $obsolete? "!" : " ";
+    $msg = "$excl File: {$t['file']}, line: {$t['line']}"
+      . ", pat: {$t['args'][2]}, rep: {$t['args'][3]}.";
+    if ($obsolete) $ObsoleteMarkups[$id] = $msg;
+    return $msg;
+  }
 }
 
+function ObsoleteMarkup($m) {
+  extract($GLOBALS['MarkupToHTML']);
+  global $ObsoleteMarkups;
+  $id = PHSC($markupid, ENT_QUOTES, null, false);
+  $txt = PHSC($m[0], ENT_QUOTES, null, false);
+  if (isset($ObsoleteMarkups[$markupid])) {
+    $dbg = PHSC($ObsoleteMarkups[$markupid], ENT_QUOTES, null, false);
+  }
+  else $dbg = '';
+  return Keep("<code title='Markup rule &quot;$id&quot; is obsolete and has been disabled. $dbg See pmwiki.org/Troubleshooting' 
+    class='obsolete-markup frame'>&#9888; $txt</code>");
+}
+
 function DisableMarkup() {
   global $MarkupTable;
   $idlist = func_get_args();
@@ -1859,7 +2316,7 @@ function BuildMarkupRules() {
     uasort($MarkupTable,'mpcmp');
     foreach($MarkupTable as $id=>$m) 
       if (@$m['pat'] && @$m['seq']) {
-        $MarkupRules[str_replace('\\L',$LinkPattern,$m['pat'])]
+        $MarkupRules[str_replace('\\L',strval(@$LinkPattern),$m['pat'])]
           = array($m['rep'], $id);
       }
   }
@@ -1892,7 +2349,7 @@ function MarkupToHTML($pagename, $text, $opt = NULL) {
         else $x=preg_replace($p,$r,$x); # simple text OR called by old addon|skin|recipe needing update, see pmwiki.org/Troubleshooting
       }
       elseif (strstr($x,$p)!==false) $x=eval($r);
-      if (isset($php_errormsg)) 
+      if (isset($php_errormsg)) ### TODO: $php_errormsg removed since PHP 8
         { echo "ERROR: pat=$p $php_errormsg"; unset($php_errormsg); }
       if ($RedoMarkupLine) { $lines=array_merge((array)$x,$lines); continue 2; }
     }
@@ -1912,7 +2369,7 @@ function HandleBrowse($pagename, $auth = 'read') {
   $page = RetrieveAuthPage($pagename, $auth, true, READPAGE_CURRENT);
   if (!$page) Abort("?cannot read $pagename");
   PCache($pagename,$page);
-  if (PageExists($pagename)) $text = @$page['text'];
+  if (PageExists($pagename)) $text = $FmtV['$PageSourceText'] = @$page['text'];
   else {
     SDV($DefaultPageTextFmt,'(:include $[{$SiteGroup}.PageNotFound]:)');
     $text = FmtPageName($DefaultPageTextFmt, $pagename);
@@ -1975,6 +2432,38 @@ function UpdatePage(&$pagename, &$page, &$new, $fnlist
   return $IsPagePosted;
 }
 
+# AutoCheckToken verifies if the posted content was sent
+# from the website forms, to prevent CSRF
+function AutoCheckToken() {
+  # TODO: Work in progress (Jan 2021), releasing for 
+  return true;
+    
+  global $EnablePost, $AutoCheckTokenActions, $EnablePmToken, 
+    $FmtV, $action, $BlockMessageFmt, $MessagesFmt;
+  
+  # a quick way to disable tokens
+  if (! IsEnabled($EnablePmToken, 1)) return true; 
+  
+  SDVA($AutoCheckTokenActions, array( # 1=POST, 2=GET, 0=disabled
+    'edit' => 1, 
+    'postattr' => 1,
+    'postupload' => 1,
+    'approvesites' => 2,
+    'approveurls' => 2,
+  ));
+  $tname = $FmtV['$TokenName'];
+  $x = @$AutoCheckTokenActions[$action];
+  if (!$x) return true;
+  elseif ($x==1) {
+    if ( count($_POST) < 1 || pmtoken(''.@$_POST[$tname]) ) return true;
+  }
+  elseif ($x==2 && pmtoken(''.@$_GET[$tname])) return true;
+  
+  $EnablePost = 0;
+  $MessagesFmt[] = $BlockMessageFmt;
+  $MessagesFmt[] = XL('Token invalid or missing.');
+  return false;
+}
 
 # EditTemplate allows a site administrator to pre-populate new pages
 # with the contents of another page.
@@ -2075,39 +2564,40 @@ function PostPage($pagename, &$page, &$new) {
   SDV($DiffKeepNum,20);
   SDV($DeleteKeyPattern,"^\\s*delete\\s*$");
   $IsPagePosted = false;
-  if ($EnablePost) {
-    $new['charset'] = $Charset; # kept for now, may be needed if custom PageStore
-    $new['author'] = @$Author;
-    $new["author:$Now"] = @$Author;
-    $new["host:$Now"] = $_SERVER['REMOTE_ADDR'];
-    $diffclass = preg_replace('/\\W/','',@$_POST['diffclass']);
-    if ($page['time']>0 && function_exists(@$DiffFunction)) 
-      $new["diff:$Now:{$page['time']}:$diffclass"] =
-        $DiffFunction($new['text'],@$page['text']);
-    $keepgmt = $Now-$DiffKeepDays * 86400;
-    $keepnum = array(); 
-    $keys = array_keys($new);
-    foreach($keys as $k)
-      if (preg_match("/^\\w+:(\\d+)/",$k,$match)) {
-        $keepnum[$match[1]] = 1;
-        if (count($keepnum)>$DiffKeepNum && $match[1]<$keepgmt) 
-          unset($new[$k]);
-      }
-    if (preg_match("/$DeleteKeyPattern/",$new['text'])){
-      if (@$new['passwdattr']>'' && !CondAuth($pagename, 'attr'))
-        Abort('$[The page has an "attr" attribute and cannot be deleted.]');
-      else  $WikiDir->delete($pagename);
-    }
-    else WritePage($pagename,$new);
+  if (!$EnablePost) return;
+  if (preg_match("/$DeleteKeyPattern/",$new['text'])) {
+    if (@$new['passwdattr']>'' && !CondAuth($pagename, 'attr'))
+      Abort('$[The page has an "attr" attribute and cannot be deleted.]');
+    else  $WikiDir->delete($pagename);
     $IsPagePosted = true;
+    return;
   }
+  $new['charset'] = $Charset; # kept for now, may be needed if custom PageStore
+  $new['author'] = @$Author;
+  $new["author:$Now"] = @$Author;
+  $new["host:$Now"] = strval(@$_SERVER['REMOTE_ADDR']);
+  $diffclass = preg_replace('/\\W/','',strval(@$_POST['diffclass']));
+  if ($page['time']>0 && function_exists(@$DiffFunction)) 
+    $new["diff:$Now:{$page['time']}:$diffclass"] =
+      $DiffFunction($new['text'],@$page['text']);
+  $keepgmt = $Now-$DiffKeepDays * 86400;
+  $keepnum = array(); 
+  $keys = array_keys($new);
+  foreach($keys as $k)
+    if (preg_match("/^\\w+:(\\d+)/",$k,$match)) {
+      $keepnum[$match[1]] = 1;
+      if (count($keepnum)>$DiffKeepNum && $match[1]<$keepgmt) 
+        unset($new[$k]);
+    }
+  WritePage($pagename,$new);
+  $IsPagePosted = true;
 }
 
 function PostRecentChanges($pagename,$page,$new,$Fmt=null) {
   global $IsPagePosted, $RecentChangesFmt, $RCDelimPattern, $RCLinesMax,
-    $EnableRCDiffBytes;
+    $EnableRCDiffBytes, $Now, $EnableLocalTimes;
   if (!$IsPagePosted && $Fmt==null) return;
-  if ($Fmt==null) $Fmt = $RecentChangesFmt;
+  if (is_null($Fmt)) $Fmt = $RecentChangesFmt;
   foreach($Fmt as $rcfmt=>$pgfmt) {
     $rcname = FmtPageName($rcfmt,$pagename);  if (!$rcname) continue;
     $pgtext = FmtPageName($pgfmt,$pagename);  if (!$pgtext) continue;
@@ -2148,16 +2638,37 @@ function AutoCreateTargets($pagename, &$page, &$new) {
 }
 
 function PreviewPage($pagename,&$page,&$new) {
-  global $IsPageSaved, $FmtV, $ROSPatterns;
+  global $IsPageSaved, $FmtV, $ROSPatterns, $PCache, 
+    $HTMLStylesFmt, $IncludedPages, $EnableListIncludedPages;
+  $text = ProcessROESPatterns($new['text'], $ROSPatterns);
+  $text = '(:groupheader:)'.$text.'(:groupfooter:)';
+  $IncludedPages = array();
+  $preview = MarkupToHTML($pagename,$text);
+  $incp = array_diff(array_keys($IncludedPages), array($pagename));
+  $cnt = count($incp);
+  if (IsEnabled($EnableListIncludedPages,0) && $cnt) {
+    $label = XL('Text or data included from other pages');
+    $edit = XL('Edit');
+    SDV($HTMLStylesFmt['inclpages'], 'details.inclpages {display: inline-block;}');
+    $out = "<br/><details class='inclpages'>"
+      . "<summary>($cnt) $label</summary><ul>\n";
+    sort($incp);
+    foreach($incp as $pn) {
+      $url = PageVar($pn, '$PageUrl');
+      $out .= "<li> <a class='wikilink' href='$url'>$pn</a> 
+        (<a class='wikilink' href='$url?action=edit'>$edit</a>)</li>\n";
+    }
+    $out .= "</ul></details>";
+    $FmtV['$IncludedPages'] = $out;
+  }
+  else $FmtV['$IncludedPages'] = '';
   if (@$_REQUEST['preview']) {
-    $text = ProcessROESPatterns($new['text'], $ROSPatterns);
-    $text = '(:groupheader:)'.$text.'(:groupfooter:)';
-    $FmtV['$PreviewText'] = MarkupToHTML($pagename,$text);
+    $FmtV['$PreviewText'] = $preview;
   }
 }
 
 function HandleEdit($pagename, $auth = 'edit') {
-  global $IsPagePosted, $EditFields, $ChangeSummary, $EditFunctions, 
+  global $IsPagePosted, $EditFields, $ChangeSummary, $EditFunctions,
     $EnablePost, $FmtV, $Now, $EditRedirectFmt, $EnableRCDiffBytes, 
     $PageEditForm, $HandleEditFmt, $PageStartFmt, $PageEditFmt, $PageEndFmt;
   SDV($EditRedirectFmt, '$FullName');
@@ -2171,13 +2682,13 @@ function HandleEdit($pagename, $auth = 'edit') {
     if (isset($_POST[$k])) $new[$k]=str_replace("\r",'',stripmagic($_POST[$k]));
     
   if (IsEnabled($EnableRCDiffBytes, 0) && isset($new['text'])) {
-    $bytes = strlen($new['text']) - strlen(@$page['text']);
+    $bytes = strlen($new['text']) - strlen(strval(@$page['text']));
     if ($bytes>=0) $bytes = "+$bytes";
     $ChangeSummary = rtrim($ChangeSummary) . " ($bytes)";
   }
   $new['csum'] = $ChangeSummary;
   if ($ChangeSummary) $new["csum:$Now"] = $ChangeSummary;
-  $EnablePost &= preg_grep('/^post/', array_keys(@$_POST));
+  $EnablePost &= (bool)preg_grep('/^post/', array_keys(@$_POST));
   $new['=preview'] = @$new['text'];
   PCache($pagename, $new);
   UpdatePage($pagename, $page, $new);
@@ -2189,6 +2700,7 @@ function HandleEdit($pagename, $auth = 'edit') {
   $FmtV['$EditText'] = 
     str_replace('$','&#036;',PHSC(@$new['text'],ENT_NOQUOTES));
   $FmtV['$EditBaseTime'] = $Now;
+  $FmtV['$TokenValue'] = pmtoken();
   if (@$PageEditForm) {
     $efpage = FmtPageName($PageEditForm, $pagename);
     $form = RetrieveAuthPage($efpage, 'read', false, READPAGE_CURRENT);
@@ -2202,9 +2714,9 @@ function HandleEdit($pagename, $auth = 'edit') {
     <input type='hidden' name='action' value='edit' />
     <input type='hidden' name='n' value='\$FullName' />
     <input type='hidden' name='basetime' value='\$EditBaseTime' />
+    <input type='hidden' name='\$TokenName' value='\$TokenValue' />
     \$EditMessageFmt
     <textarea id='text' name='text' rows='25' cols='60'
-      onkeydown='if (event.keyCode==27) event.returnValue=false;'
       >\$EditText</textarea><br />
     <input type='submit' name='post' value=' $[Save] ' />");
   SDV($HandleEditFmt, array(&$PageStartFmt, &$PageEditFmt, &$PageEndFmt));
@@ -2230,8 +2742,7 @@ function HandleSource($pagename, $auth = 'read') {
 ## GroupAttribute pages to be able to speed up subsequent calls.
 function PmWikiAuth($pagename, $level, $authprompt=true, $since=0) {
   global $DefaultPasswords, $GroupAttributesFmt, $AllowPassword,
-    $AuthCascade, $FmtV, $AuthPromptFmt, $PageStartFmt, $PageEndFmt, 
-    $AuthId, $AuthList, $NoHTMLCache;
+    $AuthCascade, $AuthId, $AuthList, $NoHTMLCache;
   static $acache;
   SDV($GroupAttributesFmt,'$Group/GroupAttributes');
   SDV($AllowPassword,'nopass');
@@ -2280,6 +2791,13 @@ function PmWikiAuth($pagename, $level, $authprompt=tru
   $GLOBALS['AuthNeeded'] = (@$_POST['authpw']) 
     ? $page['=pwsource'][$level] . ' ' . $level : '';
   PCache($pagename, $page);
+  PrintAuthForm($pagename);
+  exit;
+}
+
+## Split from PmWikiAuth to allow for recipes to call it
+function PrintAuthForm($pagename) {
+  global $FmtV, $AuthPromptFmt, $PageStartFmt, $PageEndFmt;
   $postvars = '';
   foreach($_POST as $k=>$v) {
     if ($k == 'authpw' || $k == 'authid') continue;
@@ -2299,19 +2817,18 @@ function PmWikiAuth($pagename, $level, $authprompt=tru
     }
   }
   $FmtV['$PostVars'] = $postvars;
-  $r = str_replace("'", '%37', stripmagic($_SERVER['REQUEST_URI']));
+  $r = str_replace("'", '%37', stripmagic(strval(@$_SERVER['REQUEST_URI'])));
   SDV($AuthPromptFmt,array(&$PageStartFmt,
     "<p><b>$[Password required]</b></p>
       <form name='authform' action='$r' method='post'>
         $[Password]: <input tabindex='1' type='password' name='authpw' 
-          value='' />
-        <input type='submit' value='$[OK]' />\$PostVars</form>
-        <script language='javascript' type='text/javascript'><!--
-          document.authform.authpw.focus() //--></script>", &$PageEndFmt));
+          value='' autofocus='autofocus' />
+        <input type='submit' value='$[OK]' />\$PostVars</form>", &$PageEndFmt));
   PrintFmt($pagename,$AuthPromptFmt);
   exit;
 }
 
+
 function IsAuthorized($chal, $source, &$from) {
   global $AuthList, $AuthPw, $AllowPassword;
   if (!$chal) return $from;
@@ -2352,7 +2869,7 @@ function IsAuthorized($chal, $source, &$from) {
 ## as needed.
 function SessionAuth($pagename, $auth = NULL) {
   global $AuthId, $AuthList, $AuthPw, $SessionEncode, $SessionDecode,
-    $EnableSessionPasswords;
+    $EnableSessionPasswords, $EnableAuthPostRegenerateSID;
   static $called;
 
   @$called++;
@@ -2360,7 +2877,12 @@ function SessionAuth($pagename, $auth = NULL) {
   if (!$auth && ($called > 1 || (!@$_REQUEST[$sn] && !@$_COOKIE[$sn]))) return;
 
   $sid = session_id();
-  @session_start();
+  pm_session_start();
+  if ($called == 1 && isset($_POST['authpw']) && $_POST['authpw']
+    && IsEnabled($EnableAuthPostRegenerateSID, true) && $sid) {
+    @session_regenerate_id();
+  }
+  
   foreach((array)$auth as $k => $v) {
     if ($k == 'authpw') {
       foreach((array)$v as $pw => $pv) {
@@ -2371,7 +2893,7 @@ function SessionAuth($pagename, $auth = NULL) {
     else if ($k) $_SESSION[$k] = (array)$v + (array)@$_SESSION[$k];
   }
 
-  if (!isset($AuthId)) $AuthId = @end($_SESSION['authid']);
+  if (!isset($AuthId)) $AuthId = @$_SESSION['authid'] ? @end($_SESSION['authid']) : '';
   $AuthPw = array_map($SessionDecode, array_keys((array)@$_SESSION['authpw']));
   if (!IsEnabled($EnableSessionPasswords, 1)) $_SESSION['authpw'] = array();
   $AuthList = array_merge($AuthList, (array)@$_SESSION['authlist']);
@@ -2407,8 +2929,10 @@ function PasswdVar($pagename, $level) {
 
 function PrintAttrForm($pagename) {
   global $PageAttributes, $PCache, $FmtV;
+  $FmtV['$TokenValue'] = pmtoken();
   echo FmtPageName("<form action='\$PageUrl' method='post'>
     <input type='hidden' name='action' value='postattr' />
+    <input type='hidden' name='\$TokenName' value='\$TokenValue' />
     <input type='hidden' name='n' value='\$FullName' />
     <table>",$pagename);
   $page = $PCache[$pagename];
@@ -2446,6 +2970,9 @@ function HandleAttr($pagename, $auth = 'attr') {
 
 function HandlePostAttr($pagename, $auth = 'attr') {
   global $PageAttributes, $EnablePostAttrClearSession;
+  if (! AutoCheckToken()) {
+    Abort('? $[Token invalid or missing.]');
+  }
   Lock(2);
   $page = RetrieveAuthPage($pagename, $auth, true);
   if (!$page) { Abort("?unable to read $pagename"); }
@@ -2466,7 +2993,7 @@ function HandlePostAttr($pagename, $auth = 'attr') {
   WritePage($pagename,$page);
   Lock(0);
   if (IsEnabled($EnablePostAttrClearSession, 1)) {
-    @session_start();
+    pm_session_start();
     unset($_SESSION['authid']);
     unset($_SESSION['authlist']);
     $_SESSION['authpw'] = array();
@@ -2480,7 +3007,7 @@ function HandleLogoutA($pagename, $auth = 'read') {
   global $LogoutRedirectFmt, $LogoutCookies;
   SDV($LogoutRedirectFmt, '$FullName');
   SDV($LogoutCookies, array());
-  @session_start();
+  pm_session_start();
   $_SESSION = array();
   if ( session_id() != '' || isset($_COOKIE[session_name()]) )
     pmsetcookie(session_name(), '', time()-43200, '/');
blob - 0902cdd9f1cb15d768fcb02106b17d3991517a91
blob + 16bb1b4af2afd09b9a1365cffa232b8706716bb4
--- pub/guiedit/guiedit.js
+++ pub/guiedit/guiedit.js
@@ -1,10 +1,10 @@
-/*  Copyright 2004-2019 Patrick R. Michaud (pmichaud@pobox.com)
+/*  Copyright 2004-2022 Patrick R. Michaud (pmichaud@pobox.com)
     This file is part of PmWiki; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published
     by the Free Software Foundation; either version 2 of the License, or
     (at your option) any later version.  See pmwiki.php for full details.
 
-    This file provides Javascript functions to support WYSIWYG-style
+    This file provides JavaScript functions to support WYSIWYG-style
     editing.  The concepts are borrowed from the editor used in Wikipedia,
     but the code has been rewritten from scratch to integrate better with
     PHP and PmWiki's codebase.
@@ -22,14 +22,23 @@ function insButton(mopen, mclose, mtext, mlabel, mkey)
 }
 
 function insMarkup() {
-  var func = false, tid='text', mopen = '', mclose = '', mtext = '';
+  var func = false, tid='text', mopen = '', mclose = '', mtext = '', unselect = false;
   if (arguments[0] == 'FixSelectedURL') {
     func = FixSelectedURL;
   }
   else if (typeof arguments[0] == 'function') {
     var func = arguments[0];
     if(arguments.length > 1) tid = arguments[1];
-    mtext = func('');
+    x = func('');
+    if(typeof x == 'object') {
+      if(x.mopen) mopen = x.mopen;
+      if(x.mclose) mclose = x.mclose;
+      if(x.mtext) mtext = x.mtext;
+      if(x.unselect) unselect = x.unselect;
+    }
+    else {
+      mtext = x;
+    }
   }
   else if (arguments.length >= 3) {
     var mopen = arguments[0], mclose = arguments[1], mtext = arguments[2];
@@ -37,7 +46,7 @@ function insMarkup() {
   }
 
   var tarea = document.getElementById(tid);
-  if (tarea.setSelectionRange > '') {
+  if (tarea.setSelectionRange > '') { // recent browsers
     var p0 = tarea.selectionStart;
     var p1 = tarea.selectionEnd;
     var top = tarea.scrollTop;
@@ -51,11 +60,17 @@ function insMarkup() {
       cur0 = p0 + mopen.length + str.length + mclose.length;
       cur1 = cur0;
     }
-    tarea.value = tarea.value.substring(0,p0)
-      + mopen + str + mclose
-      + tarea.value.substring(p1);
-    tarea.focus();
-    tarea.selectionStart = cur0;
+    if(document.execCommand) {
+      tarea.focus();
+      document.execCommand('insertText', false, mopen + str + mclose);
+    }
+    else {
+      tarea.value = tarea.value.substring(0,p0)
+        + mopen + str + mclose
+        + tarea.value.substring(p1);
+      tarea.focus();
+    }
+    tarea.selectionStart = unselect? cur1 : cur0;
     tarea.selectionEnd = cur1;
     tarea.scrollTop = top;
   } else if (document.selection) {
@@ -74,8 +89,10 @@ function insMarkup() {
       }
       range.text = mopen + str + mclose;
     }
-    range.select();
+    if (!unselect) range.select();
   } else { tarea.value += mopen + mtext + mclose; }
+  var evt = new Event('input');
+  tarea.dispatchEvent(evt);
   return;
 }
 
@@ -87,7 +104,6 @@ function aE(el, ev, fn) {
 function dqs(str)  { return document.querySelector(str); }
 function dqsa(str) { return document.querySelectorAll(str); }
 function tap(q, fn) { aE(q, 'click', fn); };
-function adata(el, x) { return el.getAttribute("data-"+x); }
 function FixSelectedURL(str) {
   var rx = new RegExp("[ <>\"{}|\\\\^`()\\[\\]']", 'g');
   str = str.replace(rx, function(a){
@@ -96,6 +112,8 @@ function FixSelectedURL(str) {
 }
 
 window.addEventListener('DOMContentLoaded', function(){
+  newButtons();
+  
   var NsForm = false;
 
   var sTop = dqs("#textScrollTop");
@@ -135,8 +153,57 @@ window.addEventListener('DOMContentLoaded', function()
 });
 
 /*
+ *  New GUI edit buttons, without inline JavaScript
+ *  (c) 2022 Petko Yotov www.pmwiki.org/petko
+ */
+function newButtons(){
+  var el = dqs('.GUIButtons');
+  if(! el) return;
+  
+  function unxp(a) {
+    if(typeof a == 'number') return a;
+    if(typeof a == 'string')
+      return a.replace(/\\n/g, '\n')
+        .replace(/\\\\/g, '\\').replace(/%25/g, '%');
+    var b = [];
+    for(var i=0; i<a.length; i++) {
+      b[i] = unxp(a[i]);
+    }
+    return b;
+  }
+  var buttons = unxp(JSON.parse(el.dataset.json));
+  
+  for(var i=0; i<buttons.length; i++) {
+    var b = buttons[i];
+    if(!b || !b.length) continue;
+    var mopen=b[1], mclose=b[2], mtext=b[3], tag=b[4], mkey=b[5];
+    if(tag.charAt(0) == '<') {
+      el.insertAdjacentHTML('beforeend', tag);
+      continue;
+    }
+    var x = tag.match(/^(.*\.(gif|jpg|png|webp|svg))("([^"]+)")?$/);
+    if(x) {
+      var title = x[4]? 'alt="'+x[4]+'" title="'+x[4]+'"' : '';
+      tag = "<img src='"+x[1]+"' "+title+" />";
+    }
+    var a = document.createElement('a');
+    a.setAttribute('tabindex', -1);
+    if(mkey) a.setAttribute('accesskey', mkey);
+    a.dataset.mopen = mopen;
+    a.dataset.mclose = mclose;
+    a.dataset.mtext = mtext;    
+    a.innerHTML = tag;
+    a.className = 'newbutton';
+    el.appendChild(a);
+  }
+  tap('.GUIButtons a.newbutton', function(e){
+    insMarkup(this.dataset.mopen, this.dataset.mclose, this.dataset.mtext);
+  });
+}
+
+/*
  *  Edit helper for PmWiki
- *  (c) 2016 Petko Yotov www.pmwiki.org/petko
+ *  (c) 2016-2022 Petko Yotov www.pmwiki.org/petko
  */
 function EditAutoText(){
   var t = dqs('#text');
@@ -144,22 +211,77 @@ function EditAutoText(){
 
 
   t.addEventListener('keydown', function(e){
-    if (e.keyCode != 13) return;
-    //else [Enter/Return]
-    var caret = this.selectionStart;
-    if(!caret) return true; // old MSIE, sorry
+    var caret = this.selectionStart, endcaret = this.selectionEnd;
+    if(typeof caret != 'number') return true; // old MSIE, sorry
+
     var content = this.value;
+    
+    // Ctrl+L (lowercase), Ctrl+Shift+L (uppercase)
+    if((e.key.toLowerCase() === 'l') && e.ctrlKey && caret != endcaret && document.execCommand) {
+      e.preventDefault();
+      var sel = content.substring(caret, endcaret);
+      sel = e.shiftKey? sel.toUpperCase(): sel.toLowerCase();
+      document.execCommand('insertText', false, sel);
+      this.selectionStart = caret;
+      return;
+    }
+    
+    // Ctrl+Shift+ArrowUp, Ctrl+Shift+ArrowDown: swap lines
+    else if(e.ctrlKey && e.shiftKey && e.key.match(/Arrow(Up|Down)/) && document.execCommand) {
+      e.preventDefault();
+      
+      var before = content.slice(0, caret), 
+        after = content.slice(endcaret), 
+        sel = content.slice(caret, endcaret);
+      var a = before.match(/[^\n]+$/);
+      if(a) {
+        sel = a[0]+sel;
+        before = before.slice(0, -a[0].length);
+      }
+      a = after.match(/^[^\n]*(\n|$)/);
+      sel = sel+a[0];
+      after = after.slice(a[0].length);
+      
+      if(e.key == 'ArrowUp') {
+        a = before.match(/[^\n]*\n$/);
+        if(!a) return;
+        var lineA = sel, lineB = a[0];
+        var deltacaret = -lineB.length;
+      }
+      else if(e.key == 'ArrowDown') {
+        a = after.match(/^([^\n]+$|[^\n]*\n)/);
+        if(!a) return;
+        var lineA = a[0], lineB = sel;
+        var deltacaret = lineA.length;
+      }
+      if(!lineA.match(/\n$/)) { // last line
+        lineB = "\n" + lineB.slice(0, -1);
+        if(deltacaret>0) deltacaret+=1;
+      }
+      var insert = lineA + lineB;
+      this.selectionStart = before.length + Math.min(deltacaret,0);
+      this.selectionEnd = this.selectionStart + insert.length;
+      document.execCommand('insertText', false, insert);
+      this.selectionStart = caret + deltacaret;
+      this.selectionEnd = endcaret + deltacaret;
+      return;
+    }
+    
+    if (e.key != "Enter") return;
+
     var before = content.substring(0, caret).split(/\n/g);
-    var after  = content.substring(this.selectionEnd);
+    var after  = content.substring(endcaret);
     var currline = before[before.length-1];
+    var linestartpos = content.lastIndexOf('\n', Math.max(0,caret-1));
 
-    if(currline.match(/[^\\]\\$/)) return true; // line ending with a single \ backslash
-    var insert = "\n";
+    if(currline.match(/\\$/)) return true; // line ending with a \ backslash
+                     
+    var insert;
     if(e.ctrlKey && e.shiftKey) {
-      insert = "~~~~\n";
+      insert = "~~~~";
     }
     else if(e.ctrlKey) {
-      insert = "[[<<]]\n";
+      insert = "[[<<]]";
     }
     else if(e.shiftKey) {
       insert = "\\\\\n";
@@ -167,14 +289,37 @@ function EditAutoText(){
     else {
       var m = currline.match(/^((?: *\*+| *\#+|-+[<>]|:+|\|\|| ) *)/);
       if(!m) return true;
-      var insert = "\n"+m[1];
+                     
+      if(currline==m[1] && (after === '' || after.charAt(0) == '\n')) {
+        insert = "\n";
+        if(linestartpos<0) {
+          linestartpos = 0;
+          this.selectionEnd += 1;
+        }
+        this.selectionStart = linestartpos;
+        caret = caret - currline.length - 1;
+        before = before.slice(0,-1); // if no execCommand
+      }
+      else {
+        insert = "\n"+m[1];
+      }
     }
     e.preventDefault();
 
-    content = before.join("\n") + insert + after;
-    this.value = content;
+    if(document.execCommand) {
+      document.execCommand('insertText', false, insert);
+    }
+    else {
+      content = before.join("\n") + insert + after;
+      this.value = content;
+    }
+    
     this.selectionStart = caret + insert.length;
     this.selectionEnd = caret + insert.length;
+    
+    var evt = new Event('input');
+    this.dispatchEvent(evt);
+    
     return false;
   });
 };
blob - e7a8812b568af8c3d65305ffef4ec125f59d581f
blob + 2ba06d3a629a8726c4284fd5647c5b749f3e9c9a
--- pub/skins/ircnow/skin.css
+++ pub/skins/ircnow/skin.css
@@ -216,6 +216,7 @@ pre { line-height: 18px; }
 pre code, code code, pre pre { font-size:100%; }
 /* pre, code.escaped { max-width: 100%; overflow: auto; } */
 pre.escaped {
+	max-width: 100%;
         line-height:1.3em;
         background: #f9f9f9;
         border: 1px solid #ccc;
blob - 78a26ffad2bdfafa60e7ee79b316c7f8c23b03a2
blob + d69f582cdcce1d0bcc35f3b5abd35668ad340e65
--- scripts/forms.php
+++ scripts/forms.php
@@ -1,5 +1,5 @@
 <?php if (!defined('PmWiki')) exit();
-/*  Copyright 2005-2019 Patrick R. Michaud (pmichaud@pobox.com)
+/*  Copyright 2005-2022 Patrick R. Michaud (pmichaud@pobox.com)
     This file is part of PmWiki; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published
     by the Free Software Foundation; either version 2 of the License, or
@@ -15,7 +15,7 @@ SDV($InputAttrs, array('name', 'value', 'id', 'class',
   'required', 'placeholder', 'autocomplete', 'min', 'max', 'step', 'pattern',
   'role', 'aria-label', 'aria-labelledby', 'aria-describedby',
   'aria-expanded', 'aria-pressed', 'aria-current', 'aria-hidden',
-  'formnovalidate'
+  'lang', 'formnovalidate', 'autofocus', 'accept'
   ));
 
 # Set up formatting for text, submit, hidden, radio, etc. types
@@ -23,7 +23,7 @@ foreach(array('text', 'submit', 'hidden', 'password', 
     'image', 'email', 'url', 'tel', 'number', 'search', 'date', 'button') as $t) 
   SDV($InputTags[$t][':html'], "<input type='$t' \$InputFormArgs />");
 
-foreach(array('text', 'email', 'url', 'tel', 'number', 'search', 'date') as $t) 
+foreach(array('text', 'password', 'email', 'url', 'tel', 'number', 'search', 'date') as $t) 
   SDV($InputTags[$t]['class'], "inputbox");
 
 foreach(array('submit', 'button', 'reset') as $t) 
@@ -111,10 +111,6 @@ function MarkupInputForms($m) {
 Markup('input+sp', '<split', 
   '/(\\(:input\\s+(select|datalist)\\s(?>.*?:\\)))\\s+(?=\\(:input\\s)/', '$1');
 
-SDV($InputFocusFmt, 
-  "<script language='javascript' type='text/javascript'><!--
-   document.getElementById('\$InputFocusId').focus();//--></script>");
-
 ##  InputToHTML performs standard processing on (:input ...:) arguments,
 ##  and returns the formatted HTML string.
 function InputToHTML($pagename, $type, $args, &$opt) {
@@ -127,17 +123,19 @@ function InputToHTML($pagename, $type, $args, &$opt) {
   ##  convert any positional arguments to named arguments
   $posnames = @$InputTags[$type][':args'];
   if (!$posnames) $posnames = array('name', 'value');
-  while (count($posnames) > 0 && @count(@$args['']) > 0) {
+  while (count($posnames) > 0 && @$args[''] && count($args['']) > 0) {
     $n = array_shift($posnames);
     if (!isset($args[$n])) $args[$n] = array_shift($args['']);
   }
+  
+  
   ##  merge defaults for input type with arguments
   $opt = array_merge($InputTags[$type], $args);
   ## www.w3.org/TR/html4/types
   if (isset($opt['id'])) $opt['id'] = preg_replace('/[^-A-Za-z0-9:_.]+/', '_', $opt['id']);
   ##  convert any remaining positional args to flags
   foreach ((array)@$opt[''] as $a) 
-    { $a = strtolower($a); if (!isset($opt[$a])) $opt[$a] = $a; }
+    { $a = strtolower($a); if ( preg_match('/^\\w+$/', $a) && !isset($opt[$a])) $opt[$a] = $a; }
   if (isset($opt['name'])) {
     $opt['name'] = preg_replace('/^\\$:/', 'ptv_', @$opt['name']);
     $opt['name'] = preg_replace('/[^-A-Za-z0-9:_.\\[\\]]+/', '_', $opt['name']);
@@ -152,6 +150,11 @@ function InputToHTML($pagename, $type, $args, &$opt) {
                          ? $checked : false;
       } else if (!isset($opt['value'])) $opt['value'] = $InputValues[$name];
     }
+    if ( (strpos($name, 'ptv_') === 0) && !isset($opt['value']) ) {
+      # $DefaultUnsetPageTextVars, $DefaultEmptyPageTextVars with wildcards
+      $default = PageTextVar($pagename, substr($name, 4));
+      if ($default !== '') $opt['value'] = $default;
+    }
   }
   ##  build $InputFormContent
   $FmtV['$InputFormContent'] = '';
@@ -164,7 +167,7 @@ function InputToHTML($pagename, $type, $args, &$opt) {
   if (@$opt['secure'] == '#') $opt['secure'] = rand();
   if (@$opt['secure'] > '') {
     $md5 = md5($opt['secure'] . $opt['value']);
-    @session_start(); 
+    pm_session_start(); 
     $_SESSION['forms'][$md5] = $opt['value'];
     $opt['value'] = $md5;
   }
@@ -177,13 +180,9 @@ function InputToHTML($pagename, $type, $args, &$opt) {
     $FmtV['$InputFormLabel'] = " <label for=\"{$opt['id']}\"$lbtitle>{$opt['label']}</label> ";
   }
   ##  handle focus=# option
-  $focus = @$opt['focus'];
-  if (isset($focus)
-      && (!isset($InputFocusLevel) || $focus < $InputFocusLevel)) {
-    if (!isset($opt['id'])) $opt['id'] = "wikifocus$focus";
-    $InputFocusLevel = $focus;
-    $InputFocusId = $opt['id'];
-    $HTMLFooterFmt['inputfocus'] = $InputFocusFmt;
+  if (@$opt['focus']) {
+    unset($opt['focus']);
+    $opt['autofocus'] = 'autofocus';
   }
   ##  build $InputFormArgs from $opt
   $attrlist = (isset($opt[':attr'])) ? $opt[':attr'] : $InputAttrs;
@@ -221,7 +220,7 @@ function InputDefault($pagename, $type, $args) {
   $args = ParseArgs($args);
   $args[''] = (array)@$args[''];
   $name = (isset($args['name'])) ? $args['name'] : array_shift($args['']);
-  $name = preg_replace('/^\\$:/', 'ptv_', $name);
+  $name = $name ? preg_replace('/^\\$:/', 'ptv_', $name) : '';
   $value = (isset($args['value'])) ? $args['value'] : $args[''];
   if (!isset($InputValues[$name])) $InputValues[$name] = $value;
   if (@$args['request']) {
@@ -256,6 +255,7 @@ function InputDefault($pagename, $type, $args) {
       break;
     }
   }
+  
   return '';
 }
 
@@ -320,9 +320,6 @@ SDVA($InputTags['auth_form'], array(
   'method' => 'post',
   'name' => 'authform'));
 SDV($AuthPromptFmt, array(&$PageStartFmt, 'page:$SiteGroup.AuthForm',
-  "<script language='javascript' type='text/javascript'><!--
-    try { document.authform.authid.focus(); }
-    catch(e) { document.authform.authpw.focus(); } //--></script>",
   &$PageEndFmt));
 
 ## PITS:01188, these should exist in "browse" mode
@@ -366,23 +363,24 @@ SDVA($InputTags['e_form'], array(
     \$InputFormArgs><input type='hidden' name='action' value='edit' 
     /><input type='hidden' name='n' value='{\$FullName}' 
     /><input type='hidden' name='basetime' value='\$EditBaseTime' 
+    /><input type='hidden' name='\$TokenName' value='\$TokenValue' 
     /><input type='hidden' name='textScrollTop' id='textScrollTop' value='$TextScrollTop'
     />"));
 SDVA($InputTags['e_textarea'], array(
-  ':html' => "<textarea \$InputFormArgs 
-    onkeydown='if (event.keyCode==27) event.returnValue=false;' 
-    >\$EditText</textarea>",
+  ':html' => "<textarea \$InputFormArgs>\$EditText</textarea>\$IncludedPages",
   'name' => 'text', 'id' => 'text', 'accesskey' => XL('ak_textedit'),
   'rows' => XL('e_rows'), 'cols' => XL('e_cols')));
 SDVA($InputTags['e_author'], array(
   ':html' => "<input type='text' \$InputFormArgs />",
+  'placeholder' => PHSC(XL('Author'), ENT_QUOTES),
   'name' => 'author', 'value' => $Author));
 SDVA($InputTags['e_changesummary'], array(
   ':html' => "<input type='text' \$InputFormArgs />",
   'name' => 'csum', 'size' => '60', 'maxlength' => '100',
+  'placeholder' => PHSC(XL('Summary'), ENT_QUOTES),
   'value' => PHSC(stripmagic(@$_POST['csum']), ENT_QUOTES)));
 SDVA($InputTags['e_minorcheckbox'], array(
-  ':html' => "<input type='checkbox' \$InputFormArgs />",
+  ':html' => "<input type='checkbox' \$InputFormArgs />\$InputFormLabel",
   'name' => 'diffclass', 'value' => 'minor'));
 if (@$_POST['diffclass']=='minor') 
   SDV($InputTags['e_minorcheckbox']['checked'], 'checked');
@@ -410,7 +408,7 @@ SDVA($InputTags['e_resetbutton'], array(
 if(IsEnabled($EnablePostAuthorRequired))
   $InputTags['e_author']['required'] = 'required';
 
-if(IsEnabled($EnableNotSavedWarning)) {
+if(IsEnabled($EnableNotSavedWarning, 1)) {
   $is_preview = @$_REQUEST['preview'] ? 'class="preview"' : '';
   $InputTags['e_form'][':html'] .=
     "<input type='hidden' id='EnableNotSavedWarning'
blob - 5eee5cff2e2a0de8df9e69ff2617fbe50b4a6c89
blob + 7af62b705a2203aca750129b544881d928fb5b43
--- scripts/guiedit.php
+++ scripts/guiedit.php
@@ -1,5 +1,5 @@
 <?php if (!defined('PmWiki')) exit();
-/*  Copyright 2004-2019 Patrick R. Michaud (pmichaud@pobox.com)
+/*  Copyright 2004-2022 Patrick R. Michaud (pmichaud@pobox.com)
     This file is part of PmWiki; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published
     by the Free Software Foundation; either version 2 of the License, or
@@ -23,6 +23,8 @@
     Script maintained by Petko YOTOV www.pmwiki.org/petko
 */
 
+
+## Included even if no buttons: has "not saved warning" and others
 SDVA($HTMLHeaderFmt, array('guiedit' => "<script type='text/javascript'
   src='\$FarmPubDirUrl/guiedit/guiedit.js'></script>\n"));
 
@@ -38,7 +40,7 @@ if(IsEnabled($EnableGUIButtons,0)) {
                     '$[ak_strong]'),
     'pagelink' => array(200, '[[', ']]', '$[Page link]',
                     '$GUIButtonDirUrlFmt/pagelink.gif"$[Link to internal page]"'),
-    'extlink'  => array(210, '[[', ']]', 'http:// | $[link text]',
+    'extlink'  => array(210, '[[', ']]', 'https:// | $[link text]',
                     '$GUIButtonDirUrlFmt/extlink.gif"$[Link to external page]"'),
     'big'      => array(300, "'+", "+'", '$[Big text]',
                     '$GUIButtonDirUrlFmt/big.gif"$[Big text]"'),
@@ -62,34 +64,17 @@ if(IsEnabled($EnableGUIButtons,0)) {
     '/\\(:e_guibuttons:\\)/', 'GUIButtonCode');
 }
 
-function cb_gbcompare($a, $b) {return $a[0]-$b[0];}
 function GUIButtonCode() {
   global $GUIButtons;
   extract($GLOBALS["MarkupToHTML"]); # get $pagename
 
   usort($GUIButtons, 'cb_gbcompare');
-
-  $out = "<script type='text/javascript'><!--\n";
-  foreach ($GUIButtons as $k => $g) {
-    if (!$g) continue;
-    @list($when, $mopen, $mclose, $mtext, $tag, $mkey) = $g;
-    if (@$ta[0] == '<') { 
-        $out .= "document.write(\"$tag\");\n";
-        continue; 
-    }
-    if (preg_match('/^(.*\\.(gif|jpg|png))("([^"]+)")?$/', $tag, $m)) {
-      $title = (@$m[4] > '') ? "title='{$m[4]}'" : '';
-      $tag = "<img src='{$m[1]}' $title style='border:0px;' />";
-    }
-    $mopen = str_replace(array('\\', "'"), array('\\\\', "\\\\'"), $mopen);
-    $mclose = str_replace(array('\\', "'"), array('\\\\', "\\\\'"), $mclose);
-    $mtext = str_replace(array('\\', "'"), array('\\\\', "\\\\'"), $mtext);
-    $out .= 
-      "insButton(\"$mopen\", \"$mclose\", '$mtext', \"$tag\", \"$mkey\");\n";
-  }
-  $out .= '//--></script>';
+  
+  $json = PHSC(json_encode($GUIButtons));
+  $out = "<span class='GUIButtons' data-json=\"$json\"></span>";
   return Keep(FmtPageName($out, $pagename));
 }
+function cb_gbcompare($a, $b) {return $a[0]-$b[0];}
 
 
 
blob - bebe13cf54d5f1684abe28c06d69871757263e25
blob + 1bea050bb5fbf60bb0f7f8ba38a730f1a986f89d
--- scripts/intermap.txt
+++ scripts/intermap.txt
@@ -3,7 +3,7 @@ Cookbook:   https://www.pmwiki.org/wiki/Cookbook/
 Skins:      https://www.pmwiki.org/wiki/Skins/
 Wiki:       http://www.c2.com/cgi/wiki?
 UseMod:     http://www.usemod.com/cgi-bin/wiki.pl?
-Meatball:   http://www.usemod.com/cgi-bin/mb.pl?
+Meatball:   http://meatballwiki.org/wiki/
 Wikipedia:  https://en.wikipedia.org/wiki/
 PITS:       https://www.pmwiki.org/wiki/PITS/
 PmL10n:     https://www.pmwiki.org/wiki/Localization/
blob - 39481d90250da53aff4bc2facd11049e85b1e8f8
blob + 69d456beb87c34b2686927bd88f78c2a1e8b89d4
--- scripts/markupexpr.php
+++ scripts/markupexpr.php
@@ -1,5 +1,5 @@
 <?php if (!defined('PmWiki')) exit();
-/*  Copyright 2007-2019 Patrick R. Michaud (pmichaud@pobox.com)
+/*  Copyright 2007-2021 Patrick R. Michaud (pmichaud@pobox.com)
     This file is part of PmWiki; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published
     by the Free Software Foundation; either version 2 of the License, or
@@ -86,7 +86,7 @@ function MarkupExpression($pagename, $expr) {
   $expr = preg_replace_callback('/([\'"])(.*?)\\1/','cb_keep_m2_p', $expr);
   $expr = preg_replace_callback('/\\(\\W/', 'cb_keep_m0_p', $expr);
   while (preg_match('/\\((\\w+)(\\s[^()]*)?\\)/', $expr, $match)) {
-    list($repl, $func, $params) = $match;
+    @list($repl, $func, $params) = $match;
     $code = @$MarkupExpr[$func];
     ##  if not a valid function, save this string as-is and exit
     if (!$code) break;
@@ -99,7 +99,7 @@ function MarkupExpression($pagename, $expr) {
     }
     ##  otherwise, we parse arguments into $args before evaluating
     $argp = ParseArgs($params);
-    $x = $argp['#']; $args = array();
+    $x = @$argp['#']; $args = array();
     while ($x) {
       list($k, $v) = array_splice($x, 0, 2);
       if ($k == '' || $k == '+' || $k == '-') 
@@ -120,24 +120,13 @@ function MarkupExpression($pagename, $expr) {
 function ME_ftime($arg0 = '', $arg1 = '', $argp = NULL) {
   global $TimeFmt, $Now, $FTimeFmt;
   if (@$argp['fmt']) $fmt = $argp['fmt']; 
-  else if (strpos($arg0, '%') !== false) { $fmt = $arg0; $arg0 = $arg1; }
-  else if (strpos($arg1, '%') !== false) $fmt = $arg1;
+  elseif ($arg0 && strpos($arg0, '%') !== false) { $fmt = $arg0; $arg0 = $arg1; }
+  elseif ($arg1 && strpos($arg1, '%') !== false) $fmt = $arg1;
+  else $fmt = '';
   ## determine the timestamp
   if (isset($argp['when'])) list($time, $x) = DRange($argp['when']);
-  else if ($arg0 > '') list($time, $x) = DRange($arg0);
+  elseif ($arg0 > '') list($time, $x) = DRange($arg0);
   else $time = $Now;
-  $dtz = function_exists('date_default_timezone_get') # tz=Europe/Paris
-    ? date_default_timezone_get() : false;
-  if (@$argp['tz'] && $dtz) @date_default_timezone_set($argp['tz']);
-  $dloc = setlocale(LC_TIME, 0);
-  if(@$argp['locale']) # locale=fr_FR.utf8,bg_BG,C
-    setlocale(LC_TIME, preg_split('/[, ]+/', $argp['locale'], null, PREG_SPLIT_NO_EMPTY));
-  if (@$fmt == '') { SDV($FTimeFmt, $TimeFmt); $fmt = $FTimeFmt; }
-  ##  make sure we have %F available for ISO dates
-  $fmt = str_replace(array('%F', '%s'), array('%Y-%m-%d', $time), $fmt);
-  $ret = strftime($fmt, $time);
-  if (@$argp['tz'] && $dtz) date_default_timezone_set($dtz);
-  if(@$argp['locale']) setlocale(LC_TIME, $dloc);
-  return $ret;
+  return PSFT($fmt, $time, @$argp['locale'], @$argp['tz']);
 }
 
blob - d83b272ad52e8337b76f1115d18e0f6a7534d6a8
blob + 1a568f79727edfbc876771dc7a2c6fb4de25a80c
--- scripts/notify.php
+++ scripts/notify.php
@@ -1,5 +1,5 @@
 <?php if (!defined('PmWiki')) exit();
-/*  Copyright 2006-2018 Patrick R. Michaud (pmichaud@pobox.com)
+/*  Copyright 2006-2022 Patrick R. Michaud (pmichaud@pobox.com)
     This file is part of PmWiki; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published
     by the Free Software Foundation; either version 2 of the License, or
@@ -101,7 +101,7 @@ function NotifyUpdate($pagename, $dir='') {
   ##   Read in the current notify configuration
   $pn = FmtPageName($NotifyListPageFmt, $pagename);
   $npage = ReadPage($pn, READPAGE_CURRENT);
-  preg_match_all('/^[\s*:#->]*(notify[:=].*)/m', $npage['text'], $nlist);
+  preg_match_all('/^[\s*:#>-]*(notify[:=].*)/m', strval(@$npage['text']), $nlist);
   $nlist = array_merge((array)@$NotifyList, (array)@$nlist[1]);
   if (!$nlist) return;
 
@@ -125,8 +125,8 @@ function NotifyUpdate($pagename, $dir='') {
   ##   if this is for a newly posted page, get its information
   if ($IsPagePosted || $IsUploadPosted) {
     $page = ReadPage($pagename, READPAGE_CURRENT);
-    $FmtV['$PostTime'] = strftime($NotifyTimeFmt, $Now);
-    $item = urlencode(FmtPageName($NotifyItemFmt, $pagename));
+    $FmtV['$PostTime'] = PSFT($NotifyTimeFmt, $Now);
+    $item = $tzitem = urlencode(FmtPageName($NotifyItemFmt, $pagename));
     if ($firstpost < 1) $firstpost = $Now;
   }
 
@@ -134,24 +134,28 @@ function NotifyUpdate($pagename, $dir='') {
     $opt = ParseArgs($n);
     $mailto = preg_split('/[\s,]+/', $opt['notify']);
     if (!$mailto) continue;
-    if ($opt['squelch']) 
+    if (@$opt['squelch']) 
       foreach($mailto as $m) $squelch[$m] = $opt['squelch'];
     if (!$IsPagePosted) continue;
-    if ($opt['link']) {
+    if (@$opt['link']) {
       $link = MakePageName($pagename, $opt['link']);
       if (!preg_match("/(^|,)$link(,|$)/i", $page['targets'])) continue;
     }
     $pats = @(array)$SearchPatterns[$opt['list']];
-    if ($opt['group']) $pats[] = FixGlob($opt['group'], '$1$2.*');
-    if ($opt['name']) $pats[] = FixGlob($opt['name'], '$1*.$2');
+    if (@$opt['group']) $pats[] = FixGlob($opt['group'], '$1$2.*');
+    if (@$opt['name']) $pats[] = FixGlob($opt['name'], '$1*.$2');
     if ($pats && !MatchPageNames($pagename, $pats)) continue;
-    if ($opt['trail']) {
+    if (@$opt['trail']) {
       $trail = ReadTrail($pagename, $opt['trail']);
       for ($i=0; $i<count($trail); $i++) 
         if ($trail[$i]['pagename'] == $pagename) break;
       if ($i >= count($trail)) continue;
     }
-    foreach($mailto as $m) { $notify[$m][] = $item; }
+    if (@$opt['tz']) {
+      $FmtV['$PostTime'] = PSFT($NotifyTimeFmt, $Now, @$opt['locale'], $opt['tz']);
+      $tzitem = urlencode(FmtPageName($NotifyItemFmt, $pagename));
+    }
+    foreach($mailto as $m) { $notify[$m][] = $tzitem; }
   }
 
   $nnow = time();
blob - 801bbfcfc3caeb1eb8cfa655f65653ff7cdfef6f
blob + 326351467c878fcb5ade4505f89c7271ab019dd1
--- scripts/pagelist.php
+++ scripts/pagelist.php
@@ -1,5 +1,5 @@
 <?php if (!defined('PmWiki')) exit();
-/*  Copyright 2004-2020 Patrick R. Michaud (pmichaud@pobox.com)
+/*  Copyright 2004-2023 Patrick R. Michaud (pmichaud@pobox.com)
     This file is part of PmWiki; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published
     by the Free Software Foundation; either version 2 of the License, or
@@ -31,8 +31,9 @@ if (IsEnabled($EnablePageIndex, 1)) {
   SDV($PageIndexFile, "$WorkDir/.pageindex");
   $EditFunctions[] = 'PostPageIndex';
 }
-
 SDV($StrFoldFunction, 'strtolower');
+SDV($PageIndexFoldFunction, $StrFoldFunction);
+SDV($PageIndexTermsFunction, 'PageIndexTerms');
 SDV($PageListSortCmpFunction, 'strcasecmp');
 
 ## $SearchPatterns holds patterns for list= option
@@ -154,6 +155,7 @@ function SearchBox($pagename, $opt) {
   if (isset($SearchBoxFmt)) return Keep(FmtPageName($SearchBoxFmt, $pagename));
   SDVA($SearchBoxOpt, array('size' => '40', 
     'label' => FmtPageName('$[Search]', $pagename),
+    'placeholder' => FmtPageName('$[Search]', $pagename),
     'value' => str_replace("'", "&#039;", $SearchQuery)));
   $opt = array_merge((array)$SearchBoxOpt, @$_GET, (array)$opt);
   $opt['action'] = 'search';
@@ -164,18 +166,19 @@ function SearchBox($pagename, $opt) {
                      $target);
   foreach($opt as $k => $v) {
     if ($v == '' || is_array($v)) continue;
-    $v = str_replace("'", "&#039;", $v);
+    $v = PHSC($v, ENT_QUOTES, null, false);
     $opt[$k] = $v;
     if(preg_match('/^(q|label|value|size|placeholder|aria-\\w+)$/', $k)) continue;
-    $k = str_replace("'", "&#039;", $k);
+    $k = PHSC($k, ENT_QUOTES, null, false);
     $out .= "<input type='hidden' name='$k' value='$v' />";
   }
   SDV($SearchBoxInputType, 'text');
   $out .= "<input type='$SearchBoxInputType' name='q' value='{$opt['value']}' ";
   $attrs = preg_grep('/^(placeholder|aria-\\w+)/', array_keys($opt));
   foreach ($attrs as $k) $out .= "  $k='{$opt[$k]}' ";
-  $out .= "  class='inputbox searchbox' size='{$opt['size']}' /><input type='submit' 
-    class='inputbutton searchbutton' value='{$opt['label']}' />";
+  $out .= "  class='inputbox searchbox' size='{$opt['size']}' />";
+  if($opt['label']) 
+    $out .= "<input type='submit' class='inputbutton searchbutton' value='{$opt['label']}' />";
   return '<form '.Keep($out).'</form>';
 }
 
@@ -192,7 +195,7 @@ function FmtPageList($outfmt, $pagename, $opt) {
   # Handle "group/" at the beginning of the form-submitted request
   if (preg_match("!^($GroupPattern(\\|$GroupPattern)*)?/!i", $rq, $match)) {
     $opt['group'] = @$match[1];
-    $rq = substr($rq, strlen(@$match[1])+1);
+    $rq = substr($rq, strlen(strval(@$match[1]))+1);
   }
   $opt = array_merge($opt, ParseArgs($opt['o'], $PageListArgPattern));
   # merge markup options with form and url
@@ -235,7 +238,7 @@ function FmtPageList($outfmt, $pagename, $opt) {
   $FmtV['$MatchCount'] = count($matches);
   if ($outfmt != '$MatchList')
     { $FmtV['$MatchList'] = $out; $out = FmtPageName($outfmt, $pagename); }
-  if ($out[0] == '<') $out = Keep($out);
+  if (@$out[0] == '<') $out = Keep($out);
   return PRR($out);
 }
 
@@ -249,7 +252,7 @@ function MakePageList($pagename, $opt, $retpages = 1) 
   SDVA($MakePageListOpt, array('list' => 'default'));
   $opt = array_merge((array)$MakePageListOpt, (array)$opt);
   if (!@$opt['order'] && !@$opt['trail']) $opt['order'] = 'name';
-  $opt['order'] = preg_replace('/[^-\\w:$]+/', ',', @$opt['order']);
+  $opt['order'] = preg_replace('/[^-\\w:$]+/', ',', strval(@$opt['order']));
 
   ksort($opt); $opt['=key'] = md5(serialize($opt));
 
@@ -283,7 +286,7 @@ function MakePageList($pagename, $opt, $retpages = 1) 
   
   if ($retpages) 
     for($i=0; $i<count($list); $i++)
-      $list[$i] = &$PCache[$list[$i]];
+      $list[$i] = &$PCache[@$list[$i]];
   StopWatch('MakePageList end');
   return $list;
 }
@@ -326,6 +329,7 @@ function PageListSources(&$list, &$opt, $pn, &$page) {
 
   StopWatch('PageListSources begin');
   if ($opt['list'] == 'grouphomes') EnablePageListGroupHomes();
+  if (!isset($SearchPatterns[$opt['list']])) $opt['list'] = 'default';
   ## add the list= option to our list of pagename filter patterns
   $opt['=pnfilter'] = array_merge((array)@$opt['=pnfilter'], 
                                   (array)@$SearchPatterns[$opt['list']]);
@@ -386,7 +390,7 @@ function PageListIf(&$list, &$opt, $pn, &$page) {
 }
 
 function PageListTermsTargets(&$list, &$opt, $pn, &$page) {
-  global $FmtV;
+  global $PageIndexTermsFunction, $FmtV;
   static $reindex = array();
   $fold = $GLOBALS['StrFoldFunction'];
 
@@ -398,7 +402,7 @@ function PageListTermsTargets(&$list, &$opt, $pn, &$pa
       foreach((array)@$opt['+'] as $i) { $incl[] = $fold($i); }
       foreach((array)@$opt['-'] as $i) { $excl[] = $fold($i); }
 
-      $indexterms = PageIndexTerms($incl);
+      $indexterms = $PageIndexTermsFunction($incl);
       foreach($incl as $i) {
         $delim = (!preg_match('/[^\\w\\x80-\\xff]/', $i)) ? '$' : '/';
         $opt['=inclp'][] = $delim . preg_quote($i,$delim) . $delim . 'i';
@@ -406,31 +410,46 @@ function PageListTermsTargets(&$list, &$opt, $pn, &$pa
       if ($excl) 
         $opt['=exclp'][] = '$'.implode('|', array_map('preg_quote',$excl)).'$i';
 
+      $opt['=linka'] = array();
+      if (@$opt['links']) $opt['link'] = $opt['links'];
       if (@$opt['link']) {
-        $link = MakePageName($pn, $opt['link']);
-        $opt['=linkp'] = "/(^|,)$link(,|$)/i";
-        $indexterms[] = " $link ";
+        if (preg_match('/^\s*-|[,*?![\\]]/', $opt['link']))
+          $opt['=linka'] = PageListLinkPatterns($opt['link']);
+        else {
+          $link = MakePageName($pn, $opt['link']);
+          $opt['=linkp'] = "/(^|,)$link(,|$)/i";
+          $indexterms[] = " $link ";
+        }
       }
-
+      if (@$opt['category']) {
+        $c = preg_replace('/(^,*-?|,+-?)/', '$1!', $opt['category']);
+        $opt['=linka'] = array_merge($opt['=linka'], PageListLinkPatterns($c));
+      }
+      
+      
       if (@$opt['=cached']) return 0;
-      if ($indexterms) {
+      if ($indexterms||@$opt['=linka']) {
         StopWatch("PageListTermsTargets begin count=".count($list));
-        $xlist = PageIndexGrep($indexterms, true);
+        $xlist = PageIndexGrep($indexterms, true, @$opt['=linka']);
         $list = array_diff($list, $xlist);
         StopWatch("PageListTermsTargets end count=".count($list));
       }
-
-      if (@$opt['=inclp'] || @$opt['=exclp'] || @$opt['=linkp']) 
+      if (@$opt['=inclp'] || @$opt['=exclp'] || @$opt['=linkp'] || @$opt['=linka']) 
         return PAGELIST_ITEM|PAGELIST_POST; 
       return 0;
 
     case PAGELIST_ITEM:
       if (!$page) { $page = ReadPage($pn, READPAGE_CURRENT); $opt['=readc']++; }
       if (!$page) return 0;
-      if (@$opt['=linkp'] && !preg_match($opt['=linkp'], @$page['targets'])) 
+      $targets = strval(@$page['targets']);
+      if (@$opt['=linka']) {
+        if (! PageListMatchTargets($targets, $opt['=linka']))
+          { $reindex[] = $pn; return 0; }
+      }
+      if (@$opt['=linkp'] && !preg_match($opt['=linkp'], $targets)) 
         { $reindex[] = $pn; return 0; }
       if (@$opt['=inclp'] || @$opt['=exclp']) {
-        $text = $fold($pn."\n".@$page['targets']."\n".@$page['text']);
+        $text = $fold($pn."\n$targets\n".@$page['text']);
         foreach((array)@$opt['=exclp'] as $i) 
           if (preg_match($i, $text)) return 0;
         foreach((array)@$opt['=inclp'] as $i) 
@@ -449,6 +468,33 @@ function PageListTermsTargets(&$list, &$opt, $pn, &$pa
 }
 
 
+function PageListMatchTargets($targets, $links) {
+  $targets = preg_split('/[, ]+/', trim($targets), -1, PREG_SPLIT_NO_EMPTY);
+  if (@$links['none'] && MatchNames($targets, $links['none'])) return false;
+  if (@$links['any'] && !MatchNames($targets, $links['any'])) return false;
+  if (@$links['req']) foreach($links['req'] as $pat)
+    if (!MatchNames($targets, $pat)) return false;
+  return true;
+}
+
+
+function PageListLinkPatterns($pat) {
+  # custom FixGlobToPCRE
+  $pat = str_replace('/', '.', $pat);
+  $pat = preg_replace('/([\\s,][-+]?)([^\\/.\\s,!]+)(?=[\\s,])/', '$1*.$2', ",$pat,");
+  $pat = preg_quote($pat, '/');
+  $pat = str_replace(array('\\*', '\\?', '\\[', '\\]', '\\^', '\\-', '\\+', ','),
+                     array('.*',  '.',   '[',   ']',   '^', '-', '+', ' '), $pat);
+  $req = array();
+  $patterns = array('req'=>array());
+  $args = ParseArgs($pat);
+  if (@$args['']) $patterns['any'] = '/^('.implode('|', $args['']).')$/i';
+  if (@$args['-']) $patterns['none'] = '/^('.implode('|', $args['-']).')$/i';
+  if (@$args['+']) foreach($args['+'] as $p) $patterns['req'][] = "/^$p$/i";
+  
+  return $patterns;
+}
+
 function PageListVariables(&$list, &$opt, $pn, &$page) {
   global $PageListVarFoldFn, $StrFoldFunction;
   $fold = empty($PageListVarFoldFn)
@@ -541,7 +587,7 @@ function PageListUASort($x,$y) {
 }
 
 function PageListCache(&$list, &$opt, $pn, &$page) {
-  global $PageListCacheDir, $LastModTime, $PageIndexFile;
+  global $PageListCacheDir, $LastModTime;
 
   if (@!$PageListCacheDir) return 0;
   if (isset($opt['cache']) && !$opt['cache']) return 0;
@@ -553,9 +599,10 @@ function PageListCache(&$list, &$opt, $pn, &$page) {
       if (!file_exists($cache) || filemtime($cache) <= $LastModTime)
         return PAGELIST_POST;
       StopWatch("PageListCache begin load key=$key");
-      list($list, $opt['=protectsafe']) = 
+      @list($list, $opt['=protectsafe']) = 
         unserialize(file_get_contents($cache));
       $opt['=cached'] = 1;
+      if(!is_array($opt['=protectsafe'])) $opt['=protectsafe'] = array();
       StopWatch("PageListCache end load");
       return 0;
 
@@ -563,7 +610,7 @@ function PageListCache(&$list, &$opt, $pn, &$page) {
       StopWatch("PageListCache begin save key=$key");
       $fp = @fopen($cache, "w");
       if ($fp) {
-        fputs($fp, serialize(array($list, $opt['=protectsafe'])));
+        fputs($fp, serialize(array($list, (array)@$opt['=protectsafe'])));
         fclose($fp);
       }
       StopWatch("PageListCache end save");
@@ -587,7 +634,7 @@ function HandleSearchA($pagename, $level = 'read') {
   if (!preg_match('/\\(:searchresults(\\s.*?)?:\\)/', $text))
     foreach((array)$PageSearchForm as $formfmt) {
       $form = ReadPage(FmtPageName($formfmt, $pagename), READPAGE_CURRENT);
-      if ($form['text']) break;
+      if (@$form['text']) break;
     }
   $text = @$form['text'];
   if (!$text) $text = '(:searchresults:)';
@@ -607,11 +654,13 @@ function HandleSearchA($pagename, $level = 'read') {
 function CalcRange($range, $n) {
   if ($n < 1) return array(0, 0);
   if (strpos($range, '..') === false) {
+    $range = intval($range);
     if ($range > 0) return array(1, min($range, $n));
     if ($range < 0) return array(max($n + $range + 1, 1), $n);
     return array(1, $n);
   }
   list($r0, $r1) = explode('..', $range);
+  $r0 = intval($r0); $r1 = intval($r1);
   if ($r0 < 0) $r0 += $n + 1;
   if ($r1 < 0) $r1 += $n + 1;
   else if ($r1 == 0) $r1 = $n;
@@ -651,7 +700,7 @@ function FPLTemplate($pagename, &$matches, $opt) {
 
 ## Loads a template section
 function FPLTemplateLoad($pagename, $matches, $opt, &$tparts){
-  global $Cursor, $FPLTemplatePageFmt, $RASPageName, $PageListArgPattern;
+  global $Cursor, $FPLTemplatePageFmt, $RASPageName, $PageListArgPattern, $IncludedPages;
   SDV($FPLTemplatePageFmt, array('{$FullName}',
     '{$SiteGroup}.LocalTemplates', '{$SiteGroup}.PageListTemplates'));
 
@@ -659,7 +708,9 @@ function FPLTemplateLoad($pagename, $matches, $opt, &$
   if (!$template) $template = @$opt['fmt'];
   $ttext = RetrieveAuthSection($pagename, $template, $FPLTemplatePageFmt);
   $ttext = PVSE(Qualify($RASPageName, $ttext));
+  if ($ttext) @$IncludedPages[$RASPageName]++;
 
+  
   ##  save any escapes
   $ttext = MarkupEscape($ttext);
   ##  remove any anchor markups to avoid duplications
@@ -804,11 +855,11 @@ function FPLExpandItemVars($item, $matches, $idx, $psv
 ## normalized list of associated search terms.  This reduces the
 ## size of the index and speeds up searches.
 function PageIndexTerms($terms) {
-  global $StrFoldFunction;
+  global $PageIndexFoldFunction;
   $w = array();
   foreach((array)$terms as $t) {
     $w = array_merge($w, preg_split('/[^\\w\\x80-\\xff]+/', 
-           $StrFoldFunction($t), -1, PREG_SPLIT_NO_EMPTY));
+           $PageIndexFoldFunction($t), -1, PREG_SPLIT_NO_EMPTY));
   }
  return $w;
 }
@@ -820,7 +871,7 @@ function PageIndexTerms($terms) {
 ## on us).
 function PageIndexUpdate($pagelist = NULL, $dir = '') {
   global $EnableReadOnly, $PageIndexUpdateList, $PageIndexFile, 
-    $PageIndexTime, $Now;
+    $PageIndexTermsFunction, $PageIndexTime, $Now;
   if (IsEnabled($EnableReadOnly, 0)) return;
   $abort = ignore_user_abort(true);
   if ($dir) { flush(); chdir($dir); }
@@ -841,8 +892,8 @@ function PageIndexUpdate($pagelist = NULL, $dir = '') 
     if (time() > $timeout) continue;
     $page = ReadPage($pn, READPAGE_CURRENT);
     if ($page) {
-      $targets = str_replace(',', ' ', @$page['targets']);
-      $terms = PageIndexTerms(array(@$page['text'], $targets, $pn));
+      $targets = str_replace(',', ' ', strval(@$page['targets']));
+      $terms = $PageIndexTermsFunction(array(@$page['text'], $targets, $pn));
       usort($terms, $cmpfn);
       $x = '';
       foreach($terms as $t) { if (strpos($x, $t) === false) $x .= " $t"; }
@@ -881,7 +932,7 @@ function PageIndexQueueUpdate($pagelist) {
     register_shutdown_function('PageIndexUpdate', NULL, getcwd());
   $PageIndexUpdateList = array_merge((array)@$PageIndexUpdateList,
                                      (array)$pagelist);
-  $c1 = @count($pagelist); $c2 = count($PageIndexUpdateList);
+  $c1 = @count((array)$pagelist); $c2 = count($PageIndexUpdateList);
   StopWatch("PageIndexQueueUpdate: queued $c1 pages ($c2 total)");
 }
 
@@ -891,7 +942,7 @@ function PageIndexQueueUpdate($pagelist) {
 ## Also note that this just works for the index; if the index is
 ## incomplete, then so are the results returned by this list.
 ## (MakePageList above already knows how to deal with this.)
-function PageIndexGrep($terms, $invert = false) {
+function PageIndexGrep($terms, $invert = false, $links = false) {
   global $PageIndexFile;
   if (!$PageIndexFile) return array();
   StopWatch('PageIndexGrep begin');
@@ -908,6 +959,10 @@ function PageIndexGrep($terms, $invert = false) {
       $add = true;
       foreach($terms as $t) 
         if (strpos($line, $t) === false) { $add = false; break; }
+      if ($add && $links) {
+        $parts = explode(':', $line);
+        if (! PageListMatchTargets($parts[2], $links)) $add = false;
+      }
       if ($add xor $invert) $pagelist[] = substr($line, 0, $i);
     }
     fclose($fp);
blob - dafca5e7b6fb51312c501d6e51e072141c3e91b6
blob + 42c2aa83644fe8bc61f2cf3105b3c233e506bafb
--- scripts/pagerev.php
+++ scripts/pagerev.php
@@ -1,5 +1,5 @@
 <?php if (!defined('PmWiki')) exit();
-/*  Copyright 2004-2019 Patrick R. Michaud (pmichaud@pobox.com)
+/*  Copyright 2004-2022 Patrick R. Michaud (pmichaud@pobox.com)
     This file is part of PmWiki; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published
     by the Free Software Foundation; either version 2 of the License, or
@@ -26,7 +26,7 @@ SDV($PageDiffFmt,"<h2 class='wikiaction'>$[{\$FullName
   <p>$DiffMinorFmt - $DiffSourceFmt</p>
   ");
 SDV($DiffStartFmt,"
-      <div class='diffbox'><div class='difftime'><a name='diff\$DiffGMT' href='#diff\$DiffGMT'>\$DiffTime</a>
+      <div class='diffbox \$DiffClass' data-delay='\$DiffDataDelay'><div class='difftime'><a name='diff\$DiffGMT' id='diff\$DiffGMT' href='#diff\$DiffGMT'>\$DiffTime</a>
         \$[by] <span class='diffauthor' title='\$DiffHost'>\$DiffAuthor</span> - \$DiffChangeSum</div>");
 SDV($DiffDelFmt['a'],"
         <div class='difftype'>\$[Deleted line \$DiffLines:]</div>
@@ -62,11 +62,15 @@ SDV($HTMLStylesFmt['diff'], "
     font-size:66%; margin:1.5em 0px; }
   .diffmarkup { font-family:monospace; } 
   .diffmarkup del { background:#ffff99; text-decoration: none; }
-  .diffmarkup ins { background:#99ff99; text-decoration: none; }");
+  .diffmarkup ins { background:#99ff99; text-decoration: none; }
+  .rcplus { cursor:pointer; opacity:.3; font-weight:bold; padding: 0 .3em; }
+  .rcplus:hover {color: white; background: blue; opacity: 1;}
+  .rcreload { opacity:0.2; font-size: .9rem; cursor: pointer; }
+  .rcnew {background-color: #ffa;}");
 
 function PrintDiff($pagename) {
-  global $DiffHTMLFunction,$DiffShow,$DiffStartFmt,$TimeFmt,
-    $DiffEndFmt,$DiffRestoreFmt,$FmtV, $LinkFunctions;
+  global $Now, $DiffHTMLFunction,$DiffShow,$DiffStartFmt,$TimeFmt,
+    $DiffEndFmt,$DiffRestoreFmt,$FmtV, $EnableDiffHidden, $LinkFunctions;
   $page = ReadPage($pagename);
   if (!$page) return;
   krsort($page); reset($page);
@@ -74,12 +78,24 @@ function PrintDiff($pagename) {
   $LinkFunctions['http:'] = 'LinkSuppress';
   $LinkFunctions['https:'] = 'LinkSuppress';
   SDV($DiffHTMLFunction, 'DiffHTML');
+  $prevstamp = $Now;
   foreach($page as $k=>$v) {
     if (!preg_match("/^diff:(\d+):(\d+):?([^:]*)/",$k,$match)) continue;
     $diffclass = $match[3];
+    if ($diffclass=='hidden' && !@$EnableDiffHidden) continue;
     if ($diffclass=='minor' && $DiffShow['minor']!='y') continue;
-    $diffgmt = $FmtV['$DiffGMT'] = $match[1];
-    $FmtV['$DiffTime'] = strftime($TimeFmt,$diffgmt);
+    $diffgmt = $FmtV['$DiffGMT'] = intval($match[1]);
+    $delaydays = ($prevstamp - $diffgmt) / 86400;
+    $compact = DiffTimeCompact($diffgmt, $prevstamp, 1);
+    $prevstamp = $diffgmt;
+    if ($delaydays < 1) $cname = '';
+    elseif ($delaydays < 7) $cname = 'diffday';
+    elseif ($delaydays < 31) $cname = 'diffweek';
+    elseif ($delaydays < 365) $cname = 'diffmonth';
+    else $cname = 'diffyear';
+    $FmtV['$DiffClass'] = trim("$cname $diffclass");
+    $FmtV['$DiffDataDelay'] = $compact;
+    $FmtV['$DiffTime'] = PSFT($TimeFmt,$diffgmt);
     $diffauthor = @$page["author:$diffgmt"]; 
     if (!$diffauthor) @$diffauthor=$page["host:$diffgmt"];
     if (!$diffauthor) $diffauthor="unknown";
@@ -152,6 +168,7 @@ function DiffHTML($pagename, $diff) {
 function cb_diffhtml($m) { return Keep(PHSC($m[0])); }
 
 function HandleDiff($pagename, $auth='read') {
+  if (@$_GET['fmt'] == 'rclist') return HandleDiffList($pagename, $auth);
   global $HandleDiffFmt, $PageStartFmt, $PageDiffFmt, $PageEndFmt;
   $page = RetrieveAuthPage($pagename, $auth, true, READPAGE_CURRENT);
   if (!$page) { Abort("?cannot diff $pagename"); }
@@ -160,10 +177,39 @@ function HandleDiff($pagename, $auth='read') {
     &$PageDiffFmt,"<div id='wikidiff'>", 'function:PrintDiff', '</div>',
     &$PageEndFmt));
   PrintFmt($pagename,$HandleDiffFmt);
+}
+
+function HandleDiffList($pagename, $auth='read') {
+  global $EnableDiffHidden, $Now, $Charset, $EnableLocalTimes;
+  $days = floor($EnableLocalTimes/10);
+  if(!$days) $days = 3;
+  $since = $Now - $days*24*3600;
+  header("Content-Type: text/plain; charset=$Charset");
+  $page = RetrieveAuthPage($pagename, $auth, false);
+  if (!$page) {
+    print("$Now:[No permissions to diff page]");
+    exit;
+  }
+  krsort($page); reset($page);
+  $out = "";
+  $hide = IsEnabled($EnableDiffHidden, 0)? '' : '(?!hidden)';
+  $list = preg_grep("/^diff:(\\d+):\\d+:$hide\\w*$/", array_keys($page));
+  foreach($list as $v) {
+    list($key, $stamp) = explode(':', $v);
+    if ($stamp == $page['time']) continue;
+    $author = @$page["author:$stamp"] ? $page["author:$stamp"] : '?';
+    $csum = strval(@$page["csum:$stamp"]);
+    $out .= "$stamp:".PHSC("$author: $csum")."\n";
+    if ($stamp<$since) break; # at least one after the 72 hours
+  }
+  print(trim($out));
+  exit;
 }
+
 ## Functions for simple word-diff (written by Petko Yotov)
 function DiffRenderSource($in, $out, $which) {
-  global $WordDiffFunction, $EnableDiffInline;
+  global $WordDiffFunction, $EnableDiffInline, $DiffPrepareInlineFunction;
+  SDV($DiffPrepareInlineFunction, 'DiffPrepareInline');
   if (!IsEnabled($EnableDiffInline, 1)) {
     $a = $which? $out : $in;
     return str_replace("\n","<br />",PHSC(join("\n",$a)));  
@@ -171,12 +217,12 @@ function DiffRenderSource($in, $out, $which) {
   $countdifflines = abs(count($in)-count($out));
   $lines = $cnt = $x2 = $y2 = array();
   foreach($in as $line) {
-    $tmp = $countdifflines>20 ? array($line) : DiffPrepareInline($line);
+    $tmp = $countdifflines>20 ? array($line) : $DiffPrepareInlineFunction($line);
     if (!$which) $cnt[] = array(count($x2), count($tmp));
     $x2 = array_merge($x2, $tmp);
   }
   foreach($out as $line) {
-    $tmp = $countdifflines>20 ? array($line) : DiffPrepareInline($line);
+    $tmp = $countdifflines>20 ? array($line) : $DiffPrepareInlineFunction($line);
     if ($which) $cnt[] = array(count($y2), count($tmp));
     $y2 = array_merge($y2, $tmp);
   }
blob - 4b1c42e0f9c1dde844a3b2f8160c10492db05b13
blob + dab53bf5af536edfc07cfe952be350d4462c5553
--- scripts/pgcust.php
+++ scripts/pgcust.php
@@ -1,5 +1,5 @@
 <?php if (!defined('PmWiki')) exit();
-/*  Copyright 2002-2005 Patrick R. Michaud (pmichaud@pobox.com)
+/*  Copyright 2002-2022 Patrick R. Michaud (pmichaud@pobox.com)
     This file is part of PmWiki; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published
     by the Free Software Foundation; either version 2 of the License, or
@@ -24,6 +24,7 @@
     can force group customizations to be loaded first by using include_once
     on the group customization file.
     
+    Script maintained by Petko YOTOV www.pmwiki.org/petko
 */
 
 $f = 1;
@@ -32,6 +33,11 @@ for($p=$pagename;$p;$p=preg_replace('/\\.*[^.]*$/','',
   if (file_exists("$LocalDir/$p.php")) 
     { include_once("$LocalDir/$p.php"); $f=0; }
 }
+if (IsEnabled($EnableBaseNameConfig, 0)) {
+  $p = MakeBaseName($pagename);
+  if (file_exists("$LocalDir/$p.php")) 
+    { include_once("$LocalDir/$p.php"); $f=0; }
+}
 
 if ($f && IsEnabled($EnablePGCust,1) && file_exists("$LocalDir/default.php"))
   include_once("$LocalDir/default.php");
blob - 5cbb0917e772ab886dd2c9719a5fc6e6c8a0abd0
blob + 0b486cb217b0f26f13d9410b97d5345234008ce8
--- scripts/phpdiff.php
+++ scripts/phpdiff.php
@@ -1,7 +1,7 @@
 <?php  if (!defined('PmWiki')) exit();
 /*  
     Copyright 2003,2004 Nils Knappmeier (nk@knappi.org)
-    Copyright 2004-2015 Patrick R. Michaud (pmichaud@pobox.com)
+    Copyright 2004-2021 Patrick R. Michaud (pmichaud@pobox.com)
 
     This file is part of PmWiki; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published
@@ -29,7 +29,7 @@ function PHPDiff($old, $new) 
    $t1 = explode("\n", $old);
    $x = array_pop($t1); 
    if ($x > '') $t1[] = "$x\n\\ No newline at end of file";
-   $t2 = explode("\n", $new);
+   $t2 = explode("\n", strval($new));
    $x = array_pop($t2); 
    if ($x > '') $t2[] = "$x\n\\ No newline at end of file";
 
@@ -113,6 +113,6 @@ function PHPDiff($old, $new) 
   return join("\n",$out);
 }
 
-if (!function_exists(@$DiffFunction))
+if (!@$DiffFunction || !function_exists($DiffFunction))
   $DiffFunction = 'PHPDiff';
 
blob - 6d1224533bb39944f35e7f4f8b7c977d4cd4bfaa
blob + bf78bc6962ee0b424455daf7be6b4743963802b8
--- scripts/refcount.php
+++ scripts/refcount.php
@@ -1,5 +1,5 @@
 <?php if (!defined('PmWiki')) exit();
-/*  Copyright 2004-2018 Patrick R. Michaud (pmichaud@pobox.com)
+/*  Copyright 2004-2022 Patrick R. Michaud (pmichaud@pobox.com)
     This file is part of PmWiki; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published
     by the Free Software Foundation; either version 2 of the License, or
@@ -69,7 +69,7 @@ function PrintRefCount($pagename) {
       if (!in_array('all',$flist) &&
           !in_array(FmtPageName('$Group',$pname),$flist)) continue;
       $rc = preg_match('/RecentChanges$/',$pname);
-      foreach(explode(',',@$page['targets']) as $r) {
+      foreach(explode(',',strval(@$page['targets'])) as $r) {
         if ($r=='') continue;
         if ($rc) @$tref[$r]['rc']++;
         else { @$tref[$r]['page']++; @$pref[$r][$pname]++; }
@@ -88,7 +88,7 @@ function PrintRefCount($pagename) {
       elseif ($whichrefs=='orphaned' &&
         (@$tref[$p]['page']>0 || !PageExists($p))) continue;
       echo "<tr><td valign='top'>",LinkPage($pagename, '', $p, '', $p);
-      if (@$tref[$p]['time']) echo strftime($RefCountTimeFmt,$tref[$p]['time']);
+      if (@$tref[$p]['time']) echo PSFT($RefCountTimeFmt,$tref[$p]['time']);
       if ($showrefs && is_array(@$pref[$p])) {
         foreach($pref[$p] as $pr=>$pc) 
           echo "<dd>", LinkPage($pagename, '', $pr, '', $pr);
blob - ad3de162a11498d40e33ac744469483dda66f21c
blob + d5ea8fab3829fef669a037ffa7ff47d6a1dabc72
--- scripts/skins.php
+++ scripts/skins.php
@@ -1,5 +1,5 @@
 <?php if (!defined('PmWiki')) exit();
-/*  Copyright 2004-2020 Patrick R. Michaud (pmichaud@pobox.com)
+/*  Copyright 2004-2023 Patrick R. Michaud (pmichaud@pobox.com)
     This file is part of PmWiki; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published
     by the Free Software Foundation; either version 2 of the License, or
@@ -20,6 +20,8 @@ SDV($ActionSkin['print'], 'print');
 SDV($FarmPubDirUrl, $PubDirUrl);
 SDV($PageLogoUrl, "$FarmPubDirUrl/skins/pmwiki/pmwiki-32.gif");
 SDVA($TmplDisplay, array('PageEditFmt' => 0));
+SDV($LocalCSSDir, 'pub/css');
+SDV($LocalCSSDirUrl, '$PubDirUrl/css');
 
 ## from skinchange.php
 if (IsEnabled($EnableAutoSkinList, 0) || isset($PageSkinList)) {
@@ -58,9 +60,9 @@ else {
 }
 
 SDV($PageCSSListFmt,array(
-  'pub/css/local.css' => '$PubDirUrl/css/local.css',
-  'pub/css/{$Group}.css' => '$PubDirUrl/css/{$Group}.css',
-  'pub/css/{$FullName}.css' => '$PubDirUrl/css/{$FullName}.css'));
+  "$LocalCSSDir/local.css" => "$LocalCSSDirUrl/local.css",
+  "$LocalCSSDir/{\$Group}.css" => "$LocalCSSDirUrl/{\$Group}.css",
+  "$LocalCSSDir/{\$FullName}.css" => "$LocalCSSDirUrl/{\$FullName}.css"));
 
 foreach((array)$PageCSSListFmt as $k=>$v) 
   if (file_exists(FmtPageName($k,$pagename))) 
@@ -122,6 +124,14 @@ function cb_includeskintemplate($m) {
   }
 }
 
+# Helper function for recipes
+function DisableSkinParts($x) {
+  $x = preg_split('/\\W+/', ucwords(strtolower($x)), -1, PREG_SPLIT_NO_EMPTY);
+  foreach($x as $y) {
+    SetTmplDisplay("Page{$y}Fmt",0);
+  }
+}
+
 # LoadPageTemplate loads a template into $TmplFmt
 function LoadPageTemplate($pagename,$tfilefmt) {
   global $PageStartFmt, $PageEndFmt, $SkinTemplateIncludeLevel,
blob - 926fe7d40705b26f504c84750bc19b7735241e3f
blob + 0314a9bd6a6cc985a99765cc7a4f99c573abfd35
--- scripts/stdconfig.php
+++ scripts/stdconfig.php
@@ -1,5 +1,5 @@
 <?php if (!defined('PmWiki')) exit();
-/*  Copyright 2002-2019 Patrick R. Michaud (pmichaud@pobox.com)
+/*  Copyright 2002-2022 Patrick R. Michaud (pmichaud@pobox.com)
     This file is part of PmWiki; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published
     by the Free Software Foundation; either version 2 of the License, or
@@ -47,8 +47,10 @@ if (IsEnabled($EnableCaches, 1))
   include_once("$FarmD/scripts/caches.php");
 
 ## Scripts that are part of a standard PmWiki distribution.
-if (IsEnabled($EnableAuthorTracking,1)) 
+if (IsEnabled($EnableAuthorTracking,1)) {
   include_once("$FarmD/scripts/author.php");
+  EnableSignatures();
+}
 if (IsEnabled($EnablePrefs, 1))
   include_once("$FarmD/scripts/prefs.php");
 if (IsEnabled($EnableSimulEdit, 1))
@@ -77,7 +79,7 @@ if (IsEnabled($EnablePageList,1))
   include_once("$FarmD/scripts/pagelist.php");
 if (IsEnabled($EnableVarMarkup,1))
   include_once("$FarmD/scripts/vardoc.php");
-if (!function_exists(@$DiffFunction)) 
+if (!@$DiffFunction || !function_exists($DiffFunction)) 
   include_once("$FarmD/scripts/phpdiff.php");
 if ($action=='crypt')
   include_once("$FarmD/scripts/crypt.php");
@@ -93,24 +95,10 @@ if (IsEnabled($EnableNotify,0))
   include_once("$FarmD/scripts/notify.php");
 if (IsEnabled($EnableDiag,0) || $action == 'recipecheck') 
   include_once("$FarmD/scripts/diag.php");
+if (IsEnabled($EnablePmUtils,1))
+  include_once("$FarmD/scripts/utils.php");
 
-if (IsEnabled($PmTOC['Enable'],0) || IsEnabled($PmEmbed,0) || IsEnabled($EnableSortable,0)
-  || $LinkFunctions['mailto:'] == 'ObfuscateLinkIMap' || IsEnabled($EnableHighlight, 0)
-  || IsEnabled($ToggleNextSelector, 0)
-  ) {
-  $utils = "$FarmD/pub/pmwiki-utils.js";
-  if(file_exists($utils)) {
-    $mtime = filemtime($utils);
-    $HTMLFooterFmt['pmwiki-utils'] =
-      "<script type='text/javascript' src='\$FarmPubDirUrl/pmwiki-utils.js?st=$mtime'
-        data-sortable='".@$EnableSortable."' data-highlight='".@$EnableHighlight."'
-        data-pmtoc='".PHSC(json_encode(@$PmTOC), ENT_QUOTES)."'
-        data-toggle='".PHSC(@$ToggleNextSelector, ENT_QUOTES)."'
-        data-pmembed='".PHSC(json_encode(@$PmEmbed), ENT_QUOTES)."' async></script>";
-  }
-}
-
-if (IsEnabled($EnableUpgradeCheck,1)) {
+if (IsEnabled($EnableUpgradeCheck,1) && !IsEnabled($EnableReadOnly, 0)) {
   SDV($StatusPageName, "$SiteAdminGroup.Status");
   $page = ReadPage($StatusPageName, READPAGE_CURRENT);
   if (@$page['updatedto'] != $VersionNum) 
blob - 07498b01983619aec5f60afd875f8632e9fe9fa4
blob + 5b4c49201ce7e9574f83c293e75dcb798f5ffe8b
--- scripts/stdmarkup.php
+++ scripts/stdmarkup.php
@@ -1,5 +1,5 @@
 <?php if (!defined('PmWiki')) exit();
-/*  Copyright 2004-2020 Patrick R. Michaud (pmichaud@pobox.com)
+/*  Copyright 2004-2022 Patrick R. Michaud (pmichaud@pobox.com)
     This file is part of PmWiki; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published
     by the Free Software Foundation; either version 2 of the License, or
@@ -54,7 +54,12 @@ Markup('{$var}', '>$[phrase]',
   '/\\{(\\*|!?[-\\w.\\/\\x80-\\xff]*)(\\$:?\\w[-\\w]*)\\}/',
   "MarkupPageVar");
 function MarkupPageVar($m){
+  global $IncludedPages, $Cursor;
   extract($GLOBALS["MarkupToHTML"]);
+  if($m[1] && strpos($m[2], '$:')===0) {
+    $pn = isset($Cursor[$m[1]]) ? $Cursor[$m[1]] : MakePageName($pagename, $m[1]);
+    @$IncludedPages[$pn]++;
+  }
   return PRR(PVSE(PageVar($pagename, $m[2], $m[1])));
 }
 
@@ -214,8 +219,8 @@ Markup('messages', 'directives',
 function MarkupDirectives($m) {
   extract($GLOBALS["MarkupToHTML"]);
   switch ($markupid) {
-    case 'linkwikiwords':  return PZZ($GLOBALS['LinkWikiWords']=($m[1]!='no'));
-    case 'spacewikiwords': return PZZ($GLOBALS['SpaceWikiWords']=($m[1]!='no'));
+    case 'linkwikiwords':  return PZZ($GLOBALS['LinkWikiWords']=(@$m[1]!='no'));
+    case 'spacewikiwords': return PZZ($GLOBALS['SpaceWikiWords']=(@$m[1]!='no'));
     case 'linebreaks': 
       return PZZ($GLOBALS['HTMLPNewline'] = (@$m[1]!='no') ? '<br  />' : '');
     case 'messages': 
@@ -289,11 +294,10 @@ Markup('[+','inline','/\\[(([-+])+)(.*?)\\1\\]/',
   "MarkupBigSmall");
 
 function MarkupBigSmall($m) {
-  return '<span style=\'font-size:'
-    .(round(pow(6/5,($m[2]=='-'? -1:1)*strlen($m[1]))*100,0))
-    .'%\'>'. $m[3].'</span>';
+  $size = round(pow(6/5,($m[2]=='-'? -1:1)*strlen($m[1]))*100,0);
+  return "<span style='font-size: $size%;'>{$m[3]}</span>";
 }
-    
+
 ## {+ins+}, {-del-}
 Markup('{+','inline','/\\{\\+(.*?)\\+\\}/','<ins>$1</ins>');
 Markup('{-','inline','/\\{-(.*?)-\\}/','<del>$1</del>');
@@ -307,10 +311,6 @@ function MarkupLinks($m){
   switch ($markupid) {
     case '[[': 
       return Keep(MakeLink($pagename,$m[1],NULL,$m[2]),'L');
-    case '[[!': 
-      global $CategoryGroup, $LinkCategoryFmt;
-      return Keep(MakeLink($pagename,"$CategoryGroup/{$m[1]}",NULL,'',
-        $LinkCategoryFmt),'L');
     case '[[|': 
       return Keep(MakeLink($pagename,$m[1],$m[2],$m[3]),'L');
     case '[[->': 
@@ -330,14 +330,17 @@ function MarkupLinks($m){
              $ImgTagFmt),'L');
   }
 }
+
 
 ## [[free links]]
 Markup('[[','links',"/(?>\\[\\[\\s*(.*?)\\]\\])($SuffixPattern)/", "MarkupLinks");
 
 ## [[!Category]]
+## Markup '[[!' now processed and indexed in LinkPage() 
+## with other link formats (PITS:01095, PITS:00447)
 SDV($CategoryGroup,'Category');
 SDV($LinkCategoryFmt,"<a class='categorylink' href='\$LinkUrl'>\$LinkText</a>");
-Markup('[[!','<[[','/\\[\\[!(.*?)\\]\\]/', "MarkupLinks");
+
 # This is a temporary workaround for blank category pages.
 # It may be removed in a future release (Pm, 2006-01-24)
 if (preg_match("/^$CategoryGroup\\./", $pagename)) {
@@ -389,7 +392,7 @@ function cb_qualifylinks($m) { 
   extract($GLOBALS['tmp_qualify']);
   return "{$m[1]}$group/{$m[2]}";
 }  
-  
+
 ## bare wikilinks
 ##    v2.2: markup rule moved to scripts/wikiwords.php)
 Markup('wikilink', '>urllink');
@@ -508,9 +511,12 @@ Markup('^>><<', '<^>>',
   '/^&gt;&gt;&lt;&lt;/',
   '(:divend:)');
 
+Markup('det-summ', '<table', '/(\\(:details[ ].*?)summary=(?:([\'"])(.*?)\\2
+  |(\\S+))(.*?:\\))/xi', '$1$5<summary>$3$4</summary>'); # PITS:01465 
+
 function SimpleTableAttr($attr) {
   global $SimpleTableDefaultClassName;
-  $qattr = PQA($attr);
+  $qattr = PQA($attr, true, true);
   if(IsEnabled($SimpleTableDefaultClassName) && !preg_match("/(^| )class='.*?' /", $qattr))
     $qattr .= "class='$SimpleTableDefaultClassName'";
   return $qattr;
@@ -519,7 +525,7 @@ function SimpleTableAttr($attr) {
 #### (:table:) markup (AdvancedTables)
 function Cells($name,$attr) {
   global $MarkupFrame, $EnableTableAutoValignTop;
-  $attr = PQA($attr);
+  $attr = PQA($attr, true, true);
   $tattr = @$MarkupFrame[0]['tattr'];
   $name = strtolower($name);
   $key = preg_replace('/end$/', '', $name);
@@ -551,7 +557,6 @@ function Cells($name,$attr) {
   return $out;
 }
 
-
 ## headings
 Markup('^!', 'block', '/^(!{1,6})\\s?(.*)$/', "MarkupHeadings");
 function MarkupHeadings($m) {
@@ -562,26 +567,34 @@ function MarkupHeadings($m) {
 ## horiz rule
 Markup('^----','>^->','/^----+/','<:block,1><hr />');
 
+## @2022-01-08T10:07:08Z -> <time datetime=""></time>
+Markup('<time>', '<@@', '/@\\d{4}-(0[1-9]|1[012])-(0[1-9]|[12]\\d|3[01])'
+  .'T([01]\\d|2[0-3]):([0-5]\\d)(:([0-5]\\d))?Z?/i', 'FmtDateTimeZ');
+
 #### special stuff ####
 ## (:markup:) for displaying markup examples
 function MarkupMarkup($pagename, $text, $opt = '') {
   global $MarkupWordwrapFunction, $MarkupWrapTag;
   SDV($MarkupWordwrapFunction, 'IsEnabled');
   SDV($MarkupWrapTag, 'pre');
+  $tag = $MarkupWrapTag;
   $MarkupMarkupOpt = array('class' => 'vert');
   $opt = array_merge($MarkupMarkupOpt, ParseArgs($opt));
-  $html = MarkupToHTML($pagename, $text, array('escape' => 0));
   if (@$opt['caption']) 
     $caption = str_replace("'", '&#039;', 
                            "<caption>{$opt['caption']}</caption>");
   $class = preg_replace('/[^-\\s\\w]+/', ' ', @$opt['class']);
-  if (strpos($class, 'horiz') !== false) 
-    { $sep = ''; $pretext = $MarkupWordwrapFunction($text, 40); } 
-  else 
-    { $sep = '</tr><tr>'; $pretext = $MarkupWordwrapFunction($text, 75); }
+  $sep = '';
+  if (strpos($class, 'norender') !== false) $markup2 = '';
+  else {
+    if (strpos($class, 'horiz') === false) $sep = '</tr><tr>';
+    $html = MarkupToHTML($pagename, $text, array('escape' => 0));
+    $markup2 = "<td class='markup2' valign='top'>$html</td>";
+  }
+  $pretext = $MarkupWordwrapFunction($text, ($markup2 xor $sep)? 40:75);
+  $markup1 = @"<td class='markup1' valign='top'><$tag>$pretext</$tag></td>";
   return Keep(@"<table class='markup $class' align='center'>$caption
-      <tr><td class='markup1' valign='top'><$MarkupWrapTag>$pretext</$MarkupWrapTag></td>$sep<td 
-        class='markup2' valign='top'>$html</td></tr></table>");
+      <tr>$markup1$sep$markup2</tr></table>");
 }
 
 Markup('markup', '<[=',
@@ -665,8 +678,14 @@ function FmtPmTOC($m) {
 }
 SDV($HTMLStylesFmt['PmTOC'], '.noPmTOC, .PmTOCdiv:empty {display:none;}
 .PmTOCdiv { display: inline-block; font-size: 13px; overflow: auto; max-height: 500px;}
-.PmTOCdiv a { text-decoration: none;}
-.back-arrow {font-size: .9em; text-decoration: none;}
+.PmTOCdiv a { text-decoration: none; display: block; line-height: 1;}
+.PmTOCdiv a.pmtoc-indent1 { margin-left: 1em; }
+.PmTOCdiv a.pmtoc-indent2 { margin-left: 2em; }
+.PmTOCdiv a.pmtoc-indent3 { margin-left: 3em; }
+.PmTOCdiv a.pmtoc-indent4 { margin-left: 4em; }
+.PmTOCdiv a.pmtoc-indent5 { margin-left: 5em; }
+.PmTOCdiv a.pmtoc-indent6 { margin-left: 6em; }
+.back-arrow {font-size: .8rem; text-decoration: none; vertical-align: text-top;}
 #PmTOCchk + label {cursor: pointer;}
 #PmTOCchk {display: none;}
 #PmTOCchk:not(:checked) + label > .pmtoc-show {display: none;}
@@ -679,3 +698,24 @@ table.sortable th:hover::after { color: inherit; conte
 table.sortable th.dir-u::after { color: inherit; content: "\00A0\025BE"; }
 table.sortable th.dir-d::after { color: inherit; content: "\00A0\025B4"; }');
 
+
+# Helper function for recipes
+# Generic Markup directive (:abc params:)...(:abcend:)?
+function AutoMarkupDirective($m) { # all, directive, params?, content?
+  global $MarkupToHTML, $MarkupDirectiveFunctions;
+  extract($MarkupToHTML); # get $pagename
+  @list($all, $directive, $params, $content) = $m;
+  if(!isset($MarkupDirectiveFunctions[$directive])) return Keep($all);
+  
+  $args = ParseArgs(strval(@$params));
+  $content = trim(strval(@$content));
+  
+  return $MarkupDirectiveFunctions[$directive]($pagename, $directive, $args, $content);
+}
+
+if(isset($MarkupDirectiveFunctions)) {
+  $keys = implode('|', array_keys($MarkupDirectiveFunctions));
+  Markup('anydir', 'directives', "/\\(:($keys)(\\s+.*?)?:\\)/s", 'AutoMarkupDirective');
+  Markup('anydir2', '<anydir', "/\\(:($keys)(\\s+.*?)?:\\).*?\\(:\\1end:\\)/s", 'AutoMarkupDirective');
+}
+
blob - bfd0159161934ac150b9bb1165b2a0bc4dbc3f83
blob + 710688f73a24ff6b6d5a490ac4ecb9b2dacd2535
--- scripts/trails.php
+++ scripts/trails.php
@@ -1,5 +1,5 @@
 <?php if (!defined('PmWiki')) exit();
-/*  Copyright 2002-2017 Patrick R. Michaud (pmichaud@pobox.com)
+/*  Copyright 2002-2022 Patrick R. Michaud (pmichaud@pobox.com)
     This file is part of PmWiki; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published
     by the Free Software Foundation; either version 2 of the License, or
blob - 773836d5107e24781d3e343085ae20dae077ddf4
blob + be0d979e46599be6112b741139f871e12e3da0ce
--- scripts/upload.php
+++ scripts/upload.php
@@ -1,5 +1,5 @@
 <?php if (!defined('PmWiki')) exit();
-/*  Copyright 2004-2020 Patrick R. Michaud (pmichaud@pobox.com)
+/*  Copyright 2004-2022 Patrick R. Michaud (pmichaud@pobox.com)
     This file is part of PmWiki; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published
     by the Free Software Foundation; either version 2 of the License, or
@@ -25,7 +25,7 @@ SDV($EnableUploadOverwrite,1);
 ## accept, along with the Content-Type: value appropriate for each.
 SDVA($UploadExts,array(
   'gif' => 'image/gif', 'jpg' => 'image/jpeg', 'jpeg' => 'image/jpeg',
-  'png' => 'image/png', 'bmp' => 'image/bmp', 'ico' => 'image/x-icon',
+  'png' => 'image/png', 'apng' => 'image/apng', 'bmp' => 'image/bmp', 'ico' => 'image/x-icon',
   'wbmp'=> 'image/vnd.wap.wbmp', 'xcf' => 'image/x-xcf', 'webp' => 'image/webp',
   'svg' => 'image/svg+xml', 'svgz' => 'image/svg+xml',
   'mp3' => 'audio/mpeg', 'au' => 'audio/basic', 'wav' => 'audio/x-wav',
@@ -93,6 +93,7 @@ SDV($PageUploadFmt,array("
   <form enctype='multipart/form-data' action='{\$PageUrl}?action=postupload' method='post'>
   <input type='hidden' name='n' value='{\$FullName}' />
   <input type='hidden' name='action' value='postupload' />
+  <input type='hidden' name='\$TokenName' value='\$TokenValue' />
   <table border='0'>
     <tr><td align='right'>$[File to upload:]</td><td><input
       name='uploadfile' type='file' required='required' /></td></tr>
@@ -105,7 +106,9 @@ SDV($PageUploadFmt,array("
         </td></tr></table></form></div>",
   'wiki:$[{$SiteGroup}/UploadQuickReference]'));
 XLSDV('en',array(
+  'ULby' => 'uploaded by',
   'ULsuccess' => 'successfully uploaded',
+  'ULinvalidtoken' => 'Token invalid or missing.',
   'ULauthorrequired' => 'An author name is required.',
   'ULbadname' => 'invalid attachment name',
   'ULbadtype' => '\'$upext\' is not an allowed file extension',
@@ -152,8 +155,9 @@ function MakeUploadName($pagename,$x) {
    return PPRA($MakeUploadNamePatterns, $x);
 }
 
-function LinkUpload($pagename, $imap, $path, $alt, $txt, $fmt=NULL) {
-  global $FmtV, $UploadFileFmt, $LinkUploadCreateFmt,
+##  This helper function returns the public URL for an attached file
+function DownloadUrl($pagename, $path) {
+  global $FmtV, $UploadFileFmt,
     $UploadUrlFmt, $UploadPrefixFmt, $EnableDirectDownload;
   if (preg_match('!^(.*)/([^/]+)$!', $path, $match)) {
     $pagename = MakePageName($pagename, $match[1]);
@@ -164,13 +168,19 @@ function LinkUpload($pagename, $imap, $path, $alt, $tx
   $filepath = FmtPageName("$UploadFileFmt/$upname", $pagename);
   $FmtV['$LinkUpload'] =
     FmtPageName("\$PageUrl?action=upload&amp;upname=$encname", $pagename);
+  $FmtV['$LinkDownload'] = PUE(FmtPageName(IsEnabled($EnableDirectDownload, 1) 
+      ? "$UploadUrlFmt$UploadPrefixFmt/$encname"
+      : "{\$PageUrl}?action=download&amp;upname=$encname",
+    $pagename));
+  if (!file_exists($filepath)) return false;
+  return $FmtV['$LinkDownload'];
+}
+
+function LinkUpload($pagename, $imap, $path, $alt, $txt, $fmt=NULL) {
+  global $FmtV, $LinkUploadCreateFmt;
   $FmtV['$LinkText'] = $txt;
-  if (!file_exists($filepath)) 
-    return FmtPageName($LinkUploadCreateFmt, $pagename);
-  $path = PUE(FmtPageName(IsEnabled($EnableDirectDownload, 1) 
-                            ? "$UploadUrlFmt$UploadPrefixFmt/$encname"
-                            : "{\$PageUrl}?action=download&amp;upname=$encname",
-                          $pagename));
+  $path = DownloadUrl($pagename, $path);
+  if(!$path) return FmtPageName($LinkUploadCreateFmt, $pagename);
   return LinkIMap($pagename, $imap, $path, $alt, $txt, $fmt);
 }
 
@@ -196,6 +206,7 @@ function UploadSetVars($pagename) {
   $uprname = PHSC(@$_REQUEST['uprname']);
   $FmtV['$upext'] = PHSC(@$_REQUEST['upext']);
   $FmtV['$upmax'] = PHSC(@$_REQUEST['upmax']);
+  $FmtV['$TokenValue'] = pmtoken();
   $FmtV['$UploadResult'] = ($upresult) ?
     FmtPageName("<i>$uprname</i>: $[UL$upresult]",$pagename) : 
       (@$EnableReadOnly ? XL('Cannot modify site -- $EnableReadOnly is set'): '');
@@ -272,9 +283,9 @@ function HandleDownload($pagename, $auth = 'read') {
 }
 
 function HandlePostUpload($pagename, $auth = 'upload') {
-  global $UploadVerifyFunction, $UploadFileFmt, $LastModFile, 
-    $EnableUploadVersions, $Now, $RecentUploadsFmt, $FmtV,
-    $NotifyItemUploadFmt, $NotifyItemFmt, $IsUploadPosted,
+  global $UploadVerifyFunction, $UploadFileFmt, $LastModFile, $Now, 
+    $EnableUploadVersions, $EnableRecentUploads, $RecentUploadsFmt,
+    $FmtV, $NotifyItemUploadFmt, $NotifyItemFmt, $IsUploadPosted,
     $UploadRedirectFunction, $UploadPermAdd, $UploadPermSet,
     $EnableReadOnly;
     
@@ -282,14 +293,14 @@ function HandlePostUpload($pagename, $auth = 'upload')
     Abort('Cannot modify site -- $EnableReadOnly is set', 'readonly');
 
   UploadAuth($pagename, $auth);
-  $uploadfile = $_FILES['uploadfile'];
+  $uploadfile = @$_FILES['uploadfile'];
   $upname = @$_REQUEST['upname'];
-  if ($upname=='') $upname=$uploadfile['name'];
+  if ($upname=='') $upname=strval(@$uploadfile['name']);
   $upname = MakeUploadName($pagename,$upname);
   if (!function_exists($UploadVerifyFunction))
     Abort('?no UploadVerifyFunction available');
   $filepath = FmtPageName("$UploadFileFmt/$upname",$pagename);
-  $result = $UploadVerifyFunction($pagename,$uploadfile,$filepath);
+  $result = $UploadVerifyFunction($pagename,$uploadfile,$filepath,$upname);
   if ($result=='') {
     $filedir = preg_replace('#/[^/]*$#','',$filepath);
     mkdirp($filedir);
@@ -300,8 +311,17 @@ function HandlePostUpload($pagename, $auth = 'upload')
     fixperms($filepath, $UploadPermAdd, $UploadPermSet);
     if ($LastModFile) { touch($LastModFile); fixperms($LastModFile); }
     $result = "upresult=success";
+    $FmtV['$filepath'] = $filepath;
     $FmtV['$upname'] = $upname;
     $FmtV['$upsize'] = $uploadfile['size'];
+    $FmtV['$upurl'] = DownloadUrl($pagename, $upname);
+    if (IsEnabled($EnableRecentUploads, 0)) {
+      SDV($RecentUploadsFmt, array( # not SDVA
+        '$SiteGroup.AllRecentChanges' => 
+          '* [[(Attach:){$FullName}/$upname]]  . . . $CurrentLocalTime'
+          . ' $[ULby] $AuthorLink ($upsize $[bytes])'
+      ));
+    }
     if (IsEnabled($RecentUploadsFmt, 0)) {
       PostRecentChanges($pagename, '', '', $RecentUploadsFmt);
     }
@@ -316,27 +336,46 @@ function HandlePostUpload($pagename, $auth = 'upload')
   $UploadRedirectFunction($pagename,"{\$PageUrl}?action=upload&uprname=$upname&$result");
 }
 
-function UploadVerifyBasic($pagename,$uploadfile,$filepath) {
-  global $EnableUploadOverwrite,$UploadExtSize,$UploadPrefixQuota,
-    $UploadDirQuota,$UploadDir, $UploadBlacklist,
+function UploadVerifyBasic($pagename,$uploadfile,&$filepath,&$upname=null) {
+  global $EnableUploadOverwrite, $UploadExtSize, $UploadPrefixQuota,
+    $EnableUploadVersions, $UploadDirQuota, $UploadDir, $UploadBlacklist,
     $Author, $EnablePostAuthorRequired, $EnableUploadAuthorRequired;
 
+  if(! AutoCheckToken()) {
+    return 'upresult=invalidtoken';
+  }
+  
   if (IsEnabled($EnableUploadAuthorRequired,0) && !$Author)
     return 'upresult=authorrequired';
 
   if (count($UploadBlacklist)) {
-    $tmp = explode("/", $filepath);
-    $upname = strtolower(end($tmp));
+    if (is_null($upname)) { # call from old recipe
+      $tmp = explode("/", $filepath);
+      $upname = strtolower(end($tmp));
+    }
     foreach($UploadBlacklist as $needle) {
-      if (strpos($upname, $needle)!==false) return 'upresult=badname';
+      if (stripos($upname, $needle)!==false) return 'upresult=badname';
     }
   }
+  if (IsEnabled($EnableUploadVersions, 0)>=10 && file_exists($filepath)) {
+    preg_match('!^(.*/)(.+?)(-\\d+)?(\\.[a-z0-9]+)$!i', $filepath, $m);
+    array_shift($m);
+    $m[2] = intval(@$m[2]);
+    for($i=1; $i<=$EnableUploadVersions; $i++) {
+      $m[2]--;
+      $nextpath = implode('', $m);
+      if (file_exists($nextpath)) continue;
+      $upname = substr($nextpath, strlen($m[0]));
+      $filepath = $nextpath;
+      break;
+    }
+  }
   if (!$EnableUploadOverwrite && file_exists($filepath)) 
     return 'upresult=exists';
   preg_match('/\\.([^.\\/]+)$/',$filepath,$match); $ext=@$match[1];
   $maxsize = $UploadExtSize[$ext];
   if ($maxsize<=0) return "upresult=badtype&upext=$ext";
-  if ($uploadfile['size']>$maxsize) 
+  if (intval(@$uploadfile['size'])>$maxsize) 
     return "upresult=toobigext&upext=$ext&upmax=$maxsize";
   switch (@$uploadfile['error']) {
     case 1: return 'upresult=toobig';
@@ -344,7 +383,7 @@ function UploadVerifyBasic($pagename,$uploadfile,$file
     case 3: return 'upresult=partial';
     case 4: return 'upresult=nofile';
   }
-  if (!is_uploaded_file($uploadfile['tmp_name'])) return 'upresult=nofile';
+  if (!is_uploaded_file(strval(@$uploadfile['tmp_name']))) return 'upresult=nofile';
   $filedir = preg_replace('#/[^/]*$#','',$filepath);
   if ($UploadPrefixQuota && 
       (dirsize($filedir)-@filesize($filepath)+$uploadfile['size']) >
@@ -412,7 +451,7 @@ function FmtUploadList($pagename, $args) {
     $lnk = FmtPageName($fmt, $pagename);
     $out[] = "<li> $lnk$overwrite ... ".
       number_format($stat['size']) . " bytes ... " . 
-      strftime($TimeFmt, $stat['mtime']) . "</li>";
+      PSFT($TimeFmt, $stat['mtime']) . "</li>";
   }
   return implode("\n",$out);
 }
blob - a3acfb0dd792a20a09b513bd2e36abc8cb05b429
blob + 4b815b90678e36db486be7e811be3f364f38c2f5
--- scripts/urlapprove.php
+++ scripts/urlapprove.php
@@ -1,5 +1,5 @@
 <?php if (!defined('PmWiki')) exit();
-/*  Copyright 2004-2016 Patrick R. Michaud (pmichaud@pobox.com)
+/*  Copyright 2004-2021 Patrick R. Michaud (pmichaud@pobox.com)
     This file is part of PmWiki; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published
     by the Free Software Foundation; either version 2 of the License, or
@@ -35,11 +35,11 @@ $LinkFunctions['http:'] = 'LinkHTTP';
 $LinkFunctions['https:'] = 'LinkHTTP';
 SDV($ApprovedUrlPagesFmt, array('$SiteAdminGroup.ApprovedUrls'));
 SDV($UnapprovedLinkFmt,
-  "\$LinkText<a class='apprlink' href='{\$PageUrl}?action=approvesites'>$[(approve sites)]</a>");
+  "\$LinkText<a class='apprlink' href='{\$PageUrl}?action=approvesites&amp;\$TokenName=\$TokenValue'>$[(approve sites)]</a>");
 SDVA($HTMLStylesFmt, array('urlapprove' => '.apprlink { font-size:smaller; }'));
 SDV($ApproveUrlPattern,
   "\\bhttps?:[^\\s$UrlExcludeChars]*[^\\s.,?!$UrlExcludeChars]");
-$WhiteUrlPatterns = (array)$WhiteUrlPatterns;
+$WhiteUrlPatterns = (array)@$WhiteUrlPatterns;
 SDV($HandleActions['approveurls'], 'HandleApprove');
 SDV($HandleAuth['approveurls'], 'edit');
 SDV($HandleActions['approvesites'], 'HandleApprove');
@@ -55,6 +55,10 @@ function LinkHTTP($pagename,$imap,$path,$alt,$txt,$fmt
     return LinkIMap($pagename,$imap,$path,$alt,$txt,$fmt);
   static $havereadpages;
   if (!$havereadpages) { ReadApprovedUrls($pagename); $havereadpages=true; }
+  static $token;
+  if (!$token) $token = pmtoken();
+  $FmtV['$TokenValue'] = urlencode($token);
+  
   $p = str_replace(' ','%20',$path);
   $url = str_replace('$1',$p,$IMap[$imap]);
   if (!isset($UnapprovedLink)) $UnapprovedLink = array();
@@ -100,6 +104,9 @@ function HandleApprove($pagename, $auth='edit') {
     $aname = FmtPageName($ApprovedUrlPagesFmt[0],$pagename);
     $apage = RetrieveAuthPage($aname, $auth);
     if (!$apage) Abort("?cannot edit $aname");
+    if(! AutoCheckToken()) {
+      Abort('? $[Token invalid or missing.]');
+    }
     $new = $apage;
     if (substr($new['text'],-1,1)!="\n") $new['text'].="\n";
     foreach($addpat as $a) {
blob - 90a04ddae9494a2b5e74257c7e5d81257ccd3e26
blob + 9376338185333b79c2d153c6075832b84254bf6d
--- scripts/version.php
+++ scripts/version.php
@@ -1 +1 @@
-<?php $Version="pmwiki-2.2.130"; $VersionNum=2002130; 
\ No newline at end of file
+<?php $Version="pmwiki-2.3.20"; $VersionNum=2003020; 
\ No newline at end of file
blob - fd3c273c9bb1746ebfc4288edb931535476f1b63
blob + c4f349e3bf9da42ec5f3e41d5a76b28e8bb9541e
--- scripts/wikistyles.php
+++ scripts/wikistyles.php
@@ -86,6 +86,7 @@ if (IsEnabled($EnableStdWikiStyles,1)) {
     'width' => '200px', 'apply' => 'block', 'text-align' => 'center'));
   ##  preformatted text sections
   SDV($WikiStyle['pre'], array('apply' => 'block', 'white-space' => 'pre'));
+  SDV($WikiStyle['notoc'], array('apply' => 'block', 'class' => 'notoc'));
   SDV($WikiStyle['sidehead'], array('apply' => 'block', 'class' => 'sidehead'));
   SDV($WikiStyle['reversed'], array('apply' => 'list', 'reversed' => 'reversed'));
 }
@@ -107,7 +108,7 @@ SDVA($WikiStyleRepl,array(
   ));
 
 $WikiStyleCSS[] = 'color|background-color';
-$WikiStyleCSS[] = 'text-align|text-decoration';
+$WikiStyleCSS[] = 'overflow|text-align|text-decoration';
 $WikiStyleCSS[] = 'font-size|font-family|font-weight|font-style';
 
 SDV($imgTag, '(?:img|object|embed)');  SDV($aTag, 'a'); SDV($spanTag, 'span');
@@ -127,7 +128,7 @@ function ApplyStyles($x) {
   $wikicsspat = '/^('.implode('|',(array)$WikiStyleCSS).')$/';
   while ($parts) {
     $p = array_shift($parts);
-    if (preg_match("/^$WikiStylePattern\$/",$p)) {
+    if ($p && preg_match("/^$WikiStylePattern\$/",$p)) {
       $WikiStyle['curr']=$style; $style=array();
       foreach((array)$WikiStyleRepl as $pat=>$rep)
         $p=preg_replace($pat,$rep,$p);
@@ -165,7 +166,6 @@ function ApplyStyles($x) {
       foreach((array)$s as $k=>$v) {
         $v = trim($v);
         if ($wt) $ws = str_replace('$1', "$ns$k='$v'", $wt);
-        if ($k == 'class' && $v) $spanattr = "{$ns}class='$v'";
         elseif ($k=='id') $id = preg_replace('/[^-A-Za-z0-9:_.]+/', '_', $v);
         elseif (($k=='width' || $k=='height') && !@$WikiStyleApply[$a]
             && preg_match("/\\s*<$imgTag\\b/", $p)) 
@@ -177,6 +177,8 @@ function ApplyStyles($x) {
                  "$ws<$1 $ns$k='$v' $2>", $p);
         elseif (preg_match($wikicsspat,$k)) $stylev[]="$k: $v;";
       }
+      if (@$s['class']) $spanattr = "{$ns}class='".trim($s['class'])."'";
+      
       if ($stylev) $spanattr .= " {$ns}style='".implode(' ',$stylev)."'";
       if ($id) $spanattr .= " {$ns}id='$id'";
       if ($spanattr) {
@@ -184,14 +186,14 @@ function ApplyStyles($x) {
         if (!@$WikiStyleApply[$a]) {
           $p = preg_replace("!^(.*?)($|</?($BlockPattern))!s", 
                             "$ws<$spanTag $spanattr>$1</$spanTag>$2", $p, 1);
-}
+        }
         elseif (!preg_match('/^(\\s*<[^>]+>)*$/s',$p) ||
                 preg_match("/<$imgTag\\b/", $p)) {
           $p = preg_replace("/<({$WikiStyleApply[$a]})\\b/",
                  "$ws<$1 $spanattr", $p);
         }
       }
-      if (@$s['color']) {
+      if (@$s['color']) { 
         $colorattr = "{$ns}style='color: {$s['color']}'";
         if ($wt) $ws = str_replace('$1', $colorattr, $wt);
         $p = preg_replace("/<$aTag\\b/", "$ws<$aTag $colorattr", $p);
@@ -201,4 +203,3 @@ function ApplyStyles($x) {
   }
   return $out;
 }
-
blob - a50aed10a4bea8cea61f6b7090fb87080474ae5b
blob + fe1ebfcc934fa5b480ac50b51ffa64948b859f40
--- scripts/wikiwords.php
+++ scripts/wikiwords.php
@@ -63,7 +63,7 @@ function MarkupWikiLink($m) {
 function WikiLink($pagename, $word) {
   global $LinkWikiWords, $WikiWordCount, $SpaceWikiWords, $AsSpacedFunction,
     $MarkupFrame, $WikiWordCountMax;
-  if (!$LinkWikiWords || ($WikiWordCount[$word] < 0)) return $word;
+  if (!$LinkWikiWords || (@$WikiWordCount[$word] < 0)) return $word;
   $text = ($SpaceWikiWords) ? $AsSpacedFunction($word) : $word;
   $text = preg_replace('!.*/!', '', $text);
   if (!isset($MarkupFrame[0]['wwcount'][$word]))
blob - 5c69aaa5adca9bbeb1b4ce2639160eb62ca6d7e6
blob + 34f9c1aedeed85af2ff5eb8c71cf6f73f4e866a9
--- scripts/xlpage-utf-8.php
+++ scripts/xlpage-utf-8.php
@@ -1,5 +1,5 @@
 <?php if (!defined('PmWiki')) exit();
-/*  Copyright 2004-2018 Patrick R. Michaud (pmichaud@pobox.com)
+/*  Copyright 2004-2022 Patrick R. Michaud (pmichaud@pobox.com)
     This file is part of PmWiki; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published
     by the Free Software Foundation; either version 2 of the License, or
@@ -34,8 +34,8 @@ SDVA($HTMLStylesFmt, array('rtl-ltr' => "
     margin-left:0; margin-right: 40px;
   }
   "));
-$pagename = @$_REQUEST['n'];
-if (!$pagename) $pagename = @$_REQUEST['pagename'];
+$pagename = strval(@$_REQUEST['n']);
+if (!$pagename) $pagename = strval(@$_REQUEST['pagename']);
 if (!$pagename &&
       preg_match('!^'.preg_quote($_SERVER['SCRIPT_NAME'],'!').'/?([^?]*)!',
           $_SERVER['REQUEST_URI'],$match))
@@ -75,8 +75,8 @@ function utf8toupper($x) {
   return str_replace($lower, $upper, $x);
 }
 
-
 function utf8fold($x) {
+  if(is_null($x) || $x === '') return '';
   global $StringFolding;
   static $source, $target;
   if (!@$source) {
blob - e0048a4d7042ae1bf19f16e3392138602ba9bfbd
blob + 8039b7d435656cad4a99451c7239acc9217aefda
--- wiki.d/.pageindex
+++ wiki.d/.pageindex
@@ -1,8 +1,10 @@
-DNS.Mail:1678078240: Nsd.Configure Dns.Overview Dns.FQDN DNS.SOA DNS.SPF DNS.DMARC DNS.DKIM DNS.Dnswl : tb8yiwenh01hz5xh1gjwg1v8oirnerf3482b8xrzykhjqudjcalnz9ggz9cnzahic3tsantdshdgk3c0oqjeilriw0eiakv2 migfma0gcsqgsib3dqebaquaa4gnadcbiqkbgqcmsef9dm8dx1ltmlmd56d628jbnaqus8aecdyyzvbvq4rhetzzv eeu2odwqqgyqgvv0xuk5qjsnsgf5ukkscrxmthspptoaqjt25fxnd3ptvh2zonagkzkntk kcohbemvxeotqtqzttdhxm6bkeluo0xbbhlrsq8c3q92oqztwflk 8amiibcgkcaqeaybhtr90v64hqtfw1sutfpg5byxf lmflyzipitm4egw3kadlzslycjutlkhcg5b u6wn5xxli9hmovxluwidaqab ibjdyqpndormr7r4itij6o sxutnmzigjmql81av47dg bsc2rzzszv2gzmrrr 2f4ak7xtamayful pb7pql4g86lczsf zmafjtef2rlooq x1jwlpungjgjt configuration instructions cdepmqw0xn8 discardable functioning s17qidaqab _domainkey containing postmaster diagnosing yyyymmddnn 2021050302 understand whitelists _dkimsign authority configure following qualified normally continue creating appended multiple removing interval problems overview requires concepts together exchange _dovecot groupadd properly returned private example expires running updated openssl refresh command produce joining seconds useradd nologin minimum records reports provide offline another serving servers assumes replace already deliver perform queries uun3kqc defines handle actual _smtpd genrsa serial origin lowest _dmarc dmarc1 allows mailto simple public choose filter useful others create pubout number printf adding should result sample needed taking before charge begin means value basic first start dnswl admin guide sends short 86400 takes _adsp 3vhfy using there final chmod title every chown lines empty after fully mkdir retry that then doas aaaa will sbin find next this fqdn with 1024 free want your zone 3600 spf1 like text none into last look have goes most 2602 file fccf says when name make sure imap only 1800 what asks just time etc var 3rd was rwx soa day nsd csp set txt ns1 awk ttl cat let pop any 143 dig but pct rua 163 can two ruf ns2 mx 38
-DNS.DKIM:1678078118: PGP.Intro : migfma0gcsqgsib3dqebaquaa4gnadcbiqkbgqcmsef9dm8dx1ltmlmd56d628jbnaqus8aecdyyzvbvq4rhetzzv eeu2odwqqgyqgvv0xuk5qjsnsgf5ukkscrxmthspptoaqjt25fxnd3ptvh2zonagkzkntk 8iznifrhjff4dngvx61t9xknkcjrjdc6npo0l4mvtky66saftbccjlm6jihbud5j4uou5i migfma0gcsqgsib3dqebaquaa4gnadcbiqkbgqddmzrmjrqxleuyyiymg4sua2sy mzp1ro7kidtks8ttki6z6etrw9e9ddoxzsxnuxmume60cjbu08goyhpg3 gvjebqfjovwtqhvvv3fhh0uqbw0m9untpuaagorfgki 2u1zeqyo7k03kcjbdrvw8ihjtdenggl3p7am1v8wdg gfwdg7qkdn6kr4v75mflw624vy35daxbvnltjtgrg o5o0xmhblyspbfgmw7sw2awlwu95oyhk5tezpze s8ihdcexsr5fr8yk4ivlky8jo5o0xmhblys ss5u39zlqs7ts1m8izo2tpba70t9204na8 ew72o1diyvthkycgpsys8nmeqidaqab unjqq96dt308f2rvxewa6p8hxsjd fldir2u1zeqyo7k03kcjbdrvw8 eot6n78iznifrhjff4dngvx61 u6wn5xxli9hmovxluwidaqab mwr5mghpp9dint1hriwud uylzxfem1ufoty56jbi rkukyru5msqvp01ii canonicalization pb7pql4g86lczsf iwree02clqkwg5c zmafjtef2rlooq introduction 9zpb2ajgoso4 simpletable discardable _domainkey nhsjgam5qe identified domainkeys signatures guarantees sqri4exnbg opensmtpd _dkimsign indicates integrity receiving otherwise algorithm following _dovecot removing receiver designed phishing pretends together returned selector security tampered sortable perform openssl private example headers transit display clients message nologin useradd version subject provide joining spoofed running command letters records sending signing prevent produce ensures fields filter public should sha256 sender printf border allows server checks claims detect create during forged pubout _smtpd access genrsa lookup taking result 86400 email based prove inbox notes _adsp below final above width title comes empty first setup looks valid dmarc chmod chown lines class mkdir name doas sbin then like need this will 1024 does text used that both sent next with into last from been spam help your body date here what pass also work view hash many awk may etc are dns spf rwx var see its txt pgp tag tip 100 bh jv by we
-Opensmtpd.Configure:1678077572: Dns.Overview Nsd.Configure DNS.Mail Acme-client.Configure Opensmtpd.Openrelay Dovecot.Install DNS.DKIM Opensmtpd.Troubleshoot : h5itbhzs73t4jshaj9yx6tf63yrataqugbxocx67wyekhch4zqiod6lkh userdb_quota_rule misconfiguration 83bd6b3b1669649f a8d16cd2144222fa troubleshooting authentication authenticated automatically check_fcrdns alphanumeric inconsistent permissions recommended mtaproxy511 configuring information credentials temporarily connection encryption submission optionally check_rdns characters translated california reputation postmaster abnormally interfaces authcheck fullchain specifies following explained separated addresses opensmtpd receiving listeners plaintext openrelay supported recipient mtaproxy2 identical confirmed available including exploited configure connected passwords forwarded whitelist localhost important usernames sunnyvale temporary mtaproxy1 disabling firewalls assurance dkimsign required requires checking fallback sections hostname messages loopback outgoing filtered enabling properly contains protocol matching generate virtuals outbound transfer increase security gigabyte _dovecot poolporg digicert yahoodns 00000003 starttls response selector replaced variable starting multiple packages provider ifconfig hundreds indicate possible received s_client programs delivery overview receives mailname complete tempfail related finally example sending entries reverse senders instead network aliases blocked allowed pkg_add account private records working default packets dropped domains useradd returns nothing warning maillog defines signing express nologin filters defined openssl earlier managed folders maildir relayed special already smtpctl storage actions similar because logging include without install trusted openbsd timeout suppose offline showing passing servers symptom running specify labeled spammer request written happens further limited dealing second source headed tables passwd reason answer socket _smtpd finish blocks result except handed forced delete signed emails inside should ircnow marked author checks errors letter victim trying entire unable egress please adding create verify handle single exited macros having length public github issues actual linked extras decide header before might hosts shows using which https colon first whose field pairs value enter child being lines admin vmail daily smtps other users begin often group these phase rules store basic guide queue pages 39035 third tells evpid 16h2s known setup delay spool entry times rcctl offer state depth fruit files apply route reply ports esmtp point chmod chown avoid valid doas this ipv6 many root free pony will mta5 lost your need also want vio0 have s843 each mask high sent that plus book says oath lmtp sha2 hang mean bind acme sbin test else used when pop3 must ipv4 hash imap type much sets last like safe only data ctrl quit sure make here does same been 2001 easy into real goes mta7 2602 mta6 fccf good stop note rcpt anti from more part next junk take what exec base keys they path both case proc unix done some disk 204 195 src am0 587 get www but are due way vps 15s see 220 395 lo0 104 vip 465 106 228 can bf1 ne1 jan etc 192 168 451 pki fix nsd pem 650 too 250 db8 may 163 143 gq1 new via 127 55 47 33 38 mx 81 77 29 rx 17 2b 1g
+Dovecot.Install:1678134050: Openbsd.Loginconf Openbsd.Rcctl : auth_verbose_passwords auth_debug_passwords troubleshooting _rc_parse_conf _rc_rm_runfile mail_location dovecot_flags configuration installation instructions oddprotocol verbose_ssl permissions dovecotcert _rc_quirks submission mail_debug protocols addresses suggested euhb95xlq openfiles ownership debugging indicates directory loginconf fullchain following username receives rc_check explains readable ssl_cert rc_start consider _rc_wait _dovecot doveconf blowfish cap_mkdb starting replaced starttls s_client prevents allowing settings database required comment include finally folders maildir example encrypt openbsd service defines support missing changes connect nologin warning virtual rebuild useradd coconut openssl maillog pkg_add happens managed readmes default ssl_key private adding system enable passwd domain please aiyngk script bottom remove forgot spaces failed static daemon second userdb driver exists turned scheme passdb ircnow secure _smtpd public single denied listen https vmail doing rcctl fails share error _mail block first group local world tells owned store which class order users write again empty where fatal chmod chown lines since these using need euid from real that with this your doas must lmtp will when 1003 imap best just mode sure make 0750 4096 8192 egid tabs used many sbin work note more than help find have pop3 also args want home path says sha1 host jrmu last then such 2001 case 518 can var etc 125 231 jun see may pem 143 let via blf ext out yes and aid ips don db8 168 but usr doc max crt by we if rx 80 of 41 37 35 my
+DNS.DKIM:1678133576: PGP.Intro : migfma0gcsqgsib3dqebaquaa4gnadcbiqkbgqcmsef9dm8dx1ltmlmd56d628jbnaqus8aecdyyzvbvq4rhetzzv eeu2odwqqgyqgvv0xuk5qjsnsgf5ukkscrxmthspptoaqjt25fxnd3ptvh2zonagkzkntk 8iznifrhjff4dngvx61t9xknkcjrjdc6npo0l4mvtky66saftbccjlm6jihbud5j4uou5i migfma0gcsqgsib3dqebaquaa4gnadcbiqkbgqddmzrmjrqxleuyyiymg4sua2sy mzp1ro7kidtks8ttki6z6etrw9e9ddoxzsxnuxmume60cjbu08goyhpg3 gvjebqfjovwtqhvvv3fhh0uqbw0m9untpuaagorfgki 2u1zeqyo7k03kcjbdrvw8ihjtdenggl3p7am1v8wdg gfwdg7qkdn6kr4v75mflw624vy35daxbvnltjtgrg o5o0xmhblyspbfgmw7sw2awlwu95oyhk5tezpze s8ihdcexsr5fr8yk4ivlky8jo5o0xmhblys ss5u39zlqs7ts1m8izo2tpba70t9204na8 ew72o1diyvthkycgpsys8nmeqidaqab unjqq96dt308f2rvxewa6p8hxsjd fldir2u1zeqyo7k03kcjbdrvw8 eot6n78iznifrhjff4dngvx61 u6wn5xxli9hmovxluwidaqab mwr5mghpp9dint1hriwud uylzxfem1ufoty56jbi rkukyru5msqvp01ii canonicalization pb7pql4g86lczsf iwree02clqkwg5c zmafjtef2rlooq introduction 9zpb2ajgoso4 simpletable discardable domainkeys _domainkey identified sqri4exnbg signatures nhsjgam5qe guarantees receiving indicates opensmtpd algorithm otherwise following integrity receiver removing sortable together security selector phishing returned _dovecot pretends designed tampered subject openssl private transit sending message example headers ensures records clients provide signing letters perform prevent spoofed display joining version produce command running genrsa create public sha256 sender server pubout border filter allows printf should checks detect result lookup forged claims fields during access _smtpd taking notes email below based width prove above class title chmod mkdir chown valid first looks lines comes inbox _adsp 86400 final dmarc setup dkim next this text like into will need name that both does 1024 doas used with last then sent from also hash body here date your pass spam what been view help many work etc are rwx see dns txt may pgp awk spf 100 tag tip its jv bh by we
+DNS.Mail:1678133545: Nsd.Configure Dns.Overview Dns.FQDN DNS.SOA DNS.SPF DNS.DMARC DNS.DKIM DNS.Dnswl : tb8yiwenh01hz5xh1gjwg1v8oirnerf3482b8xrzykhjqudjcalnz9ggz9cnzahic3tsantdshdgk3c0oqjeilriw0eiakv2 migfma0gcsqgsib3dqebaquaa4gnadcbiqkbgqcmsef9dm8dx1ltmlmd56d628jbnaqus8aecdyyzvbvq4rhetzzv eeu2odwqqgyqgvv0xuk5qjsnsgf5ukkscrxmthspptoaqjt25fxnd3ptvh2zonagkzkntk kcohbemvxeotqtqzttdhxm6bkeluo0xbbhlrsq8c3q92oqztwflk 8amiibcgkcaqeaybhtr90v64hqtfw1sutfpg5byxf lmflyzipitm4egw3kadlzslycjutlkhcg5b u6wn5xxli9hmovxluwidaqab ibjdyqpndormr7r4itij6o sxutnmzigjmql81av47dg bsc2rzzszv2gzmrrr pb7pql4g86lczsf 2f4ak7xtamayful zmafjtef2rlooq x1jwlpungjgjt configuration instructions functioning cdepmqw0xn8 discardable containing understand 2021050302 yyyymmddnn _domainkey postmaster whitelists s17qidaqab diagnosing configure authority qualified _dkimsign following exchange together _dovecot normally multiple removing appended returned continue problems concepts properly interval overview creating requires groupadd example records seconds expires private provide refresh minimum reports another offline openssl produce updated deliver servers serving joining command running queries already uun3kqc defines perform assumes replace _dmarc dmarc1 number serial useful public others adding pubout charge should mailto before create filter genrsa actual allows origin sample choose needed printf handle result simple _smtpd taking lowest value short there first means takes sends title chmod 86400 mkdir basic retry chown final fully every _adsp lines start dnswl begin guide admin after 3vhfy using that like this will aaaa text into free look with fqdn your next doas 3600 none 1024 have goes then most last want zone spf1 find 2602 fccf 1800 imap what make only file name sure time says just asks when was etc nsd soa rwx day 3rd set txt let ns1 cat ttl awk csp 163 but 143 pct dig any pop two can rua ruf ns2 mx 38
+Opensmtpd.Configure:1678133499: Dns.Overview Nsd.Configure DNS.Mail Acme-client.Configure Opensmtpd.Openrelay Dovecot.Install DNS.DKIM Opensmtpd.Troubleshoot : h5itbhzs73t4jshaj9yx6tf63yrataqugbxocx67wyekhch4zqiod6lkh userdb_quota_rule a8d16cd2144222fa misconfiguration 83bd6b3b1669649f troubleshooting authentication authenticated automatically check_fcrdns inconsistent alphanumeric mtaproxy511 recommended credentials permissions information configuring temporarily encryption check_rdns postmaster interfaces characters abnormally reputation translated connection optionally california submission following listeners mtaproxy1 temporary firewalls addresses configure identical specifies mtaproxy2 confirmed opensmtpd disabling authcheck explained forwarded separated recipient whitelist localhost important openrelay usernames plaintext supported passwords fullchain sunnyvale receiving available including assurance connected exploited dkimsign hostname outbound tempfail virtuals delivery complete contains replaced variable mailname poolporg sections properly matching receives checking overview programs protocol transfer requires enabling digicert filtered outgoing messages yahoodns starttls response 00000003 possible received provider packages s_client indicate _dovecot loopback starting hundreds generate fallback increase multiple ifconfig required selector security gigabyte allowed sending defines actions similar defined relayed senders example entries servers because reverse filters private finally earlier trusted domains default instead without express packets timeout showing suppose offline warning symptom blocked signing install storage special smtpctl working limited spammer maillog dropped specify happens nothing returns openssl managed folders maildir nologin useradd logging include account passing aliases openbsd network running dealing records request labeled further related pkg_add written already verify github create should passwd handle emails single socket adding _smtpd second having exited entire egress ircnow actual headed handed macros author tables forced except blocks decide marked trying public letter source errors header unable victim reason inside checks result issues finish signed length delete please before answer extras linked lines files enter admin rcctl these child shows phase queue vmail field often users spool which setup https hosts daily fruit other chown first state chmod being reply third might route using smtps depth colon pairs rules value known group esmtp times whose tells store valid point guide entry delay 16h2s ports avoid 39035 begin evpid basic pages apply offer mta5 will root ipv6 your also does ipv4 they mask want used ctrl stop that quit doas sure make note base like free unix path sbin this same disk test sent lmtp when type anti must next rcpt real acme from been part keys each have 2001 case hash need junk what mta7 easy s843 into mta6 goes good safe many pony imap here lost both vio0 take says proc exec last pop3 bind some mean book high sha2 more done oath only hang fccf 2602 else data much sets plus due fix are too pki see nsd may etc can 220 250 am0 143 but 465 www lo0 src 587 163 106 vip gq1 168 192 195 104 15s way 228 get 204 bf1 650 451 395 vps ne1 jan 127 new db8 via crt pem 29 81 38 mx 47 1g 33 77 2b 55 17 rx
+Openbsd.Ngircd:1678122185: Irc.Guide IP.Myaddress Ddos.Intro Chroot.Intro Netcat.Irc Hopm.Install Ngircd.Ssl Password.Management Dns.Vhost Ngircd.Link Syslogd.Configure Openbsd.Rcctl Anope.Install Acopm.Install : abcdefghijklmnopqrstuvwxyz noticebeforeregistration maxconnectionsip allowremoteopers defaultusermodes requireauthping troubleshooting operchanpautoop opercanusemode cloakhostmodex syslogfacility implementation configuration alternatively documentation automatically maxnicklength cloakhostsalt installation service_user unexpectedly eavesdropper service_name instructions pongtimeout maxlistsize service_pid recommended pingtimeout infrigement lightweight permissions information uncommented configuring understand adminemail connecting disconnect impossible admininfo1 admininfo2 installing management restarting maintained motdphrase harassment examplenet advantages compromise production nullrouted minimalist unfiltered terminated absolutely encryption automation uncloaking techniques references described serveruid installed essential otherwise sensitive configure necessary debugging receiving invisible generally chrootdir identical servergid unlimited firewalls sparingly interfere typically copyright suggested different character operation localhost myaddress addresses passwords untouched somewhere reloading including listening platforms developer messages commands packages stalking operator channels contains intended features includes actively enabling building download compiles chatting finished template portable helpfile precedes probably username comments motdfile remember hostmask validate connects moderate spammers overview cracking rejected gambling examples violence familiar solution software standard maxjoins provided function multiple secondly generate straight logfiles sysadmin existing official services security upgraded properly warning because replace directs filters editing network servers however instead differs openbsd written another linking contact pidfile prevent monitor process options _ngircd besides syslogd hosting listing appears heavily careful ability lookups cloaked clients periods usually perform mistake without extract libexec correct ignored cronjob crontab symlink enabled support ircnowd already expects pkg_add illegal working privacy scripts created threats slander running scratch friends outside consult inside joined remove custom verify reduce netcat handle invite limits nobody random unique glines errors should policy please string insert single blocks become stable tested needed daemon ensure secure unable entire issues events causes normal resolv sample public actual domain source global barton modern planet writes simple easily bypass ddosed since until rcctl pages match order three mkdir intro owner using power every hangs after which clean pkill users share below avoid check going ports those https needs chown these staff speak terms index while agree above begin title libel leave pgrep world aware vhost drugs earth chmod hello first acopm exact whois proxy keeps 16667 guide would abuse crash helps short anope linux setup being does will your hopm have that want turn send doas code make once when best 2001 then many used from also this note 3000 logs into xvzf runs must 6665 6664 6663 6662 6661 6660 porn stop 6666 7000 only sets free 6669 wiki been 6668 bsds docs such they text show easy real fork lead next ipv6 each ipv4 long data var usr ssl php try via may ftp dns hup was see new one has v26 few bin don org 168 tls 192 but 127 ips yes db8 get had txt day tgz let cp ix ln
+9front.RecentChanges:1678102086:  : recentchanges netsurf 9front 06t03 yonle 2023 30z 14 by
 9front.Netsurf:1678072470:  : d414500c2b89252b3c16708caef7c49a7e8d9369f228653278e32768fad4c8e5 alternatively installation lecturify globally netsurf without running github prepns nsport 9front system launch could title clone https plan9 media fetch fedi you png com cd mk by do to
-Openbsd.Ngircd:1678040259: Irc.Guide IP.Myaddress Ddos.Intro Chroot.Intro Netcat.Irc Hopm.Install Ngircd.Ssl Password.Management Dns.Vhost Ngircd.Link Syslogd.Configure Openbsd.Rcctl Anope.Install Acopm.Install : abcdefghijklmnopqrstuvwxyz noticebeforeregistration maxconnectionsip allowremoteopers defaultusermodes requireauthping troubleshooting operchanpautoop opercanusemode cloakhostmodex syslogfacility implementation configuration alternatively documentation automatically maxnicklength cloakhostsalt installation service_user unexpectedly eavesdropper service_name instructions pongtimeout maxlistsize service_pid recommended pingtimeout infrigement lightweight permissions information uncommented configuring understand adminemail connecting disconnect impossible admininfo1 admininfo2 installing management restarting maintained motdphrase harassment examplenet advantages compromise production nullrouted minimalist unfiltered terminated absolutely encryption automation uncloaking techniques references described serveruid installed essential otherwise sensitive configure necessary debugging receiving invisible generally chrootdir identical servergid unlimited firewalls sparingly interfere typically copyright suggested different character operation localhost myaddress addresses passwords untouched somewhere reloading including listening platforms developer messages commands packages stalking operator channels contains intended features includes actively enabling building download compiles chatting finished template portable helpfile precedes probably username comments motdfile remember hostmask validate connects moderate spammers overview cracking rejected gambling examples violence familiar solution software standard maxjoins provided function multiple secondly generate straight logfiles sysadmin existing official services security upgraded properly warning because replace directs filters editing network servers however instead differs openbsd written another linking contact pidfile prevent monitor process options _ngircd besides syslogd hosting listing appears heavily careful ability lookups cloaked clients periods usually perform mistake without extract libexec correct ignored cronjob crontab symlink enabled support ircnowd already expects pkg_add illegal working privacy scripts created threats slander running scratch friends outside consult inside joined remove custom verify reduce netcat handle invite limits nobody random unique glines errors should policy please string insert single blocks become stable tested needed daemon ensure secure unable entire issues events causes normal resolv sample public actual domain source global barton modern planet writes simple easily bypass ddosed since until rcctl pages match order three mkdir intro owner using power every hangs after which clean pkill users share below avoid check going ports those https needs chown these staff speak terms index while agree above begin title libel leave pgrep world aware vhost drugs earth chmod hello first acopm exact whois proxy keeps 16667 guide would abuse crash helps short anope linux setup being does will your hopm have that want turn send doas code make once when best 2001 then many used from also this note 3000 logs into xvzf runs must 6665 6664 6663 6662 6661 6660 porn stop 6666 7000 only sets free 6669 wiki been 6668 bsds docs such they text show easy real fork lead next ipv6 each ipv4 long data var usr ssl php try via may ftp dns hup was see new one has v26 few bin don org 168 tls 192 but 127 ips yes db8 get had txt day tgz let cp ix ln
 FreeIRC.RecentChanges:1678037757:  : recentchanges freeirc kilroy about march 2023 05 at 03 51 pm by
 FreeIRC.About:1678031472:  : debiankaios alternative operations connection services directly accounts dropbox webchat contact freeirc provide members welcome website mistere channel support google secure kilroy ircnow access manage server format coming there https hello about drive other shell setup cloud soon main team best what ircs info help 6697 6667 will your page this with both have they also xfnw are tls ssl and org can how znc way who don but use to q
 Openbsd.OpenTracker:1677861462:  : dwant_ip_from_query_string dwant_compression_gzip dwant_accesslist_white dwant_accesslist_black dwant_restrict_stats dwant_ip_from_proxy missconfigurations dwant_log_networks dwant_sync_scrape dwant_fullscrape dwant_sync_live distributions _opentracker experimental installation application fullscrapes statistics compressed explicitly commenting connecting bittorrent deprecated announced behaviour openbsd_7 install72 whitelist backspace configure variables sensitive currently mktorrent manually dwant_v6 features makefile initiate checking enabling normally packages torrents standard problems endpoint stemming creating groupadd anything erdgeist libowfat systemic location official declared details cvsroot provide endorse default cluster pserver anoncvs enabled address section clients disable tracked support console release baytuch control deliver program nologin useradd folders detach ircnow closed latter allows option before around daemon change legacy tracks switch sample create these chown those local guide since patch ready mkdir linux armor there chmod clone until makes below order this with will doas give them that note some home have only hash they path keys view main sign 6969 http ipv6 more sbin fefe tree mode when case your 406 run can url see usr etc don way 400 org gpg iso 162 700 its git out 38 by cd 87 12 cp z9
@@ -400,7 +402,6 @@ Duplicity.RecentChanges:1643813262:  : recentchanges d
 Duplicity.Usage:1643797886:  : duplicity username download example encrypt decrypt folder upload usage path sftp com and to
 Openssl.Encryptfile:1643794164:  : encryptfile decryptfile recoverable compatible identical function username continue openssl version example profile warning changes without folder source bottom cancel abort usage enter echo read cvzf this xvzf type data ctrl aes cat cbc tar ssh 256 not the may tgz and add be 1
 Bots.Basicbot:1643662492:  : basicbot document progress perl bots in
-Dovecot.Install:1643492127: Openbsd.Loginconf Openbsd.Rcctl : auth_verbose_passwords auth_debug_passwords troubleshooting _rc_rm_runfile _rc_parse_conf configuration dovecot_flags mail_location instructions installation oddprotocol verbose_ssl permissions dovecotcert _rc_quirks mail_debug submission loginconf openfiles debugging directory euhb95xlq protocols suggested ownership indicates fullchain following addresses ssl_cert rc_check _dovecot cap_mkdb explains readable starttls s_client prevents username required replaced rc_start consider _rc_wait starting doveconf blowfish database settings allowing receives example defines support openbsd changes folders comment finally service encrypt missing maildir include nologin warning virtual rebuild useradd coconut connect openssl maillog pkg_add happens managed readmes default ssl_key private please aiyngk domain enable system remove passwd script userdb spaces failed daemon static second bottom driver exists turned scheme ircnow passdb forgot adding denied listen single secure public _smtpd doing vmail which fails _mail rcctl users https group owned store error write block tells lines chown chmod fatal these using class empty world local share again first order since where doas your need that mode must real with imap sure 0750 from make this 1003 when will sbin work note more than help find have 4096 just best euid many lmtp 8192 egid tabs used says path want pop3 jrmu also args home then last host case 2001 sha1 such 518 etc 125 231 jun var pem can see may 143 let via blf ext out yes and aid ips don db8 168 but usr doc max by we if rx 80 of 41 37 35 my
 Openrsync.Usage:1643447060:  : synchronizes lightweight destination recursively simpletable filesystem everything ermissions corruption directory openrsync functions imestamps available following shorthand transfers verbosity explains username sortable multiple symbolic capacity increase actively complete continue designed openbsd example options current folders specify purpose however dgloprt warning special profile require mounted backing written rewrite copied source backup remote second copies server htdocs md5sum primer little common enough before cancel border rchive abort ifend space least 1005m using enter check local false quick title usage https match needs buggy class being occur width evice home make your sure have disk most will ctrl mode root dump with doas path sets take much sd0a sd0f sd0d 153g 192g sd0k 844m 111m sd0e used size date this from both then call data read echo type wner each copy roup next into turn also inks pwd dmp var dev ssh vmm tmp may mnt usr put see org man www run 9g df 12 28 7g 16 22 4g 63 14 41 2m 0g
 Gpg.RecentChanges:1643294993:  : recentchanges description naglfar january verify 2022 gpg add 08 at 09 48 pm by
 Crontab.Edit:1643182831:  : environmental undefined whatever variable crontab default program replace visual editor export actual stored change type want both your will with the are use by if
blob - 38d98bb0ec51065e34fea5929441686c4ed91f63
blob + 12aceb7bb5a937d67f186402256c15bad9b14768
--- wiki.d/DNS.DKIM
+++ wiki.d/DNS.DKIM
@@ -2,15 +2,22 @@ version=pmwiki-2.3.20 ordered=1 urlencoded=1
 agent=w3m/0.5.3+git20210102
 author=jrmu
 charset=UTF-8
-csum=Moved to /etc/dkim/ to fix permissions bugs
+csum=
 ctime=1622985562
 host=38.87.162.154
 name=DNS.DKIM
-rev=15
+rev=17
 targets=PGP.Intro
-text=(:title DomainKeys Identified Mail:)%0a%0a!! Introduction%0a%0aDomainKeys Identified Mail (DKIM) is used to detect if an e-mail is spoofed (forged).%0aIt's used to prevent spam and phishing. Signing your mail with DKIM will help%0adetect spam that pretends to come from your domain. It also ensures that your%0aletters pass spam filter checks. Otherwise, letters you send may not end up in the%0ainbox.%0a%0aAn email is signed with a private key. This allows the receiver to check if the email%0acomes from the domain it claims to be from. The receiver looks up the sender's%0apublic key in the domain's DNS record. A valid signature guarantees that the sending%0amail server has access to the private key and that the email body has not been%0atampered with during transit.%0a%0aDKIM, SPF, and DMARC are designed to work together.%0a%0a!! DKIM Header%0a%0aIn our setup, the mail server will sign the message with its private key. Here%0ais what the DKIM header looks like:%0a%0a[@%0aDKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; s=mail; bh=gVJEBqfjoVwtQhV%0a        vV3FHh0UQBW0m9unTpuaaGORFGKI=; h=subject:date:from;%0a        d=example.com; b=Jv/9zpB2AJGosO4/uYlZxFEm1UFOTy56JBi/nhsjg%0a        Am5Qe+rkuKYru5mSqvP01ii/sQRI4exNbG/S8ihdcEXsr5fr8yK4IvLkY8jO5O0xMhblyS%0a        PbFGMw7SW2AwLWu95OyHK5teZPzE/SS5U39Zlqs7tS1m8iZo2tPBa70t9204na8/eOT6N7%0a        8IzNIfRHJfF4dNGVX61t9xknkcJrJdC6npO0l4MVTky66safTbcCjlM6JihbUd5j4uOU5I%0a        WREE02CLQKWg5c/UnjQQ96Dt308f2RvxeWA6P8hxsjD/FLDIR2U1ZEQyo7k03KCJbdRVw8%0a        IHJTdENGGL3p7aM1v8wdg==%0a@]%0a%0a|| border=1 width=100%25 class="sortable simpletable"%0a||! Tag ||! Indicates ||! Example ||%0a|| v || version || v=1 ||%0a|| a || algorithm || a=rsa-sha256 ||%0a|| d || domain || d=example.com ||%0a|| s || selector || s=mail ||%0a|| c || canonicalization algorithm || c=simple/simple ||%0a|| h || header fields || h=subject:date:from ||%0a|| bh || body hash || bh=gVJEBqfjoVwtQhVvV3FHh0UQBW0m9unTpuaaGORFGKI= ||%0a|| b || signature || b=Jv/9zpB2AJGosO4/uYlZxFEm1UFOTy56JBi/nhsjgAm5Qe+rku\\%0aKYru5mSqvP01ii/sQRI4exNbG/S8ihdcEXsr5fr8yK4IvLkY8j\\%0aO5O0xMhblySPbFGMw7SW2AwLWu95OyHK5teZPzE/SS5U39Zlqs\\%0a7tS1m8iZo2tPBa70t9204na8/eOT6N78IzNIfRHJfF4dNGVX61\\%0at9xknkcJrJdC6npO0l4MVTky66safTbcCjlM6JihbUd5j4uOU5\\%0aIWREE02CLQKWg5c/UnjQQ96Dt308f2RvxeWA6P8hxsjD/FLDIR\\%0a2U1ZEQyo7k03KCJbdRVw8IHJTdENGGL3p7aM1v8wdg== ||%0a%0a''Tip'': Many mail clients let you view the mail headers in the email you receive. If you%0adisplay all headers, you can see the DKIM header.%0a%0aA receiving SMTP server will perform a DNS lookup based on the domain name and selector. In the example above, it will look up the TXT record of mail._domainkey.example.com.%0aThis TXT record returned should look like below:%0a%0a[@%0a"k=rsa; t=s; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDDmzRmJRQxLEuyYiyMg4suA2Sy%0aMwR5MGHpP9diNT1hRiwUd/mZp1ro7kIDTKS8ttkI6z6eTRW9e9dDOxzSxNuXmume60Cjbu08gOyhPG3%0aGfWdg7QkdN6kR4V75MFlw624VY35DaXBvnlTJTgRg/EW72O1DiYVThkyCgpSYS8nmEQIDAQAB"%0a@]%0a%0a!! Security Notes%0a%0aDKIM-signatures can be used to prove that a mail server sent a letter.%0a%0aNote that DKIM does not provide end-to-end integrity. For this, both sender and receiver will need to use [[PGP/intro|PGP]].%0a%0a!! OpenSMTPd and DKIM%0a%0aFor OpenSMTPd to sign its mail with DKIM, you will need to create a public and private%0aDKIM key:%0a%0a[@%0a$ doas useradd -s /sbin/nologin -d /var/empty -g _dkimsign -G _smtpd _dkimsign%0a$ openssl genrsa -out private.key 1024%0a$ openssl rsa -in private.key -pubout -out public.key%0a$ chmod og-rwx private.key%0a$ chmod og-wx public.key%0a$ chmod u-w public.key private.key%0a$ doas mkdir /etc/dkim%0a$ doas mv private.key public.key /etc/dkim/%0a$ doas chown -R _smtpd:_dovecot /etc/dkim/%0a@]%0a%0aWe then create a DKIM record by taking the public key, removing the first and last%0aline, then joining all the lines together:%0a%0a[@%0a$ doas cat /etc/dkim/public.key | awk '/-----/{if (NR!=1)print "";next}{printf $0}' -%0a@]%0a%0aRunning this command on public.key should produce text like the following:%0a%0a[@%0aMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCmseF9Dm8Dx1LtmLMD56d628JBNaQus8aEcdYYzvBVQ4rhetZzv/ZMafjTEf2RLoOQ+pb7pqL4G86lCZSF+Eeu2ODWQQGYqGVV0xUK5QJSnsGF5UKKscrxmTHSPPtoAQJt25fxNd3PtvH2ZonAGkZkntk+u6Wn5xxlI9hMOVxLUwIDAQAB%0a@]%0a%0aThis key should go into the DKIM DNS records:%0a%0a[@%0a_adsp._domainkey   86400   IN      TXT     "dkim=discardable;"%0amail._domainkey   86400   IN      TXT     "k=rsa; t=s; p=%3cpublic key>"%0a@]%0a%0aThe final result should look like this:%0a%0a[@%0a_adsp._domainkey   86400   IN      TXT     "dkim=discardable;"%0amail._domainkey   86400   IN      TXT     "k=rsa; t=s; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCmseF9Dm8Dx1LtmLMD56d628JBNaQus8aEcdYYzvBVQ4rhetZzv/ZMafjTEf2RLoOQ+pb7pqL4G86lCZSF+Eeu2ODWQQGYqGVV0xUK5QJSnsGF5UKKscrxmTHSPPtoAQJt25fxNd3PtvH2ZonAGkZkntk+u6Wn5xxlI9hMOVxLUwIDAQAB"%0a@]%0a
-time=1678078118
+text=(:title DomainKeys Identified Mail:)%0a%0a!! Introduction%0a%0aDomainKeys Identified Mail (DKIM) is used to detect if an e-mail is spoofed (forged).%0aIt's used to prevent spam and phishing. Signing your mail with DKIM will help%0adetect spam that pretends to come from your domain. It also ensures that your%0aletters pass spam filter checks. Otherwise, letters you send may not end up in the%0ainbox.%0a%0aAn email is signed with a private key. This allows the receiver to check if the email%0acomes from the domain it claims to be from. The receiver looks up the sender's%0apublic key in the domain's DNS record. A valid signature guarantees that the sending%0amail server has access to the private key and that the email body has not been%0atampered with during transit.%0a%0aDKIM, SPF, and DMARC are designed to work together.%0a%0a!! DKIM Header%0a%0aIn our setup, the mail server will sign the message with its private key. Here%0ais what the DKIM header looks like:%0a%0a[@%0aDKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; s=mail; bh=gVJEBqfjoVwtQhV%0a        vV3FHh0UQBW0m9unTpuaaGORFGKI=; h=subject:date:from;%0a        d=example.com; b=Jv/9zpB2AJGosO4/uYlZxFEm1UFOTy56JBi/nhsjg%0a        Am5Qe+rkuKYru5mSqvP01ii/sQRI4exNbG/S8ihdcEXsr5fr8yK4IvLkY8jO5O0xMhblyS%0a        PbFGMw7SW2AwLWu95OyHK5teZPzE/SS5U39Zlqs7tS1m8iZo2tPBa70t9204na8/eOT6N7%0a        8IzNIfRHJfF4dNGVX61t9xknkcJrJdC6npO0l4MVTky66safTbcCjlM6JihbUd5j4uOU5I%0a        WREE02CLQKWg5c/UnjQQ96Dt308f2RvxeWA6P8hxsjD/FLDIR2U1ZEQyo7k03KCJbdRVw8%0a        IHJTdENGGL3p7aM1v8wdg==%0a@]%0a%0a|| border=1 width=100%25 class="sortable simpletable"%0a||! Tag ||! Indicates ||! Example ||%0a|| v || version || v=1 ||%0a|| a || algorithm || a=rsa-sha256 ||%0a|| d || domain || d=example.com ||%0a|| s || selector || s=mail ||%0a|| c || canonicalization algorithm || c=simple/simple ||%0a|| h || header fields || h=subject:date:from ||%0a|| bh || body hash || bh=gVJEBqfjoVwtQhVvV3FHh0UQBW0m9unTpuaaGORFGKI= ||%0a|| b || signature || b=Jv/9zpB2AJGosO4/uYlZxFEm1UFOTy56JBi/nhsjgAm5Qe+rku\\%0aKYru5mSqvP01ii/sQRI4exNbG/S8ihdcEXsr5fr8yK4IvLkY8j\\%0aO5O0xMhblySPbFGMw7SW2AwLWu95OyHK5teZPzE/SS5U39Zlqs\\%0a7tS1m8iZo2tPBa70t9204na8/eOT6N78IzNIfRHJfF4dNGVX61\\%0at9xknkcJrJdC6npO0l4MVTky66safTbcCjlM6JihbUd5j4uOU5\\%0aIWREE02CLQKWg5c/UnjQQ96Dt308f2RvxeWA6P8hxsjD/FLDIR\\%0a2U1ZEQyo7k03KCJbdRVw8IHJTdENGGL3p7aM1v8wdg== ||%0a%0a''Tip'': Many mail clients let you view the mail headers in the email you receive. If you%0adisplay all headers, you can see the DKIM header.%0a%0aA receiving SMTP server will perform a DNS lookup based on the domain name and selector. In the example above, it will look up the TXT record of mail._domainkey.example.com.%0aThis TXT record returned should look like below:%0a%0a[@%0a"k=rsa; t=s; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDDmzRmJRQxLEuyYiyMg4suA2Sy%0aMwR5MGHpP9diNT1hRiwUd/mZp1ro7kIDTKS8ttkI6z6eTRW9e9dDOxzSxNuXmume60Cjbu08gOyhPG3%0aGfWdg7QkdN6kR4V75MFlw624VY35DaXBvnlTJTgRg/EW72O1DiYVThkyCgpSYS8nmEQIDAQAB"%0a@]%0a%0a!! Security Notes%0a%0aDKIM-signatures can be used to prove that a mail server sent a letter.%0a%0aNote that DKIM does not provide end-to-end integrity. For this, both sender and receiver will need to use [[PGP/intro|PGP]].%0a%0a!! OpenSMTPd and DKIM%0a%0aFor OpenSMTPd to sign its mail with DKIM, you will need to create a public and private%0aDKIM key:%0a%0a[@%0a$ openssl genrsa -out private.key 1024%0a$ openssl rsa -in private.key -pubout -out public.key%0a$ chmod og-rwx private.key%0a$ chmod og-wx public.key%0a$ chmod u-w public.key private.key%0a$ doas mkdir /etc/mail/dkim%0a$ doas mv private.key public.key /etc/mail/dkim/%0a$ doas chown -R _smtpd:_dovecot /etc/mail/dkim/%0a@]%0a%0aWe then create a DKIM record by taking the public key, removing the first and last%0aline, then joining all the lines together:%0a%0a[@%0a$ doas cat /etc/mail/dkim/public.key | awk '/-----/{if (NR!=1)print "";next}{printf $0}' -%0a@]%0a%0aRunning this command on public.key should produce text like the following:%0a%0a[@%0aMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCmseF9Dm8Dx1LtmLMD56d628JBNaQus8aEcdYYzvBVQ4rhetZzv/ZMafjTEf2RLoOQ+pb7pqL4G86lCZSF+Eeu2ODWQQGYqGVV0xUK5QJSnsGF5UKKscrxmTHSPPtoAQJt25fxNd3PtvH2ZonAGkZkntk+u6Wn5xxlI9hMOVxLUwIDAQAB%0a@]%0a%0aThis key should go into the DKIM DNS records:%0a%0a[@%0a_adsp._domainkey   86400   IN      TXT     "dkim=discardable;"%0amail._domainkey   86400   IN      TXT     "k=rsa; t=s; p=%3cpublic key>"%0a@]%0a%0aThe final result should look like this:%0a%0a[@%0a_adsp._domainkey   86400   IN      TXT     "dkim=discardable;"%0amail._domainkey   86400   IN      TXT     "k=rsa; t=s; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCmseF9Dm8Dx1LtmLMD56d628JBNaQus8aEcdYYzvBVQ4rhetZzv/ZMafjTEf2RLoOQ+pb7pqL4G86lCZSF+Eeu2ODWQQGYqGVV0xUK5QJSnsGF5UKKscrxmTHSPPtoAQJt25fxNd3PtvH2ZonAGkZkntk+u6Wn5xxlI9hMOVxLUwIDAQAB"%0a@]%0a
+time=1678133576
 title=DomainKeys Identified Mail
+author:1678133576=jrmu
+diff:1678133576:1678079611:=81,83c81,83%0a%3c $ doas mkdir /etc/mail/dkim%0a%3c $ doas mv private.key public.key /etc/mail/dkim/%0a%3c $ doas chown -R _smtpd:_dovecot /etc/mail/dkim/%0a---%0a> $ doas mkdir /etc/dkim%0a> $ doas mv private.key public.key /etc/dkim/%0a> $ doas chown -R _smtpd:_dovecot /etc/dkim/%0a90c90%0a%3c $ doas cat /etc/mail/dkim/public.key | awk '/-----/{if (NR!=1)print "";next}{printf $0}' -%0a---%0a> $ doas cat /etc/dkim/public.key | awk '/-----/{if (NR!=1)print "";next}{printf $0}' -%0a
+host:1678133576=38.87.162.154
+author:1678079611=jrmu
+csum:1678079611=remove unnecessary dkimsign group
+diff:1678079611:1678078118:=75a76%0a> $ doas useradd -s /sbin/nologin -d /var/empty -g _dkimsign -G _smtpd _dkimsign%0a
+host:1678079611=38.87.162.154
 author:1678078118=jrmu
 csum:1678078118=Moved to /etc/dkim/ to fix permissions bugs
 diff:1678078118:1631203235:=82,84c82,84%0a%3c $ doas mkdir /etc/dkim%0a%3c $ doas mv private.key public.key /etc/dkim/%0a%3c $ doas chown -R _smtpd:_dovecot /etc/dkim/%0a---%0a> $ doas mkdir /etc/mail/dkim%0a> $ doas mv private.key public.key /etc/mail/dkim/%0a> $ doas chown -R _smtpd:_dovecot /etc/mail/dkim/%0a91c91%0a%3c $ doas cat /etc/dkim/public.key | awk '/-----/{if (NR!=1)print "";next}{printf $0}' -%0a---%0a> $ doas cat /etc/mail/dkim/public.key | awk '/-----/{if (NR!=1)print "";next}{printf $0}' -%0a
blob - 78176d8f6eb3cd9e58a670aaa8116c6b6b973732
blob + d02806baf37389a184ad58a81474aadb77693c03
--- wiki.d/DNS.Mail
+++ wiki.d/DNS.Mail
@@ -2,15 +2,22 @@ version=pmwiki-2.3.20 ordered=1 urlencoded=1
 agent=w3m/0.5.3+git20210102
 author=jrmu
 charset=UTF-8
-csum=Moved to /etc/dkim/ to fix permissions bugs
+csum=
 ctime=1621335466
 host=38.87.162.154
 name=DNS.Mail
-rev=15
+rev=17
 targets=Nsd.Configure,Dns.Overview,Dns.FQDN,DNS.SOA,DNS.SPF,DNS.DMARC,DNS.DKIM,DNS.Dnswl
-text=(:title DNS for Mail:)%0a%0aRunning a mail server requires a proper DNS records. %0a%0a!! Before you begin%0a%0aThis guide assumes that you have already set up a properly functioning name server using%0a[[nsd/configure|nsd]]. If you have not already, you will want to read up on [[dns/overview|basic DNS concepts]] and [[nsd/configure|set up your name server]].%0a%0a!! Adding to the zone file%0a%0aFor mail, you will need to add DNS records. Let's take a look at a sample zone file%0acontaining only what is needed to handle mail:%0a%0a$ORIGIN and Start of Authority (SOA) record:%0a%0a[@%0a$ORIGIN example.com.%0aexample.com.     3600   SOA   ns1.example.com. admin.example.com. (%0a                            2021050302   ; serial YYYYMMDDnn%0a                            1800        ; refresh%0a                            3600         ; retry%0a                            86400       ; expire%0a                            3600 )      ; minimum TTL%0a@]%0a%0aHere we define the $ORIGIN to be example.com. The $ORIGIN will be appended to every record to produce a [[Dns/FQDN|fully qualified domain name]]. Make sure to read up on [[Dns/FQDN|FQDN]] if you do not understand what that means.%0a%0aThe [[DNS/SOA|Start of Authority record]] says that the serial number was last updated on May 3rd, 2021; that the refresh interval is 1800 seconds, the retry interval is 3600 seconds, the record expires after 1 day, and the minimum time to live is 3600 seconds.%0a%0a[@%0a        3600    IN      MX      10 mail%0a        3600    IN      A       38.81.163.143%0a        3600    IN      AAAA    2602:fccf:1:143::%0a        3600    IN      NS      ns1%0a        3600    IN      NS      ns2%0amail    3600    IN      A       38.81.163.143%0a        3600    IN      AAAA    2602:fccf:1:143::%0apop     3600    IN      A       38.81.163.143%0a        3600    IN      AAAA    2602:fccf:1:143::%0aimap    3600    IN      A       38.81.163.143%0a        3600    IN      AAAA    2602:fccf:1:143::%0asmtp    3600    IN      A       38.81.163.143%0a        3600    IN      AAAA    2602:fccf:1:143::%0a@]%0a%0aWhen there is no name for the record, it just takes on the value of $ORIGIN: example.com.%0a%0aLine 1 defines the mail exchange (MX) record for example.com. When another mail server sends your server mail, it will perform two DNS queries. First, it asks what your MX record is for example.com:%0a%0a[@%0a$ dig +short -t mx example.com%0a10 mail.example.com.%0a@]%0a%0aHere, the MX record for example.com is mail.example.com with a value of 10. This means%0athat mail.example.com is the actual mail server that will handle mail.%0a%0aOnce an MX record is returned, the mail server will find the A/AAAA record for that mail server:%0a%0a[@%0a$ dig +short -t a mail.example.com%0a38.81.163.143%0a@]%0a%0aNormally, a domain will have multiple MX records so that if one mail server goes offline, another can continue serving mail. Most mail servers will choose the MX record with the lowest value to deliver to first.%0a%0a!! [[DNS/SPF|SPF record]]%0a%0aYou'll want to add a TXT record in your domain's [[DNS/SPF|DNS zone for SPF]]:%0a%0a[@%0a        3600    IN      TXT     "v=spf1 mx -all"%0a@]%0a%0aThis simple SPF record allows any mail exchange (MX) server for the domain to send mail, but no others.%0a%0a!! [[DNS/DMARC|DMARC records]]%0a%0a[@%0a_dmarc  3600   IN      TXT     "v=DMARC1;p=none;pct=0;fo=1;rua=mailto:postmaster@example.com;ruf=mailto:postmaster@example.com"%0a@]%0a%0aThis record will provide you with reports for DKIM/SPF but will not filter any mail. It's useful for diagnosing problems with your configuration.%0a%0a!! DKIM records%0a%0aYou will need to follow the instructions for creating a proper [[DNS/DKIM|DKIM record]]:%0a%0aFirst, you will need to create a public and private DKIM key:%0a%0a[@%0a$ doas groupadd -v _dkimsign%0a$ doas useradd -s /sbin/nologin -d /var/empty -g _dkimsign -G _smtpd _dkimsign%0a$ openssl genrsa -out private.key 1024%0a$ openssl rsa -in private.key -pubout -out public.key%0a$ chmod og-rwx private.key%0a$ chmod og-wx public.key%0a$ chmod u-w public.key private.key%0a$ doas mkdir /etc/dkim%0a$ doas mv private.key public.key /etc/dkim/%0a$ doas chown -R _smtpd:_dovecot /etc/dkim/%0a@]%0a%0aWe then create a DKIM record by taking the public key, removing the first and last%0aline, then joining all the lines together:%0a%0a[@%0a$ doas cat /etc/dkim/public.key | awk '/-----/{if (NR!=1)print "";next}{printf $0}' -%0a@]%0a%0aRunning this command on public.key should produce text like the following:%0a%0a[@%0aMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCmseF9Dm8Dx1LtmLMD56d628JBNaQus8aEcdYYzvBVQ4rhetZzv/ZMafjTEf2RLoOQ+pb7pqL4G86lCZSF+Eeu2ODWQQGYqGVV0xUK5QJSnsGF5UKKscrxmTHSPPtoAQJt25fxNd3PtvH2ZonAGkZkntk+u6Wn5xxlI9hMOVxLUwIDAQAB%0a@]%0a%0aThis key should go into the DKIM DNS records to replace %3cpublic key>:%0a%0a[@%0a_adsp._domainkey   86400   IN      TXT     "dkim=discardable;"%0amail._domainkey   86400   IN      TXT     "k=rsa; t=s; p=%3cpublic key>"%0a@]%0a%0aThe final result should look like this:%0a%0a[@%0a_adsp._domainkey   86400   IN      TXT     "dkim=discardable;"%0amail._domainkey    86400   IN      TXT     "k=rsa; t=s; p=8AMIIBCgKCAQEAyBhtr90v64hQTfw1sUtFPg5bYXF/SxUTNMziGJMql81av47DG+cDEPmQW0XN8+Tb8yIwenh01hZ5Xh1gjWg1v8OIrnErf3482B8XRZykHJQUdjcALnZ9gGZ9CnzAhIC3TsAnTDSHdgk3c0oqJeilriW0EIAkV2+x1jWlPunGJgJT/bSc2rzZsZv2gZmrrR+2f4aK7xTamAyFUl+cSP/kcoHbEmvXEOtqTQZTTDhxM6BKELUO0xBBhlrsq8C3q92OqZtwflK+IbJDyQPndORMR7R4itIj6O+LMFlYziPitM4egw3KADLZSlycJuTLkhCG5b/3VHFy+uUn3kQc+/s17QIDAQAB"%0a@]%0a%0a!! Whitelists%0a%0a[[DNS/dnswl|dnswl]] is a DNS whitelist that is free of charge, so you should sign up for it.%0a
-time=1678078240
+text=(:title DNS for Mail:)%0a%0aRunning a mail server requires a proper DNS records. %0a%0a!! Before you begin%0a%0aThis guide assumes that you have already set up a properly functioning name server using%0a[[nsd/configure|nsd]]. If you have not already, you will want to read up on [[dns/overview|basic DNS concepts]] and [[nsd/configure|set up your name server]].%0a%0a!! Adding to the zone file%0a%0aFor mail, you will need to add DNS records. Let's take a look at a sample zone file%0acontaining only what is needed to handle mail:%0a%0a$ORIGIN and Start of Authority (SOA) record:%0a%0a[@%0a$ORIGIN example.com.%0aexample.com.     3600   SOA   ns1.example.com. admin.example.com. (%0a                            2021050302   ; serial YYYYMMDDnn%0a                            1800        ; refresh%0a                            3600         ; retry%0a                            86400       ; expire%0a                            3600 )      ; minimum TTL%0a@]%0a%0aHere we define the $ORIGIN to be example.com. The $ORIGIN will be appended to every record to produce a [[Dns/FQDN|fully qualified domain name]]. Make sure to read up on [[Dns/FQDN|FQDN]] if you do not understand what that means.%0a%0aThe [[DNS/SOA|Start of Authority record]] says that the serial number was last updated on May 3rd, 2021; that the refresh interval is 1800 seconds, the retry interval is 3600 seconds, the record expires after 1 day, and the minimum time to live is 3600 seconds.%0a%0a[@%0a        3600    IN      MX      10 mail%0a        3600    IN      A       38.81.163.143%0a        3600    IN      AAAA    2602:fccf:1:143::%0a        3600    IN      NS      ns1%0a        3600    IN      NS      ns2%0amail    3600    IN      A       38.81.163.143%0a        3600    IN      AAAA    2602:fccf:1:143::%0apop     3600    IN      A       38.81.163.143%0a        3600    IN      AAAA    2602:fccf:1:143::%0aimap    3600    IN      A       38.81.163.143%0a        3600    IN      AAAA    2602:fccf:1:143::%0asmtp    3600    IN      A       38.81.163.143%0a        3600    IN      AAAA    2602:fccf:1:143::%0a@]%0a%0aWhen there is no name for the record, it just takes on the value of $ORIGIN: example.com.%0a%0aLine 1 defines the mail exchange (MX) record for example.com. When another mail server sends your server mail, it will perform two DNS queries. First, it asks what your MX record is for example.com:%0a%0a[@%0a$ dig +short -t mx example.com%0a10 mail.example.com.%0a@]%0a%0aHere, the MX record for example.com is mail.example.com with a value of 10. This means%0athat mail.example.com is the actual mail server that will handle mail.%0a%0aOnce an MX record is returned, the mail server will find the A/AAAA record for that mail server:%0a%0a[@%0a$ dig +short -t a mail.example.com%0a38.81.163.143%0a@]%0a%0aNormally, a domain will have multiple MX records so that if one mail server goes offline, another can continue serving mail. Most mail servers will choose the MX record with the lowest value to deliver to first.%0a%0a!! [[DNS/SPF|SPF record]]%0a%0aYou'll want to add a TXT record in your domain's [[DNS/SPF|DNS zone for SPF]]:%0a%0a[@%0a        3600    IN      TXT     "v=spf1 mx -all"%0a@]%0a%0aThis simple SPF record allows any mail exchange (MX) server for the domain to send mail, but no others.%0a%0a!! [[DNS/DMARC|DMARC records]]%0a%0a[@%0a_dmarc  3600   IN      TXT     "v=DMARC1;p=none;pct=0;fo=1;rua=mailto:postmaster@example.com;ruf=mailto:postmaster@example.com"%0a@]%0a%0aThis record will provide you with reports for DKIM/SPF but will not filter any mail. It's useful for diagnosing problems with your configuration.%0a%0a!! DKIM records%0a%0aYou will need to follow the instructions for creating a proper [[DNS/DKIM|DKIM record]]:%0a%0aFirst, you will need to create a public and private DKIM key:%0a%0a[@%0a$ doas groupadd -v _dkimsign%0a$ openssl genrsa -out private.key 1024%0a$ openssl rsa -in private.key -pubout -out public.key%0a$ chmod og-rwx private.key%0a$ chmod og-wx public.key%0a$ chmod u-w public.key private.key%0a$ doas mkdir /etc/mail/dkim%0a$ doas mv private.key public.key /etc/mail/dkim/%0a$ doas chown -R _smtpd:_dovecot /etc/mail/dkim/%0a@]%0a%0aWe then create a DKIM record by taking the public key, removing the first and last%0aline, then joining all the lines together:%0a%0a[@%0a$ doas cat /etc/mail/dkim/public.key | awk '/-----/{if (NR!=1)print "";next}{printf $0}' -%0a@]%0a%0aRunning this command on public.key should produce text like the following:%0a%0a[@%0aMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCmseF9Dm8Dx1LtmLMD56d628JBNaQus8aEcdYYzvBVQ4rhetZzv/ZMafjTEf2RLoOQ+pb7pqL4G86lCZSF+Eeu2ODWQQGYqGVV0xUK5QJSnsGF5UKKscrxmTHSPPtoAQJt25fxNd3PtvH2ZonAGkZkntk+u6Wn5xxlI9hMOVxLUwIDAQAB%0a@]%0a%0aThis key should go into the DKIM DNS records to replace %3cpublic key>:%0a%0a[@%0a_adsp._domainkey   86400   IN      TXT     "dkim=discardable;"%0amail._domainkey   86400   IN      TXT     "k=rsa; t=s; p=%3cpublic key>"%0a@]%0a%0aThe final result should look like this:%0a%0a[@%0a_adsp._domainkey   86400   IN      TXT     "dkim=discardable;"%0amail._domainkey    86400   IN      TXT     "k=rsa; t=s; p=8AMIIBCgKCAQEAyBhtr90v64hQTfw1sUtFPg5bYXF/SxUTNMziGJMql81av47DG+cDEPmQW0XN8+Tb8yIwenh01hZ5Xh1gjWg1v8OIrnErf3482B8XRZykHJQUdjcALnZ9gGZ9CnzAhIC3TsAnTDSHdgk3c0oqJeilriW0EIAkV2+x1jWlPunGJgJT/bSc2rzZsZv2gZmrrR+2f4aK7xTamAyFUl+cSP/kcoHbEmvXEOtqTQZTTDhxM6BKELUO0xBBhlrsq8C3q92OqZtwflK+IbJDyQPndORMR7R4itIj6O+LMFlYziPitM4egw3KADLZSlycJuTLkhCG5b/3VHFy+uUn3kQc+/s17QIDAQAB"%0a@]%0a%0a!! Whitelists%0a%0a[[DNS/dnswl|dnswl]] is a DNS whitelist that is free of charge, so you should sign up for it.%0a
+time=1678133545
 title=DNS for Mail
+author:1678133545=jrmu
+diff:1678133545:1678079585:=93d92%0a%3c $ doas groupadd -v _dkimsign%0a99,101c98,100%0a%3c $ doas mkdir /etc/mail/dkim%0a%3c $ doas mv private.key public.key /etc/mail/dkim/%0a%3c $ doas chown -R _smtpd:_dovecot /etc/mail/dkim/%0a---%0a> $ doas mkdir /etc/dkim%0a> $ doas mv private.key public.key /etc/dkim/%0a> $ doas chown -R _smtpd:_dovecot /etc/dkim/%0a108c107%0a%3c $ doas cat /etc/mail/dkim/public.key | awk '/-----/{if (NR!=1)print "";next}{printf $0}' -%0a---%0a> $ doas cat /etc/dkim/public.key | awk '/-----/{if (NR!=1)print "";next}{printf $0}' -%0a
+host:1678133545=38.87.162.154
+author:1678079585=jrmu
+csum:1678079585=remove unnecessary dkimsign user/group
+diff:1678079585:1678078240:=92a93,94%0a> $ doas groupadd -v _dkimsign%0a> $ doas useradd -s /sbin/nologin -d /var/empty -g _dkimsign -G _smtpd _dkimsign%0a
+host:1678079585=38.87.162.154
 author:1678078240=jrmu
 csum:1678078240=Moved to /etc/dkim/ to fix permissions bugs
 diff:1678078240:1623943290:=100,102c100,102%0a%3c $ doas mkdir /etc/dkim%0a%3c $ doas mv private.key public.key /etc/dkim/%0a%3c $ doas chown -R _smtpd:_dovecot /etc/dkim/%0a---%0a> $ doas mkdir /etc/mail/dkim%0a> $ doas mv private.key public.key /etc/mail/dkim/%0a> $ doas chown -R _smtpd:_dovecot /etc/mail/dkim/%0a109c109%0a%3c $ doas cat /etc/dkim/public.key | awk '/-----/{if (NR!=1)print "";next}{printf $0}' -%0a---%0a> $ doas cat /etc/mail/dkim/public.key | awk '/-----/{if (NR!=1)print "";next}{printf $0}' -%0a
blob - 5ac385e043083281e5cd663ea3d02953df8e6e8b
blob + 18dcbb4b6530cd089d9ccf3abec1b013607c2234
--- wiki.d/DNS.RecentChanges
+++ wiki.d/DNS.RecentChanges
@@ -4,6 +4,6 @@ charset=UTF-8
 ctime=1621335466
 host=38.87.162.154
 name=DNS.RecentChanges
-rev=79
-text=* [[DNS/Mail]]  . . . @2023-03-06T04:50:40Z by [[~jrmu]]: [=Moved to /etc/dkim/ to fix permissions bugs=]%0a* [[DNS/DKIM]]  . . . @2023-03-06T04:48:38Z by [[~jrmu]]: [=Moved to /etc/dkim/ to fix permissions bugs=]%0a* [[DNS/Ipv4rDNS]]  . . . February 01, 2023, at 08:31 PM by [[~izzyb]]: [=added note to clarify what address needs to be specified.=]%0a* [[DNS/DMARC]]  . . . November 22, 2021, at 10:52 PM by [[~Hawk]]: [==]%0a* [[DNS/Ipv6rDNS]]  . . . August 23, 2021, at 11:55 AM by [[~jrmu]]: [==]%0a* [[DNS/RDNS]]  . . . August 22, 2021, at 11:20 PM by [[~jrmu]]: [==]%0a* [[DNS/Dnswl]]  . . . June 04, 2021, at 11:11 AM by [[~jrmu]]: [==]%0a* [[DNS/SPF]]  . . . June 03, 2021, at 01:27 PM by [[~jrmu]]: [==]%0a
-time=1678078240
+rev=83
+text=* [[DNS/DKIM]]  . . . @2023-03-06T20:12:56Z by [[~jrmu]]: [==]%0a* [[DNS/Mail]]  . . . @2023-03-06T20:12:25Z by [[~jrmu]]: [==]%0a* [[DNS/Ipv4rDNS]]  . . . February 01, 2023, at 08:31 PM by [[~izzyb]]: [=added note to clarify what address needs to be specified.=]%0a* [[DNS/DMARC]]  . . . November 22, 2021, at 10:52 PM by [[~Hawk]]: [==]%0a* [[DNS/Ipv6rDNS]]  . . . August 23, 2021, at 11:55 AM by [[~jrmu]]: [==]%0a* [[DNS/RDNS]]  . . . August 22, 2021, at 11:20 PM by [[~jrmu]]: [==]%0a* [[DNS/Dnswl]]  . . . June 04, 2021, at 11:11 AM by [[~jrmu]]: [==]%0a* [[DNS/SPF]]  . . . June 03, 2021, at 01:27 PM by [[~jrmu]]: [==]%0a
+time=1678133576
blob - b6f84f75d218e0cc1950d8f3d7b9a89f7e9acfeb
blob + fa6a8d5958709f997826c1a57fa6a67cd910ee71
--- wiki.d/Dovecot.Install
+++ wiki.d/Dovecot.Install
@@ -1,15 +1,25 @@
-version=pmwiki-2.2.130 ordered=1 urlencoded=1
-agent=Mozilla/5.0 (X11; Linux x86_64; rv:95.0) Gecko/20100101 Firefox/95.0
-author=forero
+version=pmwiki-2.3.20 ordered=1 urlencoded=1
+agent=w3m/0.5.3+git20210102
+author=jrmu
 charset=UTF-8
-csum=comment out
+csum=
 ctime=1621334182
-host=181.53.13.19
+host=38.87.162.154
 name=Dovecot.Install
-rev=16
+rev=19
 targets=Openbsd.Loginconf,Openbsd.Rcctl
-text=Let's set up dovecot to allow users to read mail with IMAP and POP.%0a%0a!! Installation%0a%0a[@%0a$ doas pkg_add dovecot%0a@]%0a%0a!! Configuration%0a%0aA single user vmail will receive mail for all virtual users:%0a[@%0a$ doas useradd -m -g =uid -c "Virtual Mail" -d /var/vmail -s /sbin/nologin vmail%0a@]%0a%0a/var/vmail will be used to store virtual users' maildir folders. It will be managed by%0adovecot, which receives mail via LMTP.%0a%0aIn order to secure our passwords, we need to remove world readable permissions%0afrom /etc/mail and change file ownership:%0a%0a[@%0a$ doas chmod -R o-rx /etc/mail/%0a$ doas chown -R _smtpd:_dovecot /etc/mail/%0a@]%0a%0aIn /etc/dovecot/dovecot.conf, add the following lines at the bottom of the file:%0a%0a[@%0aprotocols = imap pop3 lmtp%0alisten = 192.168.0.1, 2001:db8::%0aservice lmtp {%0a  user = vmail%0a}%0a@]%0a%0aThis tells dovecot to listen to the protocols IMAP, POP3, and LMTP.%0a'''Note''': We don't want to support submission with dovecot.%0a%0aIt also tells dovecot the public IPs you want it to listen on. Finally, the last%0ablock tells dovecot to change to the username vmail to listen for LMTP.%0a%0aTo aid with troubleshooting, you can consider adding these lines:%0a%0a[@%0aauth_verbose=yes%0aauth_debug=yes%0aauth_debug_passwords=yes%0amail_debug=yes%0aauth_verbose_passwords=sha1%0averbose_ssl=yes%0a@]%0a%0aIn /etc/dovecot/conf.d/10-auth.conf, first comment out auth-system.conf.ext %0a%0a[@%0a#!include auth-system.conf.ext%0a@]%0a%0aThis prevents dovecot from using BSD auth.%0a%0aThen at the bottom of the file, add these lines:%0a%0a[@%0apassdb {%0a   args = scheme=blf-crypt /etc/mail/passwd%0a   driver = passwd-file%0a}%0a%0auserdb {%0a   args = uid=vmail gid=vmail home=/var/vmail/%25d/%25n%0a   driver = static%0a}%0a@]%0a%0aThe first block defines our password database to use blowfish (see [[https://man.openbsd.org/blowfish|blowfish(3)]] and [[https://man.openbsd.org/encrypt|encrypt(1)]]).%0a%0aThe second block says that the mail must be read by user ID and group ID vmail, and%0athat all mail will be in the folders /var/vmail/%3cdomain>/%3cusername>.%0a%0aIn /etc/dovecot/conf.d/10-mail.conf:%0a%0a[@%0amail_location = maildir:/var/vmail/%25d/%25n/Maildir%0a@]%0a%0aThis again indicates all mail will be in the folders /var/vmail/%3cdomain>/%3cusername>.%0a%0aIn /etc/dovecot/conf.d/10-ssl.conf, make the changes to these lines:%0a%0a[@%0assl = yes%0a...%0assl_cert = %3c/etc/ssl/example.com.fullchain.pem%0assl_key = %3c/etc/ssl/private/example.com.key%0a@]%0a%0aYou will need to replace example.com with your real domain.%0a%0aPlease read the instructions in the dovecot README in @@/usr/local/share/doc/pkg-readmes/dovecot@@. That file explains that you must add this [[openbsd/loginconf|login class]] to /etc/login.conf:%0a%0a[@%0adovecot:\%0a         :openfiles-cur=4096:\%0a         :openfiles-max=8192:\%0a         :tc=daemon:%0a@]%0a%0a'''WARNING''': You must use tabs and not spaces. If you use spaces in /etc/login.conf, the settings will '''not''' work.%0a%0a'''NOTE''': Allowing more open files than suggested in the README can help if you have many IP addresses.%0a%0a'''WARNING''': If login.conf.db exists, you will need to rebuild it:%0a%0a[@%0a# [ -f /etc/login.conf.db ] && cap_mkdb /etc/login.conf%0a@]%0a%0aBut it is best to just remove /etc/login.conf.db since it is not required:%0a%0a[@%0a$ doas rm /etc/login.conf.db%0a@]%0a%0a!! Starting dovecot%0a%0aTo start dovecot via [[openbsd/rcctl|rcctl]]:%0a%0a[@%0a$ doas rcctl enable dovecot%0a$ doas rcctl start dovecot%0a@]%0a%0a!! Troubleshooting%0a%0aMake sure to check /var/log/maillog:%0a%0a[@%0a$ openssl s_client -starttls imap -connect username.coconut.ircnow.org:143%0a@]%0a%0aWhen starting dovecot, you may find it fails:%0a%0a[@%0a$ doas rcctl start dovecot%0adovecot(failed)%0a@]%0a%0aWhen this happens, run the rc.d script with debugging turned on:%0a%0a[@%0a$ doas /etc/rc.d/dovecot -d start%0adoing _rc_parse_conf%0adoing _rc_quirks%0adovecot_flags empty, using default >%3c%0adoing rc_check%0adovecot%0adoing rc_start%0adoing _rc_wait start%0adoing rc_check%0adoveconf: Fatal: Error in configuration file /etc/dovecot/conf.d/10-ssl.conf line 12: ssl_cert: Can't open file /etc/ssl/dovecotcert.pem: No such file or directory%0adoing _rc_rm_runfile%0a(failed)%0a@]%0a%0aIn this case, you can see the error is in line 12 of /etc/dovecot/conf.d/10-ssl.conf . I forgot to write the real path of the cert: @@/etc/ssl/example.com.fullchain.pem@@ (where example.com is replaced with my real domain).%0a%0a[@%0aJun  9 01:37:35 jrmu dovecot: auth: Error: passwd-file(jrmu@jrmu.host.oddprotocol.org,125.231.25.80,%3caiyNgk/EuHB95xlQ>): stat(/etc/mail/passwd) failed: Permission denied (euid=518(_dovecot) egid=518(_dovecot) missing +x perm: /etc/mail, we're not in group 1003(_mail), dir owned by 95:1003 mode=0750)%0aJun  9 01:37:41 jrmu dovecot: auth: Error: passwd-file(jrmu@jrmu.host.oddprotocol.org,125.231.25.80,%3caiyNgk/EuHB95xlQ>): stat(/etc/mail/passwd) failed: Permission denied (euid=518(_dovecot) egid=518(_dovecot) missing +x perm: /etc/mail, we're not in group 1003(_mail), dir owned by 95:1003 mode=0750)%0a@]%0a
-time=1643492127
+text=Let's set up dovecot to allow users to read mail with IMAP and POP.%0a%0a!! Installation%0a%0a[@%0a$ doas pkg_add dovecot%0a@]%0a%0a!! Configuration%0a%0aA single user vmail will receive mail for all virtual users:%0a[@%0a$ doas useradd -m -g =uid -c "Virtual Mail" -d /var/vmail -s /sbin/nologin vmail%0a@]%0a%0a/var/vmail will be used to store virtual users' maildir folders. It will be managed by%0adovecot, which receives mail via LMTP.%0a%0aIn order to secure our passwords, we need to remove world readable permissions%0afrom /etc/mail and change file ownership:%0a%0a[@%0a$ doas chmod -R o-rx /etc/mail/%0a$ doas chown -R _smtpd:_dovecot /etc/mail/%0a@]%0a%0aIn /etc/dovecot/dovecot.conf, add the following lines at the bottom of the file:%0a%0a[@%0aprotocols = imap pop3 lmtp%0alisten = 192.168.0.1, 2001:db8::%0aservice lmtp {%0a  user = vmail%0a}%0a@]%0a%0aThis tells dovecot to listen to the protocols IMAP, POP3, and LMTP.%0a'''Note''': We don't want to support submission with dovecot.%0a%0aIt also tells dovecot the public IPs you want it to listen on. Finally, the last%0ablock tells dovecot to change to the username vmail to listen for LMTP.%0a%0aTo aid with troubleshooting, you can consider adding these lines:%0a%0a[@%0aauth_verbose=yes%0aauth_debug=yes%0aauth_debug_passwords=yes%0amail_debug=yes%0aauth_verbose_passwords=sha1%0averbose_ssl=yes%0a@]%0a%0aIn /etc/dovecot/conf.d/10-auth.conf, first comment out auth-system.conf.ext %0a%0a[@%0a#!include auth-system.conf.ext%0a@]%0a%0aThis prevents dovecot from using BSD auth.%0a%0aThen at the bottom of the file, add these lines:%0a%0a[@%0apassdb {%0a   args = scheme=blf-crypt /etc/mail/passwd%0a   driver = passwd-file%0a}%0a%0auserdb {%0a   args = uid=vmail gid=vmail home=/var/vmail/%25d/%25n%0a   driver = static%0a}%0a@]%0a%0aThe first block defines our password database to use blowfish (see [[https://man.openbsd.org/blowfish|blowfish(3)]] and [[https://man.openbsd.org/encrypt|encrypt(1)]]).%0a%0aThe second block says that the mail must be read by user ID and group ID vmail, and%0athat all mail will be in the folders /var/vmail/%3cdomain>/%3cusername>.%0a%0aIn /etc/dovecot/conf.d/10-mail.conf:%0a%0a[@%0amail_location = maildir:/var/vmail/%25d/%25n/Maildir%0a@]%0a%0aThis again indicates all mail will be in the folders /var/vmail/%3cdomain>/%3cusername>.%0a%0aIn /etc/dovecot/conf.d/10-ssl.conf, make the changes to these lines:%0a%0a[@%0assl = yes%0a...%0assl_cert = %3c/etc/ssl/example.com.crt%0assl_key = %3c/etc/ssl/private/example.com.key%0a@]%0a%0aYou will need to replace example.com with your real domain.%0a%0aPlease read the instructions in the dovecot README in @@/usr/local/share/doc/pkg-readmes/dovecot@@. That file explains that you must add this [[openbsd/loginconf|login class]] to /etc/login.conf:%0a%0a[@%0adovecot:\%0a         :openfiles-cur=4096:\%0a         :openfiles-max=8192:\%0a         :tc=daemon:%0a@]%0a%0a'''WARNING''': You must use tabs and not spaces. If you use spaces in /etc/login.conf, the settings will '''not''' work.%0a%0a'''NOTE''': Allowing more open files than suggested in the README can help if you have many IP addresses.%0a%0a'''WARNING''': If login.conf.db exists, you will need to rebuild it:%0a%0a[@%0a# [ -f /etc/login.conf.db ] && cap_mkdb /etc/login.conf%0a@]%0a%0aBut it is best to just remove /etc/login.conf.db since it is not required:%0a%0a[@%0a$ doas rm /etc/login.conf.db%0a@]%0a%0a!! Starting dovecot%0a%0aTo start dovecot via [[openbsd/rcctl|rcctl]]:%0a%0a[@%0a$ doas rcctl enable dovecot%0a$ doas rcctl start dovecot%0a@]%0a%0a!! Troubleshooting%0a%0aMake sure to check /var/log/maillog:%0a%0a[@%0a$ openssl s_client -starttls imap -connect username.coconut.ircnow.org:143%0a@]%0a%0aWhen starting dovecot, you may find it fails:%0a%0a[@%0a$ doas rcctl start dovecot%0adovecot(failed)%0a@]%0a%0aWhen this happens, run the rc.d script with debugging turned on:%0a%0a[@%0a$ doas /etc/rc.d/dovecot -d start%0adoing _rc_parse_conf%0adoing _rc_quirks%0adovecot_flags empty, using default >%3c%0adoing rc_check%0adovecot%0adoing rc_start%0adoing _rc_wait start%0adoing rc_check%0adoveconf: Fatal: Error in configuration file /etc/dovecot/conf.d/10-ssl.conf line 12: ssl_cert: Can't open file /etc/ssl/dovecotcert.pem: No such file or directory%0adoing _rc_rm_runfile%0a(failed)%0a@]%0a%0aIn this case, you can see the error is in line 12 of /etc/dovecot/conf.d/10-ssl.conf . I forgot to write the real path of the cert: @@/etc/ssl/example.com.fullchain.pem@@ (where example.com is replaced with my real domain).%0a%0a[@%0aJun  9 01:37:35 jrmu dovecot: auth: Error: passwd-file(jrmu@jrmu.host.oddprotocol.org,125.231.25.80,%3caiyNgk/EuHB95xlQ>): stat(/etc/mail/passwd) failed: Permission denied (euid=518(_dovecot) egid=518(_dovecot) missing +x perm: /etc/mail, we're not in group 1003(_mail), dir owned by 95:1003 mode=0750)%0aJun  9 01:37:41 jrmu dovecot: auth: Error: passwd-file(jrmu@jrmu.host.oddprotocol.org,125.231.25.80,%3caiyNgk/EuHB95xlQ>): stat(/etc/mail/passwd) failed: Permission denied (euid=518(_dovecot) egid=518(_dovecot) missing +x perm: /etc/mail, we're not in group 1003(_mail), dir owned by 95:1003 mode=0750)%0a@]%0a
+time=1678134050
+author:1678134050=jrmu
+diff:1678134050:1678133636:=94c94%0a%3c ssl_cert = %3c/etc/ssl/example.com.crt%0a---%0a> ssl_cert = %3c/etc/ssl/example.com.fullchain.pem%0a
+host:1678134050=38.87.162.154
+author:1678133636=jrmu
+diff:1678133636:1678079855:=20,21c20,21%0a%3c from /etc/mail and change file ownership:%0a%3c %0a---%0a> from /etc/mail:%0a> %0a24d23%0a%3c $ doas chown -R _smtpd:_dovecot /etc/mail/%0a
+host:1678133636=38.87.162.154
+author:1678079855=jrmu
+csum:1678079855=dkim is moved to /etc/dkim/ so there is no longer a need to change file ownership
+diff:1678079855:1643492127:=20,21c20,21%0a%3c from /etc/mail:%0a%3c %0a---%0a> from /etc/mail and change file ownership:%0a> %0a23a24%0a> $ doas chown -R _smtpd:_dovecot /etc/mail/%0a
+host:1678079855=38.87.162.154
 author:1643492127=forero
 csum:1643492127=comment out
 diff:1643492127:1638102641:=46,50c46,50%0a%3c auth_verbose=yes%0a%3c auth_debug=yes%0a%3c auth_debug_passwords=yes%0a%3c mail_debug=yes%0a%3c auth_verbose_passwords=sha1%0a---%0a> #auth_verbose=yes%0a> #auth_debug=yes%0a> #auth_debug_passwords=yes%0a> #mail_debug=yes%0a> #auth_verbose_passwords=sha1%0a
blob - 2799fc6665c928f19ae227c983505964a03f8f8b
blob + b0b77e9f91a2dd4448afd44e90f1a41b3a267365
--- wiki.d/Dovecot.RecentChanges
+++ wiki.d/Dovecot.RecentChanges
@@ -1,9 +1,9 @@
-version=pmwiki-2.2.130 ordered=1 urlencoded=1
-agent=Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/109.0
+version=pmwiki-2.3.20 ordered=1 urlencoded=1
+agent=w3m/0.5.3+git20210102
 charset=UTF-8
 ctime=1621334182
-host=2001:56a:f8ee:bb00:5530:453a:9e38:822a
+host=38.87.162.154
 name=Dovecot.RecentChanges
-rev=31
-text=* [[Dovecot/SharedMailboxes]]  . . . January 31, 2023, at 08:29 PM by [[~izzyb]]: [==]%0a* [[Dovecot/SharedFolders]]  . . . January 31, 2023, at 06:03 AM by [[~izzyb]]: [=renaming to sharedMailboxes=]%0a* [[Dovecot/Pigeonhole]]  . . . December 30, 2022, at 04:24 PM by [[~mkf]]: [=style 2=]%0a* [[Dovecot/Install]]  . . . January 29, 2022, at 09:35 PM by [[~forero]]: [=comment out=]%0a
-time=1675196941
+rev=34
+text=* [[Dovecot/Install]]  . . . @2023-03-06T20:20:50Z by [[~jrmu]]: [==]%0a* [[Dovecot/SharedMailboxes]]  . . . January 31, 2023, at 08:29 PM by [[~izzyb]]: [==]%0a* [[Dovecot/SharedFolders]]  . . . January 31, 2023, at 06:03 AM by [[~izzyb]]: [=renaming to sharedMailboxes=]%0a* [[Dovecot/Pigeonhole]]  . . . December 30, 2022, at 04:24 PM by [[~mkf]]: [=style 2=]%0a
+time=1678134050
blob - 5e318adb6c9d3b71448d3fa1612f80049e99110e
blob + 7974dbd15c09bef167328ce58e2607a81a19df74
--- wiki.d/Openbsd.Ngircd
+++ wiki.d/Openbsd.Ngircd
@@ -1,16 +1,22 @@
 version=pmwiki-2.3.20 ordered=1 urlencoded=1
-agent=Mozilla/5.0 (X11; OpenBSD amd64; rv:102.0) Gecko/20100101 Firefox/102.0
+agent=NetSurf/3.11 (Plan9)
 author=mkf
 charset=UTF-8
 csum=
 ctime=1612974683
-host=198.251.81.133
+host=2.178.200.45
 name=Openbsd.Ngircd
-rev=123
+rev=125
 targets=Irc.Guide,IP.Myaddress,Ddos.Intro,Chroot.Intro,Netcat.Irc,Hopm.Install,Ngircd.Ssl,Password.Management,Dns.Vhost,Ngircd.Link,Syslogd.Configure,Openbsd.Rcctl,Anope.Install,Acopm.Install
-text=(:title Ngircd Install Guide:)%0a%0aIn this guide, we'll setup [[https://ngircd.barton.de/documentation.php.en|ngircd]], a free, portable, lightweight IRC server.%0a%0a!!Overview%0a%0angircd is an [[Irc/Guide|IRC]] server. It helps IRC clients send messages to one another.%0a%0aAdvantages:%0a%0a# The source code is written in modern, portable C.%0a# The code compiles easily on all BSDs, Linux, and other platforms.%0a# The code is easy to fork to add new features such as spam filters%0a# The server has a very simple, easy-to-understand configuration%0a# Documentation is short and easy to understand%0a# The server is a clean implementation which was written from scratch%0a# The lead developer po||ux actively hangs out on the IRC server barton.ngircd.de on #ngircd%0a%0a!! Docs and references%0a%0aBefore installation, please consult:%0a%0a# The [[https://ngircd.barton.de/documentation.php.en|Official ngIRCd documentation]] %0a# After installation, see also /usr/local/share/doc/ngircd/ for local documentation%0a# Consult the man pages:%0a  # @@$ man 5 ngircd.conf@@%0a  # @@$ man 8 ngircd@@%0a%0a!! Installation%0a%0a!!! Installing from OpenBSD packages%0a%0a[@%0a$ doas pkg_add ngircd%0a@]%0a%0aCopy the sample configuration file:%0a%0a[@%0a$ doas cp /usr/local/share/examples/ngircd/sample-ngircd.conf /etc/ngircd/ngircd.conf%0a@]%0a%0angIRCd v26.1 provided by OpenBSD 7.1 ports does not have ident support. On a production server, ident support is essential, so we will need to compile from source (described below). You will want to do this after installing from packages, so that rc.d scripts are created automatically.%0a%0a!!! Building from source%0a%0a'''Note''': Before building from source, make sure you have ngircd package installed using the instructions from above.%0a%0aDownload the IRC server, extract the code, and build it:%0a%0a[@%0a$ ftp https://ircnow.org/software/ircnowd.tgz%0a$ tar xvzf ircnowd.tgz%0a$ cd ircnowd/%0a$ sh build.sh %0a@]%0a%0a!! Configuring ngircd%0a%0aEdit @@/etc/ngircd/ngircd.conf@@ as root:%0a%0a'''Note''': Lines that begin with # or ; are comments and will be ignored. You will need to remove # or ; to uncomment.%0a%0aTypically, ";" precedes a line of code that has been commented, while a "#" precedes an actual note that should not be uncommented.%0a%0a!!! Global Block%0a%0a[@%0a[Global]%0a        Name = irc.example.com%0a        AdminInfo1 = Example Network%0a        AdminInfo2 = Planet Earth%0a        AdminEMail = admin@example.com%0a	HelpFile = /usr/local/share/doc/ngircd/Commands.txt%0a        Info = irc.example.com%0a@]%0a%0a* Name: Use your server's domain name.%0a* Info: Use your server's domain name.%0a%0a[@%0a        Listen = 127.0.0.1,::1,192.168.1.1,2001:db8::%0a@]%0a%0aProvide every single IP address you want ngircd to listen on. This includes localhost (127.0.0.1 and ::1), and [[IP/Myaddress|our public IPv4 and IPv6 addresses]]. Keep 127.0.0.1 and ::1 untouched, but replace 192.168.1.1 and 2001:db8:: with your real public IPs. If you are hosting a public service, avoid listing IPs that are not DDoS-filtered. IRC servers are heavily [[ddos/intro|DDoSed]] and using an unfiltered IP may get you nullrouted.%0a%0a'''Note''': if you do not uncomment this line, you will listen to all IPs by default, which is probably a mistake.%0a%0a[@%0a        MotdFile = /etc/ngircd/ngircd.motd%0a        ;MotdPhrase = "Hello world!"%0a        Network = ExampleNet%0a        ;Password = abc%0a@]%0a%0a* Network: Your network name; this usually contains no periods.%0a%0aKeep the MotdPhrase and Password commented out. First, we will be using a MotdFile instead. Secondly, we do not want a global password for a public server.%0a%0a[@%0a	PidFile = /var/run/ngircd/ngircd.pid%0a@]%0a%0aThe Pid file is where ngircd writes its process ID.%0a%0a[@%0a        Ports = 6660, 6661, 6662, 6663, 6664, 6665, 6666, 6667, 6668, 6669, 7000, 16667%0a        ServerGID = _ngircd%0a        ServerUID = _ngircd%0a@]%0a%0aIt's recommended to provide ports besides the standard 6667 to allow users to bypass network firewalls. %0a%0a'''NOTE''': Make sure to set the ServerUID and ServerGID to _ngircd. Otherwise, it runs as the user nobody by default.%0a%0a!!! Limits Block%0a%0a[@%0a[Limits]%0a        MaxConnectionsIP = 0%0a        MaxJoins = 300%0a        MaxNickLength = 16%0a        MaxListSize = 3000%0a        PingTimeout = 300%0a        PongTimeout = 300%0a@]%0a%0aWe allow unlimited connections per IP and handle abuse with other techniques.%0a%0aMaxNickLength: '''must''' be identical for all servers on the network. On IRCNow, MaxNickLength is [@16@].%0a%0a!!! Options Block%0a%0a[@%0a[Options]%0a        AllowRemoteOper = yes%0a        ChrootDir = /var/ngircd%0a	;CloakHost = %25x%0a	CloakHostModeX = %25x%0a	CloakHostSalt = abcdefghijklmnopqrstuvwxyz%0a	DefaultUserModes = ix%0a	DNS = yes%0a	Ident = yes%0a@]%0a%0aWe will turn on AllowRemoteOpers so that GLINEs function properly.%0a%0aWe want to [[Chroot.Intro|chroot]] to /var/ngircd to prevent a security compromise. %0a%0aWe will cloak the host using a unique salt; contact another sysadmin for the exact salt. If not linking to another network, you can leave it commented to use a random salt each time it runs, or you can generate your own random salt.%0a%0aWe use CloakHostModeX so that users are cloaked when mode +x is set. Users can then turn off mode x in order to remove the cloak (to show a custom hostmask). If we had used CloakHost instead, uncloaking a user would not be possible.%0a%0aUser mode +i keeps the user invisible so that /whois does not show all channels a user has joined. This helps reduce stalking and harassment.%0a%0aWe want to perform DNS lookups when a client connects so that we can validate a user's hostmask. We also want to perform IDENT lookups.%0a%0a[@%0a	NoticeBeforeRegistration = yes%0a	OperCanUseMode = yes%0a	OperChanPAutoOp = no %0a	PAM = no%0a	RequireAuthPing = yes%0a	SyslogFacility = daemon%0a@]%0a%0aReceiving a notice before registration can help with debugging with [[netcat/irc|netcat]]. It is also necessary for [[hopm/install|hopm]].%0a%0aOperCanUseMode will allow opers the ability to use mode commands when needed. '''Opers should use this power sparingly''', generally only if the channel owner is unable to moderate his channel.%0a%0aOperChanPAutoOp should be set to no so that opers are not automatically op'd in every channel they join. Opers should not interfere with normal channel operation.%0a%0aSet PAM to no because enabling PAM on OpenBSD causes issues.%0a%0aWe set RequireAuthPing to yes because it may help reduce spam.%0a%0aWe're going to log using syslog (see below) to log events.%0a%0a!!! SSL block%0a%0a[@%0a;[SSL]%0a@]%0a%0a'''This entire block should be commented'''. When you are ready to set up [[ngircd/ssl|SSL/TLS encryption]], un-comment the entire block.%0a%0a'''WARNING''': Do not send passwords or sensitive data over this server until SSL is set up.%0a%0a!!! Operator Block%0a%0aCreate one Operator block for each operator on the server:%0a%0a[@%0a[Operator]%0a        Name = username%0a        Password = password%0a	;Mask = *!ident@somewhere.example.com%0a@]%0a%0aPlease use a [[password/management|long, random string]] for your password.%0a%0aIf you uncomment Mask, your hostmask must match the operator hostmask in order for the /OPER command to work. If the hostmask differs by even a single character, then your /OPER command will be rejected. It's best to leave Mask commented out until you are familiar with ngircd.%0a%0aOnce your configuration is tested and stable, you can uncomment Mask and have it match your [[dns/vhost|vhost]]. However, please be aware that this will make it impossible to become IRC Operator if you connect from a different IP address.%0a%0a!!! Server Block%0a%0a[@%0a;[Server]%0a@]%0a%0aThe server block is used to connect to other servers to form a network. You can have multiple server blocks. For now, leave it commented out until you are ready to [[ngircd/link|link ngircd]].%0a%0aYou are now finished editing ngircd.conf, so we turn to edit other files.%0a%0a!! MOTD file%0a%0aCreate the Message of the Day in /etc/ngircd/ngircd.motd. Here is a suggested template:%0a%0a[@%0aIRCNow - The Users' Network%0a%0aIRCNow is the network of the user, by the user, for the user.%0a%0a * No porn / illegal drugs / threats of violence%0a * No slander / libel / gambling%0a * No spam, illegal cracking, or DDoS%0a * No copyright infrigement%0a%0aYou must agree to our terms of service and our privacy policy %0ato use this network:%0a%0ahttps://wiki.ircnow.org/index.php?n=Terms.Terms%0a%0aOnly 5 connections per IP address. If you need help, please speak with staff on #help.%0a@]%0a%0a!! Configuring [[syslogd/configure|syslog]]%0a%0aAll log messages from ngircd should go to [@ /var/log/ngircd.log @]. Insert these three lines starting at line 3 (at the top) in [@/etc/syslog.conf@]:%0a%0a[@%0a!!ngircd%0a*.*                                                     /var/log/ngircd.log%0a!*%0a@]%0a%0aThis directs all logs from ngircd to go straight to /var/log/ngircd.log.%0a%0aSyslogd expects all logfiles to already exist with the correct permissions. So, we will create the file /var/log/ngircd.log and restart syslogd:%0a%0a[@%0a$ doas touch /var/log/ngircd.log%0a$ doas rcctl restart syslogd%0a@]%0a%0a!! Chroot%0a%0aWe need to set up the [[chroot/intro|chroot]] for ngircd. Let's copy the files into the chroot:%0a%0a[@%0a$ doas mkdir /var/ngircd/etc/%0a$ doas cp /etc/resolv.conf /var/ngircd/etc/%0a$ doas cp -R /etc/ngircd /var/ngircd/etc/%0a$ doas chown -R _ngircd:_ngircd /var/ngircd/%0a$ doas rm -r /etc/ngircd%0a$ doas ln -s /var/ngircd/etc/ngircd /etc/ngircd%0a$ doas mkdir -p /var/ngircd/usr/local/share/doc/%0a$ doas cp -R /usr/local/share/doc/ngircd/ /var/ngircd/usr/local/share/doc/%0a$ doas chown -R _ngircd:_ngircd /var/ngircd/usr/local/share/doc/ngircd/%0a@]%0a%0aThis will create a symlink so that only one set of configuration files needs to be maintained inside and outside of the chroot. Otherwise, ngircd will require two sets of configuration files, one inside and the other outside of the chroot.%0a%0a!! Automation%0a%0aTo automatically restart ngIRCd if it was terminated unexpectedly, create a script in /usr/local/libexec/ngircd/restart.sh:%0a%0a[@%0a$ doas mkdir -p /usr/local/libexec/ngircd/%0a$ doas touch /usr/local/libexec/ngircd/restart.sh%0a$ doas chmod +x /usr/local/libexec/ngircd/restart.sh%0a@]%0a%0aEdit @@/usr/local/libexec/ngircd/restart.sh@@:%0a%0a[@%0a#!/bin/sh%0a%0aSERVICE_NAME="ngircd"%0aSERVICE_USER="_ngircd"%0aSERVICE_PID="/var/ngircd/var/run/ngircd/ngircd.pid"%0a%0aif ! pgrep -u $SERVICE_USER -x "$SERVICE_NAME" > /dev/null%0athen%0a  if [ -f $SERVICE_PID ]; then%0a    rm -f $SERVICE_PID%0a    rcctl -d restart $SERVICE_NAME%0a  fi%0afi%0a@]%0a%0aAdd this as a cronjob:%0a%0a[@%0a$ doas crontab -e%0a%0a*/5       *       *       *       *       /usr/local/libexec/ngircd/restart.sh > /dev/null 2>&1%0a@]%0a%0aFor the solution to work, make sure you have enabled the use of pid files in /etc/ngircd/ngircd.conf:%0a%0a[@%0aPidFile = /var/run/ngircd/ngircd.pid%0a@]%0a%0a!! Starting ngircd%0a%0aTo start ngircd via [[openbsd/rcctl|rcctl]]:%0a%0a[@%0adoas rcctl enable ngircd%0adoas rcctl start ngircd%0a@]%0a%0aNext, use your IRC client to connect to the server. Join a few channels and chat inside. You will need to invite your friends, since a new IRC server will have no other users on it.%0a%0a!! Troubleshooting%0a%0aIf you run into any errors, you can test to see if your configuration file has errors:%0a%0a[@%0a$ doas ngircd -t%0a@]%0a%0aTo run ngircd in debug mode:%0a%0a[@%0a$ doas ngircd -n%0a@]%0a%0aCheck [@ /var/log/ngircd.log @] to see if ngircd is listening on the correct IP addresses and ports. Connect to those ports using your IRC client to verify that the server is working as intended.%0a%0aRemember, if you are connecting using port 6667 without SSL, any eavesdropper can read all your text, including your passwords. '''Don't send any sensitive information until you have upgraded to [[ngircd/ssl|SSL]].'''%0a%0a!! Reloading and Restarting ngIRCd%0a%0aAfter you edit [@ /etc/ngircd/ngircd.conf @] for a running ngircd server, you will need to reload the configuration file:%0a%0a[@%0a$ doas rcctl reload ngircd%0a@]%0a%0aAlternatively, you can run:%0a%0a[@%0a$ doas pkill -HUP ngircd%0a@]%0a%0a'''Reloading''' a configuration file will '''not''' disconnect any active connections. So, try to reload the configuration where possible '''instead of restarting the service'''.%0a%0aTo restart the ircd:%0a%0a[@%0a$ doas rcctl restart ngircd%0a@]%0a%0a'''WARNING''':  '''Restarting''' the ircd '''will''' disconnect all existing connections. So, try to restart ngircd only when absolutely necessary.%0a%0a'''WARNING''': ngircd appears to have a bug where the ircd will crash if you reload the configuration file while a message is being sent. Be careful to avoid reloading configuration files when many users are chatting.%0a%0a!! See Also%0a%0a# Configure [[ngircd/ssl|SSL]] for ngircd to ensure secure connections%0a# [[ngircd/link|Link your ngircd]] with another server to create a network%0a# Install [[anope/install|anope]] to provide services%0a# Configure [[hopm/install|hopm]], an open proxy monitor to stop spammers.%0a# Configure [[acopm/install|acopm]], a minimalist open proxy monitor to stop spammers.%0a
-time=1678040259
+text=(:title Ngircd Install Guide:)%0a%0aIn this guide, we'll setup [[https://ngircd.barton.de/documentation.php.en|ngircd]], a free, portable, lightweight IRC server.%0a%0a!!Overview%0a%0angircd is an [[Irc/Guide|IRC]] server. It helps IRC clients send messages to one another.%0a%0aAdvantages:%0a%0a# The source code is written in modern, portable C.%0a# The code compiles easily on all BSDs, Linux, and other platforms.%0a# The code is easy to fork to add new features such as spam filters%0a# The server has a very simple, easy-to-understand configuration%0a# Documentation is short and easy to understand%0a# The server is a clean implementation which was written from scratch%0a# The lead developer po||ux actively hangs out on the IRC server barton.ngircd.de on #ngircd%0a%0a!! Docs and references%0a%0aBefore installation, please consult:%0a%0a# The [[https://ngircd.barton.de/documentation.php.en|Official ngIRCd documentation]] %0a# After installation, see also /usr/local/share/doc/ngircd/ for local documentation%0a# Consult the man pages:%0a  # @@$ man 5 ngircd.conf@@%0a  # @@$ man 8 ngircd@@%0a%0a!! Installation%0a%0a!!! Installing from OpenBSD packages%0a%0a[@%0a$ doas pkg_add ngircd%0a@]%0a%0aCopy the sample configuration file:%0a%0a[@%0a$ doas cp /usr/local/share/examples/ngircd/sample-ngircd.conf /etc/ngircd/ngircd.conf%0a@]%0a%0angIRCd v26.1 provided by OpenBSD 7.1 ports does not have ident support. On a production server, ident support is essential, so we will need to compile from source (described below). You will want to do this after installing from packages, so that rc.d scripts are created automatically.%0a%0a!!! Building from source%0a%0a'''Note''': Before building from source, make sure you have ngircd package installed using the instructions from above.%0a%0aDownload the IRC server, extract the code, and build it:%0a%0a[@%0a$ ftp https://ircnow.org/software/ircnowd.tgz%0a$ tar xvzf ircnowd.tgz%0a$ cd ircnowd/%0a$ sh build.sh %0a@]%0a%0a!! Configuring ngircd%0a%0aEdit @@/etc/ngircd/ngircd.conf@@ as root:%0a%0a'''Note''': Lines that begin with # or ; are comments and will be ignored. You will need to remove # or ; to uncomment.%0a%0aTypically, ";" precedes a line of code that has been commented, while a "#" precedes an actual note that should not be uncommented.%0a%0a!!! Global Block%0a%0a[@%0a[Global]%0a        Name = irc.example.com%0a        AdminInfo1 = Example Network%0a        AdminInfo2 = Planet Earth%0a        AdminEMail = admin@example.com%0a	HelpFile = /usr/local/share/doc/ngircd/Commands.txt%0a        Info = irc.example.com%0a@]%0a%0a* Name: Use your server's domain name.%0a* Info: Use your server's domain name.%0a%0a[@%0a        Listen = 127.0.0.1,::1,192.168.1.1,2001:db8::%0a@]%0a%0aProvide every single IP address you want ngircd to listen on. This includes localhost (127.0.0.1 and ::1), and [[IP/Myaddress|our public IPv4 and IPv6 addresses]]. Keep 127.0.0.1 and ::1 untouched, but replace 192.168.1.1 and 2001:db8:: with your real public IPs. If you are hosting a public service, avoid listing IPs that are not DDoS-filtered. IRC servers are heavily [[ddos/intro|DDoSed]] and using an unfiltered IP may get you nullrouted.%0a%0a'''Note''': if you do not uncomment this line, you will listen to all IPs by default, which is probably a mistake.%0a%0a[@%0a        MotdFile = /etc/ngircd/ngircd.motd%0a        ;MotdPhrase = "Hello world!"%0a        Network = ExampleNet%0a        ;Password = abc%0a@]%0a%0a* Network: Your network name; this usually contains no periods.%0a%0aKeep the MotdPhrase and Password commented out. First, we will be using a MotdFile instead. Secondly, we do not want a global password for a public server.%0a%0a[@%0a	PidFile = /var/run/ngircd/ngircd.pid%0a@]%0a%0aThe Pid file is where ngircd writes its process ID.%0a%0a[@%0a        Ports = 6660, 6661, 6662, 6663, 6664, 6665, 6666, 6667, 6668, 6669, 7000, 16667%0a        ServerGID = _ngircd%0a        ServerUID = _ngircd%0a@]%0a%0aIt's recommended to provide ports besides the standard 6667 to allow users to bypass network firewalls. %0a%0a'''NOTE''': Make sure to set the ServerUID and ServerGID to _ngircd. Otherwise, it runs as the user nobody by default.%0a%0a!!! Limits Block%0a%0a[@%0a[Limits]%0a        MaxConnectionsIP = 0%0a        MaxJoins = 300%0a        MaxNickLength = 16%0a        MaxListSize = 3000%0a        PingTimeout = 300%0a        PongTimeout = 300%0a@]%0a%0aWe allow unlimited connections per IP and handle abuse with other techniques.%0a%0aMaxNickLength: '''must''' be identical for all servers on the network. On IRCNow, MaxNickLength is [@16@].%0a%0a!!! Options Block%0a%0a[@%0a[Options]%0a        AllowRemoteOper = yes%0a        ChrootDir = /var/ngircd%0a	;CloakHost = %25x%0a	CloakHostModeX = %25x%0a	CloakHostSalt = abcdefghijklmnopqrstuvwxyz%0a	DefaultUserModes = ix%0a	DNS = yes%0a	Ident = yes%0a@]%0a%0aWe will turn on AllowRemoteOpers so that GLINEs function properly.%0a%0aWe want to [[Chroot.Intro|chroot]] to /var/ngircd to prevent a security compromise. %0a%0aWe will cloak the host using a unique salt; contact another sysadmin for the exact salt. If not linking to another network, you can leave it commented to use a random salt each time it runs, or you can generate your own random salt.%0a%0aWe use CloakHostModeX so that users are cloaked when mode +x is set. Users can then turn off mode x in order to remove the cloak (to show a custom hostmask). If we had used CloakHost instead, uncloaking a user would not be possible.%0a%0aUser mode +i keeps the user invisible so that /whois does not show all channels a user has joined. This helps reduce stalking and harassment.%0a%0aWe want to perform DNS lookups when a client connects so that we can validate a user's hostmask. We also want to perform IDENT lookups.%0a%0a[@%0a	NoticeBeforeRegistration = yes%0a	OperCanUseMode = yes%0a	OperChanPAutoOp = no %0a	PAM = no%0a	RequireAuthPing = yes%0a	SyslogFacility = daemon%0a@]%0a%0aReceiving a notice before registration can help with debugging with [[netcat/irc|netcat]]. It is also necessary for [[hopm/install|hopm]].%0a%0aOperCanUseMode will allow opers the ability to use mode commands when needed. '''Opers should use this power sparingly''', generally only if the channel owner is unable to moderate his channel.%0a%0aOperChanPAutoOp should be set to no so that opers are not automatically op'd in every channel they join. Opers should not interfere with normal channel operation.%0a%0aSet PAM to no because enabling PAM on OpenBSD causes issues.%0a%0aWe set RequireAuthPing to yes because it may help reduce spam.%0a%0aWe're going to log using syslog (see below) to log events.%0a%0a!!! SSL block%0a%0a[@%0a;[SSL]%0a@]%0a%0a'''This entire block should be commented'''. When you are ready to set up [[ngircd/ssl|SSL/TLS encryption]], un-comment the entire block.%0a%0a'''WARNING''': Do not send passwords or sensitive data over this server until SSL is set up.%0a%0a!!! Operator Block%0a%0aCreate one Operator block for each operator on the server:%0a%0a[@%0a[Operator]%0a        Name = username%0a        Password = password%0a	;Mask = *!ident@somewhere.example.com%0a@]%0a%0aPlease use a [[password/management|long, random string]] for your password.%0a%0aIf you uncomment Mask, your hostmask must match the operator hostmask in order for the /OPER command to work. If the hostmask differs by even a single character, then your /OPER command will be rejected. It's best to leave Mask commented out until you are familiar with ngircd.%0a%0aOnce your configuration is tested and stable, you can uncomment Mask and have it match your [[dns/vhost|vhost]]. However, please be aware that this will make it impossible to become IRC Operator if you connect from a different IP address.%0a%0a!!! Server Block%0a%0a[@%0a;[Server]%0a@]%0a%0aThe server block is used to connect to other servers to form a network. You can have multiple server blocks. For now, leave it commented out until you are ready to [[ngircd/link|link ngircd]].%0a%0aYou are now finished editing ngircd.conf, so we turn to edit other files.%0a%0a!! MOTD file%0a%0aCreate the Message of the Day in /etc/ngircd/ngircd.motd. Here is a suggested template:%0a%0a[@%0aIRCNow - The Users' Network%0a%0aIRCNow is the network of the user, by the user, for the user.%0a%0a * No porn / illegal drugs / threats of violence%0a * No slander / libel / gambling%0a * No spam, illegal cracking, or DDoS%0a * No copyright infrigement%0a%0aYou must agree to our terms of service and our privacy policy %0ato use this network:%0a%0ahttps://wiki.ircnow.org/index.php?n=Terms.Terms%0a%0aOnly 5 connections per IP address. If you need help, please speak with staff on #help.%0a@]%0a%0a!! Configuring [[syslogd/configure|syslog]]%0a%0aAll log messages from ngircd should go to [@ /var/log/ngircd.log @]. Insert these three lines starting at line 3 (at the top) in [@/etc/syslog.conf@]:%0a%0a[@%0a!!ngircd%0a*.*                                                     /var/log/ngircd.log%0a!*%0a@]%0a%0aThis directs all logs from ngircd to go straight to /var/log/ngircd.log.%0a%0aSyslogd expects all logfiles to already exist with the correct permissions. So, we will create the file /var/log/ngircd.log and restart syslogd:%0a%0a[@%0a$ doas touch /var/log/ngircd.log%0a$ doas rcctl restart syslogd%0a@]%0a%0a!! Chroot%0a%0aWe need to set up the [[chroot/intro|chroot]] for ngircd. Let's copy the files into the chroot:%0a%0a[@%0a$ doas mkdir /var/ngircd/etc/%0a$ doas cp /etc/resolv.conf /var/ngircd/etc/%0a$ doas cp -R /etc/ngircd /var/ngircd/etc/%0a$ doas chown -R _ngircd:_ngircd /var/ngircd/%0a$ doas rm -r /etc/ngircd%0a$ doas ln -s /var/ngircd/etc/ngircd /etc/ngircd%0a$ doas mkdir -p /var/ngircd/usr/local/share/doc/%0a$ doas cp -R /usr/local/share/doc/ngircd/ /var/ngircd/usr/local/share/doc/%0a$ doas chown -R _ngircd:_ngircd /var/ngircd/usr/local/share/doc/ngircd/%0a@]%0a%0aThis will create a symlink so that only one set of configuration files needs to be maintained inside and outside of the chroot. Otherwise, ngircd will require two sets of configuration files, one inside and the other outside of the chroot.%0a%0a!! Automation%0a%0aTo automatically restart ngIRCd if it was terminated unexpectedly, create a script in /usr/local/libexec/ngircd/restart.sh:%0a%0a[@%0a$ doas mkdir -p /usr/local/libexec/ngircd/%0a$ doas touch /usr/local/libexec/ngircd/restart.sh%0a$ doas chmod +x /usr/local/libexec/ngircd/restart.sh%0a@]%0a%0aEdit @@/usr/local/libexec/ngircd/restart.sh@@:%0a%0a[@%0a#!/bin/sh%0a%0aSERVICE_NAME="ngircd"%0aSERVICE_USER="_ngircd"%0aSERVICE_PID="/var/ngircd/var/run/ngircd/ngircd.pid"%0a%0aif ! pgrep -u $SERVICE_USER -x "$SERVICE_NAME" > /dev/null%0athen%0a  if [ -f $SERVICE_PID ]; then%0a    rm -f $SERVICE_PID%0a    rcctl -d restart $SERVICE_NAME%0a  fi%0afi%0a@]%0a%0aAdd this as a cronjob:%0a%0a[@%0a$ doas crontab -e%0a%0a*/5       *       *       *       *       /usr/local/libexec/ngircd/restart.sh > /dev/null 2>&1%0a@]%0a%0aFor the solution to work, make sure you have enabled the use of pid files in /etc/ngircd/ngircd.conf:%0a%0a[@%0aPidFile = /var/run/ngircd/ngircd.pid%0a@]%0a%0a!! Starting ngircd%0a%0aTo start ngircd via [[openbsd/rcctl|rcctl]]:%0a%0a[@%0a$ doas rcctl enable ngircd%0a$ doas rcctl start ngircd%0a@]%0a%0aNext, use your IRC client to connect to the server. Join a few channels and chat inside. You will need to invite your friends, since a new IRC server will have no other users on it.%0a%0a!! Troubleshooting%0a%0aIf you run into any errors, you can test to see if your configuration file has errors:%0a%0a[@%0a$ doas ngircd -t%0a@]%0a%0aTo run ngircd in debug mode:%0a%0a[@%0a$ doas ngircd -n%0a@]%0a%0aCheck [@ /var/log/ngircd.log @] to see if ngircd is listening on the correct IP addresses and ports. Connect to those ports using your IRC client to verify that the server is working as intended.%0a%0aRemember, if you are connecting using port 6667 without SSL, any eavesdropper can read all your text, including your passwords. '''Don't send any sensitive information until you have upgraded to [[ngircd/ssl|SSL]].'''%0a%0a!! Reloading and Restarting ngIRCd%0a%0aAfter you edit [@ /etc/ngircd/ngircd.conf @] for a running ngircd server, you will need to reload the configuration file:%0a%0a[@%0a$ doas rcctl reload ngircd%0a@]%0a%0aAlternatively, you can run:%0a%0a[@%0a$ doas pkill -HUP ngircd%0a@]%0a%0a'''Reloading''' a configuration file will '''not''' disconnect any active connections. So, try to reload the configuration where possible '''instead of restarting the service'''.%0a%0aTo restart the ircd:%0a%0a[@%0a$ doas rcctl restart ngircd%0a@]%0a%0a'''WARNING''':  '''Restarting''' the ircd '''will''' disconnect all existing connections. So, try to restart ngircd only when absolutely necessary.%0a%0a'''WARNING''': ngircd appears to have a bug where the ircd will crash if you reload the configuration file while a message is being sent. Be careful to avoid reloading configuration files when many users are chatting.%0a%0a!! See Also%0a%0a# Configure [[ngircd/ssl|SSL]] for ngircd to ensure secure connections%0a# [[ngircd/link|Link your ngircd]] with another server to create a network%0a# Install [[anope/install|anope]] to provide services%0a# Configure [[hopm/install|hopm]], an open proxy monitor to stop spammers.%0a# Configure [[acopm/install|acopm]], a minimalist open proxy monitor to stop spammers.%0a
+time=1678122185
 title=Ngircd Install Guide
+author:1678122185=mkf
+diff:1678122185:1678122055:=
+host:1678122185=2.178.200.45
+author:1678122055=mkf
+diff:1678122055:1678040259:=322,323c322,323%0a%3c $ doas rcctl enable ngircd%0a%3c $ doas rcctl start ngircd%0a---%0a> doas rcctl enable ngircd%0a> doas rcctl start ngircd%0a
+host:1678122055=2.178.200.45
 author:1678040259=mkf
 diff:1678040259:1678040136:=181c181%0a%3c [@%0a---%0a> [@ %0a
 host:1678040259=198.251.81.133
blob - e0801330ca7799d1ae8dfb672128028c53413c04
blob + 10a85d60e752bfe6697793a2ea9a7abfed4ae1d5
--- wiki.d/Openbsd.RecentChanges
+++ wiki.d/Openbsd.RecentChanges
@@ -1,9 +1,9 @@
 version=pmwiki-2.3.20 ordered=1 urlencoded=1
-agent=Mozilla/5.0 (X11; OpenBSD amd64; rv:102.0) Gecko/20100101 Firefox/102.0
+agent=NetSurf/3.11 (Plan9)
 charset=UTF-8
 ctime=1596189997
-host=198.251.81.133
+host=2.178.200.45
 name=Openbsd.RecentChanges
-rev=1935
-text=* [[Openbsd/Ngircd]]  . . . @2023-03-05T18:17:39Z by [[~mkf]]: [==]%0a* [[Openbsd/OpenTracker]]  . . . March 03, 2023, at 04:37 PM by [[~baytuch]]: [==]%0a* [[Openbsd/Gotweb]]  . . . February 26, 2023, at 05:04 PM by [[~fossdev]]: [==]%0a* [[Openbsd/Plermoa]]  . . . February 16, 2023, at 04:52 AM by [[~Yonle]]: [=Redirect=]%0a* [[Openbsd/Pleroma]]  . . . February 12, 2023, at 02:49 AM by [[~Yonle]]: [=Oops=]%0a* [[Openbsd/Akkoma]]  . . . February 12, 2023, at 02:48 AM by [[~Yonle]]: [=Oof=]%0a* [[Openbsd/Mlmmj]]  . . . February 08, 2023, at 02:50 AM by [[~Yonle]]: [==]%0a* [[Openbsd/Mosh]]  . . . February 07, 2023, at 11:30 AM by [[~Yonle]]: [==]%0a* [[Openbsd/Passwords]]  . . . February 03, 2023, at 07:49 PM by [[~izzyb]]: [==]%0a* [[Openbsd/Biboumi]]  . . . January 20, 2023, at 08:11 PM by [[~mkf]]: [==]%0a* [[Openbsd/Unrealircd]]  . . . January 20, 2023, at 07:27 PM by [[~mkf]]: [==]%0a* [[Openbsd/Vipw]]  . . . January 18, 2023, at 11:01 PM by [[~zen]]: [=added two spaces=]%0a* [[Openbsd/Loginconf]]  . . . January 18, 2023, at 10:48 PM by [[~zen]]: [=OpenBSD FAQ link refenrece=]%0a* [[Openbsd/Singleuser]]  . . . January 18, 2023, at 10:26 PM by [[~zen]]: [=changed the link reference=]%0a* [[Openbsd/Dump]]  . . . January 10, 2023, at 04:48 PM by [[~mkf]]: [=add -u, improve dump-ssh funcationality.=]%0a* [[Openbsd/Quota]]  . . . December 29, 2022, at 06:51 PM by [[~mkf]]: [==]%0a* [[Openbsd/Minetest]]  . . . December 26, 2022, at 07:23 PM by [[~miniontoby]]: [=Added more ways to install=]%0a* [[Openbsd/Honk]]  . . . December 17, 2022, at 08:45 AM by [[~Yonle]]: [==]%0a* [[Openbsd/Icecast]]  . . . November 17, 2022, at 11:35 AM by [[~Yonle]]: [==]%0a* [[Openbsd/Geomyidae]]  . . . September 10, 2022, at 02:31 AM by [[~akoizumi]]: [==]%0a* [[Openbsd/INN]]  . . . September 10, 2022, at 02:23 AM by [[~akoizumi]]: [=Fix some types=]%0a* [[Openbsd/VsFTP]]  . . . August 10, 2022, at 03:18 PM by [[~mkf]]: [=snipped unneeded output=]%0a* [[Openbsd/Apmd]]  . . . July 03, 2022, at 11:36 AM by [[~mkf]]: [==]%0a* [[Openbsd/Pkg]]  . . . June 12, 2022, at 12:32 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Intro]]  . . . June 09, 2022, at 07:53 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Bsdrd]]  . . . June 09, 2022, at 07:17 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Sysupgrade71]]  . . . June 05, 2022, at 11:49 PM by [[~jrmu]]: [==]%0a* [[Openbsd/Growfs]]  . . . June 01, 2022, at 12:34 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Nsd]]  . . . May 10, 2022, at 12:33 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Ports]]  . . . May 09, 2022, at 05:54 AM by [[~mkf]]: [==]%0a* [[Openbsd/Rcctl]]  . . . May 09, 2022, at 05:53 AM by [[~mkf]]: [==]%0a* [[Openbsd/Upgrade71]]  . . . May 03, 2022, at 06:36 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Install71]]  . . . April 24, 2022, at 09:55 PM by [[~jrmu]]: [==]%0a* [[Openbsd/Botnow]]  . . . April 24, 2022, at 06:14 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Gopher]]  . . . April 20, 2022, at 08:29 PM by [[~jrmu]]: [==]%0a* [[Openbsd/Adduser]]  . . . April 20, 2022, at 08:07 PM by [[~jrmu]]: [==]%0a* [[Openbsd/Ntpd]]  . . . April 20, 2022, at 06:16 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Vmmlinux]]  . . . April 20, 2022, at 05:33 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Iked]]  . . . April 20, 2022, at 05:16 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Team]]  . . . April 20, 2022, at 04:54 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Announce]]  . . . April 19, 2022, at 04:14 PM by [[~jrmu]]: [==]%0a* [[Openbsd/Install70]]  . . . April 19, 2022, at 06:52 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Upgrade70]]  . . . April 19, 2022, at 06:49 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Censord]]  . . . April 05, 2022, at 06:16 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Hopm]]  . . . April 05, 2022, at 06:09 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Dns]]  . . . April 05, 2022, at 05:24 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Psybnc]]  . . . March 30, 2022, at 09:56 PM by [[~jrmu]]: [==]%0a* [[Openbsd/Ddos]]  . . . March 24, 2022, at 04:22 PM by [[~jrmu]]: [==]%0a* [[Openbsd/IRCBridge]]  . . . February 28, 2022, at 02:59 AM by [[~suzerain]]: [==]%0a* [[Openbsd/Wesnothd]]  . . . February 21, 2022, at 06:28 AM by [[~mkf]]: [=Wesnothd=]%0a* [[Openbsd/Xonotic]]  . . . February 20, 2022, at 07:43 AM by [[~mkf]]: [=A xonotic server has apperad! pt.2=]%0a* [[Openbsd/Police]]  . . . February 10, 2022, at 07:36 PM by [[~jrmu]]: [==]%0a* [[Openbsd/Tcpip]]  . . . January 24, 2022, at 05:45 PM by [[~jrmu]]: [==]%0a* [[Openbsd/U9fs]]  . . . January 16, 2022, at 06:23 PM by [[~mkf]]: [==]%0a* [[Openbsd/Locale]]  . . . January 12, 2022, at 01:23 PM by [[~baytuch]]: [==]%0a* [[Openbsd/Openbsd]]  . . . January 12, 2022, at 01:19 PM by [[~baytuch]]: [==]%0a* [[Openbsd/BBB]]  . . . January 03, 2022, at 12:06 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Sftp]]  . . . December 30, 2021, at 06:01 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Uim]]  . . . December 26, 2021, at 01:45 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Wifi]]  . . . December 22, 2021, at 02:59 PM by [[~jrmu]]: [==]%0a* [[Openbsd/Recordaudio]]  . . . December 22, 2021, at 01:24 PM by [[~jrmu]]: [==]%0a* [[Openbsd/Training]]  . . . November 16, 2021, at 03:30 PM by [[~Hawk]]: [==]%0a* [[Openbsd/Got]]  . . . November 07, 2021, at 03:16 PM by [[~jrmu]]: [==]%0a* [[Openbsd/Drawtermssh]]  . . . November 04, 2021, at 03:54 PM by [[~meeekeeef]]: [=ssh bad >:[=]%0a* [[Openbsd/Sysupgrade70]]  . . . October 15, 2021, at 11:02 AM by [[~mkf]]: [=humans are easily confused.=]%0a* [[Openbsd/Ilines]]  . . . October 15, 2021, at 02:36 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Pmwiki]]  . . . October 14, 2021, at 02:14 PM by [[~miniontoby]]: [=added credits =]%0a* [[Openbsd/Install69]]  . . . September 27, 2021, at 05:59 PM by [[~jrmu]]: [==]%0a* [[Openbsd/PFStable]]  . . . September 24, 2021, at 03:28 PM by [[~miniontoby]]: [==]%0a* [[Openbsd/Mailopenproxy]]  . . . August 25, 2021, at 08:19 PM by [[~mkf]]: [==]%0a* [[Openbsd/Two-FactorAuth]]  . . . August 23, 2021, at 07:39 PM by [[~mkf]]: [=login.db compiling is no longer recommended.=]%0a* [[Openbsd/Npppd]]  . . . August 21, 2021, at 01:43 PM by [[~mkf]]: [==]%0a* [[Openbsd/FilePermissions]]  . . . August 20, 2021, at 02:20 AM by [[~Nate S]]: [==]%0a* [[Openbsd/Gophernicus]]  . . . August 15, 2021, at 02:06 AM by [[~mkf]]: [==]%0a* [[Openbsd/Openhttpd]]  . . . August 13, 2021, at 07:29 AM by [[~jrmu]]: [==]%0a* [[Openbsd/ZNCModules]]  . . . August 11, 2021, at 03:06 PM by [[~wiz]]: [==]%0a* [[Openbsd/Bitlbee]]  . . . August 10, 2021, at 12:03 PM by [[~mkf]]: [==]%0a* [[Openbsd/Pppoe]]  . . . August 10, 2021, at 11:56 AM by [[~mkf]]: [==]%0a* [[Openbsd/Sshkeys]]  . . . August 09, 2021, at 04:42 PM by [[~jrmu]]: [==]%0a* [[Openbsd/Squirrelmail]]  . . . August 06, 2021, at 10:32 AM by [[~baytuch]]: [==]%0a* [[Openbsd/Dnszones]]  . . . August 03, 2021, at 09:26 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Matterbridge]]  . . . August 02, 2021, at 12:33 PM by [[~mkf]]: [==]%0a* [[Openbsd/Vhost]]  . . . August 02, 2021, at 02:32 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Chroot]]  . . . July 31, 2021, at 02:47 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Vmmuser]]  . . . July 29, 2021, at 05:31 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Vmminstall]]  . . . July 29, 2021, at 05:28 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Vmm]]  . . . July 29, 2021, at 05:24 AM by [[~jrmu]]: [==]%0a* [[Openbsd/ZNCAdmin]]  . . . July 28, 2021, at 06:14 AM by [[~jrmu]]: [==]%0a* [[Openbsd/ZNCSupport]]  . . . July 28, 2021, at 06:14 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Php]]  . . . July 27, 2021, at 02:53 PM by [[~jrmu]]: [==]%0a* [[Openbsd/Dig]]  . . . July 25, 2021, at 06:50 AM by [[~jrmu]]: [==]%0a* [[Openbsd/RDNS]]  . . . July 23, 2021, at 06:44 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Sic]]  . . . July 21, 2021, at 05:57 PM by [[~mkf]]: [=first edit.=]%0a* [[Openbsd/Openrsync]]  . . . July 18, 2021, at 02:01 PM by [[~jrmu]]: [==]%0a* [[Openbsd/Znc]]  . . . July 16, 2021, at 10:43 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Staticnet]]  . . . July 12, 2021, at 05:48 PM by [[~jrmu]]: [==]%0a* [[Openbsd/Dovecot]]  . . . July 12, 2021, at 02:58 PM by [[~jrmu]]: [==]%0a* [[Openbsd/Relayd]]  . . . July 12, 2021, at 02:45 PM by [[~jrmu]]: [==]%0a* [[Openbsd/Spf]]  . . . July 12, 2021, at 03:08 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Eggdrop]]  . . . July 02, 2021, at 03:20 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Newdisk]]  . . . June 29, 2021, at 03:23 PM by [[~jrmu]]: [==]%0a* [[Openbsd/Ed]]  . . . June 28, 2021, at 04:04 PM by [[~mkf]]: [==]%0a* [[Openbsd/Unbound]]  . . . June 27, 2021, at 12:12 PM by [[~jrmu]]: [==]%0a* [[Openbsd/Dkimproxy]]  . . . June 25, 2021, at 12:56 PM by [[~jrmu]]: [==]%0a* [[Openbsd/Sysupgrade69]]  . . . June 25, 2021, at 05:46 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Opensmtpd]]  . . . June 23, 2021, at 02:21 AM by [[~jrmu]]: [==]%0a* [[Openbsd/NgircdLink]]  . . . June 22, 2021, at 07:50 PM by [[~mkf]]: [=delete=]%0a* [[Openbsd/Doas]]  . . . June 13, 2021, at 01:19 PM by [[~jrmu]]: [==]%0a* [[Openbsd/Shell]]  . . . June 11, 2021, at 09:36 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Books]]  . . . June 06, 2021, at 12:46 PM by [[~jrmu]]: [==]%0a* [[Openbsd/Pfa]]  . . . June 06, 2021, at 03:49 AM by [[~navic]]: [==]%0a* [[Openbsd/Wordpress]]  . . . June 04, 2021, at 04:55 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Anope]]  . . . May 31, 2021, at 10:24 AM by [[~miniontoby]]: [=cp=]%0a* [[Openbsd/ACKFlood]]  . . . May 29, 2021, at 06:20 AM by [[~mkf]]: [==]%0a* [[Openbsd/SSDP]]  . . . May 29, 2021, at 06:18 AM by [[~mkf]]: [==]%0a* [[Openbsd/Anycast]]  . . . May 29, 2021, at 06:01 AM by [[~mkf]]: [==]%0a* [[Openbsd/Dmarc]]  . . . May 21, 2021, at 09:22 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Disklabel]]  . . . May 17, 2021, at 03:33 AM by [[~bejelentkezni]]: [==]%0a* [[Openbsd/Fdisk]]  . . . May 17, 2021, at 03:27 AM by [[~bejelentkezni]]: [==]%0a* [[Openbsd/Security]]  . . . May 14, 2021, at 03:14 AM by [[~caesar]]: [==]%0a* [[Openbsd/Hopm-Arthur]]  . . . May 07, 2021, at 12:28 PM by [[~Arthur]]: [==]%0a* [[Openbsd/Syspatch]]  . . . February 14, 2021, at 11:00 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Netadmin]]  . . . February 14, 2021, at 10:56 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Leafnode]]  . . . February 12, 2021, at 01:40 PM by [[~chewy]]: [==]%0a* [[Openbsd/Pylink]]  . . . February 08, 2021, at 08:33 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Stable]]  . . . February 02, 2021, at 02:25 PM by [[~jrmu]]: [==]%0a* [[Openbsd/Base64]]  . . . February 02, 2021, at 06:37 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Unboundadblock]]  . . . February 02, 2021, at 04:29 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Pfbadhost]]  . . . February 02, 2021, at 04:29 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Wraith]]  . . . February 02, 2021, at 04:22 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Delphinusdnsd]]  . . . February 02, 2021, at 01:51 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Abuse]]  . . . January 31, 2021, at 05:33 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Phishing]]  . . . January 31, 2021, at 05:02 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Audit]]  . . . January 31, 2021, at 04:46 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Ongoing]]  . . . January 31, 2021, at 01:19 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Httpopenproxy]]  . . . January 29, 2021, at 11:01 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Zncadmin]]  . . . January 29, 2021, at 10:00 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Rbldns]]  . . . January 29, 2021, at 05:45 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Setuid]]  . . . January 28, 2021, at 06:53 AM by [[~jrmu]]: [==]%0a* [[Openbsd/PFTesting]]  . . . January 25, 2021, at 03:28 PM by [[~jrmu]]: [==]%0a* [[Openbsd/ZNCDaily]]  . . . January 25, 2021, at 11:35 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Irssi]]  . . . January 25, 2021, at 07:08 AM by [[~jrmu]]: [==]%0a* [[Openbsd/XTerm]]  . . . January 17, 2021, at 01:48 PM by [[~miniontoby]]: [=copyright=]%0a* [[Openbsd/Slrn]]  . . . January 12, 2021, at 02:40 PM by [[~Noxturnix]]: [==]%0a* [[Openbsd/Netcat]]  . . . January 09, 2021, at 02:20 PM by [[~jrmu]]: [==]%0a* [[Openbsd/Perl]]  . . . January 09, 2021, at 01:52 PM by [[~jrmu]]: [==]%0a* [[Openbsd/Backup]]  . . . January 03, 2021, at 01:46 PM by [[~jrmu]]: [==]%0a* [[Openbsd/Backups]]  . . . January 02, 2021, at 11:44 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Sshbackdoor]]  . . . December 30, 2020, at 12:14 PM by [[~jrmu]]: [==]%0a* [[Openbsd/Pf-bnc]]  . . . December 29, 2020, at 06:30 PM by [[~jrmu]]: [==]%0a* [[Openbsd/Tcltls]]  . . . December 29, 2020, at 09:53 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Amplification]]  . . . December 19, 2020, at 05:42 AM by [[~jrmu]]: [==]%0a* [[Openbsd/UDPFlood]]  . . . December 18, 2020, at 10:39 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Tcpdump]]  . . . December 18, 2020, at 09:12 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Tcpackflood]]  . . . December 17, 2020, at 10:36 AM by [[~jrmu]]: [==]%0a* [[Openbsd/RSTFlood]]  . . . December 17, 2020, at 10:34 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Tcpresetflood]]  . . . December 17, 2020, at 10:34 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Ssdp]]  . . . December 15, 2020, at 12:59 PM by [[~jrmu]]: [==]%0a* [[Openbsd/Pf]]  . . . December 13, 2020, at 12:03 PM by [[~jrmu]]: [==]%0a* [[Openbsd/Upgrade68]]  . . . December 13, 2020, at 11:12 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Install68]]  . . . December 13, 2020, at 10:13 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Upgrade67]]  . . . December 13, 2020, at 04:02 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Sysupgrade68]]  . . . December 11, 2020, at 10:27 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Dokuwiki]]  . . . December 10, 2020, at 02:23 PM by [[~miniontoby]]: [=code blocks fixed=]%0a* [[Openbsd/Acme-client]]  . . . December 09, 2020, at 06:47 PM by [[~miniontoby]]: [=fixed troubleshooting links=]%0a* [[Openbsd/Install67]]  . . . December 06, 2020, at 11:03 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Buyvm]]  . . . December 06, 2020, at 02:42 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Install]]  . . . December 04, 2020, at 04:15 PM by [[~jrmu]]: [==]%0a* [[Openbsd/Oidentd]]  . . . November 30, 2020, at 11:42 PM by [[~jrmu]]: [==]%0a* [[Openbsd/Checklist]]  . . . November 20, 2020, at 12:44 AM by [[~gry]]: [=+=]%0a* [[Openbsd/Acopm]]  . . . November 04, 2020, at 03:32 PM by [[~jrmu]]: [==]%0a* [[Openbsd/Achurch]]  . . . November 04, 2020, at 02:25 PM by [[~jrmu]]: [==]%0a* [[Openbsd/Vi]]  . . . November 04, 2020, at 12:51 PM by [[~jrmu]]: [==]%0a* [[Openbsd/Sudo]]  . . . November 04, 2020, at 12:38 PM by [[~jrmu]]: [==]%0a* [[Openbsd/Easyapp]]  . . . September 29, 2020, at 12:13 PM by [[~jrmu]]: [==]%0a* [[Openbsd/Cgit]]  . . . September 01, 2020, at 05:51 PM by [[~baytuch]]: [==]%0a* [[Openbsd/Bchs]]  . . . August 20, 2020, at 07:11 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Fdm]]  . . . August 18, 2020, at 10:06 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Opensmtpd-2]]  . . . August 18, 2020, at 09:59 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Opensmtpd-relay]]  . . . August 18, 2020, at 09:56 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Identd]]  . . . August 18, 2020, at 09:39 AM by [[~jrmu]]: [==]%0a* [[Openbsd/IPv6]]  . . . August 12, 2020, at 02:21 PM by [[~jrmu]]: [==]%0a* [[Openbsd/Oscommerce]]  . . . August 12, 2020, at 10:00 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Ping]]  . . . August 12, 2020, at 08:34 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Sockets]]  . . . August 12, 2020, at 07:16 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Guides]]  . . . August 10, 2020, at 03:42 AM by [[~jrmu]]: [==]%0a
-time=1678040259
+rev=1937
+text=* [[Openbsd/Ngircd]]  . . . @2023-03-06T17:03:05Z by [[~mkf]]: [==]%0a* [[Openbsd/OpenTracker]]  . . . March 03, 2023, at 04:37 PM by [[~baytuch]]: [==]%0a* [[Openbsd/Gotweb]]  . . . February 26, 2023, at 05:04 PM by [[~fossdev]]: [==]%0a* [[Openbsd/Plermoa]]  . . . February 16, 2023, at 04:52 AM by [[~Yonle]]: [=Redirect=]%0a* [[Openbsd/Pleroma]]  . . . February 12, 2023, at 02:49 AM by [[~Yonle]]: [=Oops=]%0a* [[Openbsd/Akkoma]]  . . . February 12, 2023, at 02:48 AM by [[~Yonle]]: [=Oof=]%0a* [[Openbsd/Mlmmj]]  . . . February 08, 2023, at 02:50 AM by [[~Yonle]]: [==]%0a* [[Openbsd/Mosh]]  . . . February 07, 2023, at 11:30 AM by [[~Yonle]]: [==]%0a* [[Openbsd/Passwords]]  . . . February 03, 2023, at 07:49 PM by [[~izzyb]]: [==]%0a* [[Openbsd/Biboumi]]  . . . January 20, 2023, at 08:11 PM by [[~mkf]]: [==]%0a* [[Openbsd/Unrealircd]]  . . . January 20, 2023, at 07:27 PM by [[~mkf]]: [==]%0a* [[Openbsd/Vipw]]  . . . January 18, 2023, at 11:01 PM by [[~zen]]: [=added two spaces=]%0a* [[Openbsd/Loginconf]]  . . . January 18, 2023, at 10:48 PM by [[~zen]]: [=OpenBSD FAQ link refenrece=]%0a* [[Openbsd/Singleuser]]  . . . January 18, 2023, at 10:26 PM by [[~zen]]: [=changed the link reference=]%0a* [[Openbsd/Dump]]  . . . January 10, 2023, at 04:48 PM by [[~mkf]]: [=add -u, improve dump-ssh funcationality.=]%0a* [[Openbsd/Quota]]  . . . December 29, 2022, at 06:51 PM by [[~mkf]]: [==]%0a* [[Openbsd/Minetest]]  . . . December 26, 2022, at 07:23 PM by [[~miniontoby]]: [=Added more ways to install=]%0a* [[Openbsd/Honk]]  . . . December 17, 2022, at 08:45 AM by [[~Yonle]]: [==]%0a* [[Openbsd/Icecast]]  . . . November 17, 2022, at 11:35 AM by [[~Yonle]]: [==]%0a* [[Openbsd/Geomyidae]]  . . . September 10, 2022, at 02:31 AM by [[~akoizumi]]: [==]%0a* [[Openbsd/INN]]  . . . September 10, 2022, at 02:23 AM by [[~akoizumi]]: [=Fix some types=]%0a* [[Openbsd/VsFTP]]  . . . August 10, 2022, at 03:18 PM by [[~mkf]]: [=snipped unneeded output=]%0a* [[Openbsd/Apmd]]  . . . July 03, 2022, at 11:36 AM by [[~mkf]]: [==]%0a* [[Openbsd/Pkg]]  . . . June 12, 2022, at 12:32 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Intro]]  . . . June 09, 2022, at 07:53 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Bsdrd]]  . . . June 09, 2022, at 07:17 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Sysupgrade71]]  . . . June 05, 2022, at 11:49 PM by [[~jrmu]]: [==]%0a* [[Openbsd/Growfs]]  . . . June 01, 2022, at 12:34 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Nsd]]  . . . May 10, 2022, at 12:33 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Ports]]  . . . May 09, 2022, at 05:54 AM by [[~mkf]]: [==]%0a* [[Openbsd/Rcctl]]  . . . May 09, 2022, at 05:53 AM by [[~mkf]]: [==]%0a* [[Openbsd/Upgrade71]]  . . . May 03, 2022, at 06:36 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Install71]]  . . . April 24, 2022, at 09:55 PM by [[~jrmu]]: [==]%0a* [[Openbsd/Botnow]]  . . . April 24, 2022, at 06:14 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Gopher]]  . . . April 20, 2022, at 08:29 PM by [[~jrmu]]: [==]%0a* [[Openbsd/Adduser]]  . . . April 20, 2022, at 08:07 PM by [[~jrmu]]: [==]%0a* [[Openbsd/Ntpd]]  . . . April 20, 2022, at 06:16 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Vmmlinux]]  . . . April 20, 2022, at 05:33 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Iked]]  . . . April 20, 2022, at 05:16 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Team]]  . . . April 20, 2022, at 04:54 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Announce]]  . . . April 19, 2022, at 04:14 PM by [[~jrmu]]: [==]%0a* [[Openbsd/Install70]]  . . . April 19, 2022, at 06:52 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Upgrade70]]  . . . April 19, 2022, at 06:49 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Censord]]  . . . April 05, 2022, at 06:16 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Hopm]]  . . . April 05, 2022, at 06:09 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Dns]]  . . . April 05, 2022, at 05:24 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Psybnc]]  . . . March 30, 2022, at 09:56 PM by [[~jrmu]]: [==]%0a* [[Openbsd/Ddos]]  . . . March 24, 2022, at 04:22 PM by [[~jrmu]]: [==]%0a* [[Openbsd/IRCBridge]]  . . . February 28, 2022, at 02:59 AM by [[~suzerain]]: [==]%0a* [[Openbsd/Wesnothd]]  . . . February 21, 2022, at 06:28 AM by [[~mkf]]: [=Wesnothd=]%0a* [[Openbsd/Xonotic]]  . . . February 20, 2022, at 07:43 AM by [[~mkf]]: [=A xonotic server has apperad! pt.2=]%0a* [[Openbsd/Police]]  . . . February 10, 2022, at 07:36 PM by [[~jrmu]]: [==]%0a* [[Openbsd/Tcpip]]  . . . January 24, 2022, at 05:45 PM by [[~jrmu]]: [==]%0a* [[Openbsd/U9fs]]  . . . January 16, 2022, at 06:23 PM by [[~mkf]]: [==]%0a* [[Openbsd/Locale]]  . . . January 12, 2022, at 01:23 PM by [[~baytuch]]: [==]%0a* [[Openbsd/Openbsd]]  . . . January 12, 2022, at 01:19 PM by [[~baytuch]]: [==]%0a* [[Openbsd/BBB]]  . . . January 03, 2022, at 12:06 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Sftp]]  . . . December 30, 2021, at 06:01 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Uim]]  . . . December 26, 2021, at 01:45 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Wifi]]  . . . December 22, 2021, at 02:59 PM by [[~jrmu]]: [==]%0a* [[Openbsd/Recordaudio]]  . . . December 22, 2021, at 01:24 PM by [[~jrmu]]: [==]%0a* [[Openbsd/Training]]  . . . November 16, 2021, at 03:30 PM by [[~Hawk]]: [==]%0a* [[Openbsd/Got]]  . . . November 07, 2021, at 03:16 PM by [[~jrmu]]: [==]%0a* [[Openbsd/Drawtermssh]]  . . . November 04, 2021, at 03:54 PM by [[~meeekeeef]]: [=ssh bad >:[=]%0a* [[Openbsd/Sysupgrade70]]  . . . October 15, 2021, at 11:02 AM by [[~mkf]]: [=humans are easily confused.=]%0a* [[Openbsd/Ilines]]  . . . October 15, 2021, at 02:36 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Pmwiki]]  . . . October 14, 2021, at 02:14 PM by [[~miniontoby]]: [=added credits =]%0a* [[Openbsd/Install69]]  . . . September 27, 2021, at 05:59 PM by [[~jrmu]]: [==]%0a* [[Openbsd/PFStable]]  . . . September 24, 2021, at 03:28 PM by [[~miniontoby]]: [==]%0a* [[Openbsd/Mailopenproxy]]  . . . August 25, 2021, at 08:19 PM by [[~mkf]]: [==]%0a* [[Openbsd/Two-FactorAuth]]  . . . August 23, 2021, at 07:39 PM by [[~mkf]]: [=login.db compiling is no longer recommended.=]%0a* [[Openbsd/Npppd]]  . . . August 21, 2021, at 01:43 PM by [[~mkf]]: [==]%0a* [[Openbsd/FilePermissions]]  . . . August 20, 2021, at 02:20 AM by [[~Nate S]]: [==]%0a* [[Openbsd/Gophernicus]]  . . . August 15, 2021, at 02:06 AM by [[~mkf]]: [==]%0a* [[Openbsd/Openhttpd]]  . . . August 13, 2021, at 07:29 AM by [[~jrmu]]: [==]%0a* [[Openbsd/ZNCModules]]  . . . August 11, 2021, at 03:06 PM by [[~wiz]]: [==]%0a* [[Openbsd/Bitlbee]]  . . . August 10, 2021, at 12:03 PM by [[~mkf]]: [==]%0a* [[Openbsd/Pppoe]]  . . . August 10, 2021, at 11:56 AM by [[~mkf]]: [==]%0a* [[Openbsd/Sshkeys]]  . . . August 09, 2021, at 04:42 PM by [[~jrmu]]: [==]%0a* [[Openbsd/Squirrelmail]]  . . . August 06, 2021, at 10:32 AM by [[~baytuch]]: [==]%0a* [[Openbsd/Dnszones]]  . . . August 03, 2021, at 09:26 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Matterbridge]]  . . . August 02, 2021, at 12:33 PM by [[~mkf]]: [==]%0a* [[Openbsd/Vhost]]  . . . August 02, 2021, at 02:32 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Chroot]]  . . . July 31, 2021, at 02:47 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Vmmuser]]  . . . July 29, 2021, at 05:31 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Vmminstall]]  . . . July 29, 2021, at 05:28 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Vmm]]  . . . July 29, 2021, at 05:24 AM by [[~jrmu]]: [==]%0a* [[Openbsd/ZNCAdmin]]  . . . July 28, 2021, at 06:14 AM by [[~jrmu]]: [==]%0a* [[Openbsd/ZNCSupport]]  . . . July 28, 2021, at 06:14 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Php]]  . . . July 27, 2021, at 02:53 PM by [[~jrmu]]: [==]%0a* [[Openbsd/Dig]]  . . . July 25, 2021, at 06:50 AM by [[~jrmu]]: [==]%0a* [[Openbsd/RDNS]]  . . . July 23, 2021, at 06:44 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Sic]]  . . . July 21, 2021, at 05:57 PM by [[~mkf]]: [=first edit.=]%0a* [[Openbsd/Openrsync]]  . . . July 18, 2021, at 02:01 PM by [[~jrmu]]: [==]%0a* [[Openbsd/Znc]]  . . . July 16, 2021, at 10:43 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Staticnet]]  . . . July 12, 2021, at 05:48 PM by [[~jrmu]]: [==]%0a* [[Openbsd/Dovecot]]  . . . July 12, 2021, at 02:58 PM by [[~jrmu]]: [==]%0a* [[Openbsd/Relayd]]  . . . July 12, 2021, at 02:45 PM by [[~jrmu]]: [==]%0a* [[Openbsd/Spf]]  . . . July 12, 2021, at 03:08 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Eggdrop]]  . . . July 02, 2021, at 03:20 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Newdisk]]  . . . June 29, 2021, at 03:23 PM by [[~jrmu]]: [==]%0a* [[Openbsd/Ed]]  . . . June 28, 2021, at 04:04 PM by [[~mkf]]: [==]%0a* [[Openbsd/Unbound]]  . . . June 27, 2021, at 12:12 PM by [[~jrmu]]: [==]%0a* [[Openbsd/Dkimproxy]]  . . . June 25, 2021, at 12:56 PM by [[~jrmu]]: [==]%0a* [[Openbsd/Sysupgrade69]]  . . . June 25, 2021, at 05:46 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Opensmtpd]]  . . . June 23, 2021, at 02:21 AM by [[~jrmu]]: [==]%0a* [[Openbsd/NgircdLink]]  . . . June 22, 2021, at 07:50 PM by [[~mkf]]: [=delete=]%0a* [[Openbsd/Doas]]  . . . June 13, 2021, at 01:19 PM by [[~jrmu]]: [==]%0a* [[Openbsd/Shell]]  . . . June 11, 2021, at 09:36 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Books]]  . . . June 06, 2021, at 12:46 PM by [[~jrmu]]: [==]%0a* [[Openbsd/Pfa]]  . . . June 06, 2021, at 03:49 AM by [[~navic]]: [==]%0a* [[Openbsd/Wordpress]]  . . . June 04, 2021, at 04:55 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Anope]]  . . . May 31, 2021, at 10:24 AM by [[~miniontoby]]: [=cp=]%0a* [[Openbsd/ACKFlood]]  . . . May 29, 2021, at 06:20 AM by [[~mkf]]: [==]%0a* [[Openbsd/SSDP]]  . . . May 29, 2021, at 06:18 AM by [[~mkf]]: [==]%0a* [[Openbsd/Anycast]]  . . . May 29, 2021, at 06:01 AM by [[~mkf]]: [==]%0a* [[Openbsd/Dmarc]]  . . . May 21, 2021, at 09:22 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Disklabel]]  . . . May 17, 2021, at 03:33 AM by [[~bejelentkezni]]: [==]%0a* [[Openbsd/Fdisk]]  . . . May 17, 2021, at 03:27 AM by [[~bejelentkezni]]: [==]%0a* [[Openbsd/Security]]  . . . May 14, 2021, at 03:14 AM by [[~caesar]]: [==]%0a* [[Openbsd/Hopm-Arthur]]  . . . May 07, 2021, at 12:28 PM by [[~Arthur]]: [==]%0a* [[Openbsd/Syspatch]]  . . . February 14, 2021, at 11:00 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Netadmin]]  . . . February 14, 2021, at 10:56 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Leafnode]]  . . . February 12, 2021, at 01:40 PM by [[~chewy]]: [==]%0a* [[Openbsd/Pylink]]  . . . February 08, 2021, at 08:33 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Stable]]  . . . February 02, 2021, at 02:25 PM by [[~jrmu]]: [==]%0a* [[Openbsd/Base64]]  . . . February 02, 2021, at 06:37 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Unboundadblock]]  . . . February 02, 2021, at 04:29 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Pfbadhost]]  . . . February 02, 2021, at 04:29 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Wraith]]  . . . February 02, 2021, at 04:22 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Delphinusdnsd]]  . . . February 02, 2021, at 01:51 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Abuse]]  . . . January 31, 2021, at 05:33 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Phishing]]  . . . January 31, 2021, at 05:02 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Audit]]  . . . January 31, 2021, at 04:46 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Ongoing]]  . . . January 31, 2021, at 01:19 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Httpopenproxy]]  . . . January 29, 2021, at 11:01 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Zncadmin]]  . . . January 29, 2021, at 10:00 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Rbldns]]  . . . January 29, 2021, at 05:45 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Setuid]]  . . . January 28, 2021, at 06:53 AM by [[~jrmu]]: [==]%0a* [[Openbsd/PFTesting]]  . . . January 25, 2021, at 03:28 PM by [[~jrmu]]: [==]%0a* [[Openbsd/ZNCDaily]]  . . . January 25, 2021, at 11:35 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Irssi]]  . . . January 25, 2021, at 07:08 AM by [[~jrmu]]: [==]%0a* [[Openbsd/XTerm]]  . . . January 17, 2021, at 01:48 PM by [[~miniontoby]]: [=copyright=]%0a* [[Openbsd/Slrn]]  . . . January 12, 2021, at 02:40 PM by [[~Noxturnix]]: [==]%0a* [[Openbsd/Netcat]]  . . . January 09, 2021, at 02:20 PM by [[~jrmu]]: [==]%0a* [[Openbsd/Perl]]  . . . January 09, 2021, at 01:52 PM by [[~jrmu]]: [==]%0a* [[Openbsd/Backup]]  . . . January 03, 2021, at 01:46 PM by [[~jrmu]]: [==]%0a* [[Openbsd/Backups]]  . . . January 02, 2021, at 11:44 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Sshbackdoor]]  . . . December 30, 2020, at 12:14 PM by [[~jrmu]]: [==]%0a* [[Openbsd/Pf-bnc]]  . . . December 29, 2020, at 06:30 PM by [[~jrmu]]: [==]%0a* [[Openbsd/Tcltls]]  . . . December 29, 2020, at 09:53 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Amplification]]  . . . December 19, 2020, at 05:42 AM by [[~jrmu]]: [==]%0a* [[Openbsd/UDPFlood]]  . . . December 18, 2020, at 10:39 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Tcpdump]]  . . . December 18, 2020, at 09:12 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Tcpackflood]]  . . . December 17, 2020, at 10:36 AM by [[~jrmu]]: [==]%0a* [[Openbsd/RSTFlood]]  . . . December 17, 2020, at 10:34 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Tcpresetflood]]  . . . December 17, 2020, at 10:34 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Ssdp]]  . . . December 15, 2020, at 12:59 PM by [[~jrmu]]: [==]%0a* [[Openbsd/Pf]]  . . . December 13, 2020, at 12:03 PM by [[~jrmu]]: [==]%0a* [[Openbsd/Upgrade68]]  . . . December 13, 2020, at 11:12 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Install68]]  . . . December 13, 2020, at 10:13 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Upgrade67]]  . . . December 13, 2020, at 04:02 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Sysupgrade68]]  . . . December 11, 2020, at 10:27 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Dokuwiki]]  . . . December 10, 2020, at 02:23 PM by [[~miniontoby]]: [=code blocks fixed=]%0a* [[Openbsd/Acme-client]]  . . . December 09, 2020, at 06:47 PM by [[~miniontoby]]: [=fixed troubleshooting links=]%0a* [[Openbsd/Install67]]  . . . December 06, 2020, at 11:03 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Buyvm]]  . . . December 06, 2020, at 02:42 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Install]]  . . . December 04, 2020, at 04:15 PM by [[~jrmu]]: [==]%0a* [[Openbsd/Oidentd]]  . . . November 30, 2020, at 11:42 PM by [[~jrmu]]: [==]%0a* [[Openbsd/Checklist]]  . . . November 20, 2020, at 12:44 AM by [[~gry]]: [=+=]%0a* [[Openbsd/Acopm]]  . . . November 04, 2020, at 03:32 PM by [[~jrmu]]: [==]%0a* [[Openbsd/Achurch]]  . . . November 04, 2020, at 02:25 PM by [[~jrmu]]: [==]%0a* [[Openbsd/Vi]]  . . . November 04, 2020, at 12:51 PM by [[~jrmu]]: [==]%0a* [[Openbsd/Sudo]]  . . . November 04, 2020, at 12:38 PM by [[~jrmu]]: [==]%0a* [[Openbsd/Easyapp]]  . . . September 29, 2020, at 12:13 PM by [[~jrmu]]: [==]%0a* [[Openbsd/Cgit]]  . . . September 01, 2020, at 05:51 PM by [[~baytuch]]: [==]%0a* [[Openbsd/Bchs]]  . . . August 20, 2020, at 07:11 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Fdm]]  . . . August 18, 2020, at 10:06 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Opensmtpd-2]]  . . . August 18, 2020, at 09:59 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Opensmtpd-relay]]  . . . August 18, 2020, at 09:56 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Identd]]  . . . August 18, 2020, at 09:39 AM by [[~jrmu]]: [==]%0a* [[Openbsd/IPv6]]  . . . August 12, 2020, at 02:21 PM by [[~jrmu]]: [==]%0a* [[Openbsd/Oscommerce]]  . . . August 12, 2020, at 10:00 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Ping]]  . . . August 12, 2020, at 08:34 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Sockets]]  . . . August 12, 2020, at 07:16 AM by [[~jrmu]]: [==]%0a* [[Openbsd/Guides]]  . . . August 10, 2020, at 03:42 AM by [[~jrmu]]: [==]%0a
+time=1678122185
blob - d74d11e4fd015f674fa82b9dd39a36891c2aeb89
blob + 79885efd5d412a8d8f7eb0e9d5a0608fa9c72d1f
--- wiki.d/Opensmtpd.Configure
+++ wiki.d/Opensmtpd.Configure
@@ -2,14 +2,27 @@ version=pmwiki-2.3.20 ordered=1 urlencoded=1
 agent=w3m/0.5.3+git20210102
 author=jrmu
 charset=UTF-8
-csum=Moved to /etc/dkim/ to fix permissions bugs
+csum=
 ctime=1621253792
 host=38.87.162.154
 name=Opensmtpd.Configure
-rev=52
+rev=56
 targets=Dns.Overview,Nsd.Configure,DNS.Mail,Acme-client.Configure,Opensmtpd.Openrelay,Dovecot.Install,DNS.DKIM,Opensmtpd.Troubleshoot
-text=Let's set up a mail server with dkim signing and basic spam checks:%0a%0a!! Before we begin%0a%0aRead the the man pages for [[https://man.openbsd.org/smtpd|opensmtpd]], [[https://man.openbsd.org/smtpd.conf|smtpd.conf]], and [[https://man.openbsd.org/smtpctl|smtpctl]]. %0a%0aRead the [[https://github.com/poolpOrg/OpenSMTPD-book|free OpenSMTPd book]] by the%0aauthor of OpenSMTPd%0a%0a!! DNS%0a%0aRunning a mail server requires proper DNS records. If you have not already, you will%0awant to read up on [[dns/overview|DNS]] and [[nsd/configure|set up your name server]].%0a%0aYou will need to [[DNS/Mail|add proper DNS records]] to your domain and make sure they work.%0a%0a!! Install%0a%0aOpensmtpd is part of OpenBSD base, but we will also want to install some%0aopensmtpd-related packages and dovecot:%0a%0a[@%0a$ doas pkg_add opensmtpd-extras opensmtpd-filter-dkimsign-- dovecot%0a@]%0a%0a!! Configuration%0a%0a!!! TLS%0a%0aYou will want to use [[acme-client/configure|acme-client]] to request a TLS public cert and private key%0ain @@/etc/ssl/@@.%0a%0aNext, we'll create our smtpd configuration file in @@/etc/mail/smtpd.conf@@:%0a%0a[@%0a# PKI for TLS%0apki example.com cert "/etc/ssl/example.com.fullchain.pem"%0apki example.com key "/etc/ssl/private/example.com.key"%0a@]%0a%0aThis defines our public and private key pair for TLS encryption.%0a%0a!!! Tables%0a%0aNext, we define 5 tables:%0a%0a[@%0a# tables setup%0atable domains file:/etc/mail/domains%0atable passwd passwd:/etc/mail/passwd%0atable virtuals file:/etc/mail/virtuals%0atable hosts file:/etc/mail/hosts%0atable users file:/etc/mail/users%0a@]%0a%0aThe domains table contains a list of domains that our mail server should %0areceive mail on.%0a%0aThe passwd table contains a colon-separated list of username/password/disk quota%0aentries.%0a%0aThe virtuals file shows which virtual user should handle whose mail. They are written as @@key: value@@ pairs.%0aSee [[https://man.openbsd.org/aliases|aliases(5)]] for more information.%0a%0aThe hosts file contains a list of trusted sending hosts.%0a%0aThe users file contains a list of valid sending users.%0a%0aAll of these tables will be explained further in the following sections.%0a%0a!!! Dealing with Spam%0a%0a[@%0a# Blocks junk mail%0afilter check_rdns phase connect match !rdns junk%0afilter check_fcrdns phase connect match !fcrdns junk%0afilter "dkimsign" proc-exec "filter-dkimsign -d example.com -s mail -k /etc/dkim/private.key" user _smtpd group _smtpd%0a@]%0a%0aThe first filter will check if the sender has an rdns entry. If not, the mail%0awill be labeled as junk.%0a%0aThe second filter will check if the sender's forward and reverse dns entry match. If%0anot, the mail will be labeled as junk.%0a%0aThe third filter will sign any email with the DKIM private key.%0a%0a# -d specifies the domain name to sign for; you must replace example.com with your real domain.%0a# -s specifies the selector (in this case mail).%0a# -k specifies the path of the private key.%0a# user and group both specify _smtpd, the user and group that does the signing%0a%0a!!! Macros%0a%0aA macro defines a variable that will be replaced with a block of text:%0a%0a[@%0a# macros%0aipv4 = "192.168.0.1"%0aipv6 = "2001:db8::"%0acheck = "pki example.com mask-src filter { check_rdns check_fcrdns } hostname example.com"%0aauthcheck = "pki example.com auth %3cpasswd> mask-src senders %3cusers> filter { check_rdns check_fcrdns dkimsign } hostname example.com"%0a@]%0a%0aLines 2 and 3 define the IPv4 and IPv6 addresses used for sending and receiving mail.%0a%0aLine 4 tells opensmtpd to use the public/private keys we defined earlier for @@example.com@@. We mask the sender's source (the '''from''' part of the @@Received@@ header). We also apply two filters to check for proper forward and reverse confirmed DNS entries. Finally, we indicate that the sending hostname must be example.com instead of the default server name.%0a%0aLine 5 is identical to line 4 except it requires authentication with the password file and it checks if the sender is allowed.%0a%0a!!! Listeners%0a%0aThe listeners tell us what network interfaces, IP addresses, and ports to listen on.%0a%0a[@%0a# listeners%0alisten on socket filter "dkimsign"%0alisten on lo0 filter "dkimsign"%0alisten on $ipv4 port 25 tls $check%0alisten on $ipv6 port 25 tls $check%0alisten on $ipv4 port 465 smtps $authcheck%0alisten on $ipv6 port 465 smtps $authcheck%0alisten on $ipv4 port 587 tls-require $authcheck%0alisten on $ipv6 port 587 tls-require $authcheck%0a@]%0a%0aLine 2 tells smtpd to listen to the UNIX domain socket and to DKIM sign all %0aemails. Line 3 tells us to listen to the loopback interface and also%0asign all emails.%0a%0aLines 4-5 tells smtpd to listen on the IPv4 and IPv6 address on port 25, to provide%0aTLS if supported but to offer plaintext as a fallback. Only basic checking is done.%0a%0aLines 6-7 tells smtpd to listen on the IPv4 and IPv6 address on port 465, for SMTPS.%0aTLS encryption is required and authentication checking is forced because this socket%0acan be used for sending mail to other servers. We want to avoid an%0a[[opensmtpd/openrelay|open mail relay]].%0a%0aLines 8-9 is similar except it's for port 587, which is the SMTP submission port.%0a%0a!!! Rules%0a%0aNext we define the actions that opensmtpd can take and how to decide which%0aaction to follow:%0a%0a[@%0a# rules%0aaction "lmtp" lmtp "/var/dovecot/lmtp" rcpt-to virtual %3cvirtuals>%0aaction "outbound" relay src $ipv4%0a%0amatch from any for domain %3cdomains> action "lmtp"%0amatch from local for any action "outbound"%0amatch from src %3chosts> for any action "outbound"%0amatch auth from any for any action "outbound"%0a@]%0a%0aIn line 2, we define the action "lmtp": we pass the mail to dovecot to handle using the Local Mail Transfer Protocol (LMTP). The actual recipient will be translated using the virtuals table.%0a%0aIn line 3, we define the action "outbound": we relay (send) the email out.%0a%0aLine 4 defines our first matching rule: any email headed for one of our domains should be handed over to lmtp (handed over to dovecot).%0a%0aLine 5 defines our second matching rule: any email from a local IP address or queue can relay (send) without authentication.%0a%0aLine 6 defines our third matching rule: any email from our trusted @@/etc/mail/hosts@@ file will automatically be relayed (sent) without authentication.%0a%0aLine 7 defines our last matching rule: any email that has been properly authenticated will be relayed (sent).%0a%0a!!! Complete configuration file%0a%0aHere is the entire configuration file in @@/etc/mail/smtpd.conf@@:%0a%0a[@%0a# PKI for TLS%0apki example.com cert "/etc/ssl/example.com.fullchain.pem"%0apki example.com key "/etc/ssl/private/example.com.key"%0a%0a# tables setup%0atable domains file:/etc/mail/domains%0atable passwd passwd:/etc/mail/passwd%0atable virtuals file:/etc/mail/virtuals%0atable hosts file:/etc/mail/hosts%0atable users file:/etc/mail/users%0a%0a# Blocks junk mail%0afilter check_rdns phase connect match !rdns junk%0afilter check_fcrdns phase connect match !fcrdns junk%0afilter "dkimsign" proc-exec "filter-dkimsign -d example.com -s mail -k /etc/dkim/private.key" user _smtpd group _smtpd%0a%0a# macros%0aipv4 = "192.168.0.1"%0aipv6 = "2001:db8::"%0acheck = "pki example.com mask-src filter { check_rdns check_fcrdns } hostname example.com"%0aauthcheck = "pki example.com auth %3cpasswd> mask-src senders %3cusers> filter { check_rdns check_fcrdns dkimsign } hostname example.com"%0a%0a# listeners%0alisten on socket filter "dkimsign"%0alisten on lo0 filter "dkimsign"%0alisten on $ipv4 port 25 tls $check%0alisten on $ipv6 port 25 tls $check%0alisten on $ipv4 port 465 smtps $authcheck%0alisten on $ipv6 port 465 smtps $authcheck%0alisten on $ipv4 port 587 tls-require $authcheck%0alisten on $ipv6 port 587 tls-require $authcheck%0a%0a# rules%0aaction "lmtp" lmtp "/var/dovecot/lmtp" rcpt-to virtual %3cvirtuals>%0aaction "outbound" relay src $ipv4%0a%0amatch from any for domain %3cdomains> action "lmtp"%0amatch from local for any action "outbound"%0amatch from src %3chosts> for any action "outbound"%0amatch auth from any for any action "outbound"%0a@]%0a%0a!! Configuring Virtual Users%0a%0aA single user vmail will receive mail for all virtual users:%0a%0a[@%0a$ doas useradd -m -g =uid -c "Virtual Mail" -d /var/vmail -s /sbin/nologin vmail%0a@]%0a%0a/var/vmail will be used to store virtual users' maildir folders. It will be managed by dovecot, which receives mail via LMTP.%0a%0a!! Adding users%0a%0aCreate a new file @@/etc/mail/virtuals@@ and add these lines:%0a%0a[@%0aroot   admin@example.com%0aadmin@example.com        vmail%0ausername@example.com      vmail%0a@]%0a%0aNow, any mail sent to root will get forwarded to admin@example.com.%0a%0aThis is recommended to do so, as daily(8) and other programs will send mails to root. check the mail account linked to root account often!%0a%0aYou can optionally add one line for each user to provide aliases.%0a%0aFor each new user account, you will want to create a new line.%0a%0aYou'll also need to create one line for each user in @@/etc/mail/users@@:%0a%0a[@%0aadmin@example.com:	admin@example.com%0ausername@example.com:	username@example.com%0a@]%0a%0aA whitelist of known good senders goes into @@/etc/mail/hosts@@:%0a%0a[@%0alocalhost%0a127.0.0.1%0a192.168.1.1%0a2001:db8::%0a@]%0a%0aReplace IP addresses 192.168.1.1 and 2001:db8:: with your server's real IP addresses.%0a%0aIn @@/etc/mail/mailname@@, put in the name you want to use for your mail server. This%0ais very important for passing anti-spam checks:%0a%0a[@%0aexample.com%0a@]%0a%0aThe list of domains this mail server can receive emails for will go inside @@/etc/mail/domains@@:%0a%0a[@%0aexample.com%0amail.example.com%0a@]%0a%0aIn @@/etc/mail/passwd@@, we have a list of colon-separated user credentials:%0a%0a[@%0aadmin@example.com:$2b$10$h5itbhzs73T4jsHAj9YX6Tf63yRatAquGBxoCX67wyekhCH4ZqioD6lKh::::::userdb_quota_rule=*:storage=1G%0ausername@example.com:$2b$10$h5itbhzs73T4jsHAj9YX6Tf63yRatAquGBxoCX67wyekhCH4ZqioD6lKh::::::userdb_quota_rule=*:storage=1G%0a@]%0a%0aEach field is separated with a colon.%0a%0aThe first field tells you the username. Note that usernames include a domain -- this is because you might host mail for multiple domains. So, when logging in to the mail server, your mail client must be of the format username@example.com.%0a%0aThe second field is the password hash. To generate a hash, you can run encrypt:%0a%0a[@%0a$ encrypt%0a@]%0a%0aType your password, then press @@enter@@. Type @@ctrl+d@@ to quit.%0a%0a@@smtpctl encrypt@@ also does the same thing:%0a%0a[@%0a$ smtpctl encrypt%0a@]%0a%0a'''WARNING''': Special characters like $, when used in passwords, may cause issues with your mail client or with opensmtpd. To be safe, you might want to use only alphanumeric characters for your password. You can increase the length of the password for more security.%0a%0aThe last field sets how much data storage each user is allowed. The default here is 1 gigabyte.%0a%0a!!! File Permissions%0a%0aMake sure to set the proper permissions:%0a%0a[@%0a$ doas chown -R _smtpd:_dovecot /etc/dkim/%0a$ doas chmod -R o-rx /etc/{dkim,mail}/%0a@]%0a%0a!! IMAP and POP3 via dovecot%0a%0aTo finish the setup, we need to [[dovecot/install|install and configure dovecot]].%0a%0a!! DKIM signing%0a%0aWe will need to set up [[DNS/DKIM|dkim]] to have the mail properly signed.%0a%0a!! Troubleshooting%0a%0aOpenSMTPD may end up in an inconsistent state. This can happen due to a misconfiguration. One symptom is you see this error:%0a%0asmtpd[]: pony express: smtpd: socket: Too many open files%0a%0aTo fix this, you can delete all the temporary files inside OpenSMTPD.%0a%0a'''WARNING''': this will delete any messages in the queue:%0a%0a[@%0a$ doas rcctl stop smtpd%0a$ doas rm -r /var/spool/smtpd/queue/*%0a$ doas rm -r /var/spool/smtpd/offline/*%0a@]%0a%0aAt times, opensmtpd may be unable to connect because outgoing packets are being filtered. For example, suppose you are trying to send a letter to yahoo, but you get errors similar to following, showing a connection timeout:%0a%0a[@%0asmtpd[]: smtp-out: Enabling route [] %3c-> 67.195.204.77 (mtaproxy1.free.mail.vip.bf1.yahoo.com)%0asmtpd[]: smtp-out: Enabling route [] %3c-> 67.195.228.106 (mtaproxy2.free.mail.vip.gq1.yahoo.com)%0asmtpd[]: mta error reason=Connection timeout%0asmtpd[]: smtp-out: Disabling route [] %3c-> 104.47.55.33 (104.47.55.33) for 15s%0a@]%0a%0aAn easy way to test if your packets are being filtered is:%0a%0a[@%0a$ dig -t mx yahoo.com%0a;; ANSWER SECTION:%0ayahoo.com.              395     IN      MX      1 mta6.am0.yahoodns.net.%0ayahoo.com.              395     IN      MX      1 mta5.am0.yahoodns.net.%0ayahoo.com.              395     IN      MX      1 mta7.am0.yahoodns.net.%0a$ nc mta5.am0.yahoodns.net 25%0a@]%0a%0aIf you get no response, then outgoing packets to port 25 are being blocked (often due to firewalls by your VPS provider to block spam). If mail is working, you should see a 220 reply:%0a%0a[@%0a$ nc mta5.am0.yahoodns.net 25%0a220 mtaproxy511.free.mail.ne1.yahoo.com ESMTP ready%0a@]%0a%0aIt is also possible that TLS is being dropped by the firewall. You can test using openssl:%0a%0a[@%0a$ openssl s_client -starttls smtp -connect mta5.am0.yahoodns.net:25%0aCONNECTED(00000003)%0adepth=2 C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert High Assurance EV Root CA%0averify return:1%0adepth=1 C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert SHA2 High Assurance Server CA%0averify return:1%0adepth=0 C = US, ST = California, L = Sunnyvale, O = Oath Inc, CN = *.am0.yahoodns.net%0a...%0a250 STARTTLS%0a@]%0a%0aYou should see the entire SSL cert plus 250 STARTTLS reply. If you see the response hang at any point (eg, it returns CONNECTED(00000003) and nothing else), then TLS on port 25 is being filtered.%0a%0aIf you see this warning message in /var/log/maillog:%0a%0a[@%0aDec  6 03:44:17 smtpd[]: info: OpenSMTPD 6.7.0 starting                                 %0aDec  6 03:44:17 smtpd[]: pony express: smtpd: socket: Too many open files               %0aDec  6 03:44:17 smtpd[]: warn: lost child: pony express exited abnormally               %0a@]%0a%0aThis is due to having too many IP addresses that opensmtpd tries to bind to. This happens when you have a rule that says @@listen on egress@@:%0a%0a[@%0alisten on egress port 25 tls pki fruit.ircnow.org mask-src filter { check_rdns check_fcrdns }%0alisten on egress port 587 tls-require pki fruit.ircnow.org auth %3cpasswd> mask-src filter { check_rdns check_fcrdns }%0a@]%0a%0aThese two lines mean that opensmtpd will listen to '''all''' available ip addresses, including the hundreds of IPv6 addresses you may have in @@/etc/hostname.vio0@@ and @@ifconfig vio0@@. To fix this, you must specify the IP addresses you want to listen to:%0a%0a[@%0aipv4 = "38.81.163.143"%0aipv6 = "2602:fccf:1:143::"%0acheck = "pki example.com filter { check_rdns check_fcrdns } hostname example.com"%0aauthcheck = "pki example.com auth %3cpasswd> filter { check_rdns check_fcrdns dkimsign } hostname example.com"%0a%0a# listeners%0alisten on socket filter "dkimsign"%0alisten on lo0 filter "dkimsign"%0alisten on $ipv4 port 25 tls $check%0alisten on $ipv6 port 25 tls $check%0alisten on $ipv4 port 465 smtps $authcheck%0alisten on $ipv6 port 465 smtps $authcheck%0alisten on $ipv4 port 587 tls-require $authcheck%0alisten on $ipv6 port 587 tls-require $authcheck%0a@]%0a%0a!!! Open Mail Relay%0a%0aIf all your email is being marked as spam, check @@/var/log/maillog@@ . If you see a message like the following:%0a[@%0aJan  8 11:00:29 smtpd[39035]: 83bd6b3b1669649f mta delivery evpid=a8d16cd2144222fa from=%3cspammer@example.com> to=%3cvictim@example.com> rcpt=%3c-> source="192.168.0.1" relay="10.0.0.1 (10.0.0.1)" delay=16h2s result="TempFail" stat="451 4.7.650 The mail server [192.168.0.1] has been temporarily rate limited due to IP reputation. For e-mail delivery information, see https://postmaster.example.com (S843)"%0a@]%0aThen your server is being exploited as an [[opensmtpd/openrelay|open mail relay]]! Please follow the guide to fix it.%0a%0a!! [[opensmtpd/troubleshoot|Troubleshooting OpenSMTPd]]%0a
-time=1678077572
+text=Let's set up a mail server with dkim signing and basic spam checks:%0a%0a!! Before we begin%0a%0aRead the the man pages for [[https://man.openbsd.org/smtpd|opensmtpd]], [[https://man.openbsd.org/smtpd.conf|smtpd.conf]], and [[https://man.openbsd.org/smtpctl|smtpctl]]. %0a%0aRead the [[https://github.com/poolpOrg/OpenSMTPD-book|free OpenSMTPd book]] by the%0aauthor of OpenSMTPd%0a%0a!! DNS%0a%0aRunning a mail server requires proper DNS records. If you have not already, you will%0awant to read up on [[dns/overview|DNS]] and [[nsd/configure|set up your name server]].%0a%0aYou will need to [[DNS/Mail|add proper DNS records]] to your domain and make sure they work.%0a%0a!! Install%0a%0aOpensmtpd is part of OpenBSD base, but we will also want to install some%0aopensmtpd-related packages and dovecot:%0a%0a[@%0a$ doas pkg_add opensmtpd-extras opensmtpd-filter-dkimsign-- dovecot%0a@]%0a%0a!! Configuration%0a%0a!!! TLS%0a%0aYou will want to use [[acme-client/configure|acme-client]] to request a TLS public cert and private key%0ain @@/etc/ssl/@@.%0a%0aNext, we'll create our smtpd configuration file in @@/etc/mail/smtpd.conf@@:%0a%0a[@%0a# PKI for TLS%0apki example.com cert "/etc/ssl/example.com.crt"%0apki example.com key "/etc/ssl/private/example.com.key"%0a@]%0a%0aThis defines our public and private key pair for TLS encryption.%0a%0a!!! Tables%0a%0aNext, we define 5 tables:%0a%0a[@%0a# tables setup%0atable domains file:/etc/mail/domains%0atable passwd passwd:/etc/mail/passwd%0atable virtuals file:/etc/mail/virtuals%0atable hosts file:/etc/mail/hosts%0atable users file:/etc/mail/users%0a@]%0a%0aThe domains table contains a list of domains that our mail server should %0areceive mail on.%0a%0aThe passwd table contains a colon-separated list of username/password/disk quota%0aentries.%0a%0aThe virtuals file shows which virtual user should handle whose mail. They are written as @@key: value@@ pairs.%0aSee [[https://man.openbsd.org/aliases|aliases(5)]] for more information.%0a%0aThe hosts file contains a list of trusted sending hosts.%0a%0aThe users file contains a list of valid sending users.%0a%0aAll of these tables will be explained further in the following sections.%0a%0a!!! Dealing with Spam%0a%0a[@%0a# Blocks junk mail%0afilter check_rdns phase connect match !rdns junk%0afilter check_fcrdns phase connect match !fcrdns junk%0afilter "dkimsign" proc-exec "filter-dkimsign -d example.com -s mail -k /etc/mail/dkim/private.key" user _smtpd group _smtpd%0a@]%0a%0aThe first filter will check if the sender has an rdns entry. If not, the mail%0awill be labeled as junk.%0a%0aThe second filter will check if the sender's forward and reverse dns entry match. If%0anot, the mail will be labeled as junk.%0a%0aThe third filter will sign any email with the DKIM private key.%0a%0a# -d specifies the domain name to sign for; you must replace example.com with your real domain.%0a# -s specifies the selector (in this case mail).%0a# -k specifies the path of the private key.%0a# user and group both specify _smtpd, the user and group that does the signing%0a%0a!!! Macros%0a%0aA macro defines a variable that will be replaced with a block of text:%0a%0a[@%0a# macros%0aipv4 = "192.168.0.1"%0aipv6 = "2001:db8::"%0acheck = "pki example.com mask-src filter { check_rdns check_fcrdns } hostname example.com"%0aauthcheck = "pki example.com auth %3cpasswd> mask-src senders %3cusers> filter { check_rdns check_fcrdns dkimsign } hostname example.com"%0a@]%0a%0aLines 2 and 3 define the IPv4 and IPv6 addresses used for sending and receiving mail.%0a%0aLine 4 tells opensmtpd to use the public/private keys we defined earlier for @@example.com@@. We mask the sender's source (the '''from''' part of the @@Received@@ header). We also apply two filters to check for proper forward and reverse confirmed DNS entries. Finally, we indicate that the sending hostname must be example.com instead of the default server name.%0a%0aLine 5 is identical to line 4 except it requires authentication with the password file and it checks if the sender is allowed.%0a%0a!!! Listeners%0a%0aThe listeners tell us what network interfaces, IP addresses, and ports to listen on.%0a%0a[@%0a# listeners%0alisten on socket filter "dkimsign"%0alisten on lo0 filter "dkimsign"%0alisten on $ipv4 port 25 tls $check%0alisten on $ipv6 port 25 tls $check%0alisten on $ipv4 port 465 smtps $authcheck%0alisten on $ipv6 port 465 smtps $authcheck%0alisten on $ipv4 port 587 tls-require $authcheck%0alisten on $ipv6 port 587 tls-require $authcheck%0a@]%0a%0aLine 2 tells smtpd to listen to the UNIX domain socket and to DKIM sign all %0aemails. Line 3 tells us to listen to the loopback interface and also%0asign all emails.%0a%0aLines 4-5 tells smtpd to listen on the IPv4 and IPv6 address on port 25, to provide%0aTLS if supported but to offer plaintext as a fallback. Only basic checking is done.%0a%0aLines 6-7 tells smtpd to listen on the IPv4 and IPv6 address on port 465, for SMTPS.%0aTLS encryption is required and authentication checking is forced because this socket%0acan be used for sending mail to other servers. We want to avoid an%0a[[opensmtpd/openrelay|open mail relay]].%0a%0aLines 8-9 is similar except it's for port 587, which is the SMTP submission port.%0a%0a!!! Rules%0a%0aNext we define the actions that opensmtpd can take and how to decide which%0aaction to follow:%0a%0a[@%0a# rules%0aaction "lmtp" lmtp "/var/dovecot/lmtp" rcpt-to virtual %3cvirtuals>%0aaction "outbound" relay src $ipv4%0a%0amatch from any for domain %3cdomains> action "lmtp"%0amatch from local for any action "outbound"%0amatch from src %3chosts> for any action "outbound"%0amatch auth from any for any action "outbound"%0a@]%0a%0aIn line 2, we define the action "lmtp": we pass the mail to dovecot to handle using the Local Mail Transfer Protocol (LMTP). The actual recipient will be translated using the virtuals table.%0a%0aIn line 3, we define the action "outbound": we relay (send) the email out.%0a%0aLine 4 defines our first matching rule: any email headed for one of our domains should be handed over to lmtp (handed over to dovecot).%0a%0aLine 5 defines our second matching rule: any email from a local IP address or queue can relay (send) without authentication.%0a%0aLine 6 defines our third matching rule: any email from our trusted @@/etc/mail/hosts@@ file will automatically be relayed (sent) without authentication.%0a%0aLine 7 defines our last matching rule: any email that has been properly authenticated will be relayed (sent).%0a%0a!!! Complete configuration file%0a%0aHere is the entire configuration file in @@/etc/mail/smtpd.conf@@:%0a%0a[@%0a# PKI for TLS%0apki example.com cert "/etc/ssl/example.com.fullchain.pem"%0apki example.com key "/etc/ssl/private/example.com.key"%0a%0a# tables setup%0atable domains file:/etc/mail/domains%0atable passwd passwd:/etc/mail/passwd%0atable virtuals file:/etc/mail/virtuals%0atable hosts file:/etc/mail/hosts%0atable users file:/etc/mail/users%0a%0a# Blocks junk mail%0afilter check_rdns phase connect match !rdns junk%0afilter check_fcrdns phase connect match !fcrdns junk%0afilter "dkimsign" proc-exec "filter-dkimsign -d example.com -s mail -k /etc/mail/dkim/private.key" user _smtpd group _smtpd%0a%0a# macros%0aipv4 = "192.168.0.1"%0aipv6 = "2001:db8::"%0acheck = "pki example.com mask-src filter { check_rdns check_fcrdns } hostname example.com"%0aauthcheck = "pki example.com auth %3cpasswd> mask-src senders %3cusers> filter { check_rdns check_fcrdns dkimsign } hostname example.com"%0a%0a# listeners%0alisten on socket filter "dkimsign"%0alisten on lo0 filter "dkimsign"%0alisten on $ipv4 port 25 tls $check%0alisten on $ipv6 port 25 tls $check%0alisten on $ipv4 port 465 smtps $authcheck%0alisten on $ipv6 port 465 smtps $authcheck%0alisten on $ipv4 port 587 tls-require $authcheck%0alisten on $ipv6 port 587 tls-require $authcheck%0a%0a# rules%0aaction "lmtp" lmtp "/var/dovecot/lmtp" rcpt-to virtual %3cvirtuals>%0aaction "outbound" relay src $ipv4%0a%0amatch from any for domain %3cdomains> action "lmtp"%0amatch from local for any action "outbound"%0amatch from src %3chosts> for any action "outbound"%0amatch auth from any for any action "outbound"%0a@]%0a%0a!! Configuring Virtual Users%0a%0aA single user vmail will receive mail for all virtual users:%0a%0a[@%0a$ doas useradd -m -g =uid -c "Virtual Mail" -d /var/vmail -s /sbin/nologin vmail%0a@]%0a%0a/var/vmail will be used to store virtual users' maildir folders. It will be managed by dovecot, which receives mail via LMTP.%0a%0a!! Adding users%0a%0aCreate a new file @@/etc/mail/virtuals@@ and add these lines:%0a%0a[@%0aroot   admin@example.com%0aadmin@example.com        vmail%0ausername@example.com      vmail%0a@]%0a%0aNow, any mail sent to root will get forwarded to admin@example.com.%0a%0aThis is recommended to do so, as daily(8) and other programs will send mails to root. check the mail account linked to root account often!%0a'''NOTE''': Make sure to check the mail account linked to root often! [[https://man.openbsd.org/daily|daily(8)]] and other programs will send mails to root.%0a%0a%0aYou can optionally add one line for each user to provide aliases.%0a%0aFor each new user account, you will want to create a new line.%0a%0aYou'll also need to create one line for each user in @@/etc/mail/users@@:%0a%0a[@%0aadmin@example.com:	admin@example.com%0ausername@example.com:	username@example.com%0a@]%0a%0aA whitelist of known good senders goes into @@/etc/mail/hosts@@:%0a%0a[@%0alocalhost%0a127.0.0.1%0a192.168.1.1%0a2001:db8::%0a@]%0a%0aReplace IP addresses 192.168.1.1 and 2001:db8:: with your server's real IP addresses.%0a%0aIn @@/etc/mail/mailname@@, put in the name you want to use for your mail server. This%0ais very important for passing anti-spam checks:%0a%0a[@%0aexample.com%0a@]%0a%0aThe list of domains this mail server can receive emails for will go inside @@/etc/mail/domains@@:%0a%0a[@%0aexample.com%0amail.example.com%0a@]%0a%0aIn @@/etc/mail/passwd@@, we have a list of colon-separated user credentials:%0a%0a[@%0aadmin@example.com:$2b$10$h5itbhzs73T4jsHAj9YX6Tf63yRatAquGBxoCX67wyekhCH4ZqioD6lKh::::::userdb_quota_rule=*:storage=1G%0ausername@example.com:$2b$10$h5itbhzs73T4jsHAj9YX6Tf63yRatAquGBxoCX67wyekhCH4ZqioD6lKh::::::userdb_quota_rule=*:storage=1G%0a@]%0a%0aEach field is separated with a colon.%0a%0aThe first field tells you the username. Note that usernames include a domain -- this is because you might host mail for multiple domains. So, when logging in to the mail server, your mail client must be of the format username@example.com.%0a%0aThe second field is the password hash. To generate a hash, you can run encrypt:%0a%0a[@%0a$ encrypt%0a@]%0a%0aType your password, then press @@enter@@. Type @@ctrl+d@@ to quit.%0a%0a@@smtpctl encrypt@@ also does the same thing:%0a%0a[@%0a$ smtpctl encrypt%0a@]%0a%0a'''WARNING''': Special characters like $, when used in passwords, may cause issues with your mail client or with opensmtpd. To be safe, you might want to use only alphanumeric characters for your password. You can increase the length of the password for more security.%0a%0aThe last field sets how much data storage each user is allowed. The default here is 1 gigabyte.%0a%0a!!! File Permissions%0a%0aMake sure to set the proper permissions:%0a%0a[@%0a$ doas chown -R _smtpd:_dovecot /etc/mail/%0a$ doas chmod -R o-rx /etc/mail/%0a@]%0a%0a!! IMAP and POP3 via dovecot%0a%0aTo finish the setup, we need to [[dovecot/install|install and configure dovecot]].%0a%0a!! DKIM signing%0a%0aWe will need to set up [[DNS/DKIM|dkim]] to have the mail properly signed.%0a%0a!! Troubleshooting%0a%0aOpenSMTPD may end up in an inconsistent state. This can happen due to a misconfiguration. One symptom is you see this error:%0a%0asmtpd[]: pony express: smtpd: socket: Too many open files%0a%0aTo fix this, you can delete all the temporary files inside OpenSMTPD.%0a%0a'''WARNING''': this will delete any messages in the queue:%0a%0a[@%0a$ doas rcctl stop smtpd%0a$ doas rm -r /var/spool/smtpd/queue/*%0a$ doas rm -r /var/spool/smtpd/offline/*%0a@]%0a%0aAt times, opensmtpd may be unable to connect because outgoing packets are being filtered. For example, suppose you are trying to send a letter to yahoo, but you get errors similar to following, showing a connection timeout:%0a%0a[@%0asmtpd[]: smtp-out: Enabling route [] %3c-> 67.195.204.77 (mtaproxy1.free.mail.vip.bf1.yahoo.com)%0asmtpd[]: smtp-out: Enabling route [] %3c-> 67.195.228.106 (mtaproxy2.free.mail.vip.gq1.yahoo.com)%0asmtpd[]: mta error reason=Connection timeout%0asmtpd[]: smtp-out: Disabling route [] %3c-> 104.47.55.33 (104.47.55.33) for 15s%0a@]%0a%0aAn easy way to test if your packets are being filtered is:%0a%0a[@%0a$ dig -t mx yahoo.com%0a;; ANSWER SECTION:%0ayahoo.com.              395     IN      MX      1 mta6.am0.yahoodns.net.%0ayahoo.com.              395     IN      MX      1 mta5.am0.yahoodns.net.%0ayahoo.com.              395     IN      MX      1 mta7.am0.yahoodns.net.%0a$ nc mta5.am0.yahoodns.net 25%0a@]%0a%0aIf you get no response, then outgoing packets to port 25 are being blocked (often due to firewalls by your VPS provider to block spam). If mail is working, you should see a 220 reply:%0a%0a[@%0a$ nc mta5.am0.yahoodns.net 25%0a220 mtaproxy511.free.mail.ne1.yahoo.com ESMTP ready%0a@]%0a%0aIt is also possible that TLS is being dropped by the firewall. You can test using openssl:%0a%0a[@%0a$ openssl s_client -starttls smtp -connect mta5.am0.yahoodns.net:25%0aCONNECTED(00000003)%0adepth=2 C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert High Assurance EV Root CA%0averify return:1%0adepth=1 C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert SHA2 High Assurance Server CA%0averify return:1%0adepth=0 C = US, ST = California, L = Sunnyvale, O = Oath Inc, CN = *.am0.yahoodns.net%0a...%0a250 STARTTLS%0a@]%0a%0aYou should see the entire SSL cert plus 250 STARTTLS reply. If you see the response hang at any point (eg, it returns CONNECTED(00000003) and nothing else), then TLS on port 25 is being filtered.%0a%0aIf you see this warning message in /var/log/maillog:%0a%0a[@%0aDec  6 03:44:17 smtpd[]: info: OpenSMTPD 6.7.0 starting                                 %0aDec  6 03:44:17 smtpd[]: pony express: smtpd: socket: Too many open files               %0aDec  6 03:44:17 smtpd[]: warn: lost child: pony express exited abnormally               %0a@]%0a%0aThis is due to having too many IP addresses that opensmtpd tries to bind to. This happens when you have a rule that says @@listen on egress@@:%0a%0a[@%0alisten on egress port 25 tls pki fruit.ircnow.org mask-src filter { check_rdns check_fcrdns }%0alisten on egress port 587 tls-require pki fruit.ircnow.org auth %3cpasswd> mask-src filter { check_rdns check_fcrdns }%0a@]%0a%0aThese two lines mean that opensmtpd will listen to '''all''' available ip addresses, including the hundreds of IPv6 addresses you may have in @@/etc/hostname.vio0@@ and @@ifconfig vio0@@. To fix this, you must specify the IP addresses you want to listen to:%0a%0a[@%0aipv4 = "38.81.163.143"%0aipv6 = "2602:fccf:1:143::"%0acheck = "pki example.com filter { check_rdns check_fcrdns } hostname example.com"%0aauthcheck = "pki example.com auth %3cpasswd> filter { check_rdns check_fcrdns dkimsign } hostname example.com"%0a%0a# listeners%0alisten on socket filter "dkimsign"%0alisten on lo0 filter "dkimsign"%0alisten on $ipv4 port 25 tls $check%0alisten on $ipv6 port 25 tls $check%0alisten on $ipv4 port 465 smtps $authcheck%0alisten on $ipv6 port 465 smtps $authcheck%0alisten on $ipv4 port 587 tls-require $authcheck%0alisten on $ipv6 port 587 tls-require $authcheck%0a@]%0a%0a!!! Open Mail Relay%0a%0aIf all your email is being marked as spam, check @@/var/log/maillog@@ . If you see a message like the following:%0a[@%0aJan  8 11:00:29 smtpd[39035]: 83bd6b3b1669649f mta delivery evpid=a8d16cd2144222fa from=%3cspammer@example.com> to=%3cvictim@example.com> rcpt=%3c-> source="192.168.0.1" relay="10.0.0.1 (10.0.0.1)" delay=16h2s result="TempFail" stat="451 4.7.650 The mail server [192.168.0.1] has been temporarily rate limited due to IP reputation. For e-mail delivery information, see https://postmaster.example.com (S843)"%0a@]%0aThen your server is being exploited as an [[opensmtpd/openrelay|open mail relay]]! Please follow the guide to fix it.%0a%0a!! [[opensmtpd/troubleshoot|Troubleshooting OpenSMTPd]]%0a
+time=1678133499
+author:1678133499=jrmu
+diff:1678133499:1678133430:=37c37%0a%3c pki example.com cert "/etc/ssl/example.com.crt"%0a---%0a> pki example.com cert "/etc/ssl/example.com.fullchain.pem"%0a239,240d238%0a%3c '''NOTE''': Make sure to check the mail account linked to root often! [[https://man.openbsd.org/daily|daily(8)]] and other programs will send mails to root.%0a%3c %0a
+host:1678133499=38.87.162.154
+author:1678133430=jrmu
+diff:1678133430:1678127206:=37c37%0a%3c pki example.com cert "/etc/ssl/example.com.fullchain.pem"%0a---%0a> pki example.com cert "/etc/ssl/example.com.crt"%0a77c77%0a%3c filter "dkimsign" proc-exec "filter-dkimsign -d example.com -s mail -k /etc/mail/dkim/private.key" user _smtpd group _smtpd%0a---%0a> filter "dkimsign" proc-exec "filter-dkimsign -d example.com -s mail -k /etc/dkim/private.key" user _smtpd group _smtpd%0a175c175%0a%3c pki example.com cert "/etc/ssl/example.com.fullchain.pem"%0a---%0a> pki example.com cert "/etc/ssl/example.com.crt"%0a188,189c188,189%0a%3c filter "dkimsign" proc-exec "filter-dkimsign -d example.com -s mail -k /etc/mail/dkim/private.key" user _smtpd group _smtpd%0a%3c %0a---%0a> filter "dkimsign" proc-exec "filter-dkimsign -d example.com -s mail -k /etc/dkim/private.key" user _smtpd group _smtpd%0a> %0a238,239c238,239%0a%3c This is recommended to do so, as daily(8) and other programs will send mails to root. check the mail account linked to root account often!%0a%3c %0a---%0a> '''NOTE''': Make sure to check the mail account linked to root often! [[https://man.openbsd.org/daily|daily(8)]] and other programs will send mails to root.%0a> %0a310,311c310,311%0a%3c $ doas chown -R _smtpd:_dovecot /etc/mail/%0a%3c $ doas chmod -R o-rx /etc/mail/%0a---%0a> $ doas chown -R _smtpd:_dovecot /etc/dkim/%0a> $ doas chmod -R o-rx /etc/{dkim,mail}/%0a
+host:1678133430=38.87.162.154
+author:1678127206=jrmu
+csum:1678127206=Updated to use .crt since relayd follows that convention
+diff:1678127206:1678080465:=37c37%0a%3c pki example.com cert "/etc/ssl/example.com.crt"%0a---%0a> pki example.com cert "/etc/ssl/example.com.fullchain.pem"%0a175c175%0a%3c pki example.com cert "/etc/ssl/example.com.crt"%0a---%0a> pki example.com cert "/etc/ssl/example.com.fullchain.pem"%0a
+host:1678127206=38.87.162.154
+author:1678080465=jrmu
+diff:1678080465:1678077572:minor=238c238%0a%3c '''NOTE''': Make sure to check the mail account linked to root often! [[https://man.openbsd.org/daily|daily(8)]] and other programs will send mails to root.%0a---%0a> This is recommended to do so, as daily(8) and other programs will send mails to root. check the mail account linked to root account often!%0a
+host:1678080465=38.87.162.154
 author:1678077572=jrmu
 csum:1678077572=Moved to /etc/dkim/ to fix permissions bugs
 diff:1678077572:1672417020:=77c77%0a%3c filter "dkimsign" proc-exec "filter-dkimsign -d example.com -s mail -k /etc/dkim/private.key" user _smtpd group _smtpd%0a---%0a> filter "dkimsign" proc-exec "filter-dkimsign -d example.com -s mail -k /etc/mail/dkim/private.key" user _smtpd group _smtpd%0a188,189c188,189%0a%3c filter "dkimsign" proc-exec "filter-dkimsign -d example.com -s mail -k /etc/dkim/private.key" user _smtpd group _smtpd%0a%3c %0a---%0a> filter "dkimsign" proc-exec "filter-dkimsign -d example.com -s mail -k /etc/mail/dkim/private.key" user _smtpd group _smtpd%0a> %0a310,311c310,311%0a%3c $ doas chown -R _smtpd:_dovecot /etc/dkim/%0a%3c $ doas chmod -R o-rx /etc/{dkim,mail}/%0a---%0a> $ doas chown -R _smtpd:_dovecot /etc/mail/%0a> $ doas chmod -R o-rx /etc/mail/%0a
blob - ae18f54024c69be665d7a37768fb983a2cccf167
blob + 5b9f87ec58910ac3dda8eed9e18b1b018d5d2821
--- wiki.d/Opensmtpd.RecentChanges
+++ wiki.d/Opensmtpd.RecentChanges
@@ -4,6 +4,6 @@ charset=UTF-8
 ctime=1621253792
 host=38.87.162.154
 name=Opensmtpd.RecentChanges
-rev=76
-text=* [[Opensmtpd/Configure]]  . . . @2023-03-06T04:39:32Z by [[~jrmu]]: [=Moved to /etc/dkim/ to fix permissions bugs=]%0a* [[Opensmtpd/Troubleshoot]]  . . . July 20, 2022, at 03:58 PM by [[~jlj]]: [=Added notes about how I resolved the first two errors, on nastycode=]%0a* [[Opensmtpd/Test]]  . . . July 03, 2022, at 11:13 AM by [[~mkf]]: [==]%0a* [[Opensmtpd/Openrelay]]  . . . November 11, 2021, at 10:37 AM by [[~mkf]]: [==]%0a
-time=1678077572
+rev=80
+text=* [[Opensmtpd/Configure]]  . . . @2023-03-06T20:11:39Z by [[~jrmu]]: [==]%0a* [[Opensmtpd/Troubleshoot]]  . . . July 20, 2022, at 03:58 PM by [[~jlj]]: [=Added notes about how I resolved the first two errors, on nastycode=]%0a* [[Opensmtpd/Test]]  . . . July 03, 2022, at 11:13 AM by [[~mkf]]: [==]%0a* [[Opensmtpd/Openrelay]]  . . . November 11, 2021, at 10:37 AM by [[~mkf]]: [==]%0a
+time=1678133499
blob - 76c922c8b2683b955ab6217e03c13c0204767294
blob + 8f9613806697da8b548d3c7adaa23abf8aeb7e0b
--- wiki.d/Site.AllRecentChanges
+++ wiki.d/Site.AllRecentChanges
@@ -4,8 +4,8 @@ charset=UTF-8
 ctime=1596101899
 host=38.87.162.154
 name=Site.AllRecentChanges
-rev=11455
-text=* [[DNS.Mail]]  . . . @2023-03-06T04:50:40Z by [[~jrmu]]: [=Moved to /etc/dkim/ to fix permissions bugs=]%0a* [[DNS.DKIM]]  . . . @2023-03-06T04:48:38Z by [[~jrmu]]: [=Moved to /etc/dkim/ to fix permissions bugs=]%0a* [[Opensmtpd.Configure]]  . . . @2023-03-06T04:39:32Z by [[~jrmu]]: [=Moved to /etc/dkim/ to fix permissions bugs=]%0a* [[9front.Netsurf]]  . . . @2023-03-06T03:14:30Z by [[~Yonle]]: [==]%0a* [[Openbsd.Ngircd]]  . . . @2023-03-05T18:17:39Z by [[~mkf]]: [==]%0a* [[FreeIRC.About]]  . . . March 05, 2023, at 03:51 PM by [[~kilroy]]: [==]%0a* [[Openbsd.OpenTracker]]  . . . March 03, 2023, at 04:37 PM by [[~baytuch]]: [==]%0a* [[SiteAdmin.AuthUser]]  . . . March 03, 2023, at 05:31 AM by [[~jrmu]]: [==]%0a* [[Almanack.Almanack]]  . . . March 02, 2023, at 05:10 AM by [[~jrmu]]: [==]%0a* [[Ircnow.Roadmap]]  . . . March 02, 2023, at 05:10 AM by [[~jrmu]]: [==]%0a* [[Ircnow.Roadmap2023]]  . . . March 02, 2023, at 05:07 AM by [[~jrmu]]: [==]%0a* [[Oidentd.ZNC]]  . . . February 28, 2023, at 02:34 AM by [[~jrmu]]: [==]%0a* [[Oidentd.Changeident]]  . . . February 28, 2023, at 02:33 AM by [[~jrmu]]: [=This was suggested by another author, but because the solution is not permanent, we move it to a sep=]%0a* [[Acme-client.Configure]]  . . . February 26, 2023, at 10:06 PM by [[~jrmu]]: [=Revert as I'm not sure if /etc/daily.local is better=]%0a* [[Ircnow.Servers]]  . . . February 26, 2023, at 05:42 PM by [[~Yonle]]: [=No.=]%0a* [[Stagit.Install]]  . . . February 26, 2023, at 05:24 PM by [[~fossdev]]: [==]%0a* [[Openbsd.Gotweb]]  . . . February 26, 2023, at 05:04 PM by [[~fossdev]]: [==]%0a* [[Got.Repo]]  . . . February 26, 2023, at 05:02 PM by [[~fossdev]]: [==]%0a* [[Oidentd.Install]]  . . . February 26, 2023, at 01:59 AM by [[~jrmu]]: [=Revert erroneous change=]%0a* [[Ircnow.Explorer]]  . . . February 26, 2023, at 01:35 AM by [[~jrmu]]: [==]%0a* [[Ircnow.Codeforce]]  . . . February 26, 2023, at 01:03 AM by [[~jrmu]]: [==]%0a* [[Donations.Donations]]  . . . February 25, 2023, at 08:36 PM by [[~jrmu]]: [==]%0a* [[Main.HomePage]]  . . . February 25, 2023, at 05:39 AM by [[~jrmu]]: [==]%0a* [[Vps.Vps]]  . . . February 25, 2023, at 12:31 AM by [[~jrmu]]: [==]%0a* [[Botnow.Install]]  . . . February 24, 2023, at 11:24 PM by [[~Naglfar]]: [=Add a list with new parameters=]%0a* [[Hardware.Ps2]]  . . . February 24, 2023, at 04:26 PM by [[~mkf]]: [==]%0a* [[Bouncer.Bouncer]]  . . . February 22, 2023, at 02:06 PM by [[~Yonle]]: [==]%0a* [[Ircnow.Minutemin]]  . . . February 18, 2023, at 05:41 AM by [[~jrmu]]: [==]%0a* [[Ircnow.SSHFingerprints]]  . . . February 17, 2023, at 05:39 PM by [[~jrmu]]: [==]%0a* [[Baytuch.Bio]]  . . . February 17, 2023, at 12:00 PM by [[~baytuch]]: [==]%0a* [[Openhttpd.Configure]]  . . . February 17, 2023, at 11:39 AM by [[~baytuch]]: [==]%0a* [[Openbsd.Plermoa]]  . . . February 16, 2023, at 04:52 AM by [[~Yonle]]: [=Redirect=]%0a* [[Openbsd.Pleroma]]  . . . February 12, 2023, at 02:49 AM by [[~Yonle]]: [=Oops=]%0a* [[Openbsd.Akkoma]]  . . . February 12, 2023, at 02:48 AM by [[~Yonle]]: [=Oof=]%0a* [[Akkoma.Install]]  . . . February 09, 2023, at 12:49 PM by [[~Yonle]]: [==]%0a* [[Google.Sins]]  . . . February 08, 2023, at 05:13 AM by [[~Yonle]]: [==]%0a* [[Debate.Googledanger]]  . . . February 08, 2023, at 05:01 AM by [[~Yonle]]: [==]%0a* [[Debate.Outreachkids]]  . . . February 08, 2023, at 04:34 AM by [[~Yonle]]: [==]%0a* [[Openbsd.Mlmmj]]  . . . February 08, 2023, at 02:50 AM by [[~Yonle]]: [==]%0a* [[Openbsd.Mosh]]  . . . February 07, 2023, at 11:30 AM by [[~Yonle]]: [==]%0a* [[Shelllabs.Reading]]  . . . February 07, 2023, at 02:06 AM by [[~jrmu]]: [==]%0a* [[Squirrelmail.Install]]  . . . February 06, 2023, at 09:24 PM by [[~Naglfar]]: [=Add snapshot download reference=]%0a* [[Route.Usage]]  . . . February 06, 2023, at 02:38 PM by [[~mkf]]: [==]%0a* [[Mkf.Wikiv1]]  . . . February 06, 2023, at 02:31 PM by [[~mkf]]: [==]%0a* [[Psybnc.Install]]  . . . February 06, 2023, at 02:31 PM by [[~mkf]]: [==]%0a* [[Debate.Openweb]]  . . . February 06, 2023, at 02:15 PM by [[~Yonle]]: [==]%0a* [[Debate.Youtubedanger]]  . . . February 06, 2023, at 02:10 PM by [[~Yonle]]: [==]%0a* [[Debate.Providers]]  . . . February 06, 2023, at 01:41 PM by [[~Yonle]]: [==]%0a* [[Paster.Install]]  . . . February 06, 2023, at 10:22 AM by [[~mkf]]: [==]%0a* [[Anope.Install]]  . . . February 06, 2023, at 09:46 AM by [[~mkf]]: [==]%0a* [[9.Drawterm]]  . . . February 05, 2023, at 09:18 PM by [[~mkf]]: [==]%0a* [[Znc.Chroot]]  . . . February 04, 2023, at 04:45 PM by [[~Francis]]: [==]%0a* [[Password.Hashes]]  . . . February 04, 2023, at 07:27 AM by [[~izzyb]]: [=formatting fixes=]%0a* [[Chess.Chessgogi]]  . . . February 04, 2023, at 03:49 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Passwords]]  . . . February 03, 2023, at 07:49 PM by [[~izzyb]]: [==]%0a* [[Password.Management]]  . . . February 03, 2023, at 07:44 PM by [[~izzyb]]: [==]%0a* [[DNS.Ipv4rDNS]]  . . . February 01, 2023, at 08:31 PM by [[~izzyb]]: [=added note to clarify what address needs to be specified.=]%0a* [[Dovecot.SharedMailboxes]]  . . . January 31, 2023, at 08:29 PM by [[~izzyb]]: [==]%0a* [[Dovecot.SharedFolders]]  . . . January 31, 2023, at 06:03 AM by [[~izzyb]]: [=renaming to sharedMailboxes=]%0a* [[Soju.Install]]  . . . January 24, 2023, at 11:29 AM by [[~mkf]]: [=minor changes on style=]%0a* [[Lilywhitebot.Install]]  . . . January 24, 2023, at 11:23 AM by [[~mkf]]: [==]%0a* [[SendMoneyToSplinter0616Outlook.Com]]  . . . January 24, 2023, at 11:19 AM by [[~mkf]]: [==]%0a* [[9.9gridchan]]  . . . January 22, 2023, at 07:01 AM by [[~jrmu]]: [==]%0a* [[Ircnow.Milestones]]  . . . January 21, 2023, at 03:59 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Biboumi]]  . . . January 20, 2023, at 08:11 PM by [[~mkf]]: [==]%0a* [[Biboumi.Install]]  . . . January 20, 2023, at 08:10 PM by [[~mkf]]: [==]%0a* [[Texlive.Install]]  . . . January 20, 2023, at 08:05 PM by [[~mkf]]: [==]%0a* [[Rcctl.Rcctl]]  . . . January 20, 2023, at 08:00 PM by [[~mkf]]: [==]%0a* [[Vmm.Configure]]  . . . January 20, 2023, at 07:59 PM by [[~mkf]]: [==]%0a* [[Hopm.Install]]  . . . January 20, 2023, at 07:32 PM by [[~mkf]]: [==]%0a* [[Openbsd.Unrealircd]]  . . . January 20, 2023, at 07:27 PM by [[~mkf]]: [==]%0a* [[Unrealircd.Install]]  . . . January 20, 2023, at 07:24 PM by [[~mkf]]: [==]%0a* [[Pleroma.Install]]  . . . January 20, 2023, at 07:18 PM by [[~mkf]]: [==]%0a* [[Gomuks.Install]]  . . . January 20, 2023, at 07:08 PM by [[~mkf]]: [==]%0a* [[Gotweb.Install]]  . . . January 20, 2023, at 07:02 PM by [[~mkf]]: [==]%0a* [[Webnews.Install]]  . . . January 20, 2023, at 06:57 PM by [[~mkf]]: [==]%0a* [[Php.Install]]  . . . January 20, 2023, at 06:52 PM by [[~mkf]]: [==]%0a* [[Mlmmj.Install]]  . . . January 20, 2023, at 06:48 PM by [[~mkf]]: [==]%0a* [[Fiche.Install]]  . . . January 20, 2023, at 06:44 PM by [[~mkf]]: [==]%0a* [[Prosody.Install]]  . . . January 20, 2023, at 06:42 PM by [[~mkf]]: [==]%0a* [[Bitlbee.Install]]  . . . January 20, 2023, at 06:36 PM by [[~mkf]]: [==]%0a* [[TigerVNC.Install]]  . . . January 20, 2023, at 06:30 PM by [[~mkf]]: [==]%0a* [[NodeJS.Install]]  . . . January 20, 2023, at 06:27 PM by [[~mkf]]: [==]%0a* [[Pmwiki.Install]]  . . . January 20, 2023, at 06:19 PM by [[~mkf]]: [==]%0a* [[Xfce.Install]]  . . . January 20, 2023, at 06:17 PM by [[~mkf]]: [==]%0a* [[Ngircd.Install]]  . . . January 20, 2023, at 06:08 PM by [[~mkf]]: [==]%0a* [[Openbsd.Vipw]]  . . . January 18, 2023, at 11:01 PM by [[~zen]]: [=added two spaces=]%0a* [[Grep.Usage]]  . . . January 18, 2023, at 10:54 PM by [[~zen]]: [==]%0a* [[Openbsd.Loginconf]]  . . . January 18, 2023, at 10:48 PM by [[~zen]]: [=OpenBSD FAQ link refenrece=]%0a* [[Openbsd.Singleuser]]  . . . January 18, 2023, at 10:26 PM by [[~zen]]: [=changed the link reference=]%0a* [[Ssh.Fingerprints]]  . . . January 14, 2023, at 04:31 PM by [[~izzyb]]: [=added link to ircnow network ssh fingerprints as example.=]%0a* [[Team.Networks]]  . . . January 12, 2023, at 06:36 PM by [[~kilroy]]: [=Updated Sturtz IRC=]%0a* [[Openbsd.Dump]]  . . . January 10, 2023, at 04:48 PM by [[~mkf]]: [=add -u, improve dump-ssh funcationality.=]%0a* [[Znc.Install]]  . . . January 07, 2023, at 11:58 PM by [[~jrmu]]: [==]%0a* [[Jrmu.Bio]]  . . . January 05, 2023, at 07:23 PM by [[~jrmu]]: [==]%0a* [[Rspamd.Configure]]  . . . January 03, 2023, at 04:55 PM by [[~mkf]]: [==]%0a* [[Eggdrop191.Install]]  . . . December 31, 2022, at 05:29 PM by [[~Yonle]]: [==]%0a* [[Dovecot.Pigeonhole]]  . . . December 30, 2022, at 04:24 PM by [[~mkf]]: [=style 2=]%0a* [[Openbsd.Quota]]  . . . December 29, 2022, at 06:51 PM by [[~mkf]]: [==]%0a* [[Minutemin.Bootcamp]]  . . . December 29, 2022, at 04:38 PM by [[~mkf]]: [==]%0a* [[Profiles.Miniontoby]]  . . . December 26, 2022, at 07:26 PM by [[~miniontoby]]: [=Created=]%0a* [[Minetest.Minetest]]  . . . December 26, 2022, at 07:25 PM by [[~miniontoby]]: [=Added building guide link=]%0a* [[Openbsd.Minetest]]  . . . December 26, 2022, at 07:23 PM by [[~miniontoby]]: [=Added more ways to install=]%0a* [[Splinter0616Outlook.Com]]  . . . December 25, 2022, at 02:37 AM by [[~SplinTer]]: [==]%0a* [[Ngircd.Oper]]  . . . December 25, 2022, at 12:03 AM by [[~forero]]: [==]%0a* [[Profiles.Yonle]]  . . . December 24, 2022, at 03:29 PM by [[~Yonle]]: [==]%0a* [[Openbsd.Honk]]  . . . December 17, 2022, at 08:45 AM by [[~Yonle]]: [==]%0a* [[Yonle.Bio]]  . . . December 13, 2022, at 05:18 PM by [[~Yonle]]: [==]%0a* [[Camping.Gear]]  . . . December 12, 2022, at 04:39 AM by [[~jrmu]]: [==]%0a* [[Vhost.Vhost]]  . . . December 12, 2022, at 03:36 AM by [[~xfnw]]: [==]%0a* [[Vhost.Ircnow]]  . . . December 12, 2022, at 03:13 AM by [[~xfnw]]: [=ircfree.com is not an ircnow domain=]%0a* [[Shelllabs.Openaccess]]  . . . December 08, 2022, at 10:02 PM by [[~redrum88]]: [==]%0a* [[I2Pd.Install]]  . . . December 07, 2022, at 01:16 AM by [[~Yonle]]: [=Again not 7070=]%0a* [[I2Pd.Tunnels]]  . . . December 06, 2022, at 02:52 PM by [[~Yonle]]: [=There we go. =]%0a* [[I2pd.Tunnels]]  . . . December 06, 2022, at 02:45 PM by [[~Yonle]]: [==]%0a* [[Unbound.Configure]]  . . . December 04, 2022, at 03:59 AM by [[~Yonle]]: [==]%0a* [[Profiles.Xfnw]]  . . . November 28, 2022, at 10:38 PM by [[~xfnw]]: [=add pgp keys=]%0a* [[Unwind.Configure]]  . . . November 26, 2022, at 09:23 PM by [[~akoizumi]]: [=add unwind=]%0a* [[Openbsd.Icecast]]  . . . November 17, 2022, at 11:35 AM by [[~Yonle]]: [==]%0a* [[Debian.Install]]  . . . November 13, 2022, at 11:43 AM by [[~suzerain]]: [=writing=]%0a* [[Lemon.Lemon]]  . . . November 10, 2022, at 01:48 PM by [[~mkf]]: [==]%0a* [[Bouncer.JmIRC]]  . . . November 04, 2022, at 06:18 PM by [[~baytuch]]: [=Added screenshots about setup=]%0a* [[Ambassador.Ilines]]  . . . October 22, 2022, at 04:40 AM by [[~jrmu]]: [==]%0a* [[Bouncer.XChat]]  . . . October 16, 2022, at 11:09 PM by [[~xfnw]]: [=XChat is unmaintained=]%0a* [[Eggdrop.VHost]]  . . . October 02, 2022, at 01:05 PM by [[~sulieztya]]: [==]%0a* [[Eggdrop.VhostTCL]]  . . . October 02, 2022, at 07:06 AM by [[~sulieztya]]: [==]%0a* [[Eggdrop.BotZNC]]  . . . October 02, 2022, at 01:29 AM by [[~sulieztya]]: [==]%0a* [[Shelllabs.Intro]]  . . . September 28, 2022, at 06:53 PM by [[~jrmu]]: [==]%0a* [[He.IPv6Certification]]  . . . September 16, 2022, at 05:32 PM by [[~xfnw]]: [=create page=]%0a* [[Shelllabs.Education]]  . . . September 14, 2022, at 07:30 PM by [[~jrmu]]: [==]%0a* [[About.AboutUs]]  . . . September 13, 2022, at 06:42 PM by [[~zleap]]: [==]%0a* [[Site.SideBar]]  . . . September 13, 2022, at 06:21 PM by [[~jrmu]]: [==]%0a* [[LegalAndSafety.LegalAndSafety]]  . . . September 13, 2022, at 05:19 PM by [[~zleap]]: [==]%0a* [[LegalAndSafety.LegalAmpSafety]]  . . . September 13, 2022, at 05:17 PM by [[~zleap]]: [==]%0a* [[LegalAmpSafety.Subheading]]  . . . September 13, 2022, at 05:15 PM by [[~zleap]]: [==]%0a* [[Acmesh.Configure]]  . . . September 11, 2022, at 06:03 PM by [[~akoizumi]]: [=Added acme.sh (currently a WIP)=]%0a* [[Dehydrated.Configure]]  . . . September 11, 2022, at 02:52 PM by [[~akoizumi]]: [=Add dehydrated=]%0a* [[Profiles.Izzyb]]  . . . September 11, 2022, at 06:28 AM by [[~izzyb]]: [==]%0a* [[Site.EditForm]]  . . . September 11, 2022, at 06:22 AM by [[~izzyb]]: [=Make Author none editable field=]%0a* [[Netcat.Irc]]  . . . September 11, 2022, at 04:21 AM by [[~izzyb]]: [=Removed info about PASS - moving to different doc as per jrmu request=]%0a* [[Openbsd.Geomyidae]]  . . . September 10, 2022, at 02:31 AM by [[~akoizumi]]: [==]%0a* [[Openbsd.INN]]  . . . September 10, 2022, at 02:23 AM by [[~akoizumi]]: [=Fix some types=]%0a* [[Ngircd.Loginconf]]  . . . September 10, 2022, at 01:51 AM by [[~jrmu]]: [==]%0a* [[Heading.Subheading]]  . . . September 07, 2022, at 07:23 PM by [[~zleap]]: [==]%0a* [[Eggdrop193.Install]]  . . . September 07, 2022, at 04:48 PM by [[~jrmu]]: [==]%0a* [[Letsencrypt.Expired]]  . . . September 06, 2022, at 12:00 AM by [[~xfnw]]: [=be less misleading about Let's Encrypt's reasoning for keeping the expired chain=]%0a* [[Ircnow.Pioneer]]  . . . August 14, 2022, at 05:06 AM by [[~jrmu]]: [==]%0a* [[Openbsd.VsFTP]]  . . . August 10, 2022, at 03:18 PM by [[~mkf]]: [=snipped unneeded output=]%0a* [[C.Scanf]]  . . . August 10, 2022, at 09:51 AM by [[~mkf]]: [==]%0a* [[Vmm.Install]]  . . . August 10, 2022, at 08:05 AM by [[~miniontoby]]: [=coconut to host=]%0a* [[Orange.CertsReissue]]  . . . August 08, 2022, at 05:35 AM by [[~baytuch]]: [==]%0a* [[Team.Security]]  . . . August 08, 2022, at 12:53 AM by [[~jrmu]]: [==]%0a* [[Netcat.Usage]]  . . . August 04, 2022, at 01:12 AM by [[~tiramisu]]: [==]%0a* [[Freedom.Universal]]  . . . August 03, 2022, at 06:33 PM by [[~jrmu]]: [==]%0a* [[Pgp.Upload]]  . . . August 01, 2022, at 01:21 PM by [[~jan6]]: [=keys.openpgp.org uses a superior implementation, less vulnerable to various issues=]%0a* [[Lemon.Packages]]  . . . July 30, 2022, at 07:52 PM by [[~mkf]]: [==]%0a* [[Netizen.Ellisisland]]  . . . July 27, 2022, at 07:05 PM by [[~jrmu]]: [==]%0a* [[Ircnow.Newdeal]]  . . . July 27, 2022, at 06:55 PM by [[~jrmu]]: [==]%0a* [[Ircnow.Daughtersofliberty]]  . . . July 27, 2022, at 06:45 PM by [[~jrmu]]: [==]%0a* [[Ircnow.Womenstem]]  . . . July 21, 2022, at 05:59 PM by [[~jrmu]]: [==]%0a* [[Eggdrop.RC]]  . . . July 20, 2022, at 06:55 PM by [[~baytuch]]: [==]%0a* [[Opensmtpd.Troubleshoot]]  . . . July 20, 2022, at 03:58 PM by [[~jlj]]: [=Added notes about how I resolved the first two errors, on nastycode=]%0a* [[Eggdrop.Nickserv]]  . . . July 19, 2022, at 10:05 AM by [[~baytuch]]: [==]%0a* [[Chroot.Intro]]  . . . July 18, 2022, at 04:23 PM by [[~mkf]]: [==]%0a* [[Ircnow.Media]]  . . . July 15, 2022, at 05:54 AM by [[~jrmu]]: [==]%0a* [[Iked.Linuxstrongswan]]  . . . July 03, 2022, at 11:29 PM by [[~jrmu]]: [==]%0a* [[Acme-client.AutoRenew]]  . . . July 03, 2022, at 11:50 AM by [[~mkf]]: [==]%0a* [[Openbsd.Apmd]]  . . . July 03, 2022, at 11:36 AM by [[~mkf]]: [==]%0a* [[Opensmtpd.Test]]  . . . July 03, 2022, at 11:13 AM by [[~mkf]]: [==]%0a* [[Ircnow.Roadmap2022]]  . . . July 03, 2022, at 11:04 AM by [[~mkf]]: [==]%0a* [[Iked.Android]]  . . . July 01, 2022, at 12:14 AM by [[~jrmu]]: [==]%0a* [[Vpn.Myipaddress]]  . . . June 30, 2022, at 09:51 PM by [[~jrmu]]: [==]%0a* [[Olympics.Games]]  . . . June 27, 2022, at 10:42 PM by [[~jrmu]]: [==]%0a* [[Iked.Configure]]  . . . June 25, 2022, at 02:28 PM by [[~jrmu]]: [==]%0a* [[Unbound.Blacklists]]  . . . June 25, 2022, at 06:02 AM by [[~jrmu]]: [==]%0a* [[Iked.Linux]]  . . . June 23, 2022, at 07:10 AM by [[~jrmu]]: [==]%0a* [[Vpn.Vpn]]  . . . June 23, 2022, at 06:42 AM by [[~jrmu]]: [==]%0a* [[Ircnow.Nsf]]  . . . June 20, 2022, at 05:05 PM by [[~jrmu]]: [==]%0a* [[Debate.Debate]]  . . . June 19, 2022, at 04:12 PM by [[~jrmu]]: [==]%0a* [[Ircnow.Metrics]]  . . . June 19, 2022, at 04:12 PM by [[~jrmu]]: [==]%0a* [[Nsd.Masterslave]]  . . . June 19, 2022, at 06:34 AM by [[~jrmu]]: [==]%0a* [[Dns.Overview]]  . . . June 19, 2022, at 05:45 AM by [[~jrmu]]: [==]%0a* [[Dns.Records]]  . . . June 19, 2022, at 05:44 AM by [[~jrmu]]: [==]%0a* [[Syspatch.Syspatch]]  . . . June 17, 2022, at 06:24 AM by [[~jrmu]]: [==]%0a* [[Tmux.Config]]  . . . June 14, 2022, at 12:34 AM by [[~jrmu]]: [==]%0a* [[Vmm.Alpine]]  . . . June 13, 2022, at 05:42 PM by [[~fossdev]]: [==]%0a* [[Team.Announce]]  . . . June 13, 2022, at 03:52 PM by [[~jrmu]]: [==]%0a* [[Vmm.Arch]]  . . . June 12, 2022, at 04:11 PM by [[~g1n]]: [=Added article about Arch Linux setup on VMM=]%0a* [[Znc.Patch]]  . . . June 12, 2022, at 12:48 AM by [[~jrmu]]: [==]%0a* [[Unveil.Intro]]  . . . June 12, 2022, at 12:40 AM by [[~jrmu]]: [==]%0a* [[Pledge.Intro]]  . . . June 12, 2022, at 12:39 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Pkg]]  . . . June 12, 2022, at 12:32 AM by [[~jrmu]]: [==]%0a* [[Doas.Configure]]  . . . June 09, 2022, at 07:56 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Intro]]  . . . June 09, 2022, at 07:53 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Bsdrd]]  . . . June 09, 2022, at 07:17 AM by [[~jrmu]]: [==]%0a* [[Vnc.Vnc]]  . . . June 08, 2022, at 04:04 PM by [[~miniontoby]]: [=Added RealVNC Viewer to the list (might need some more extra stuff, but yeah its fine)=]%0a* [[Unix101.Unix101]]  . . . June 07, 2022, at 03:12 PM by [[~jrmu]]: [==]%0a* [[Openbsd.Sysupgrade71]]  . . . June 05, 2022, at 11:49 PM by [[~jrmu]]: [==]%0a* [[Openbsd.Growfs]]  . . . June 01, 2022, at 12:34 AM by [[~jrmu]]: [==]%0a* [[Team.Welcome]]  . . . May 31, 2022, at 10:20 PM by [[~jrmu]]: [==]%0a* [[Hostnameif.Static-v2]]  . . . May 23, 2022, at 06:29 AM by [[~theguest]]: [==]%0a* [[Hostnameif.Static]]  . . . May 23, 2022, at 05:01 AM by [[~theguest]]: [==]%0a* [[Ircnow.Team]]  . . . May 12, 2022, at 03:44 PM by [[~jrmu]]: [==]%0a* [[Grape.Minetest]]  . . . May 10, 2022, at 10:48 AM by [[~baytuch]]: [==]%0a* [[Irc.Emoji]]  . . . May 10, 2022, at 10:23 AM by [[~baytuch]]: [==]%0a* [[Openbsd.Nsd]]  . . . May 10, 2022, at 12:33 AM by [[~jrmu]]: [==]%0a* [[Opsofliberty.Bootcamp]]  . . . May 09, 2022, at 08:38 AM by [[~mkf]]: [==]%0a* [[Openbsd.Ports]]  . . . May 09, 2022, at 05:54 AM by [[~mkf]]: [==]%0a* [[Openbsd.Rcctl]]  . . . May 09, 2022, at 05:53 AM by [[~mkf]]: [==]%0a* [[Ngircd.Ssl]]  . . . May 08, 2022, at 03:30 PM by [[~miniontoby]]: [=fixed the text=]%0a* [[Openbsd.Upgrade71]]  . . . May 03, 2022, at 06:36 AM by [[~jrmu]]: [==]%0a* [[Codeforce.Training]]  . . . May 03, 2022, at 03:02 AM by [[~jrmu]]: [==]%0a* [[Civics.Intro]]  . . . May 03, 2022, at 01:06 AM by [[~jrmu]]: [==]%0a* [[OpenBSD.EdgeRouter-Lite]]  . . . April 28, 2022, at 02:50 PM by [[~pufferf]]: [==]%0a* [[Math.Reading]]  . . . April 27, 2022, at 08:23 PM by [[~jrmu]]: [==]%0a* [[Openbsd.Install71]]  . . . April 24, 2022, at 09:55 PM by [[~jrmu]]: [==]%0a* [[Openbsd.Botnow]]  . . . April 24, 2022, at 06:14 AM by [[~jrmu]]: [==]%0a* [[Buyvm.Ipv6]]  . . . April 24, 2022, at 06:10 AM by [[~jrmu]]: [==]%0a* [[Eggdrop.Rss]]  . . . April 23, 2022, at 04:20 PM by [[~jrmu]]: [==]%0a* [[Team.Testing]]  . . . April 20, 2022, at 09:45 PM by [[~jrmu]]: [==]%0a* [[Dns.Registrars]]  . . . April 20, 2022, at 09:30 PM by [[~jrmu]]: [==]%0a* [[Hosting.Providers]]  . . . April 20, 2022, at 08:52 PM by [[~jrmu]]: [==]%0a* [[Openbsd.Gopher]]  . . . April 20, 2022, at 08:29 PM by [[~jrmu]]: [==]%0a* [[Openbsd.Adduser]]  . . . April 20, 2022, at 08:07 PM by [[~jrmu]]: [==]%0a* [[Signify.Verify]]  . . . April 20, 2022, at 06:24 PM by [[~jrmu]]: [==]%0a* [[Almanack.Route]]  . . . April 20, 2022, at 06:23 AM by [[~jrmu]]: [==]%0a* [[Ntpd.Configure]]  . . . April 20, 2022, at 06:17 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Ntpd]]  . . . April 20, 2022, at 06:16 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Vmmlinux]]  . . . April 20, 2022, at 05:33 AM by [[~jrmu]]: [==]%0a* [[Vmm.Linux]]  . . . April 20, 2022, at 05:33 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Iked]]  . . . April 20, 2022, at 05:16 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Team]]  . . . April 20, 2022, at 04:54 AM by [[~jrmu]]: [==]%0a* [[Ircnow.Networks]]  . . . April 19, 2022, at 04:22 PM by [[~jrmu]]: [==]%0a* [[Openbsd.Announce]]  . . . April 19, 2022, at 04:14 PM by [[~jrmu]]: [==]%0a* [[Ircnow.Ally]]  . . . April 19, 2022, at 04:11 PM by [[~jrmu]]: [==]%0a* [[Openhttpd.Chroot]]  . . . April 19, 2022, at 04:05 PM by [[~jrmu]]: [==]%0a* [[Openbsd.Install70]]  . . . April 19, 2022, at 06:52 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Upgrade70]]  . . . April 19, 2022, at 06:49 AM by [[~jrmu]]: [==]%0a* [[CodeForce.Bootcamp]]  . . . April 19, 2022, at 06:29 AM by [[~jrmu]]: [==]%0a* [[Perl101.Perl101]]  . . . April 19, 2022, at 06:15 AM by [[~jrmu]]: [==]%0a* [[Vmm.Vmm]]  . . . April 15, 2022, at 12:20 PM by [[~Naglfar]]: [=Update: report from PiRATA=]%0a* [[Ngircd.Link]]  . . . April 07, 2022, at 06:52 AM by [[~jrmu]]: [==]%0a* [[Minutemin.Minutemin]]  . . . April 06, 2022, at 02:55 AM by [[~jrmu]]: [==]%0a* [[Openhttpd.CGI]]  . . . April 05, 2022, at 04:22 PM by [[~gtlsgamr]]: [==]%0a* [[Openbsd.Censord]]  . . . April 05, 2022, at 06:16 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Hopm]]  . . . April 05, 2022, at 06:09 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Dns]]  . . . April 05, 2022, at 05:24 AM by [[~jrmu]]: [==]%0a* [[Debate.Zncflaws]]  . . . April 05, 2022, at 05:18 AM by [[~jrmu]]: [==]%0a* [[Debate.Debiandanger]]  . . . April 04, 2022, at 04:30 AM by [[~jrmu]]: [==]%0a* [[Openhttpd.Tls]]  . . . April 04, 2022, at 04:25 AM by [[~jrmu]]: [==]%0a* [[Openhttpd.Website]]  . . . April 03, 2022, at 11:03 PM by [[~jrmu]]: [==]%0a* [[Soju.Guide]]  . . . April 02, 2022, at 03:46 PM by [[~Yonle]]: [==]%0a* [[Nitter.Install]]  . . . April 02, 2022, at 01:08 AM by [[~fallback]]: [=first nitter install page=]%0a* [[Debiankaios.Bio]]  . . . April 01, 2022, at 05:10 PM by [[~debiankaios]]: [==]%0a* [[Openbsd.Psybnc]]  . . . March 30, 2022, at 09:56 PM by [[~jrmu]]: [==]%0a* [[Sshd.Disablepassword]]  . . . March 30, 2022, at 08:27 PM by [[~xfnw]]: [=undo accidental revert=]%0a* [[Tor.Irc]]  . . . March 30, 2022, at 12:40 PM by [[~m16]]: [==]%0a* [[Chess.Reading]]  . . . March 29, 2022, at 10:02 PM by [[~jrmu]]: [==]%0a* [[Linux.Reading]]  . . . March 29, 2022, at 03:31 PM by [[~jrmu]]: [==]%0a* [[Unix.Reading]]  . . . March 28, 2022, at 03:24 PM by [[~jrmu]]: [==]%0a* [[Irc.Services]]  . . . March 25, 2022, at 04:29 AM by [[~jrmu]]: [==]%0a* [[Syslogd.Configure]]  . . . March 25, 2022, at 04:07 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Ddos]]  . . . March 24, 2022, at 04:22 PM by [[~jrmu]]: [==]%0a* [[Ddos.Intro]]  . . . March 24, 2022, at 04:22 PM by [[~jrmu]]: [==]%0a* [[Bouncer.ZNC]]  . . . March 19, 2022, at 07:31 AM by [[~fallback]]: [==]%0a* [[ISCABBS.DownloadingAndInstalling]]  . . . March 15, 2022, at 10:42 PM by [[~Mandarax]]: [==]%0a* [[ISCABBS.ISCABBS]]  . . . March 15, 2022, at 09:24 PM by [[~Mandarax]]: [==]%0a* [[Unix.History]]  . . . March 14, 2022, at 06:07 PM by [[~jrmu]]: [==]%0a* [[Unix.Exhibit]]  . . . March 13, 2022, at 11:37 PM by [[~jrmu]]: [==]%0a* [[Debate.Dogfooding]]  . . . March 10, 2022, at 05:14 AM by [[~jrmu]]: [==]%0a* [[Irc.Easy]]  . . . March 05, 2022, at 08:56 PM by [[~jrmu]]: [==]%0a* [[Doxing.Defense]]  . . . March 05, 2022, at 08:54 PM by [[~jrmu]]: [==]%0a* [[Mlmmj-archivist.Install]]  . . . March 03, 2022, at 05:26 AM by [[~error]]: [==]%0a* [[Openbsd.IRCBridge]]  . . . February 28, 2022, at 02:59 AM by [[~suzerain]]: [==]%0a* [[Unix101.Vi]]  . . . February 27, 2022, at 08:16 PM by [[~jrmu]]: [==]%0a* [[Vi.Intro]]  . . . February 27, 2022, at 04:16 PM by [[~Limits]]: [=Add Introduction to Vi=]%0a* [[Irc201.Irc201]]  . . . February 27, 2022, at 04:21 AM by [[~suzerain]]: [==]%0a* [[9.Ideas]]  . . . February 23, 2022, at 05:19 PM by [[~mkf]]: [==]%0a* [[Main.WikiSandbox]]  . . . February 22, 2022, at 11:05 PM by [[~mkf]]: [==]%0a* [[Openhttpd.Perl]]  . . . February 21, 2022, at 07:18 AM by [[~Naglfar]]: [==]%0a* [[Openbsd.Wesnothd]]  . . . February 21, 2022, at 06:28 AM by [[~mkf]]: [=Wesnothd=]%0a* [[9.Audio]]  . . . February 20, 2022, at 08:07 PM by [[~jrmu]]: [==]%0a* [[Cloud9p.Roadmap]]  . . . February 20, 2022, at 06:54 PM by [[~xfnw]]: [==]%0a* [[Openbsd.Xonotic]]  . . . February 20, 2022, at 07:43 AM by [[~mkf]]: [=A xonotic server has apperad! pt.2=]%0a* [[Bouncer.Irssi]]  . . . February 16, 2022, at 06:26 PM by [[~izzyb]]: [=clarified wording in example=]%0a* [[PuTTY.PuTTYgen]]  . . . February 16, 2022, at 05:24 AM by [[~jrmu]]: [==]%0a* [[Rcd.Configure]]  . . . February 15, 2022, at 04:46 PM by [[~xfnw]]: [=fix title formatting=]%0a* [[Debate.Ircnowd]]  . . . February 14, 2022, at 06:24 PM by [[~jrmu]]: [==]%0a* [[Stopm.Stopm]]  . . . February 14, 2022, at 06:16 PM by [[~jrmu]]: [==]%0a* [[Police.Fingerprints]]  . . . February 12, 2022, at 02:09 PM by [[~xfnw]]: [=ip addresses should be sorted with sort -V=]%0a* [[Openbsd.Police]]  . . . February 10, 2022, at 07:36 PM by [[~jrmu]]: [==]%0a* [[Dns.Dns]]  . . . February 10, 2022, at 07:39 AM by [[~nixdork]]: [=Fix typo=]%0a* [[Dns.BindResolver]]  . . . February 10, 2022, at 07:30 AM by [[~nixdork]]: [=First draft of bind resolver howto=]%0a* [[Botnow.SqliteViews]]  . . . February 10, 2022, at 02:00 AM by [[~xfnw]]: [==]%0a* [[Relayd.TLSMulti]]  . . . February 08, 2022, at 06:45 AM by [[~Naglfar]]: [=Fix listening port for https=]%0a* [[Relayd.Acceleration]]  . . . February 08, 2022, at 06:27 AM by [[~Naglfar]]: [=Fix: https forwarding port=]%0a* [[AncientWisdom.Bio]]  . . . February 07, 2022, at 01:18 PM by [[~AncientWisdom]]: [==]%0a* [[Minutemin.Questions]]  . . . February 05, 2022, at 09:16 AM by [[~jrmu]]: [==]%0a* [[Minutemin.Server]]  . . . February 05, 2022, at 08:14 AM by [[~jrmu]]: [==]%0a* [[Vmm.SlackwareIso]]  . . . February 03, 2022, at 10:53 PM by [[~Naglfar]]: [=Slackware 15.0 x86 stable is released=]%0a* [[Vmctl.Usage]]  . . . February 03, 2022, at 06:24 PM by [[~miniontoby]]: [=fixed attachment=]%0a* [[Duplicity.Usage]]  . . . February 02, 2022, at 10:31 AM by [[~jrmu]]: [==]%0a* [[Openssl.Encryptfile]]  . . . February 02, 2022, at 09:29 AM by [[~jrmu]]: [==]%0a* [[Bots.Basicbot]]  . . . January 31, 2022, at 08:54 PM by [[~izzyb]]: [==]%0a* [[Dovecot.Install]]  . . . January 29, 2022, at 09:35 PM by [[~forero]]: [=comment out=]%0a* [[Openrsync.Usage]]  . . . January 29, 2022, at 09:04 AM by [[~Naglfar]]: [=update from rsync to openrsync=]%0a* [[Openbsd.Tcpip]]  . . . January 24, 2022, at 05:45 PM by [[~jrmu]]: [==]%0a* [[Synclient.Configure]]  . . . January 24, 2022, at 06:02 AM by [[~jrmu]]: [==]%0a* [[Crontab.Edit]]  . . . January 23, 2022, at 05:46 PM by [[~mkf]]: [==]%0a* [[9.Install]]  . . . January 22, 2022, at 06:57 AM by [[~mkf]]: [==]%0a* [[Asterisk.Install]]  . . . January 19, 2022, at 05:34 AM by [[~jrmu]]: [==]%0a* [[9.Rcpu]]  . . . January 17, 2022, at 10:19 PM by [[~jrmu]]: [==]%0a* [[9.9p]]  . . . January 17, 2022, at 08:47 PM by [[~mkf]]: [==]%0a* [[9.Ndb]]  . . . January 16, 2022, at 06:46 PM by [[~mkf]]: [==]%0a* [[Openbsd.U9fs]]  . . . January 16, 2022, at 06:23 PM by [[~mkf]]: [==]%0a* [[Dns.FQDN]]  . . . January 15, 2022, at 10:16 PM by [[~jrmu]]: [==]%0a* [[Pgp.Create]]  . . . January 14, 2022, at 09:14 AM by [[~baytuch]]: [==]%0a* [[Nsd.DNSSec]]  . . . January 14, 2022, at 02:53 AM by [[~pyr3x]]: [==]%0a* [[Openbsd.Locale]]  . . . January 12, 2022, at 01:23 PM by [[~baytuch]]: [==]%0a* [[Openbsd.Openbsd]]  . . . January 12, 2022, at 01:19 PM by [[~baytuch]]: [==]%0a* [[Ksh.Autocomplete]]  . . . January 11, 2022, at 01:44 PM by [[~miniontoby]]: [=updated url=]%0a* [[Gpg.Verify]]  . . . January 08, 2022, at 09:48 PM by [[~Naglfar]]: [=Add description=]%0a* [[Mlmmj.Archive]]  . . . January 06, 2022, at 10:52 PM by [[~Hawk]]: [==]%0a* [[9.Hostowner]]  . . . January 06, 2022, at 11:29 AM by [[~mkf]]: [==]%0a* [[Ircnow.Dogfood]]  . . . January 06, 2022, at 08:48 AM by [[~jrmu]]: [==]%0a* [[9.Authsrv]]  . . . January 05, 2022, at 04:59 AM by [[~mkf]]: [=hmm=]%0a* [[9.Chording]]  . . . January 03, 2022, at 02:40 PM by [[~jrmu]]: [==]%0a* [[Ircnow.Status]]  . . . January 03, 2022, at 06:06 AM by [[~jrmu]]: [==]%0a* [[Openbsd.BBB]]  . . . January 03, 2022, at 12:06 AM by [[~jrmu]]: [==]%0a* [[Got.Server]]  . . . January 02, 2022, at 05:42 PM by [[~jrmu]]: [==]%0a* [[Census.Census]]  . . . January 02, 2022, at 11:27 AM by [[~jrmu]]: [==]%0a* [[Bncnow.Bncnow]]  . . . January 02, 2022, at 11:18 AM by [[~jrmu]]: [==]%0a* [[Ircnow.Projects]]  . . . January 02, 2022, at 11:09 AM by [[~jrmu]]: [==]%0a* [[Ircfs.Intro]]  . . . January 02, 2022, at 10:49 AM by [[~jrmu]]: [==]%0a* [[Ircnowd.Ircnowd]]  . . . January 02, 2022, at 06:32 AM by [[~jrmu]]: [==]%0a* [[Marketing.Marketing]]  . . . January 02, 2022, at 06:20 AM by [[~jrmu]]: [==]%0a* [[Ircnow.Sonsofliberty]]  . . . January 02, 2022, at 06:06 AM by [[~jrmu]]: [==]%0a* [[Pkgadd.CheckUpdates]]  . . . January 01, 2022, at 04:29 AM by [[~pyr3x]]: [==]%0a* [[Ircnow.Roadmap2021]]  . . . December 30, 2021, at 06:31 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Sftp]]  . . . December 30, 2021, at 06:01 AM by [[~jrmu]]: [==]%0a* [[Sftp.Chroot]]  . . . December 30, 2021, at 06:01 AM by [[~jrmu]]: [==]%0a* [[Ircnow.Status2022]]  . . . December 30, 2021, at 05:35 AM by [[~jrmu]]: [==]%0a* [[Eggdrop.UTF8]]  . . . December 28, 2021, at 08:21 PM by [[~jrmu]]: [==]%0a* [[Openbsd.Uim]]  . . . December 26, 2021, at 01:45 AM by [[~jrmu]]: [==]%0a* [[Sshwifty.Install]]  . . . December 23, 2021, at 02:49 PM by [[~miniontoby]]: [=created=]%0a* [[Nsd.Zone]]  . . . December 23, 2021, at 10:33 AM by [[~jrmu]]: [==]%0a* [[Openhttpd.Hosting]]  . . . December 23, 2021, at 03:06 AM by [[~jrmu]]: [==]%0a* [[OpenSSH.RSAkeys]]  . . . December 22, 2021, at 03:18 PM by [[~miniontoby]]: [==]%0a* [[Openbsd.Wifi]]  . . . December 22, 2021, at 02:59 PM by [[~jrmu]]: [==]%0a* [[Openbsd.Recordaudio]]  . . . December 22, 2021, at 01:24 PM by [[~jrmu]]: [==]%0a* [[9.9]]  . . . December 22, 2021, at 11:30 AM by [[~xfnw]]: [=fix some grammatical errors=]%0a* [[Parec.Record]]  . . . December 22, 2021, at 07:02 AM by [[~jrmu]]: [==]%0a* [[Sox.Concat]]  . . . December 22, 2021, at 07:01 AM by [[~jrmu]]: [==]%0a* [[Ffmpeg.Recordscreen]]  . . . December 22, 2021, at 07:00 AM by [[~jrmu]]: [==]%0a* [[JuiceSSH.Connect]]  . . . December 20, 2021, at 01:03 PM by [[~jrmu]]: [==]%0a* [[Marketing.Memes]]  . . . December 20, 2021, at 12:55 PM by [[~jrmu]]: [==]%0a* [[9.Independent]]  . . . December 20, 2021, at 12:47 PM by [[~jrmu]]: [==]%0a* [[MacScreenSharing.Connect]]  . . . December 20, 2021, at 11:57 AM by [[~jrmu]]: [==]%0a* [[9.Partdisk]]  . . . December 20, 2021, at 11:39 AM by [[~jrmu]]: [==]%0a* [[Got.Usage]]  . . . December 17, 2021, at 04:44 PM by [[~jrmu]]: [==]%0a* [[Irc.Federation]]  . . . December 17, 2021, at 02:03 PM by [[~jrmu]]: [==]%0a* [[Irc.Chanop]]  . . . December 14, 2021, at 04:58 AM by [[~mkf]]: [==]%0a* [[9.Todo]]  . . . December 03, 2021, at 07:52 PM by [[~mkf]]: [==]%0a* [[Pylink.Chroot]]  . . . December 02, 2021, at 02:03 PM by [[~jrmu]]: [==]%0a* [[Pylink.Install]]  . . . December 02, 2021, at 02:02 PM by [[~jrmu]]: [==]%0a* [[Jrmu.Marriage]]  . . . December 02, 2021, at 06:09 AM by [[~jrmu]]: [==]%0a* [[Hosting.Hosting]]  . . . December 01, 2021, at 02:01 PM by [[~jrmu]]: [==]%0a* [[Mc.Usage]]  . . . November 29, 2021, at 07:53 PM by [[~mkf]]: [==]%0a* [[PuTTY.Connect]]  . . . November 29, 2021, at 12:13 PM by [[~jrmu]]: [==]%0a* [[Email.Email]]  . . . November 29, 2021, at 04:19 AM by [[~mkf]]: [==]%0a* [[Texlive.Sinhala]]  . . . November 28, 2021, at 06:35 AM by [[~jrmu]]: [==]%0a* [[MailWindows.Connect]]  . . . November 27, 2021, at 03:12 PM by [[~jrmu]]: [==]%0a* [[Gajim.Biboumi]]  . . . November 27, 2021, at 01:02 PM by [[~jrmu]]: [==]%0a* [[Xmpp.Xmpp]]  . . . November 27, 2021, at 12:33 PM by [[~jrmu]]: [==]%0a* [[Mcabber.Connect]]  . . . November 26, 2021, at 01:38 PM by [[~jrmu]]: [==]%0a* [[ChatSecure.Connect]]  . . . November 26, 2021, at 11:36 AM by [[~jrmu]]: [==]%0a* [[9.9pfs]]  . . . November 24, 2021, at 02:00 PM by [[~mkf]]: [==]%0a* [[Vmm.DebianInstall]]  . . . November 24, 2021, at 11:44 AM by [[~nicoz]]: [==]%0a* [[Siskin.Connect]]  . . . November 23, 2021, at 04:38 PM by [[~jrmu]]: [==]%0a* [[Dino.Connect]]  . . . November 23, 2021, at 02:10 PM by [[~mkf]]: [==]%0a* [[Monal.Connect]]  . . . November 23, 2021, at 10:32 AM by [[~jrmu]]: [==]%0a* [[Xabber.Connect]]  . . . November 23, 2021, at 10:20 AM by [[~jrmu]]: [==]%0a* [[DNS.DMARC]]  . . . November 22, 2021, at 10:52 PM by [[~Hawk]]: [==]%0a* [[StorkIM.Connect]]  . . . November 21, 2021, at 05:03 AM by [[~jrmu]]: [==]%0a* [[Conversations.Connect]]  . . . November 20, 2021, at 05:37 PM by [[~jrmu]]: [==]%0a* [[Yaxim.Connect]]  . . . November 20, 2021, at 05:09 PM by [[~jrmu]]: [==]%0a* [[Adium.Connect]]  . . . November 20, 2021, at 07:32 AM by [[~jrmu]]: [==]%0a* [[Vmm.AlmaLinux]]  . . . November 20, 2021, at 06:47 AM by [[~dodocrypto]]: [==]%0a* [[Vmm.DebianIso]]  . . . November 19, 2021, at 09:35 PM by [[~nicoz]]: [==]%0a* [[Psi.Connect]]  . . . November 17, 2021, at 03:23 PM by [[~jrmu]]: [==]%0a* [[Pidgin.Connect]]  . . . November 17, 2021, at 10:18 AM by [[~jrmu]]: [==]%0a* [[Gajim.Connect]]  . . . November 17, 2021, at 08:01 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Training]]  . . . November 16, 2021, at 03:30 PM by [[~Hawk]]: [==]%0a* [[Opera.Connect]]  . . . November 16, 2021, at 12:12 AM by [[~wiz]]: [==]%0a* [[0dev.0dev]]  . . . November 12, 2021, at 03:00 AM by [[~dodocrypto]]: [==]%0a* [[Vmm.RockyLinux]]  . . . November 11, 2021, at 10:51 AM by [[~dodocrypto]]: [==]%0a* [[Opensmtpd.Openrelay]]  . . . November 11, 2021, at 10:37 AM by [[~mkf]]: [==]%0a* [[Sandbox.0dev]]  . . . November 11, 2021, at 01:45 AM by [[~dodocrypto]]: [==]%0a* [[Nsd.Configure]]  . . . November 10, 2021, at 11:58 AM by [[~Hawk]]: [==]%0a* [[Got.Mirror]]  . . . November 07, 2021, at 05:22 PM by [[~jrmu]]: [==]%0a* [[Vpn.OpenIKED]]  . . . November 07, 2021, at 03:45 PM by [[~gloNO]]: [==]%0a* [[Openbsd.Got]]  . . . November 07, 2021, at 03:16 PM by [[~jrmu]]: [==]%0a* [[Ircnow.Opsofliberty]]  . . . November 06, 2021, at 05:15 PM by [[~jrmu]]: [==]%0a* [[Emacs.Emacs]]  . . . November 06, 2021, at 04:39 PM by [[~LohanG]]: [==]%0a* [[ZNC.Support]]  . . . November 06, 2021, at 03:53 PM by [[~LohanG]]: [=added libera=]%0a* [[Vmm.Plan9]]  . . . November 05, 2021, at 09:31 PM by [[~mkf]]: [=???=]%0a* [[9.Stone]]  . . . November 04, 2021, at 04:09 PM by [[~meeekeeef]]: [==]%0a* [[9.Zuke]]  . . . November 04, 2021, at 04:01 PM by [[~meeekeeef]]: [==]%0a* [[Openbsd.Drawtermssh]]  . . . November 04, 2021, at 03:54 PM by [[~meeekeeef]]: [=ssh bad >:[=]%0a* [[Netcat.Http]]  . . . November 03, 2021, at 02:30 PM by [[~jrmu]]: [==]%0a* [[Telnet.Http]]  . . . November 03, 2021, at 02:18 PM by [[~jrmu]]: [==]%0a* [[Znc.Relayd]]  . . . November 03, 2021, at 10:18 AM by [[~jrmu]]: [==]%0a* [[ZNC.Admin]]  . . . November 02, 2021, at 05:44 PM by [[~jrmu]]: [==]%0a* [[Znc.Debug]]  . . . November 02, 2021, at 03:23 PM by [[~jrmu]]: [==]%0a* [[Znc.Usage]]  . . . November 02, 2021, at 03:09 PM by [[~jrmu]]: [==]%0a* [[Ambassador.Markets]]  . . . November 02, 2021, at 01:29 PM by [[~jrmu]]: [==]%0a* [[Almanack.Rewrite]]  . . . October 31, 2021, at 10:30 PM by [[~hydragyrum]]: [==]%0a* [[9.Sysupdate]]  . . . October 31, 2021, at 10:21 PM by [[~meeekeeef]]: [==]%0a* [[Debian.Debian]]  . . . October 31, 2021, at 12:34 PM by [[~monaco]]: [==]%0a* [[Ircnow.Victorycpus]]  . . . October 30, 2021, at 08:17 AM by [[~jrmu]]: [==]%0a* [[Gnus.Connect]]  . . . October 30, 2021, at 01:32 AM by [[~hydragyrum]]: [==]%0a* [[Ircnow.Settler]]  . . . October 29, 2021, at 04:03 PM by [[~jrmu]]: [==]%0a* [[Debian.Nginxphpfpm]]  . . . October 29, 2021, at 12:26 PM by [[~monaco]]: [==]%0a* [[Debian.Nginx]]  . . . October 29, 2021, at 12:18 PM by [[~monaco]]: [==]%0a* [[Vmm.Homerouter]]  . . . October 26, 2021, at 05:08 PM by [[~jrmu]]: [==]%0a* [[9.Netcat]]  . . . October 25, 2021, at 03:40 PM by [[~jrmu]]: [==]%0a* [[9.Plan9ini]]  . . . October 24, 2021, at 04:30 PM by [[~jrmu]]: [==]%0a* [[Iked.Newconfig]]  . . . October 24, 2021, at 03:49 PM by [[~tool]]: [==]%0a* [[Lua.Minetest-1]]  . . . October 24, 2021, at 10:30 AM by [[~debiankaios]]: [==]%0a* [[9.Links]]  . . . October 24, 2021, at 06:29 AM by [[~mkf]]: [==]%0a* [[9.Keybindings]]  . . . October 24, 2021, at 06:15 AM by [[~mkf]]: [=heheheheheh=]%0a* [[Xdefaults.Configure]]  . . . October 23, 2021, at 02:40 PM by [[~jrmu]]: [==]%0a* [[TigerVNC.SSH]]  . . . October 23, 2021, at 11:56 AM by [[~Hawk]]: [==]%0a* [[Rio.Customize]]  . . . October 22, 2021, at 09:22 AM by [[~jrmu]]: [==]%0a* [[9.Ssh]]  . . . October 22, 2021, at 12:54 AM by [[~jrmu]]: [==]%0a* [[Vmm.Devuan4Iso]]  . . . October 21, 2021, at 04:29 PM by [[~debiankaios]]: [=changed beowulf_3.1.1 to chimaera_4.0.0=]%0a* [[9.101]]  . . . October 20, 2021, at 04:53 PM by [[~jrmu]]: [==]%0a* [[Fvwm.Configure]]  . . . October 18, 2021, at 10:20 AM by [[~jrmu]]: [==]%0a* [[KISSmo.KISSmo]]  . . . October 18, 2021, at 09:58 AM by [[~monaco]]: [==]%0a* [[KISSmo.Download]]  . . . October 18, 2021, at 09:53 AM by [[~monaco]]: [==]%0a* [[KISSmo.About]]  . . . October 18, 2021, at 09:52 AM by [[~monaco]]: [==]%0a* [[KISSmo.Install]]  . . . October 18, 2021, at 09:44 AM by [[~monaco]]: [==]%0a* [[Cvs.Repo]]  . . . October 17, 2021, at 08:32 AM by [[~jrmu]]: [==]%0a* [[Cvs.Anoncvs]]  . . . October 17, 2021, at 04:00 AM by [[~jrmu]]: [==]%0a* [[Cvs.Commit]]  . . . October 17, 2021, at 03:58 AM by [[~jrmu]]: [==]%0a* [[Cvs.Cvsweb]]  . . . October 17, 2021, at 03:28 AM by [[~jrmu]]: [==]%0a* [[9.Cvsfs]]  . . . October 15, 2021, at 12:58 PM by [[~mkf]]: [==]%0a* [[Openbsd.Sysupgrade70]]  . . . October 15, 2021, at 11:02 AM by [[~mkf]]: [=humans are easily confused.=]%0a* [[Openbsd.Ilines]]  . . . October 15, 2021, at 02:36 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Pmwiki]]  . . . October 14, 2021, at 02:14 PM by [[~miniontoby]]: [=added credits =]%0a* [[Vmm.Devuan-ISO]]  . . . October 14, 2021, at 09:50 AM by [[~siva]]: [==]%0a* [[Vmm.Devuan-Simple]]  . . . October 14, 2021, at 09:48 AM by [[~siva]]: [=Tutorial Created=]%0a* [[Cvs.Intro]]  . . . October 13, 2021, at 03:49 PM by [[~jrmu]]: [==]%0a* [[Synapse.Install]]  . . . October 12, 2021, at 02:49 PM by [[~miniontoby]]: [=Created=]%0a* [[Ircnow.Oper]]  . . . October 12, 2021, at 03:02 AM by [[~jrmu]]: [==]%0a* [[Terms.Privacy]]  . . . October 11, 2021, at 11:48 AM by [[~jrmu]]: [==]%0a* [[Ircnow.Diversity]]  . . . October 09, 2021, at 02:56 AM by [[~jrmu]]: [==]%0a* [[Ircnow.Linux]]  . . . October 08, 2021, at 04:51 AM by [[~jrmu]]: [==]%0a* [[OpenBSD.ResetPassword]]  . . . October 07, 2021, at 03:56 AM by [[~jrmu]]: [==]%0a* [[Terms.Vps]]  . . . October 06, 2021, at 12:30 AM by [[~jrmu]]: [==]%0a* [[9.JSDrawterm]]  . . . September 30, 2021, at 06:06 PM by [[~jrmu]]: [==]%0a* [[9.Fonts]]  . . . September 28, 2021, at 05:13 PM by [[~jrmu]]: [==]%0a* [[Openbsd.Install69]]  . . . September 27, 2021, at 05:59 PM by [[~jrmu]]: [==]%0a* [[Cvs.Guide]]  . . . September 26, 2021, at 02:28 PM by [[~Miniontoby]]: [==]%0a* [[Openbsd.PFStable]]  . . . September 24, 2021, at 03:28 PM by [[~miniontoby]]: [==]%0a* [[License.IrcnowV2]]  . . . September 21, 2021, at 03:53 AM by [[~jrmu]]: [==]%0a* [[Dhcpd.Configure]]  . . . September 15, 2021, at 04:02 PM by [[~jrmu]]: [==]%0a* [[Vmm.Router]]  . . . September 14, 2021, at 12:11 PM by [[~jrmu]]: [==]%0a* [[Weechat.Relay]]  . . . September 11, 2021, at 05:46 PM by [[~mkf]]: [==]%0a* [[Gry.Bio]]  . . . September 11, 2021, at 02:49 AM by [[~jrmu]]: [==]%0a* [[Hopm.Telnet]]  . . . September 10, 2021, at 06:13 AM by [[~mkf]]: [==]%0a* [[Wraith.Chroot]]  . . . September 10, 2021, at 06:11 AM by [[~mkf]]: [==]%0a* [[Mutt.Connect]]  . . . September 10, 2021, at 06:01 AM by [[~mkf]]: [=6.8 -> 6.9=]%0a* [[ZNC.Skins]]  . . . September 06, 2021, at 07:58 AM by [[~mkf]]: [="Huh, pmwiki has a bug." no numbered list if use monospaced text. :(=]%0a* [[Seamonkey.Connect]]  . . . August 28, 2021, at 01:05 PM by [[~mkf]]: [==]%0a* [[Debate.Wikistyle]]  . . . August 27, 2021, at 03:29 PM by [[~mkf]]: [==]%0a* [[Email.EmailAndroidEmailApp]]  . . . August 27, 2021, at 02:37 PM by [[~mkf]]: [==]%0a* [[Tmux.Shortcuts]]  . . . August 27, 2021, at 12:56 PM by [[~mkf]]: [==]%0a* [[Vmm.Haiku]]  . . . August 27, 2021, at 12:53 PM by [[~mkf]]: [==]%0a* [[Openbsd.Mailopenproxy]]  . . . August 25, 2021, at 08:19 PM by [[~mkf]]: [==]%0a* [[Openbsd.Two-FactorAuth]]  . . . August 23, 2021, at 07:39 PM by [[~mkf]]: [=login.db compiling is no longer recommended.=]%0a* [[Vmm.DragonflyBSD]]  . . . August 23, 2021, at 07:31 PM by [[~mkf]]: [=logs=]%0a* [[Vmm.NetBSD]]  . . . August 23, 2021, at 07:01 PM by [[~mkf]]: [=better logs?=]%0a* [[Mariadb.Install]]  . . . August 23, 2021, at 04:42 PM by [[~wiz]]: [==]%0a* [[DNS.Ipv6rDNS]]  . . . August 23, 2021, at 11:55 AM by [[~jrmu]]: [==]%0a* [[Pipes.Redirection]]  . . . August 23, 2021, at 03:50 AM by [[~jrmu]]: [==]%0a* [[Ksh.Redirection]]  . . . August 23, 2021, at 03:50 AM by [[~jrmu]]: [==]%0a* [[DNS.RDNS]]  . . . August 22, 2021, at 11:20 PM by [[~jrmu]]: [==]%0a* [[Rbldnsd.Install]]  . . . August 22, 2021, at 07:58 PM by [[~mkf]]: [=wiki-ish.=]%0a* [[Netcat.Smtp]]  . . . August 22, 2021, at 06:58 PM by [[~mkf]]: [=byebye=]%0a* [[Vmm.UbuntuIso]]  . . . August 22, 2021, at 06:40 AM by [[~jrmu]]: [==]%0a* [[Vmm.DevuanIso]]  . . . August 22, 2021, at 05:44 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Npppd]]  . . . August 21, 2021, at 01:43 PM by [[~mkf]]: [==]%0a* [[Shell.Shell]]  . . . August 21, 2021, at 11:42 AM by [[~jrmu]]: [==]%0a* [[Tls.CA]]  . . . August 21, 2021, at 11:10 AM by [[~jrmu]]: [==]%0a* [[Openssl.Imap]]  . . . August 21, 2021, at 04:05 AM by [[~AncientWisdom]]: [==]%0a* [[Openbsd.FilePermissions]]  . . . August 20, 2021, at 02:20 AM by [[~Nate S]]: [==]%0a* [[Ircnow.Todo]]  . . . August 17, 2021, at 08:41 AM by [[~mkf]]: [==]%0a* [[Vmm.GuixIso]]  . . . August 16, 2021, at 05:12 PM by [[~jrmu]]: [==]%0a* [[Vmm.VoidIso]]  . . . August 16, 2021, at 06:19 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Gophernicus]]  . . . August 15, 2021, at 02:06 AM by [[~mkf]]: [==]%0a* [[Gazette.Gazette]]  . . . August 15, 2021, at 01:14 AM by [[~mkf]]: [=a bit polishing=]%0a* [[EmailTray.Connect]]  . . . August 15, 2021, at 12:11 AM by [[~mkf]]: [==]%0a* [[Bouncer.Konversation]]  . . . August 14, 2021, at 02:46 PM by [[~mkf]]: [==]%0a* [[Squirrelmail.Connect]]  . . . August 14, 2021, at 04:47 AM by [[~mkf]]: [==]%0a* [[Termius.Connect]]  . . . August 14, 2021, at 04:42 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Openhttpd]]  . . . August 13, 2021, at 07:29 AM by [[~jrmu]]: [==]%0a* [[ConnectBot.Keys]]  . . . August 12, 2021, at 06:58 AM by [[~jrmu]]: [==]%0a* [[Debate.Monopolydanger]]  . . . August 11, 2021, at 07:01 PM by [[~mkf]]: [==]%0a* [[ConnectBot.Connect]]  . . . August 11, 2021, at 04:34 PM by [[~jrmu]]: [==]%0a* [[Openbsd.ZNCModules]]  . . . August 11, 2021, at 03:06 PM by [[~wiz]]: [==]%0a* [[Termux.Connect]]  . . . August 11, 2021, at 05:28 AM by [[~jrmu]]: [==]%0a* [[Web101.Web101]]  . . . August 10, 2021, at 04:20 PM by [[~craziness]]: [=started web101=]%0a* [[Openbsd.Bitlbee]]  . . . August 10, 2021, at 12:03 PM by [[~mkf]]: [==]%0a* [[Openbsd.Pppoe]]  . . . August 10, 2021, at 11:56 AM by [[~mkf]]: [==]%0a* [[Sylpheed.Connect]]  . . . August 10, 2021, at 11:50 AM by [[~mkf]]: [=eh, forgot that "[" again=]%0a* [[MacTerminal.Connect]]  . . . August 10, 2021, at 10:33 AM by [[~jrmu]]: [==]%0a* [[OpenSSH.Connect]]  . . . August 10, 2021, at 10:19 AM by [[~jrmu]]: [==]%0a* [[Fdroid.Install]]  . . . August 10, 2021, at 09:05 AM by [[~jrmu]]: [==]%0a* [[Shell.Sshfingerprints]]  . . . August 10, 2021, at 08:55 AM by [[~jrmu]]: [==]%0a* [[OpenSSH.Keygen]]  . . . August 09, 2021, at 06:27 PM by [[~jrmu]]: [==]%0a* [[Openbsd.Sshkeys]]  . . . August 09, 2021, at 04:42 PM by [[~jrmu]]: [==]%0a* [[Vmm.9front]]  . . . August 09, 2021, at 06:16 AM by [[~mkf]]: [==]%0a* [[Bouncer.WinIRC]]  . . . August 09, 2021, at 06:03 AM by [[~mkf]]: [==]%0a* [[IP.Myaddress]]  . . . August 07, 2021, at 05:14 PM by [[~jrmu]]: [==]%0a* [[SerFISH.Connect]]  . . . August 06, 2021, at 05:05 PM by [[~jrmu]]: [==]%0a* [[Sshwifty.Connect]]  . . . August 06, 2021, at 05:00 PM by [[~jrmu]]: [==]%0a* [[Openbsd.Squirrelmail]]  . . . August 06, 2021, at 10:32 AM by [[~baytuch]]: [==]%0a* [[Eggdrop.NickServ]]  . . . August 05, 2021, at 07:27 AM by [[~jrmu]]: [==]%0a* [[Medals.Intro]]  . . . August 04, 2021, at 08:34 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Dnszones]]  . . . August 03, 2021, at 09:26 AM by [[~jrmu]]: [==]%0a* [[Dns.Zonefile]]  . . . August 03, 2021, at 09:21 AM by [[~jrmu]]: [==]%0a* [[Irc.Clients]]  . . . August 02, 2021, at 02:54 PM by [[~mkf]]: [==]%0a* [[Minutemin.Ifconfig]]  . . . August 02, 2021, at 12:59 PM by [[~mkf]]: [==]%0a* [[Openbsd.Matterbridge]]  . . . August 02, 2021, at 12:33 PM by [[~mkf]]: [==]%0a* [[Znc.I18n]]  . . . August 02, 2021, at 09:12 AM by [[~mkf]]: [==]%0a* [[Almanack.Alt]]  . . . August 02, 2021, at 07:52 AM by [[~jrmu]]: [==]%0a* [[Eggdrop.Simple]]  . . . August 02, 2021, at 07:49 AM by [[~jrmu]]: [==]%0a* [[Eggdrop.Install]]  . . . August 02, 2021, at 05:11 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Vhost]]  . . . August 02, 2021, at 02:32 AM by [[~jrmu]]: [==]%0a* [[Ircnow.Hardware]]  . . . August 01, 2021, at 01:48 PM by [[~jrmu]]: [==]%0a* [[Thunderirc.Hardware]]  . . . August 01, 2021, at 01:47 PM by [[~jrmu]]: [==]%0a* [[Planetofnix.Hardware]]  . . . August 01, 2021, at 01:46 PM by [[~jrmu]]: [==]%0a* [[Bsdforall.Hardware]]  . . . August 01, 2021, at 01:45 PM by [[~jrmu]]: [==]%0a* [[Oddprotocol.Hardware]]  . . . August 01, 2021, at 01:28 PM by [[~jrmu]]: [==]%0a* [[Lecturify.Hardware]]  . . . August 01, 2021, at 01:27 PM by [[~jrmu]]: [==]%0a* [[Eggdrop184.Install]]  . . . August 01, 2021, at 07:07 AM by [[~jrmu]]: [==]%0a* [[Congress.Procedure]]  . . . August 01, 2021, at 06:41 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Chroot]]  . . . July 31, 2021, at 02:47 AM by [[~jrmu]]: [==]%0a* [[Syslogd.Remote]]  . . . July 30, 2021, at 03:30 PM by [[~jrmu]]: [==]%0a* [[Openbsd.Vmmuser]]  . . . July 29, 2021, at 05:31 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Vmminstall]]  . . . July 29, 2021, at 05:28 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Vmm]]  . . . July 29, 2021, at 05:24 AM by [[~jrmu]]: [==]%0a* [[Openbsd.ZNCAdmin]]  . . . July 28, 2021, at 06:14 AM by [[~jrmu]]: [==]%0a* [[Openbsd.ZNCSupport]]  . . . July 28, 2021, at 06:14 AM by [[~jrmu]]: [==]%0a* [[ZNC.Troubleshoot]]  . . . July 28, 2021, at 06:12 AM by [[~jrmu]]: [==]%0a* [[Znc.Troubleshoot]]  . . . July 28, 2021, at 06:11 AM by [[~jrmu]]: [==]%0a* [[Kill.Usage]]  . . . July 28, 2021, at 03:42 AM by [[~jrmu]]: [==]%0a* [[Ps.Usage]]  . . . July 28, 2021, at 03:42 AM by [[~jrmu]]: [==]%0a* [[Dns.Vhost]]  . . . July 28, 2021, at 03:05 AM by [[~jrmu]]: [==]%0a* [[Host.Usage]]  . . . July 28, 2021, at 01:57 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Php]]  . . . July 27, 2021, at 02:53 PM by [[~jrmu]]: [==]%0a* [[UsersCategoryMirrory.IRCFreeHomesteadVPS]]  . . . July 26, 2021, at 06:12 AM by [[~category_mirror]]: [==]%0a* [[Ircnow.PioneerTldr]]  . . . July 26, 2021, at 06:04 AM by [[~jrmu]]: [==]%0a* [[UsersCategoryMirrory.Pioneer]]  . . . July 26, 2021, at 04:22 AM by [[~category_mirror]]: [==]%0a* [[Openbsd.Dig]]  . . . July 25, 2021, at 06:50 AM by [[~jrmu]]: [==]%0a* [[Openbsd.RDNS]]  . . . July 23, 2021, at 06:44 AM by [[~jrmu]]: [==]%0a* [[Wordpress.Install]]  . . . July 21, 2021, at 06:59 PM by [[~mkf]]: [==]%0a* [[Bouncer.All]]  . . . July 21, 2021, at 06:37 PM by [[~mkf]]: [==]%0a* [[Lemon.Todo]]  . . . July 21, 2021, at 06:21 PM by [[~mkf]]: [==]%0a* [[Irc.Guide]]  . . . July 21, 2021, at 06:02 PM by [[~mkf]]: [=client -> clients=]%0a* [[Openbsd.Sic]]  . . . July 21, 2021, at 05:57 PM by [[~mkf]]: [=first edit.=]%0a* [[Minutemin.Progress]]  . . . July 21, 2021, at 08:10 AM by [[~jrmu]]: [==]%0a* [[Openssl.Check]]  . . . July 20, 2021, at 01:27 PM by [[~jrmu]]: [==]%0a* [[Rsync.Usage]]  . . . July 19, 2021, at 02:30 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Openrsync]]  . . . July 18, 2021, at 02:01 PM by [[~jrmu]]: [==]%0a* [[Eggdrop.DuckHunt]]  . . . July 17, 2021, at 06:34 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Znc]]  . . . July 16, 2021, at 10:43 AM by [[~jrmu]]: [==]%0a* [[Netizen.Become]]  . . . July 14, 2021, at 09:47 AM by [[~jrmu]]: [==]%0a* [[Freedom.Bearcode]]  . . . July 14, 2021, at 09:42 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Staticnet]]  . . . July 12, 2021, at 05:48 PM by [[~jrmu]]: [==]%0a* [[Openbsd.Dovecot]]  . . . July 12, 2021, at 02:58 PM by [[~jrmu]]: [==]%0a* [[Openbsd.Relayd]]  . . . July 12, 2021, at 02:45 PM by [[~jrmu]]: [==]%0a* [[Openbsd.Spf]]  . . . July 12, 2021, at 03:08 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Eggdrop]]  . . . July 02, 2021, at 03:20 AM by [[~jrmu]]: [==]%0a* [[Openssl.Http]]  . . . June 30, 2021, at 04:44 AM by [[~mkf]]: [==]%0a* [[Debate.Oldsoftware]]  . . . June 29, 2021, at 03:56 PM by [[~mkf]]: [==]%0a* [[Debate.Xmlflaws]]  . . . June 29, 2021, at 03:54 PM by [[~mkf]]: [==]%0a* [[Debate.Wikipediadanger]]  . . . June 29, 2021, at 03:51 PM by [[~mkf]]: [==]%0a* [[Debate.DCC]]  . . . June 29, 2021, at 03:49 PM by [[~mkf]]: [==]%0a* [[Debate.Matrixflaws]]  . . . June 29, 2021, at 03:48 PM by [[~mkf]]: [==]%0a* [[Debate.Webirc]]  . . . June 29, 2021, at 03:48 PM by [[~mkf]]: [==]%0a* [[Debate.Nodejstrap]]  . . . June 29, 2021, at 03:48 PM by [[~mkf]]: [==]%0a* [[Debate.Ircv3defense]]  . . . June 29, 2021, at 03:45 PM by [[~mkf]]: [==]%0a* [[Openbsd.Newdisk]]  . . . June 29, 2021, at 03:23 PM by [[~jrmu]]: [==]%0a* [[AndroidEmail.AndroidEmail]]  . . . June 29, 2021, at 03:11 PM by [[~jrmu]]: [==]%0a* [[Openbsd.Ed]]  . . . June 28, 2021, at 04:04 PM by [[~mkf]]: [==]%0a* [[Openbsd.Unbound]]  . . . June 27, 2021, at 12:12 PM by [[~jrmu]]: [==]%0a* [[Freedom.Religion]]  . . . June 27, 2021, at 02:02 AM by [[~jrmu]]: [==]%0a* [[Tor.Hidden]]  . . . June 26, 2021, at 08:56 PM by [[~mkf]]: [==]%0a* [[Freedom.Union]]  . . . June 26, 2021, at 01:01 PM by [[~jrmu]]: [==]%0a* [[Freedom.Firstamendment]]  . . . June 26, 2021, at 11:45 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Dkimproxy]]  . . . June 25, 2021, at 12:56 PM by [[~jrmu]]: [==]%0a* [[MIF.Test]]  . . . June 25, 2021, at 12:42 PM by [[~nsturtz]]: [==]%0a* [[Openbsd.Sysupgrade69]]  . . . June 25, 2021, at 05:46 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Opensmtpd]]  . . . June 23, 2021, at 02:21 AM by [[~jrmu]]: [==]%0a* [[Openbsd.NgircdLink]]  . . . June 22, 2021, at 07:50 PM by [[~mkf]]: [=delete=]%0a* [[File.File]]  . . . June 22, 2021, at 07:43 PM by [[~mkf]]: [=linking=]%0a* [[Debate.Linuxflaws]]  . . . June 20, 2021, at 08:03 AM by [[~mkf]]: [=making hyperlinks=]%0a* [[Police.Intro]]  . . . June 19, 2021, at 11:42 AM by [[~jrmu]]: [==]%0a* [[Freedom.Destiny]]  . . . June 18, 2021, at 05:31 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Doas]]  . . . June 13, 2021, at 01:19 PM by [[~jrmu]]: [==]%0a* [[Freedom.Freedom]]  . . . June 13, 2021, at 09:13 AM by [[~jrmu]]: [==]%0a* [[Freedom.Press]]  . . . June 13, 2021, at 09:12 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Shell]]  . . . June 11, 2021, at 09:36 AM by [[~jrmu]]: [==]%0a* [[Ircnow.Constitution]]  . . . June 10, 2021, at 03:48 PM by [[~jrmu]]: [==]%0a* [[Netizen.Rights]]  . . . June 10, 2021, at 03:21 PM by [[~jrmu]]: [==]%0a* [[IPv4.Overview]]  . . . June 10, 2021, at 10:13 AM by [[~jrmu]]: [==]%0a* [[Ksh.Bash]]  . . . June 09, 2021, at 11:31 AM by [[~jrmu]]: [==]%0a* [[PowerShell.Connect]]  . . . June 09, 2021, at 11:10 AM by [[~jrmu]]: [==]%0a* [[Code.Code]]  . . . June 08, 2021, at 05:24 PM by [[~mkf]]: [=better formating=]%0a* [[Grape.DonateUs]]  . . . June 06, 2021, at 03:41 PM by [[~fizi]]: [==]%0a* [[Openbsd.Books]]  . . . June 06, 2021, at 12:46 PM by [[~jrmu]]: [==]%0a* [[Grape.Grape]]  . . . June 06, 2021, at 11:39 AM by [[~fizi]]: [==]%0a* [[Openbsd.Pfa]]  . . . June 06, 2021, at 03:49 AM by [[~navic]]: [==]%0a* [[Vmm.Debian]]  . . . June 04, 2021, at 07:48 PM by [[~mkf]]: [="LOL"=]%0a* [[DNS.Dnswl]]  . . . June 04, 2021, at 11:11 AM by [[~jrmu]]: [==]%0a* [[Netcat.SMTP]]  . . . June 04, 2021, at 09:59 AM by [[~jrmu]]: [==]%0a* [[Dkim.Dkimsign]]  . . . June 04, 2021, at 09:07 AM by [[~jrmu]]: [==]%0a* [[Tor.Torsocks]]  . . . June 04, 2021, at 06:16 AM by [[~jrmu]]: [==]%0a* [[Vpn.VpnIos]]  . . . June 04, 2021, at 05:52 AM by [[~jrmu]]: [==]%0a* [[Vpn.VpnMac]]  . . . June 04, 2021, at 05:40 AM by [[~jrmu]]: [==]%0a* [[Fdisk.Usage]]  . . . June 04, 2021, at 05:04 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Wordpress]]  . . . June 04, 2021, at 04:55 AM by [[~jrmu]]: [==]%0a* [[DNS.SPF]]  . . . June 03, 2021, at 01:27 PM by [[~jrmu]]: [==]%0a* [[Terms.Terms]]  . . . June 02, 2021, at 01:40 PM by [[~jrmu]]: [==]%0a* [[HostServ.Rules]]  . . . June 01, 2021, at 08:11 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Anope]]  . . . May 31, 2021, at 10:24 AM by [[~miniontoby]]: [=cp=]%0a* [[Openbsd.ACKFlood]]  . . . May 29, 2021, at 06:20 AM by [[~mkf]]: [==]%0a* [[Openbsd.SSDP]]  . . . May 29, 2021, at 06:18 AM by [[~mkf]]: [==]%0a* [[Openbsd.Anycast]]  . . . May 29, 2021, at 06:01 AM by [[~mkf]]: [==]%0a* [[Ambassador.Networks]]  . . . May 27, 2021, at 04:05 PM by [[~jrmu]]: [==]%0a* [[Marketing.Rules]]  . . . May 26, 2021, at 06:15 AM by [[~jrmu]]: [==]%0a* [[Freenode.Power]]  . . . May 26, 2021, at 04:38 AM by [[~jrmu]]: [==]%0a* [[Freenode.Money]]  . . . May 25, 2021, at 03:29 PM by [[~jrmu]]: [==]%0a* [[Freenode.Takeover]]  . . . May 25, 2021, at 05:28 AM by [[~jrmu]]: [==]%0a* [[Freedom.Freenode]]  . . . May 25, 2021, at 01:48 AM by [[~jrmu]]: [==]%0a* [[Bouncer.Atomic]]  . . . May 24, 2021, at 03:22 PM by [[~mkf]]: [=spacing=]%0a* [[Minetest.Updating]]  . . . May 24, 2021, at 08:10 AM by [[~mkf]]: [=monospaced commands=]%0a* [[Shell.Putty]]  . . . May 24, 2021, at 06:16 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Dmarc]]  . . . May 21, 2021, at 09:22 AM by [[~jrmu]]: [==]%0a* [[Vmm.Optimize]]  . . . May 19, 2021, at 04:04 AM by [[~jrmu]]: [==]%0a* [[Ircnow.Stable]]  . . . May 18, 2021, at 10:15 AM by [[~mkf]]: [==]%0a* [[Ircnow.VicePresident]]  . . . May 18, 2021, at 08:15 AM by [[~jrmu]]: [==]%0a* [[Ircnow.Sheriff]]  . . . May 18, 2021, at 08:00 AM by [[~jrmu]]: [==]%0a* [[Ircnow.Ambassador]]  . . . May 18, 2021, at 07:42 AM by [[~jrmu]]: [==]%0a* [[Pf.Guide]]  . . . May 17, 2021, at 03:37 AM by [[~bejelentkezni]]: [==]%0a* [[Openbsd.Disklabel]]  . . . May 17, 2021, at 03:33 AM by [[~bejelentkezni]]: [==]%0a* [[Openbsd.Fdisk]]  . . . May 17, 2021, at 03:27 AM by [[~bejelentkezni]]: [==]%0a* [[NewsNow.Install]]  . . . May 16, 2021, at 06:49 AM by [[~mkf]]: [="$"=]%0a* [[Tmux.Share]]  . . . May 15, 2021, at 02:27 AM by [[~mistera]]: [==]%0a* [[Openbsd.Security]]  . . . May 14, 2021, at 03:14 AM by [[~caesar]]: [==]%0a* [[Bouncer.Vision]]  . . . May 13, 2021, at 09:47 AM by [[~mkf]]: [=added home page, removed "..."s=]%0a* [[Minetest.Worldbackup]]  . . . May 12, 2021, at 11:02 AM by [[~AES]]: [==]%0a* [[Minetest.Texturestyle]]  . . . May 12, 2021, at 11:00 AM by [[~AES]]: [==]%0a* [[Minetest.Serverlocations]]  . . . May 12, 2021, at 10:59 AM by [[~AES]]: [==]%0a* [[Minetest.Addingarenas]]  . . . May 12, 2021, at 10:58 AM by [[~jrmu]]: [==]%0a* [[Relay.Relay]]  . . . May 12, 2021, at 09:10 AM by [[~jrmu]]: [==]%0a* [[Ngircd.Install-bej]]  . . . May 11, 2021, at 05:26 AM by [[~bejelentkezni]]: [==]%0a* [[Botnow.Botnow]]  . . . May 08, 2021, at 09:44 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Hopm-Arthur]]  . . . May 07, 2021, at 12:28 PM by [[~Arthur]]: [==]%0a* [[Znc.Chroot69]]  . . . May 06, 2021, at 03:36 AM by [[~bejelentkezni]]: [=back to 6.9 to see real changes=]%0a* [[Dig.Usage]]  . . . May 04, 2021, at 02:36 AM by [[~sarah]]: [==]%0a* [[Bgpd.Configure]]  . . . May 03, 2021, at 06:26 AM by [[~jrmu]]: [==]%0a* [[Cherry.Cherry]]  . . . May 02, 2021, at 01:43 PM by [[~Oz]]: [==]%0a* [[Freedom.Unix]]  . . . April 29, 2021, at 03:39 PM by [[~jrmu]]: [==]%0a* [[Pmwiki.Simpleurl]]  . . . April 29, 2021, at 02:46 PM by [[~punk]]: [==]%0a* [[Gpl.Flaws]]  . . . April 24, 2021, at 04:56 PM by [[~jrmu]]: [==]%0a* [[Iked.Windows]]  . . . April 18, 2021, at 07:38 PM by [[~st13g]]: [==]%0a* [[Freedom.Libertyordeath]]  . . . April 17, 2021, at 12:35 PM by [[~jrmu]]: [==]%0a* [[Minetest.Economy]]  . . . April 15, 2021, at 02:32 PM by [[~jrmu]]: [==]%0a* [[Vim.Vim]]  . . . April 11, 2021, at 11:14 PM by [[~monaco]]: [==]%0a* [[Minutemin.Duty]]  . . . April 11, 2021, at 04:53 AM by [[~jrmu]]: [==]%0a* [[License.License]]  . . . April 04, 2021, at 02:00 AM by [[~jrmu]]: [==]%0a* [[EthicalSource.HolierThanThou]]  . . . April 04, 2021, at 01:56 AM by [[~jrmu]]: [==]%0a* [[Jrmu.Rmsboycott]]  . . . April 03, 2021, at 01:36 AM by [[~jrmu]]: [==]%0a* [[Jrmu.Libertyordeath]]  . . . April 02, 2021, at 12:56 PM by [[~jrmu]]: [==]%0a* [[Fig.Fig]]  . . . March 31, 2021, at 10:15 AM by [[~chewy]]: [==]%0a* [[Coconut.Coconut]]  . . . March 29, 2021, at 12:28 PM by [[~jrmu]]: [==]%0a* [[Ircnow.CodeForce]]  . . . March 29, 2021, at 12:04 PM by [[~jrmu]]: [==]%0a* [[ClawsMail.Connect]]  . . . March 29, 2021, at 08:42 AM by [[~miniontoby]]: [==]%0a* [[Freedom.Madeonirc]]  . . . March 27, 2021, at 11:48 AM by [[~jrmu]]: [==]%0a* [[Third.Devs]]  . . . March 27, 2021, at 11:41 AM by [[~jrmu]]: [==]%0a* [[Minutemin.Code]]  . . . March 24, 2021, at 03:26 AM by [[~jrmu]]: [==]%0a* [[Cherry.Todo]]  . . . March 23, 2021, at 03:23 PM by [[~Oz]]: [==]%0a* [[Freedom.Independence]]  . . . March 22, 2021, at 01:13 PM by [[~wiz]]: [==]%0a* [[Ifconfig.Change]]  . . . March 20, 2021, at 11:15 AM by [[~jrmu]]: [==]%0a* [[Marketing.Founders]]  . . . March 20, 2021, at 01:40 AM by [[~jrmu]]: [==]%0a* [[NewsNow.Teams]]  . . . March 18, 2021, at 09:47 AM by [[~miniontoby]]: [=banana=]%0a* [[NewsNow.NewsNow]]  . . . March 17, 2021, at 04:33 PM by [[~miniontoby]]: [=more ways=]%0a* [[Vhost.Freedns]]  . . . March 16, 2021, at 12:22 PM by [[~wiz]]: [==]%0a* [[Marketing.Freedom]]  . . . March 15, 2021, at 01:30 PM by [[~jrmu]]: [==]%0a* [[Bsd.Labor]]  . . . March 15, 2021, at 06:12 AM by [[~jrmu]]: [==]%0a* [[License.Discriminatory]]  . . . March 15, 2021, at 06:12 AM by [[~jrmu]]: [==]%0a* [[Bsd.Hope]]  . . . March 14, 2021, at 11:05 PM by [[~jrmu]]: [==]%0a* [[License.Publicdomain]]  . . . March 14, 2021, at 10:02 AM by [[~jrmu]]: [==]%0a* [[Linux.Flaws]]  . . . March 14, 2021, at 05:13 AM by [[~jrmu]]: [==]%0a* [[NewsNow.Browser]]  . . . March 12, 2021, at 08:00 AM by [[~miniontoby]]: [==]%0a* [[Abuse.Code]]  . . . March 09, 2021, at 03:44 PM by [[~jrmu]]: [==]%0a* [[Congress.Documents]]  . . . March 07, 2021, at 04:50 AM by [[~jrmu]]: [==]%0a* [[Ircnow.Goals]]  . . . March 06, 2021, at 09:33 AM by [[~jrmu]]: [==]%0a* [[Ircnow.Chatforce]]  . . . March 05, 2021, at 02:15 PM by [[~jrmu]]: [==]%0a* [[Shell.Bash]]  . . . March 05, 2021, at 10:19 AM by [[~jrmu]]: [==]%0a* [[User.Welcome]]  . . . March 05, 2021, at 07:34 AM by [[~jrmu]]: [==]%0a* [[Immigrant.Welcome]]  . . . March 05, 2021, at 06:59 AM by [[~jrmu]]: [==]%0a* [[Mail.Openrelay]]  . . . March 04, 2021, at 03:20 PM by [[~jrmu]]: [==]%0a* [[Mail.Test]]  . . . March 04, 2021, at 03:07 PM by [[~jrmu]]: [==]%0a* [[Minutemin.Game]]  . . . March 04, 2021, at 10:16 AM by [[~jrmu]]: [==]%0a* [[Marketing.Recruit]]  . . . March 04, 2021, at 09:39 AM by [[~jrmu]]: [==]%0a* [[Ircnow.Howtoask]]  . . . March 03, 2021, at 12:35 PM by [[~jrmu]]: [==]%0a* [[Ircnow.Netizen]]  . . . February 28, 2021, at 03:18 PM by [[~jrmu]]: [==]%0a* [[Servers.Rights]]  . . . February 28, 2021, at 12:37 PM by [[~jrmu]]: [==]%0a* [[Marketing.Enterprise]]  . . . February 28, 2021, at 11:52 AM by [[~jrmu]]: [==]%0a* [[Minutemin.Creed]]  . . . February 28, 2021, at 03:21 AM by [[~jrmu]]: [==]%0a* [[Ln.Intro]]  . . . February 25, 2021, at 12:20 PM by [[~jrmu]]: [==]%0a* [[Leafnode.Install]]  . . . February 25, 2021, at 10:56 AM by [[~jrmu]]: [==]%0a* [[Guava.Todo]]  . . . February 23, 2021, at 10:47 AM by [[~quofan]]: [==]%0a* [[Relays.Relays]]  . . . February 22, 2021, at 04:22 PM by [[~jrmu]]: [==]%0a* [[Jujube.Jujube]]  . . . February 21, 2021, at 04:22 PM by [[~fizi]]: [==]%0a* [[PSFTP.Connect]]  . . . February 21, 2021, at 03:57 PM by [[~jrmu]]: [==]%0a* [[Outlook.Connect]]  . . . February 21, 2021, at 03:23 PM by [[~jrmu]]: [==]%0a* [[AppleMail.Connect]]  . . . February 20, 2021, at 04:38 PM by [[~jrmu]]: [==]%0a* [[Thunderbird.Pgp]]  . . . February 19, 2021, at 04:44 PM by [[~jrmu]]: [==]%0a* [[License.Ircnow]]  . . . February 19, 2021, at 09:45 AM by [[~miniontoby]]: [=2021=]%0a* [[Thunderbird.Connect]]  . . . February 19, 2021, at 09:36 AM by [[~jrmu]]: [==]%0a* [[Shell.Mac]]  . . . February 19, 2021, at 09:14 AM by [[~jrmu]]: [==]%0a* [[Minutemin.Training]]  . . . February 18, 2021, at 06:42 AM by [[~jrmu]]: [==]%0a* [[Freedom.Openforeveryone]]  . . . February 16, 2021, at 04:33 AM by [[~jrmu]]: [==]%0a* [[Ircnow.IRCitizen]]  . . . February 15, 2021, at 05:32 AM by [[~jrmu]]: [==]%0a* [[IPv6.Overview]]  . . . February 14, 2021, at 11:09 AM by [[~jrmu]]: [==]%0a* [[Tcpip.Overview]]  . . . February 14, 2021, at 11:02 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Syspatch]]  . . . February 14, 2021, at 11:00 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Netadmin]]  . . . February 14, 2021, at 10:56 AM by [[~jrmu]]: [==]%0a* [[Marketing.Religion]]  . . . February 14, 2021, at 10:37 AM by [[~jrmu]]: [==]%0a* [[Marketing.Independence]]  . . . February 13, 2021, at 04:59 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Leafnode]]  . . . February 12, 2021, at 01:40 PM by [[~chewy]]: [==]%0a* [[Oidentd.Pylink]]  . . . February 12, 2021, at 01:25 PM by [[~jrmu]]: [==]%0a* [[Marketing.Opportunity]]  . . . February 11, 2021, at 12:58 PM by [[~jrmu]]: [==]%0a* [[Marketing.Republic]]  . . . February 11, 2021, at 06:45 AM by [[~jrmu]]: [==]%0a* [[Achurch.Install]]  . . . February 10, 2021, at 04:33 PM by [[~jrmu]]: [==]%0a* [[Openbsd.Pylink]]  . . . February 08, 2021, at 08:33 AM by [[~jrmu]]: [==]%0a* [[Ircnow.OpofLiberty]]  . . . February 06, 2021, at 12:53 PM by [[~jrmu]]: [==]%0a* [[Ircnow.Allies]]  . . . February 06, 2021, at 12:47 PM by [[~jrmu]]: [==]%0a* [[Freedom.Dueprocess]]  . . . February 06, 2021, at 12:25 PM by [[~jrmu]]: [==]%0a* [[Freedom.Checks]]  . . . February 06, 2021, at 12:21 PM by [[~jrmu]]: [==]%0a* [[Freedom.Rulebylaw]]  . . . February 06, 2021, at 12:12 PM by [[~jrmu]]: [==]%0a* [[Freedom.Startupdream]]  . . . February 06, 2021, at 12:12 PM by [[~jrmu]]: [==]%0a* [[Freedom.Federation]]  . . . February 06, 2021, at 11:44 AM by [[~jrmu]]: [==]%0a* [[Freedom.Selfadmin]]  . . . February 06, 2021, at 11:26 AM by [[~jrmu]]: [==]%0a* [[Ircnow.OpsofLiberty]]  . . . February 06, 2021, at 02:13 AM by [[~jrmu]]: [==]%0a* [[Freedom.Homestead]]  . . . February 05, 2021, at 12:49 PM by [[~jrmu]]: [==]%0a* [[Freedom.Software]]  . . . February 05, 2021, at 11:31 AM by [[~jrmu]]: [==]%0a* [[Freedom.Opportunity]]  . . . February 05, 2021, at 08:55 AM by [[~jrmu]]: [==]%0a* [[Unix.Workethic]]  . . . February 05, 2021, at 08:49 AM by [[~jrmu]]: [==]%0a* [[Unix.Ethic]]  . . . February 05, 2021, at 08:48 AM by [[~jrmu]]: [==]%0a* [[Freedom.Privacy]]  . . . February 05, 2021, at 07:26 AM by [[~jrmu]]: [==]%0a* [[Debate.Privacy]]  . . . February 05, 2021, at 07:05 AM by [[~jrmu]]: [==]%0a* [[Team.Policy]]  . . . February 04, 2021, at 04:08 PM by [[~jrmu]]: [==]%0a* [[Freedom.Serversrights]]  . . . February 04, 2021, at 02:43 PM by [[~jrmu]]: [==]%0a* [[Freedom.Serverrights]]  . . . February 04, 2021, at 02:42 PM by [[~jrmu]]: [==]%0a* [[Freedom.Fork]]  . . . February 04, 2021, at 02:39 PM by [[~jrmu]]: [==]%0a* [[Freedom.Lanofopportunity]]  . . . February 04, 2021, at 01:24 PM by [[~jrmu]]: [==]%0a* [[Freedom.Opentoall]]  . . . February 04, 2021, at 01:17 PM by [[~jrmu]]: [==]%0a* [[Freedom.Refuge]]  . . . February 04, 2021, at 09:31 AM by [[~jrmu]]: [==]%0a* [[Dns.Providers]]  . . . February 04, 2021, at 04:27 AM by [[~jrmu]]: [==]%0a* [[Guava.Guava]]  . . . February 03, 2021, at 02:30 AM by [[~st13g]]: [==]%0a* [[Openbsd.Stable]]  . . . February 02, 2021, at 02:25 PM by [[~jrmu]]: [==]%0a* [[Openbsd.Base64]]  . . . February 02, 2021, at 06:37 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Unboundadblock]]  . . . February 02, 2021, at 04:29 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Pfbadhost]]  . . . February 02, 2021, at 04:29 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Wraith]]  . . . February 02, 2021, at 04:22 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Delphinusdnsd]]  . . . February 02, 2021, at 01:51 AM by [[~jrmu]]: [==]%0a* [[Mango.Mango]]  . . . January 31, 2021, at 12:01 PM by [[~nix]]: [==]%0a* [[Openbsd.Abuse]]  . . . January 31, 2021, at 05:33 AM by [[~jrmu]]: [==]%0a* [[Freedom.Censorship]]  . . . January 31, 2021, at 05:23 AM by [[~jrmu]]: [==]%0a* [[Debate.Firstamendment]]  . . . January 31, 2021, at 05:20 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Phishing]]  . . . January 31, 2021, at 05:02 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Audit]]  . . . January 31, 2021, at 04:46 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Ongoing]]  . . . January 31, 2021, at 01:19 AM by [[~jrmu]]: [==]%0a* [[Ircnow.Partners]]  . . . January 31, 2021, at 12:32 AM by [[~jrmu]]: [==]%0a* [[Orange.Todo]]  . . . January 30, 2021, at 11:31 AM by [[~jrmu]]: [==]%0a* [[Pear.Pear]]  . . . January 29, 2021, at 06:09 PM by [[~dennis]]: [==]%0a* [[Openbsd.Httpopenproxy]]  . . . January 29, 2021, at 11:01 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Zncadmin]]  . . . January 29, 2021, at 10:00 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Rbldns]]  . . . January 29, 2021, at 05:45 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Setuid]]  . . . January 28, 2021, at 06:53 AM by [[~jrmu]]: [==]%0a* [[Openbsd.PFTesting]]  . . . January 25, 2021, at 03:28 PM by [[~jrmu]]: [==]%0a* [[Openbsd.ZNCDaily]]  . . . January 25, 2021, at 11:35 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Irssi]]  . . . January 25, 2021, at 07:08 AM by [[~jrmu]]: [==]%0a* [[Ircnow.Sysadmins]]  . . . January 24, 2021, at 10:36 AM by [[~jrmu]]: [==]%0a* [[Debate.UnixPhilosophy]]  . . . January 18, 2021, at 05:05 AM by [[~category_mirror]]: [==]%0a* [[Openbsd.XTerm]]  . . . January 17, 2021, at 01:48 PM by [[~miniontoby]]: [=copyright=]%0a* [[UsersCategoryMirrory.Statement]]  . . . January 17, 2021, at 02:44 AM by [[~category_mirror]]: [==]%0a* [[Email.Outlook]]  . . . January 16, 2021, at 05:13 PM by [[~Zouheir]]: [==]%0a* [[Plum.Todo]]  . . . January 16, 2021, at 12:09 AM by [[~st13g]]: [==]%0a* [[Debate.Ipsec]]  . . . January 13, 2021, at 10:39 AM by [[~jrmu]]: [==]%0a* [[Plum.Plum]]  . . . January 12, 2021, at 03:02 PM by [[~wiz]]: [==]%0a* [[Openbsd.Slrn]]  . . . January 12, 2021, at 02:40 PM by [[~Noxturnix]]: [==]%0a* [[OpenBSD.CPAN]]  . . . January 12, 2021, at 01:48 PM by [[~Dima]]: [==]%0a* [[Jujube.Todo]]  . . . January 11, 2021, at 05:13 PM by [[~fizi]]: [==]%0a* [[Ircnow.Ilines]]  . . . January 11, 2021, at 09:55 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Netcat]]  . . . January 09, 2021, at 02:20 PM by [[~jrmu]]: [==]%0a* [[OpenBSD.Perl]]  . . . January 09, 2021, at 02:04 PM by [[~dima]]: [==]%0a* [[Openbsd.Perl]]  . . . January 09, 2021, at 01:52 PM by [[~jrmu]]: [==]%0a* [[Fig.Log]]  . . . January 07, 2021, at 11:23 AM by [[~dima]]: [=test=]%0a* [[Fig.Todo]]  . . . January 06, 2021, at 01:06 PM by [[~jrmu]]: [==]%0a* [[Grape.Todo]]  . . . January 06, 2021, at 01:05 PM by [[~jrmu]]: [==]%0a* [[Pear.Todo]]  . . . January 06, 2021, at 01:05 PM by [[~jrmu]]: [==]%0a* [[Jujube.Team]]  . . . January 06, 2021, at 01:04 PM by [[~jrmu]]: [==]%0a* [[Mango.Todo]]  . . . January 06, 2021, at 01:04 PM by [[~jrmu]]: [==]%0a* [[Ircnow.Censorship]]  . . . January 06, 2021, at 03:01 AM by [[~jrmu]]: [==]%0a* [[Ircnow.Pentesters]]  . . . January 05, 2021, at 11:17 AM by [[~jrmu]]: [==]%0a* [[Ircnow.Coders]]  . . . January 05, 2021, at 11:11 AM by [[~jrmu]]: [==]%0a* [[Banana.Todo]]  . . . January 04, 2021, at 09:41 AM by [[~miniontoby]]: [=znc=]%0a* [[Users.CategoryMirrory]]  . . . January 04, 2021, at 01:10 AM by [[~category_mirror]]: [==]%0a* [[UsersCategoryMirrory.Test]]  . . . January 03, 2021, at 08:17 PM by [[~category_mirrory]]: [==]%0a* [[Users.Categorymirrory]]  . . . January 03, 2021, at 08:12 PM by [[~category_mirrory]]: [=wrong caps=]%0a* [[Banana.Banana]]  . . . January 03, 2021, at 02:39 PM by [[~miniontoby]]: [==]%0a* [[Orange.Orange]]  . . . January 03, 2021, at 02:10 PM by [[~jrmu]]: [==]%0a* [[Openbsd.Backup]]  . . . January 03, 2021, at 01:46 PM by [[~jrmu]]: [==]%0a* [[Openbsd.Backups]]  . . . January 02, 2021, at 11:44 AM by [[~jrmu]]: [==]%0a* [[Debate.Appledanger]]  . . . January 02, 2021, at 01:35 AM by [[~jrmu]]: [==]%0a* [[Grape.Tasks]]  . . . January 01, 2021, at 07:52 PM by [[~fizi]]: [==]%0a* [[Ircnow.Helpers]]  . . . January 01, 2021, at 04:36 AM by [[~jrmu]]: [==]%0a* [[Ircnow.Finances]]  . . . January 01, 2021, at 04:15 AM by [[~jrmu]]: [==]%0a* [[Tutorial.Tutorial]]  . . . January 01, 2021, at 03:25 AM by [[~jrmu]]: [==]%0a* [[Ircnow.Testing]]  . . . December 30, 2020, at 12:58 PM by [[~jrmu]]: [==]%0a* [[Openbsd.Sshbackdoor]]  . . . December 30, 2020, at 12:14 PM by [[~jrmu]]: [==]%0a* [[Mango.Packages]]  . . . December 30, 2020, at 10:48 AM by [[~nix]]: [==]%0a* [[Ircnow.Contact]]  . . . December 30, 2020, at 03:18 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Pf-bnc]]  . . . December 29, 2020, at 06:30 PM by [[~jrmu]]: [==]%0a* [[Ircnow.Partners2]]  . . . December 29, 2020, at 02:52 PM by [[~jrmu]]: [==]%0a* [[Openbsd.Tcltls]]  . . . December 29, 2020, at 09:53 AM by [[~jrmu]]: [==]%0a* [[Debate.Mozilladanger]]  . . . December 27, 2020, at 03:05 AM by [[~jrmu]]: [==]%0a* [[Debate.Controlcomputer]]  . . . December 27, 2020, at 03:02 AM by [[~jrmu]]: [==]%0a* [[Debate.Facebookdanger]]  . . . December 27, 2020, at 03:01 AM by [[~jrmu]]: [==]%0a* [[Debate.Slackdanger]]  . . . December 27, 2020, at 02:56 AM by [[~jrmu]]: [==]%0a* [[Debate.Freespeech]]  . . . December 27, 2020, at 02:36 AM by [[~jrmu]]: [==]%0a* [[Debate.Ethicalflaws]]  . . . December 27, 2020, at 02:31 AM by [[~jrmu]]: [==]%0a* [[Debate.Hatespeech]]  . . . December 27, 2020, at 02:20 AM by [[~jrmu]]: [==]%0a* [[Debate.Monero]]  . . . December 27, 2020, at 02:02 AM by [[~jrmu]]: [==]%0a* [[Debate.WhyNotC]]  . . . December 26, 2020, at 06:43 PM by [[~searchsocial]]: [==]%0a* [[Debate.Python]]  . . . December 26, 2020, at 06:21 PM by [[~jrmu]]: [==]%0a* [[Debate.Cash]]  . . . December 26, 2020, at 06:18 PM by [[~jrmu]]: [==]%0a* [[Debate.Uberdanger]]  . . . December 26, 2020, at 06:16 PM by [[~jrmu]]: [==]%0a* [[Debate.Microsoftdanger]]  . . . December 26, 2020, at 06:15 PM by [[~jrmu]]: [==]%0a* [[Debate.Accessibility]]  . . . December 26, 2020, at 06:14 PM by [[~jrmu]]: [==]%0a* [[Debate.Zoomdanger]]  . . . December 26, 2020, at 06:08 PM by [[~jrmu]]: [==]%0a* [[Shell.Applications]]  . . . December 19, 2020, at 06:21 PM by [[~fizi]]: [==]%0a* [[Third.Dillo]]  . . . December 19, 2020, at 01:52 PM by [[~jrmu]]: [==]%0a* [[Third.Basilisk]]  . . . December 19, 2020, at 01:38 PM by [[~jrmu]]: [==]%0a* [[Third.Directory]]  . . . December 19, 2020, at 01:35 PM by [[~jrmu]]: [==]%0a* [[Guava.Packages]]  . . . December 19, 2020, at 06:14 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Amplification]]  . . . December 19, 2020, at 05:42 AM by [[~jrmu]]: [==]%0a* [[Openbsd.UDPFlood]]  . . . December 18, 2020, at 10:39 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Tcpdump]]  . . . December 18, 2020, at 09:12 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Tcpackflood]]  . . . December 17, 2020, at 10:36 AM by [[~jrmu]]: [==]%0a* [[Openbsd.RSTFlood]]  . . . December 17, 2020, at 10:34 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Tcpresetflood]]  . . . December 17, 2020, at 10:34 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Ssdp]]  . . . December 15, 2020, at 12:59 PM by [[~jrmu]]: [==]%0a* [[Bouncer.Igloo]]  . . . December 14, 2020, at 09:39 AM by [[~Noxturnix]]: [==]%0a* [[Main.Terms]]  . . . December 13, 2020, at 01:35 PM by [[~jrmu]]: [==]%0a* [[Openbsd.Pf]]  . . . December 13, 2020, at 12:03 PM by [[~jrmu]]: [==]%0a* [[Openbsd.Upgrade68]]  . . . December 13, 2020, at 11:12 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Install68]]  . . . December 13, 2020, at 10:13 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Upgrade67]]  . . . December 13, 2020, at 04:02 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Sysupgrade68]]  . . . December 11, 2020, at 10:27 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Dokuwiki]]  . . . December 10, 2020, at 02:23 PM by [[~miniontoby]]: [=code blocks fixed=]%0a* [[Openbsd.Acme-client]]  . . . December 09, 2020, at 06:47 PM by [[~miniontoby]]: [=fixed troubleshooting links=]%0a* [[Freedom.Christian]]  . . . December 08, 2020, at 01:12 AM by [[~jrmu]]: [==]%0a* [[Freedom.Finances]]  . . . December 08, 2020, at 01:04 AM by [[~jrmu]]: [==]%0a* [[Shell.Sshkeys]]  . . . December 07, 2020, at 10:36 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Install67]]  . . . December 06, 2020, at 11:03 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Buyvm]]  . . . December 06, 2020, at 02:42 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Install]]  . . . December 04, 2020, at 04:15 PM by [[~jrmu]]: [==]%0a* [[Opernbsd.Buyvm]]  . . . December 04, 2020, at 12:06 PM by [[~jrmu]]: [==]%0a* [[Bouncer.WeeChat]]  . . . December 02, 2020, at 12:43 PM by [[~jrmu]]: [==]%0a* [[Bouncer.SimpleIRC]]  . . . December 02, 2020, at 12:31 PM by [[~jrmu]]: [==]%0a* [[Freedom.Militia]]  . . . December 02, 2020, at 04:18 AM by [[~jrmu]]: [==]%0a* [[Third.Third]]  . . . December 01, 2020, at 01:49 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Oidentd]]  . . . November 30, 2020, at 11:42 PM by [[~jrmu]]: [==]%0a* [[Ircnow.Helper]]  . . . November 28, 2020, at 02:21 AM by [[~jrmu]]: [==]%0a* [[Bouncer.Hexchat]]  . . . November 27, 2020, at 12:52 PM by [[~jrmu]]: [==]%0a* [[Bouncer.IRCCloud]]  . . . November 24, 2020, at 11:53 AM by [[~jrmu]]: [==]%0a* [[Bouncer.AdiIRC]]  . . . November 24, 2020, at 11:42 AM by [[~jrmu]]: [==]%0a* [[Bouncer.RevolutionIRC]]  . . . November 24, 2020, at 11:35 AM by [[~jrmu]]: [==]%0a* [[Bouncer.KiwiIRC]]  . . . November 24, 2020, at 11:34 AM by [[~jrmu]]: [==]%0a* [[Bouncer.KVIrc]]  . . . November 24, 2020, at 11:33 AM by [[~jrmu]]: [==]%0a* [[Bouncer.IceChat]]  . . . November 24, 2020, at 11:27 AM by [[~jrmu]]: [==]%0a* [[Bouncer.IRCCloudiOS]]  . . . November 24, 2020, at 11:20 AM by [[~jrmu]]: [==]%0a* [[Bouncer.IRCCloudAndroid]]  . . . November 24, 2020, at 11:20 AM by [[~jrmu]]: [==]%0a* [[Bouncer.IRCCloudWeb]]  . . . November 24, 2020, at 11:19 AM by [[~jrmu]]: [==]%0a* [[Third.Catalog]]  . . . November 23, 2020, at 07:52 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Checklist]]  . . . November 20, 2020, at 12:44 AM by [[~gry]]: [=+=]%0a* [[Openbsd.Acopm]]  . . . November 04, 2020, at 03:32 PM by [[~jrmu]]: [==]%0a* [[Openbsd.Achurch]]  . . . November 04, 2020, at 02:25 PM by [[~jrmu]]: [==]%0a* [[Openbsd.Vi]]  . . . November 04, 2020, at 12:51 PM by [[~jrmu]]: [==]%0a* [[Openbsd.Sudo]]  . . . November 04, 2020, at 12:38 PM by [[~jrmu]]: [==]%0a* [[Freedom.Denomination]]  . . . October 23, 2020, at 09:20 AM by [[~jrmu]]: [==]%0a* [[Vps.Intro]]  . . . October 10, 2020, at 08:22 AM by [[~jrmu]]: [==]%0a* [[Ircweb.Ircweb]]  . . . October 05, 2020, at 01:10 AM by [[~jrmu]]: [==]%0a* [[Http2irc.Http2irc]]  . . . October 05, 2020, at 01:04 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Easyapp]]  . . . September 29, 2020, at 12:13 PM by [[~jrmu]]: [==]%0a* [[Orange.Nl]]  . . . September 17, 2020, at 08:43 AM by [[~miniontoby]]: [=Dutch correct page=]%0a* [[Grape.Guide]]  . . . September 16, 2020, at 08:42 AM by [[~baytuch]]: [==]%0a* [[Orange.Id]]  . . . September 08, 2020, at 09:51 AM by [[~gry]]: [=+=]%0a* [[Orange.Ru]]  . . . September 07, 2020, at 11:29 PM by [[~gry]]: [=+=]%0a* [[Bouncer.MIRC]]  . . . September 06, 2020, at 03:59 AM by [[~jrmu]]: [==]%0a* [[Debate.Bncnow]]  . . . September 04, 2020, at 04:36 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Cgit]]  . . . September 01, 2020, at 05:51 PM by [[~baytuch]]: [==]%0a* [[Orange.Notes]]  . . . August 27, 2020, at 03:38 AM by [[~gry]]: [=expanded=]%0a* [[Shell.ShellSSHKEYS]]  . . . August 25, 2020, at 10:00 PM by [[~gry]]: [=permissions added=]%0a* [[Bots.Bots]]  . . . August 25, 2020, at 12:02 PM by [[~jrmu]]: [==]%0a* [[Bouncer.Irccloud]]  . . . August 24, 2020, at 12:20 PM by [[~jrmu]]: [==]%0a* [[GrapeTeam.Tracker]]  . . . August 24, 2020, at 10:16 AM by [[~gry]]: [=+=]%0a* [[GrapeTeam.GrapeTeam]]  . . . August 24, 2020, at 10:13 AM by [[~jrmu]]: [==]%0a* [[Ircnow.Course]]  . . . August 21, 2020, at 05:01 AM by [[~gry]]: [==]%0a* [[Openbsd.Bchs]]  . . . August 20, 2020, at 07:11 AM by [[~jrmu]]: [==]%0a* [[Ircnow.Todo]]  . . . August 20, 2020, at 06:48 AM by [[~jrmu]]: on_is_active php_session_active squirrelmailing sqsession_start troubleshooting authentication session_status config_default webmail_access modifications configuration unfortunately accessibility administrator webmail_error compatibility acceleration default_pref organization replacement disposition alternative information sourceforge permissions certificate interactive configuring preferences letsencrypt development compatible javascript configtest connection additional nameserver configured afterwards extracting attempting installing documents complains openhttpd functions localhost opensmtpd challenge supported subdomain receiving databases recommend necessary following languages delimiter directory debugging fusername essential addresses installed chrooted smtphost projects browsers normally location provides tlsmulti 26214400 required remember original security listener optional settings sendmail properly software specific licensed messages brackets instance writable services browsing defaults drawback continue opening control dovecot fastcgi already contact defines example initial unbound folders unusual request plugins general command servers defined private options however records contrib include restart because nologin disable exiting keypair baytuch strings misused charset appears content instead openbsd release sending mt_rand another subject version tarball warning charlie without changes resolve foxtrot uploads written client relayd needed return logout syntax longer cannot latest htdocs braces rather offset typing before themes ircnow frames across making should switch please detect secure invert readme global create update system locale report serial delete femail myname daemon lookup socket number errors trying issues actual stable inline attach master reload touch could color chown check chmod needs first intro shell rcctl php74 mkdir books hosts write above https there false using might every ascii happy delta curly array fatal bravo query where since which setup exist works notes saved files press alpha enter means class block title index chain strip lines known worry based ifend about zones this doas 2001 imap will well page your real acme make sure that aaaa ipv4 does fccf want 1008 2602 than sbin chsh help bind body some copy runs both must logs like when ctrl type echo xvzf find uses html many wiki easy fees more exec text once were have made mime done next move into ipv6 pop3 menu sign quit full motd hide give edit time www ssl etc var 127 day see has 162 bad gpl 451 fix ksh 644 zip its 755 ftp net way crt 634 usr 403 src nsd fpm dns max few db8 143 via by gz 22 cd rx 38 87 mv 80 9
-time=1678078240
+rev=11468
+text=* [[Dovecot.Install]]  . . . @2023-03-06T20:20:50Z by [[~jrmu]]: [==]%0a* [[DNS.DKIM]]  . . . @2023-03-06T20:12:56Z by [[~jrmu]]: [==]%0a* [[DNS.Mail]]  . . . @2023-03-06T20:12:25Z by [[~jrmu]]: [==]%0a* [[Opensmtpd.Configure]]  . . . @2023-03-06T20:11:39Z by [[~jrmu]]: [==]%0a* [[Openbsd.Ngircd]]  . . . @2023-03-06T17:03:05Z by [[~mkf]]: [==]%0a* [[9front.Netsurf]]  . . . @2023-03-06T03:14:30Z by [[~Yonle]]: [==]%0a* [[FreeIRC.About]]  . . . March 05, 2023, at 03:51 PM by [[~kilroy]]: [==]%0a* [[Openbsd.OpenTracker]]  . . . March 03, 2023, at 04:37 PM by [[~baytuch]]: [==]%0a* [[SiteAdmin.AuthUser]]  . . . March 03, 2023, at 05:31 AM by [[~jrmu]]: [==]%0a* [[Almanack.Almanack]]  . . . March 02, 2023, at 05:10 AM by [[~jrmu]]: [==]%0a* [[Ircnow.Roadmap]]  . . . March 02, 2023, at 05:10 AM by [[~jrmu]]: [==]%0a* [[Ircnow.Roadmap2023]]  . . . March 02, 2023, at 05:07 AM by [[~jrmu]]: [==]%0a* [[Oidentd.ZNC]]  . . . February 28, 2023, at 02:34 AM by [[~jrmu]]: [==]%0a* [[Oidentd.Changeident]]  . . . February 28, 2023, at 02:33 AM by [[~jrmu]]: [=This was suggested by another author, but because the solution is not permanent, we move it to a sep=]%0a* [[Acme-client.Configure]]  . . . February 26, 2023, at 10:06 PM by [[~jrmu]]: [=Revert as I'm not sure if /etc/daily.local is better=]%0a* [[Ircnow.Servers]]  . . . February 26, 2023, at 05:42 PM by [[~Yonle]]: [=No.=]%0a* [[Stagit.Install]]  . . . February 26, 2023, at 05:24 PM by [[~fossdev]]: [==]%0a* [[Openbsd.Gotweb]]  . . . February 26, 2023, at 05:04 PM by [[~fossdev]]: [==]%0a* [[Got.Repo]]  . . . February 26, 2023, at 05:02 PM by [[~fossdev]]: [==]%0a* [[Oidentd.Install]]  . . . February 26, 2023, at 01:59 AM by [[~jrmu]]: [=Revert erroneous change=]%0a* [[Ircnow.Explorer]]  . . . February 26, 2023, at 01:35 AM by [[~jrmu]]: [==]%0a* [[Ircnow.Codeforce]]  . . . February 26, 2023, at 01:03 AM by [[~jrmu]]: [==]%0a* [[Donations.Donations]]  . . . February 25, 2023, at 08:36 PM by [[~jrmu]]: [==]%0a* [[Main.HomePage]]  . . . February 25, 2023, at 05:39 AM by [[~jrmu]]: [==]%0a* [[Vps.Vps]]  . . . February 25, 2023, at 12:31 AM by [[~jrmu]]: [==]%0a* [[Botnow.Install]]  . . . February 24, 2023, at 11:24 PM by [[~Naglfar]]: [=Add a list with new parameters=]%0a* [[Hardware.Ps2]]  . . . February 24, 2023, at 04:26 PM by [[~mkf]]: [==]%0a* [[Bouncer.Bouncer]]  . . . February 22, 2023, at 02:06 PM by [[~Yonle]]: [==]%0a* [[Ircnow.Minutemin]]  . . . February 18, 2023, at 05:41 AM by [[~jrmu]]: [==]%0a* [[Ircnow.SSHFingerprints]]  . . . February 17, 2023, at 05:39 PM by [[~jrmu]]: [==]%0a* [[Baytuch.Bio]]  . . . February 17, 2023, at 12:00 PM by [[~baytuch]]: [==]%0a* [[Openhttpd.Configure]]  . . . February 17, 2023, at 11:39 AM by [[~baytuch]]: [==]%0a* [[Openbsd.Plermoa]]  . . . February 16, 2023, at 04:52 AM by [[~Yonle]]: [=Redirect=]%0a* [[Openbsd.Pleroma]]  . . . February 12, 2023, at 02:49 AM by [[~Yonle]]: [=Oops=]%0a* [[Openbsd.Akkoma]]  . . . February 12, 2023, at 02:48 AM by [[~Yonle]]: [=Oof=]%0a* [[Akkoma.Install]]  . . . February 09, 2023, at 12:49 PM by [[~Yonle]]: [==]%0a* [[Google.Sins]]  . . . February 08, 2023, at 05:13 AM by [[~Yonle]]: [==]%0a* [[Debate.Googledanger]]  . . . February 08, 2023, at 05:01 AM by [[~Yonle]]: [==]%0a* [[Debate.Outreachkids]]  . . . February 08, 2023, at 04:34 AM by [[~Yonle]]: [==]%0a* [[Openbsd.Mlmmj]]  . . . February 08, 2023, at 02:50 AM by [[~Yonle]]: [==]%0a* [[Openbsd.Mosh]]  . . . February 07, 2023, at 11:30 AM by [[~Yonle]]: [==]%0a* [[Shelllabs.Reading]]  . . . February 07, 2023, at 02:06 AM by [[~jrmu]]: [==]%0a* [[Squirrelmail.Install]]  . . . February 06, 2023, at 09:24 PM by [[~Naglfar]]: [=Add snapshot download reference=]%0a* [[Route.Usage]]  . . . February 06, 2023, at 02:38 PM by [[~mkf]]: [==]%0a* [[Mkf.Wikiv1]]  . . . February 06, 2023, at 02:31 PM by [[~mkf]]: [==]%0a* [[Psybnc.Install]]  . . . February 06, 2023, at 02:31 PM by [[~mkf]]: [==]%0a* [[Debate.Openweb]]  . . . February 06, 2023, at 02:15 PM by [[~Yonle]]: [==]%0a* [[Debate.Youtubedanger]]  . . . February 06, 2023, at 02:10 PM by [[~Yonle]]: [==]%0a* [[Debate.Providers]]  . . . February 06, 2023, at 01:41 PM by [[~Yonle]]: [==]%0a* [[Paster.Install]]  . . . February 06, 2023, at 10:22 AM by [[~mkf]]: [==]%0a* [[Anope.Install]]  . . . February 06, 2023, at 09:46 AM by [[~mkf]]: [==]%0a* [[9.Drawterm]]  . . . February 05, 2023, at 09:18 PM by [[~mkf]]: [==]%0a* [[Znc.Chroot]]  . . . February 04, 2023, at 04:45 PM by [[~Francis]]: [==]%0a* [[Password.Hashes]]  . . . February 04, 2023, at 07:27 AM by [[~izzyb]]: [=formatting fixes=]%0a* [[Chess.Chessgogi]]  . . . February 04, 2023, at 03:49 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Passwords]]  . . . February 03, 2023, at 07:49 PM by [[~izzyb]]: [==]%0a* [[Password.Management]]  . . . February 03, 2023, at 07:44 PM by [[~izzyb]]: [==]%0a* [[DNS.Ipv4rDNS]]  . . . February 01, 2023, at 08:31 PM by [[~izzyb]]: [=added note to clarify what address needs to be specified.=]%0a* [[Dovecot.SharedMailboxes]]  . . . January 31, 2023, at 08:29 PM by [[~izzyb]]: [==]%0a* [[Dovecot.SharedFolders]]  . . . January 31, 2023, at 06:03 AM by [[~izzyb]]: [=renaming to sharedMailboxes=]%0a* [[Soju.Install]]  . . . January 24, 2023, at 11:29 AM by [[~mkf]]: [=minor changes on style=]%0a* [[Lilywhitebot.Install]]  . . . January 24, 2023, at 11:23 AM by [[~mkf]]: [==]%0a* [[SendMoneyToSplinter0616Outlook.Com]]  . . . January 24, 2023, at 11:19 AM by [[~mkf]]: [==]%0a* [[9.9gridchan]]  . . . January 22, 2023, at 07:01 AM by [[~jrmu]]: [==]%0a* [[Ircnow.Milestones]]  . . . January 21, 2023, at 03:59 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Biboumi]]  . . . January 20, 2023, at 08:11 PM by [[~mkf]]: [==]%0a* [[Biboumi.Install]]  . . . January 20, 2023, at 08:10 PM by [[~mkf]]: [==]%0a* [[Texlive.Install]]  . . . January 20, 2023, at 08:05 PM by [[~mkf]]: [==]%0a* [[Rcctl.Rcctl]]  . . . January 20, 2023, at 08:00 PM by [[~mkf]]: [==]%0a* [[Vmm.Configure]]  . . . January 20, 2023, at 07:59 PM by [[~mkf]]: [==]%0a* [[Hopm.Install]]  . . . January 20, 2023, at 07:32 PM by [[~mkf]]: [==]%0a* [[Openbsd.Unrealircd]]  . . . January 20, 2023, at 07:27 PM by [[~mkf]]: [==]%0a* [[Unrealircd.Install]]  . . . January 20, 2023, at 07:24 PM by [[~mkf]]: [==]%0a* [[Pleroma.Install]]  . . . January 20, 2023, at 07:18 PM by [[~mkf]]: [==]%0a* [[Gomuks.Install]]  . . . January 20, 2023, at 07:08 PM by [[~mkf]]: [==]%0a* [[Gotweb.Install]]  . . . January 20, 2023, at 07:02 PM by [[~mkf]]: [==]%0a* [[Webnews.Install]]  . . . January 20, 2023, at 06:57 PM by [[~mkf]]: [==]%0a* [[Php.Install]]  . . . January 20, 2023, at 06:52 PM by [[~mkf]]: [==]%0a* [[Mlmmj.Install]]  . . . January 20, 2023, at 06:48 PM by [[~mkf]]: [==]%0a* [[Fiche.Install]]  . . . January 20, 2023, at 06:44 PM by [[~mkf]]: [==]%0a* [[Prosody.Install]]  . . . January 20, 2023, at 06:42 PM by [[~mkf]]: [==]%0a* [[Bitlbee.Install]]  . . . January 20, 2023, at 06:36 PM by [[~mkf]]: [==]%0a* [[TigerVNC.Install]]  . . . January 20, 2023, at 06:30 PM by [[~mkf]]: [==]%0a* [[NodeJS.Install]]  . . . January 20, 2023, at 06:27 PM by [[~mkf]]: [==]%0a* [[Pmwiki.Install]]  . . . January 20, 2023, at 06:19 PM by [[~mkf]]: [==]%0a* [[Xfce.Install]]  . . . January 20, 2023, at 06:17 PM by [[~mkf]]: [==]%0a* [[Ngircd.Install]]  . . . January 20, 2023, at 06:08 PM by [[~mkf]]: [==]%0a* [[Openbsd.Vipw]]  . . . January 18, 2023, at 11:01 PM by [[~zen]]: [=added two spaces=]%0a* [[Grep.Usage]]  . . . January 18, 2023, at 10:54 PM by [[~zen]]: [==]%0a* [[Openbsd.Loginconf]]  . . . January 18, 2023, at 10:48 PM by [[~zen]]: [=OpenBSD FAQ link refenrece=]%0a* [[Openbsd.Singleuser]]  . . . January 18, 2023, at 10:26 PM by [[~zen]]: [=changed the link reference=]%0a* [[Ssh.Fingerprints]]  . . . January 14, 2023, at 04:31 PM by [[~izzyb]]: [=added link to ircnow network ssh fingerprints as example.=]%0a* [[Team.Networks]]  . . . January 12, 2023, at 06:36 PM by [[~kilroy]]: [=Updated Sturtz IRC=]%0a* [[Openbsd.Dump]]  . . . January 10, 2023, at 04:48 PM by [[~mkf]]: [=add -u, improve dump-ssh funcationality.=]%0a* [[Znc.Install]]  . . . January 07, 2023, at 11:58 PM by [[~jrmu]]: [==]%0a* [[Jrmu.Bio]]  . . . January 05, 2023, at 07:23 PM by [[~jrmu]]: [==]%0a* [[Rspamd.Configure]]  . . . January 03, 2023, at 04:55 PM by [[~mkf]]: [==]%0a* [[Eggdrop191.Install]]  . . . December 31, 2022, at 05:29 PM by [[~Yonle]]: [==]%0a* [[Dovecot.Pigeonhole]]  . . . December 30, 2022, at 04:24 PM by [[~mkf]]: [=style 2=]%0a* [[Openbsd.Quota]]  . . . December 29, 2022, at 06:51 PM by [[~mkf]]: [==]%0a* [[Minutemin.Bootcamp]]  . . . December 29, 2022, at 04:38 PM by [[~mkf]]: [==]%0a* [[Profiles.Miniontoby]]  . . . December 26, 2022, at 07:26 PM by [[~miniontoby]]: [=Created=]%0a* [[Minetest.Minetest]]  . . . December 26, 2022, at 07:25 PM by [[~miniontoby]]: [=Added building guide link=]%0a* [[Openbsd.Minetest]]  . . . December 26, 2022, at 07:23 PM by [[~miniontoby]]: [=Added more ways to install=]%0a* [[Splinter0616Outlook.Com]]  . . . December 25, 2022, at 02:37 AM by [[~SplinTer]]: [==]%0a* [[Ngircd.Oper]]  . . . December 25, 2022, at 12:03 AM by [[~forero]]: [==]%0a* [[Profiles.Yonle]]  . . . December 24, 2022, at 03:29 PM by [[~Yonle]]: [==]%0a* [[Openbsd.Honk]]  . . . December 17, 2022, at 08:45 AM by [[~Yonle]]: [==]%0a* [[Yonle.Bio]]  . . . December 13, 2022, at 05:18 PM by [[~Yonle]]: [==]%0a* [[Camping.Gear]]  . . . December 12, 2022, at 04:39 AM by [[~jrmu]]: [==]%0a* [[Vhost.Vhost]]  . . . December 12, 2022, at 03:36 AM by [[~xfnw]]: [==]%0a* [[Vhost.Ircnow]]  . . . December 12, 2022, at 03:13 AM by [[~xfnw]]: [=ircfree.com is not an ircnow domain=]%0a* [[Shelllabs.Openaccess]]  . . . December 08, 2022, at 10:02 PM by [[~redrum88]]: [==]%0a* [[I2Pd.Install]]  . . . December 07, 2022, at 01:16 AM by [[~Yonle]]: [=Again not 7070=]%0a* [[I2Pd.Tunnels]]  . . . December 06, 2022, at 02:52 PM by [[~Yonle]]: [=There we go. =]%0a* [[I2pd.Tunnels]]  . . . December 06, 2022, at 02:45 PM by [[~Yonle]]: [==]%0a* [[Unbound.Configure]]  . . . December 04, 2022, at 03:59 AM by [[~Yonle]]: [==]%0a* [[Profiles.Xfnw]]  . . . November 28, 2022, at 10:38 PM by [[~xfnw]]: [=add pgp keys=]%0a* [[Unwind.Configure]]  . . . November 26, 2022, at 09:23 PM by [[~akoizumi]]: [=add unwind=]%0a* [[Openbsd.Icecast]]  . . . November 17, 2022, at 11:35 AM by [[~Yonle]]: [==]%0a* [[Debian.Install]]  . . . November 13, 2022, at 11:43 AM by [[~suzerain]]: [=writing=]%0a* [[Lemon.Lemon]]  . . . November 10, 2022, at 01:48 PM by [[~mkf]]: [==]%0a* [[Bouncer.JmIRC]]  . . . November 04, 2022, at 06:18 PM by [[~baytuch]]: [=Added screenshots about setup=]%0a* [[Ambassador.Ilines]]  . . . October 22, 2022, at 04:40 AM by [[~jrmu]]: [==]%0a* [[Bouncer.XChat]]  . . . October 16, 2022, at 11:09 PM by [[~xfnw]]: [=XChat is unmaintained=]%0a* [[Eggdrop.VHost]]  . . . October 02, 2022, at 01:05 PM by [[~sulieztya]]: [==]%0a* [[Eggdrop.VhostTCL]]  . . . October 02, 2022, at 07:06 AM by [[~sulieztya]]: [==]%0a* [[Eggdrop.BotZNC]]  . . . October 02, 2022, at 01:29 AM by [[~sulieztya]]: [==]%0a* [[Shelllabs.Intro]]  . . . September 28, 2022, at 06:53 PM by [[~jrmu]]: [==]%0a* [[He.IPv6Certification]]  . . . September 16, 2022, at 05:32 PM by [[~xfnw]]: [=create page=]%0a* [[Shelllabs.Education]]  . . . September 14, 2022, at 07:30 PM by [[~jrmu]]: [==]%0a* [[About.AboutUs]]  . . . September 13, 2022, at 06:42 PM by [[~zleap]]: [==]%0a* [[Site.SideBar]]  . . . September 13, 2022, at 06:21 PM by [[~jrmu]]: [==]%0a* [[LegalAndSafety.LegalAndSafety]]  . . . September 13, 2022, at 05:19 PM by [[~zleap]]: [==]%0a* [[LegalAndSafety.LegalAmpSafety]]  . . . September 13, 2022, at 05:17 PM by [[~zleap]]: [==]%0a* [[LegalAmpSafety.Subheading]]  . . . September 13, 2022, at 05:15 PM by [[~zleap]]: [==]%0a* [[Acmesh.Configure]]  . . . September 11, 2022, at 06:03 PM by [[~akoizumi]]: [=Added acme.sh (currently a WIP)=]%0a* [[Dehydrated.Configure]]  . . . September 11, 2022, at 02:52 PM by [[~akoizumi]]: [=Add dehydrated=]%0a* [[Profiles.Izzyb]]  . . . September 11, 2022, at 06:28 AM by [[~izzyb]]: [==]%0a* [[Site.EditForm]]  . . . September 11, 2022, at 06:22 AM by [[~izzyb]]: [=Make Author none editable field=]%0a* [[Netcat.Irc]]  . . . September 11, 2022, at 04:21 AM by [[~izzyb]]: [=Removed info about PASS - moving to different doc as per jrmu request=]%0a* [[Openbsd.Geomyidae]]  . . . September 10, 2022, at 02:31 AM by [[~akoizumi]]: [==]%0a* [[Openbsd.INN]]  . . . September 10, 2022, at 02:23 AM by [[~akoizumi]]: [=Fix some types=]%0a* [[Ngircd.Loginconf]]  . . . September 10, 2022, at 01:51 AM by [[~jrmu]]: [==]%0a* [[Heading.Subheading]]  . . . September 07, 2022, at 07:23 PM by [[~zleap]]: [==]%0a* [[Eggdrop193.Install]]  . . . September 07, 2022, at 04:48 PM by [[~jrmu]]: [==]%0a* [[Letsencrypt.Expired]]  . . . September 06, 2022, at 12:00 AM by [[~xfnw]]: [=be less misleading about Let's Encrypt's reasoning for keeping the expired chain=]%0a* [[Ircnow.Pioneer]]  . . . August 14, 2022, at 05:06 AM by [[~jrmu]]: [==]%0a* [[Openbsd.VsFTP]]  . . . August 10, 2022, at 03:18 PM by [[~mkf]]: [=snipped unneeded output=]%0a* [[C.Scanf]]  . . . August 10, 2022, at 09:51 AM by [[~mkf]]: [==]%0a* [[Vmm.Install]]  . . . August 10, 2022, at 08:05 AM by [[~miniontoby]]: [=coconut to host=]%0a* [[Orange.CertsReissue]]  . . . August 08, 2022, at 05:35 AM by [[~baytuch]]: [==]%0a* [[Team.Security]]  . . . August 08, 2022, at 12:53 AM by [[~jrmu]]: [==]%0a* [[Netcat.Usage]]  . . . August 04, 2022, at 01:12 AM by [[~tiramisu]]: [==]%0a* [[Freedom.Universal]]  . . . August 03, 2022, at 06:33 PM by [[~jrmu]]: [==]%0a* [[Pgp.Upload]]  . . . August 01, 2022, at 01:21 PM by [[~jan6]]: [=keys.openpgp.org uses a superior implementation, less vulnerable to various issues=]%0a* [[Lemon.Packages]]  . . . July 30, 2022, at 07:52 PM by [[~mkf]]: [==]%0a* [[Netizen.Ellisisland]]  . . . July 27, 2022, at 07:05 PM by [[~jrmu]]: [==]%0a* [[Ircnow.Newdeal]]  . . . July 27, 2022, at 06:55 PM by [[~jrmu]]: [==]%0a* [[Ircnow.Daughtersofliberty]]  . . . July 27, 2022, at 06:45 PM by [[~jrmu]]: [==]%0a* [[Ircnow.Womenstem]]  . . . July 21, 2022, at 05:59 PM by [[~jrmu]]: [==]%0a* [[Eggdrop.RC]]  . . . July 20, 2022, at 06:55 PM by [[~baytuch]]: [==]%0a* [[Opensmtpd.Troubleshoot]]  . . . July 20, 2022, at 03:58 PM by [[~jlj]]: [=Added notes about how I resolved the first two errors, on nastycode=]%0a* [[Eggdrop.Nickserv]]  . . . July 19, 2022, at 10:05 AM by [[~baytuch]]: [==]%0a* [[Chroot.Intro]]  . . . July 18, 2022, at 04:23 PM by [[~mkf]]: [==]%0a* [[Ircnow.Media]]  . . . July 15, 2022, at 05:54 AM by [[~jrmu]]: [==]%0a* [[Iked.Linuxstrongswan]]  . . . July 03, 2022, at 11:29 PM by [[~jrmu]]: [==]%0a* [[Acme-client.AutoRenew]]  . . . July 03, 2022, at 11:50 AM by [[~mkf]]: [==]%0a* [[Openbsd.Apmd]]  . . . July 03, 2022, at 11:36 AM by [[~mkf]]: [==]%0a* [[Opensmtpd.Test]]  . . . July 03, 2022, at 11:13 AM by [[~mkf]]: [==]%0a* [[Ircnow.Roadmap2022]]  . . . July 03, 2022, at 11:04 AM by [[~mkf]]: [==]%0a* [[Iked.Android]]  . . . July 01, 2022, at 12:14 AM by [[~jrmu]]: [==]%0a* [[Vpn.Myipaddress]]  . . . June 30, 2022, at 09:51 PM by [[~jrmu]]: [==]%0a* [[Olympics.Games]]  . . . June 27, 2022, at 10:42 PM by [[~jrmu]]: [==]%0a* [[Iked.Configure]]  . . . June 25, 2022, at 02:28 PM by [[~jrmu]]: [==]%0a* [[Unbound.Blacklists]]  . . . June 25, 2022, at 06:02 AM by [[~jrmu]]: [==]%0a* [[Iked.Linux]]  . . . June 23, 2022, at 07:10 AM by [[~jrmu]]: [==]%0a* [[Vpn.Vpn]]  . . . June 23, 2022, at 06:42 AM by [[~jrmu]]: [==]%0a* [[Ircnow.Nsf]]  . . . June 20, 2022, at 05:05 PM by [[~jrmu]]: [==]%0a* [[Debate.Debate]]  . . . June 19, 2022, at 04:12 PM by [[~jrmu]]: [==]%0a* [[Ircnow.Metrics]]  . . . June 19, 2022, at 04:12 PM by [[~jrmu]]: [==]%0a* [[Nsd.Masterslave]]  . . . June 19, 2022, at 06:34 AM by [[~jrmu]]: [==]%0a* [[Dns.Overview]]  . . . June 19, 2022, at 05:45 AM by [[~jrmu]]: [==]%0a* [[Dns.Records]]  . . . June 19, 2022, at 05:44 AM by [[~jrmu]]: [==]%0a* [[Syspatch.Syspatch]]  . . . June 17, 2022, at 06:24 AM by [[~jrmu]]: [==]%0a* [[Tmux.Config]]  . . . June 14, 2022, at 12:34 AM by [[~jrmu]]: [==]%0a* [[Vmm.Alpine]]  . . . June 13, 2022, at 05:42 PM by [[~fossdev]]: [==]%0a* [[Team.Announce]]  . . . June 13, 2022, at 03:52 PM by [[~jrmu]]: [==]%0a* [[Vmm.Arch]]  . . . June 12, 2022, at 04:11 PM by [[~g1n]]: [=Added article about Arch Linux setup on VMM=]%0a* [[Znc.Patch]]  . . . June 12, 2022, at 12:48 AM by [[~jrmu]]: [==]%0a* [[Unveil.Intro]]  . . . June 12, 2022, at 12:40 AM by [[~jrmu]]: [==]%0a* [[Pledge.Intro]]  . . . June 12, 2022, at 12:39 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Pkg]]  . . . June 12, 2022, at 12:32 AM by [[~jrmu]]: [==]%0a* [[Doas.Configure]]  . . . June 09, 2022, at 07:56 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Intro]]  . . . June 09, 2022, at 07:53 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Bsdrd]]  . . . June 09, 2022, at 07:17 AM by [[~jrmu]]: [==]%0a* [[Vnc.Vnc]]  . . . June 08, 2022, at 04:04 PM by [[~miniontoby]]: [=Added RealVNC Viewer to the list (might need some more extra stuff, but yeah its fine)=]%0a* [[Unix101.Unix101]]  . . . June 07, 2022, at 03:12 PM by [[~jrmu]]: [==]%0a* [[Openbsd.Sysupgrade71]]  . . . June 05, 2022, at 11:49 PM by [[~jrmu]]: [==]%0a* [[Openbsd.Growfs]]  . . . June 01, 2022, at 12:34 AM by [[~jrmu]]: [==]%0a* [[Team.Welcome]]  . . . May 31, 2022, at 10:20 PM by [[~jrmu]]: [==]%0a* [[Hostnameif.Static-v2]]  . . . May 23, 2022, at 06:29 AM by [[~theguest]]: [==]%0a* [[Hostnameif.Static]]  . . . May 23, 2022, at 05:01 AM by [[~theguest]]: [==]%0a* [[Ircnow.Team]]  . . . May 12, 2022, at 03:44 PM by [[~jrmu]]: [==]%0a* [[Grape.Minetest]]  . . . May 10, 2022, at 10:48 AM by [[~baytuch]]: [==]%0a* [[Irc.Emoji]]  . . . May 10, 2022, at 10:23 AM by [[~baytuch]]: [==]%0a* [[Openbsd.Nsd]]  . . . May 10, 2022, at 12:33 AM by [[~jrmu]]: [==]%0a* [[Opsofliberty.Bootcamp]]  . . . May 09, 2022, at 08:38 AM by [[~mkf]]: [==]%0a* [[Openbsd.Ports]]  . . . May 09, 2022, at 05:54 AM by [[~mkf]]: [==]%0a* [[Openbsd.Rcctl]]  . . . May 09, 2022, at 05:53 AM by [[~mkf]]: [==]%0a* [[Ngircd.Ssl]]  . . . May 08, 2022, at 03:30 PM by [[~miniontoby]]: [=fixed the text=]%0a* [[Openbsd.Upgrade71]]  . . . May 03, 2022, at 06:36 AM by [[~jrmu]]: [==]%0a* [[Codeforce.Training]]  . . . May 03, 2022, at 03:02 AM by [[~jrmu]]: [==]%0a* [[Civics.Intro]]  . . . May 03, 2022, at 01:06 AM by [[~jrmu]]: [==]%0a* [[OpenBSD.EdgeRouter-Lite]]  . . . April 28, 2022, at 02:50 PM by [[~pufferf]]: [==]%0a* [[Math.Reading]]  . . . April 27, 2022, at 08:23 PM by [[~jrmu]]: [==]%0a* [[Openbsd.Install71]]  . . . April 24, 2022, at 09:55 PM by [[~jrmu]]: [==]%0a* [[Openbsd.Botnow]]  . . . April 24, 2022, at 06:14 AM by [[~jrmu]]: [==]%0a* [[Buyvm.Ipv6]]  . . . April 24, 2022, at 06:10 AM by [[~jrmu]]: [==]%0a* [[Eggdrop.Rss]]  . . . April 23, 2022, at 04:20 PM by [[~jrmu]]: [==]%0a* [[Team.Testing]]  . . . April 20, 2022, at 09:45 PM by [[~jrmu]]: [==]%0a* [[Dns.Registrars]]  . . . April 20, 2022, at 09:30 PM by [[~jrmu]]: [==]%0a* [[Hosting.Providers]]  . . . April 20, 2022, at 08:52 PM by [[~jrmu]]: [==]%0a* [[Openbsd.Gopher]]  . . . April 20, 2022, at 08:29 PM by [[~jrmu]]: [==]%0a* [[Openbsd.Adduser]]  . . . April 20, 2022, at 08:07 PM by [[~jrmu]]: [==]%0a* [[Signify.Verify]]  . . . April 20, 2022, at 06:24 PM by [[~jrmu]]: [==]%0a* [[Almanack.Route]]  . . . April 20, 2022, at 06:23 AM by [[~jrmu]]: [==]%0a* [[Ntpd.Configure]]  . . . April 20, 2022, at 06:17 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Ntpd]]  . . . April 20, 2022, at 06:16 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Vmmlinux]]  . . . April 20, 2022, at 05:33 AM by [[~jrmu]]: [==]%0a* [[Vmm.Linux]]  . . . April 20, 2022, at 05:33 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Iked]]  . . . April 20, 2022, at 05:16 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Team]]  . . . April 20, 2022, at 04:54 AM by [[~jrmu]]: [==]%0a* [[Ircnow.Networks]]  . . . April 19, 2022, at 04:22 PM by [[~jrmu]]: [==]%0a* [[Openbsd.Announce]]  . . . April 19, 2022, at 04:14 PM by [[~jrmu]]: [==]%0a* [[Ircnow.Ally]]  . . . April 19, 2022, at 04:11 PM by [[~jrmu]]: [==]%0a* [[Openhttpd.Chroot]]  . . . April 19, 2022, at 04:05 PM by [[~jrmu]]: [==]%0a* [[Openbsd.Install70]]  . . . April 19, 2022, at 06:52 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Upgrade70]]  . . . April 19, 2022, at 06:49 AM by [[~jrmu]]: [==]%0a* [[CodeForce.Bootcamp]]  . . . April 19, 2022, at 06:29 AM by [[~jrmu]]: [==]%0a* [[Perl101.Perl101]]  . . . April 19, 2022, at 06:15 AM by [[~jrmu]]: [==]%0a* [[Vmm.Vmm]]  . . . April 15, 2022, at 12:20 PM by [[~Naglfar]]: [=Update: report from PiRATA=]%0a* [[Ngircd.Link]]  . . . April 07, 2022, at 06:52 AM by [[~jrmu]]: [==]%0a* [[Minutemin.Minutemin]]  . . . April 06, 2022, at 02:55 AM by [[~jrmu]]: [==]%0a* [[Openhttpd.CGI]]  . . . April 05, 2022, at 04:22 PM by [[~gtlsgamr]]: [==]%0a* [[Openbsd.Censord]]  . . . April 05, 2022, at 06:16 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Hopm]]  . . . April 05, 2022, at 06:09 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Dns]]  . . . April 05, 2022, at 05:24 AM by [[~jrmu]]: [==]%0a* [[Debate.Zncflaws]]  . . . April 05, 2022, at 05:18 AM by [[~jrmu]]: [==]%0a* [[Debate.Debiandanger]]  . . . April 04, 2022, at 04:30 AM by [[~jrmu]]: [==]%0a* [[Openhttpd.Tls]]  . . . April 04, 2022, at 04:25 AM by [[~jrmu]]: [==]%0a* [[Openhttpd.Website]]  . . . April 03, 2022, at 11:03 PM by [[~jrmu]]: [==]%0a* [[Soju.Guide]]  . . . April 02, 2022, at 03:46 PM by [[~Yonle]]: [==]%0a* [[Nitter.Install]]  . . . April 02, 2022, at 01:08 AM by [[~fallback]]: [=first nitter install page=]%0a* [[Debiankaios.Bio]]  . . . April 01, 2022, at 05:10 PM by [[~debiankaios]]: [==]%0a* [[Openbsd.Psybnc]]  . . . March 30, 2022, at 09:56 PM by [[~jrmu]]: [==]%0a* [[Sshd.Disablepassword]]  . . . March 30, 2022, at 08:27 PM by [[~xfnw]]: [=undo accidental revert=]%0a* [[Tor.Irc]]  . . . March 30, 2022, at 12:40 PM by [[~m16]]: [==]%0a* [[Chess.Reading]]  . . . March 29, 2022, at 10:02 PM by [[~jrmu]]: [==]%0a* [[Linux.Reading]]  . . . March 29, 2022, at 03:31 PM by [[~jrmu]]: [==]%0a* [[Unix.Reading]]  . . . March 28, 2022, at 03:24 PM by [[~jrmu]]: [==]%0a* [[Irc.Services]]  . . . March 25, 2022, at 04:29 AM by [[~jrmu]]: [==]%0a* [[Syslogd.Configure]]  . . . March 25, 2022, at 04:07 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Ddos]]  . . . March 24, 2022, at 04:22 PM by [[~jrmu]]: [==]%0a* [[Ddos.Intro]]  . . . March 24, 2022, at 04:22 PM by [[~jrmu]]: [==]%0a* [[Bouncer.ZNC]]  . . . March 19, 2022, at 07:31 AM by [[~fallback]]: [==]%0a* [[ISCABBS.DownloadingAndInstalling]]  . . . March 15, 2022, at 10:42 PM by [[~Mandarax]]: [==]%0a* [[ISCABBS.ISCABBS]]  . . . March 15, 2022, at 09:24 PM by [[~Mandarax]]: [==]%0a* [[Unix.History]]  . . . March 14, 2022, at 06:07 PM by [[~jrmu]]: [==]%0a* [[Unix.Exhibit]]  . . . March 13, 2022, at 11:37 PM by [[~jrmu]]: [==]%0a* [[Debate.Dogfooding]]  . . . March 10, 2022, at 05:14 AM by [[~jrmu]]: [==]%0a* [[Irc.Easy]]  . . . March 05, 2022, at 08:56 PM by [[~jrmu]]: [==]%0a* [[Doxing.Defense]]  . . . March 05, 2022, at 08:54 PM by [[~jrmu]]: [==]%0a* [[Mlmmj-archivist.Install]]  . . . March 03, 2022, at 05:26 AM by [[~error]]: [==]%0a* [[Openbsd.IRCBridge]]  . . . February 28, 2022, at 02:59 AM by [[~suzerain]]: [==]%0a* [[Unix101.Vi]]  . . . February 27, 2022, at 08:16 PM by [[~jrmu]]: [==]%0a* [[Vi.Intro]]  . . . February 27, 2022, at 04:16 PM by [[~Limits]]: [=Add Introduction to Vi=]%0a* [[Irc201.Irc201]]  . . . February 27, 2022, at 04:21 AM by [[~suzerain]]: [==]%0a* [[9.Ideas]]  . . . February 23, 2022, at 05:19 PM by [[~mkf]]: [==]%0a* [[Main.WikiSandbox]]  . . . February 22, 2022, at 11:05 PM by [[~mkf]]: [==]%0a* [[Openhttpd.Perl]]  . . . February 21, 2022, at 07:18 AM by [[~Naglfar]]: [==]%0a* [[Openbsd.Wesnothd]]  . . . February 21, 2022, at 06:28 AM by [[~mkf]]: [=Wesnothd=]%0a* [[9.Audio]]  . . . February 20, 2022, at 08:07 PM by [[~jrmu]]: [==]%0a* [[Cloud9p.Roadmap]]  . . . February 20, 2022, at 06:54 PM by [[~xfnw]]: [==]%0a* [[Openbsd.Xonotic]]  . . . February 20, 2022, at 07:43 AM by [[~mkf]]: [=A xonotic server has apperad! pt.2=]%0a* [[Bouncer.Irssi]]  . . . February 16, 2022, at 06:26 PM by [[~izzyb]]: [=clarified wording in example=]%0a* [[PuTTY.PuTTYgen]]  . . . February 16, 2022, at 05:24 AM by [[~jrmu]]: [==]%0a* [[Rcd.Configure]]  . . . February 15, 2022, at 04:46 PM by [[~xfnw]]: [=fix title formatting=]%0a* [[Debate.Ircnowd]]  . . . February 14, 2022, at 06:24 PM by [[~jrmu]]: [==]%0a* [[Stopm.Stopm]]  . . . February 14, 2022, at 06:16 PM by [[~jrmu]]: [==]%0a* [[Police.Fingerprints]]  . . . February 12, 2022, at 02:09 PM by [[~xfnw]]: [=ip addresses should be sorted with sort -V=]%0a* [[Openbsd.Police]]  . . . February 10, 2022, at 07:36 PM by [[~jrmu]]: [==]%0a* [[Dns.Dns]]  . . . February 10, 2022, at 07:39 AM by [[~nixdork]]: [=Fix typo=]%0a* [[Dns.BindResolver]]  . . . February 10, 2022, at 07:30 AM by [[~nixdork]]: [=First draft of bind resolver howto=]%0a* [[Botnow.SqliteViews]]  . . . February 10, 2022, at 02:00 AM by [[~xfnw]]: [==]%0a* [[Relayd.TLSMulti]]  . . . February 08, 2022, at 06:45 AM by [[~Naglfar]]: [=Fix listening port for https=]%0a* [[Relayd.Acceleration]]  . . . February 08, 2022, at 06:27 AM by [[~Naglfar]]: [=Fix: https forwarding port=]%0a* [[AncientWisdom.Bio]]  . . . February 07, 2022, at 01:18 PM by [[~AncientWisdom]]: [==]%0a* [[Minutemin.Questions]]  . . . February 05, 2022, at 09:16 AM by [[~jrmu]]: [==]%0a* [[Minutemin.Server]]  . . . February 05, 2022, at 08:14 AM by [[~jrmu]]: [==]%0a* [[Vmm.SlackwareIso]]  . . . February 03, 2022, at 10:53 PM by [[~Naglfar]]: [=Slackware 15.0 x86 stable is released=]%0a* [[Vmctl.Usage]]  . . . February 03, 2022, at 06:24 PM by [[~miniontoby]]: [=fixed attachment=]%0a* [[Duplicity.Usage]]  . . . February 02, 2022, at 10:31 AM by [[~jrmu]]: [==]%0a* [[Openssl.Encryptfile]]  . . . February 02, 2022, at 09:29 AM by [[~jrmu]]: [==]%0a* [[Bots.Basicbot]]  . . . January 31, 2022, at 08:54 PM by [[~izzyb]]: [==]%0a* [[Openrsync.Usage]]  . . . January 29, 2022, at 09:04 AM by [[~Naglfar]]: [=update from rsync to openrsync=]%0a* [[Openbsd.Tcpip]]  . . . January 24, 2022, at 05:45 PM by [[~jrmu]]: [==]%0a* [[Synclient.Configure]]  . . . January 24, 2022, at 06:02 AM by [[~jrmu]]: [==]%0a* [[Crontab.Edit]]  . . . January 23, 2022, at 05:46 PM by [[~mkf]]: [==]%0a* [[9.Install]]  . . . January 22, 2022, at 06:57 AM by [[~mkf]]: [==]%0a* [[Asterisk.Install]]  . . . January 19, 2022, at 05:34 AM by [[~jrmu]]: [==]%0a* [[9.Rcpu]]  . . . January 17, 2022, at 10:19 PM by [[~jrmu]]: [==]%0a* [[9.9p]]  . . . January 17, 2022, at 08:47 PM by [[~mkf]]: [==]%0a* [[9.Ndb]]  . . . January 16, 2022, at 06:46 PM by [[~mkf]]: [==]%0a* [[Openbsd.U9fs]]  . . . January 16, 2022, at 06:23 PM by [[~mkf]]: [==]%0a* [[Dns.FQDN]]  . . . January 15, 2022, at 10:16 PM by [[~jrmu]]: [==]%0a* [[Pgp.Create]]  . . . January 14, 2022, at 09:14 AM by [[~baytuch]]: [==]%0a* [[Nsd.DNSSec]]  . . . January 14, 2022, at 02:53 AM by [[~pyr3x]]: [==]%0a* [[Openbsd.Locale]]  . . . January 12, 2022, at 01:23 PM by [[~baytuch]]: [==]%0a* [[Openbsd.Openbsd]]  . . . January 12, 2022, at 01:19 PM by [[~baytuch]]: [==]%0a* [[Ksh.Autocomplete]]  . . . January 11, 2022, at 01:44 PM by [[~miniontoby]]: [=updated url=]%0a* [[Gpg.Verify]]  . . . January 08, 2022, at 09:48 PM by [[~Naglfar]]: [=Add description=]%0a* [[Mlmmj.Archive]]  . . . January 06, 2022, at 10:52 PM by [[~Hawk]]: [==]%0a* [[9.Hostowner]]  . . . January 06, 2022, at 11:29 AM by [[~mkf]]: [==]%0a* [[Ircnow.Dogfood]]  . . . January 06, 2022, at 08:48 AM by [[~jrmu]]: [==]%0a* [[9.Authsrv]]  . . . January 05, 2022, at 04:59 AM by [[~mkf]]: [=hmm=]%0a* [[9.Chording]]  . . . January 03, 2022, at 02:40 PM by [[~jrmu]]: [==]%0a* [[Ircnow.Status]]  . . . January 03, 2022, at 06:06 AM by [[~jrmu]]: [==]%0a* [[Openbsd.BBB]]  . . . January 03, 2022, at 12:06 AM by [[~jrmu]]: [==]%0a* [[Got.Server]]  . . . January 02, 2022, at 05:42 PM by [[~jrmu]]: [==]%0a* [[Census.Census]]  . . . January 02, 2022, at 11:27 AM by [[~jrmu]]: [==]%0a* [[Bncnow.Bncnow]]  . . . January 02, 2022, at 11:18 AM by [[~jrmu]]: [==]%0a* [[Ircnow.Projects]]  . . . January 02, 2022, at 11:09 AM by [[~jrmu]]: [==]%0a* [[Ircfs.Intro]]  . . . January 02, 2022, at 10:49 AM by [[~jrmu]]: [==]%0a* [[Ircnowd.Ircnowd]]  . . . January 02, 2022, at 06:32 AM by [[~jrmu]]: [==]%0a* [[Marketing.Marketing]]  . . . January 02, 2022, at 06:20 AM by [[~jrmu]]: [==]%0a* [[Ircnow.Sonsofliberty]]  . . . January 02, 2022, at 06:06 AM by [[~jrmu]]: [==]%0a* [[Pkgadd.CheckUpdates]]  . . . January 01, 2022, at 04:29 AM by [[~pyr3x]]: [==]%0a* [[Ircnow.Roadmap2021]]  . . . December 30, 2021, at 06:31 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Sftp]]  . . . December 30, 2021, at 06:01 AM by [[~jrmu]]: [==]%0a* [[Sftp.Chroot]]  . . . December 30, 2021, at 06:01 AM by [[~jrmu]]: [==]%0a* [[Ircnow.Status2022]]  . . . December 30, 2021, at 05:35 AM by [[~jrmu]]: [==]%0a* [[Eggdrop.UTF8]]  . . . December 28, 2021, at 08:21 PM by [[~jrmu]]: [==]%0a* [[Openbsd.Uim]]  . . . December 26, 2021, at 01:45 AM by [[~jrmu]]: [==]%0a* [[Sshwifty.Install]]  . . . December 23, 2021, at 02:49 PM by [[~miniontoby]]: [=created=]%0a* [[Nsd.Zone]]  . . . December 23, 2021, at 10:33 AM by [[~jrmu]]: [==]%0a* [[Openhttpd.Hosting]]  . . . December 23, 2021, at 03:06 AM by [[~jrmu]]: [==]%0a* [[OpenSSH.RSAkeys]]  . . . December 22, 2021, at 03:18 PM by [[~miniontoby]]: [==]%0a* [[Openbsd.Wifi]]  . . . December 22, 2021, at 02:59 PM by [[~jrmu]]: [==]%0a* [[Openbsd.Recordaudio]]  . . . December 22, 2021, at 01:24 PM by [[~jrmu]]: [==]%0a* [[9.9]]  . . . December 22, 2021, at 11:30 AM by [[~xfnw]]: [=fix some grammatical errors=]%0a* [[Parec.Record]]  . . . December 22, 2021, at 07:02 AM by [[~jrmu]]: [==]%0a* [[Sox.Concat]]  . . . December 22, 2021, at 07:01 AM by [[~jrmu]]: [==]%0a* [[Ffmpeg.Recordscreen]]  . . . December 22, 2021, at 07:00 AM by [[~jrmu]]: [==]%0a* [[JuiceSSH.Connect]]  . . . December 20, 2021, at 01:03 PM by [[~jrmu]]: [==]%0a* [[Marketing.Memes]]  . . . December 20, 2021, at 12:55 PM by [[~jrmu]]: [==]%0a* [[9.Independent]]  . . . December 20, 2021, at 12:47 PM by [[~jrmu]]: [==]%0a* [[MacScreenSharing.Connect]]  . . . December 20, 2021, at 11:57 AM by [[~jrmu]]: [==]%0a* [[9.Partdisk]]  . . . December 20, 2021, at 11:39 AM by [[~jrmu]]: [==]%0a* [[Got.Usage]]  . . . December 17, 2021, at 04:44 PM by [[~jrmu]]: [==]%0a* [[Irc.Federation]]  . . . December 17, 2021, at 02:03 PM by [[~jrmu]]: [==]%0a* [[Irc.Chanop]]  . . . December 14, 2021, at 04:58 AM by [[~mkf]]: [==]%0a* [[9.Todo]]  . . . December 03, 2021, at 07:52 PM by [[~mkf]]: [==]%0a* [[Pylink.Chroot]]  . . . December 02, 2021, at 02:03 PM by [[~jrmu]]: [==]%0a* [[Pylink.Install]]  . . . December 02, 2021, at 02:02 PM by [[~jrmu]]: [==]%0a* [[Jrmu.Marriage]]  . . . December 02, 2021, at 06:09 AM by [[~jrmu]]: [==]%0a* [[Hosting.Hosting]]  . . . December 01, 2021, at 02:01 PM by [[~jrmu]]: [==]%0a* [[Mc.Usage]]  . . . November 29, 2021, at 07:53 PM by [[~mkf]]: [==]%0a* [[PuTTY.Connect]]  . . . November 29, 2021, at 12:13 PM by [[~jrmu]]: [==]%0a* [[Email.Email]]  . . . November 29, 2021, at 04:19 AM by [[~mkf]]: [==]%0a* [[Texlive.Sinhala]]  . . . November 28, 2021, at 06:35 AM by [[~jrmu]]: [==]%0a* [[MailWindows.Connect]]  . . . November 27, 2021, at 03:12 PM by [[~jrmu]]: [==]%0a* [[Gajim.Biboumi]]  . . . November 27, 2021, at 01:02 PM by [[~jrmu]]: [==]%0a* [[Xmpp.Xmpp]]  . . . November 27, 2021, at 12:33 PM by [[~jrmu]]: [==]%0a* [[Mcabber.Connect]]  . . . November 26, 2021, at 01:38 PM by [[~jrmu]]: [==]%0a* [[ChatSecure.Connect]]  . . . November 26, 2021, at 11:36 AM by [[~jrmu]]: [==]%0a* [[9.9pfs]]  . . . November 24, 2021, at 02:00 PM by [[~mkf]]: [==]%0a* [[Vmm.DebianInstall]]  . . . November 24, 2021, at 11:44 AM by [[~nicoz]]: [==]%0a* [[Siskin.Connect]]  . . . November 23, 2021, at 04:38 PM by [[~jrmu]]: [==]%0a* [[Dino.Connect]]  . . . November 23, 2021, at 02:10 PM by [[~mkf]]: [==]%0a* [[Monal.Connect]]  . . . November 23, 2021, at 10:32 AM by [[~jrmu]]: [==]%0a* [[Xabber.Connect]]  . . . November 23, 2021, at 10:20 AM by [[~jrmu]]: [==]%0a* [[DNS.DMARC]]  . . . November 22, 2021, at 10:52 PM by [[~Hawk]]: [==]%0a* [[StorkIM.Connect]]  . . . November 21, 2021, at 05:03 AM by [[~jrmu]]: [==]%0a* [[Conversations.Connect]]  . . . November 20, 2021, at 05:37 PM by [[~jrmu]]: [==]%0a* [[Yaxim.Connect]]  . . . November 20, 2021, at 05:09 PM by [[~jrmu]]: [==]%0a* [[Adium.Connect]]  . . . November 20, 2021, at 07:32 AM by [[~jrmu]]: [==]%0a* [[Vmm.AlmaLinux]]  . . . November 20, 2021, at 06:47 AM by [[~dodocrypto]]: [==]%0a* [[Vmm.DebianIso]]  . . . November 19, 2021, at 09:35 PM by [[~nicoz]]: [==]%0a* [[Psi.Connect]]  . . . November 17, 2021, at 03:23 PM by [[~jrmu]]: [==]%0a* [[Pidgin.Connect]]  . . . November 17, 2021, at 10:18 AM by [[~jrmu]]: [==]%0a* [[Gajim.Connect]]  . . . November 17, 2021, at 08:01 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Training]]  . . . November 16, 2021, at 03:30 PM by [[~Hawk]]: [==]%0a* [[Opera.Connect]]  . . . November 16, 2021, at 12:12 AM by [[~wiz]]: [==]%0a* [[0dev.0dev]]  . . . November 12, 2021, at 03:00 AM by [[~dodocrypto]]: [==]%0a* [[Vmm.RockyLinux]]  . . . November 11, 2021, at 10:51 AM by [[~dodocrypto]]: [==]%0a* [[Opensmtpd.Openrelay]]  . . . November 11, 2021, at 10:37 AM by [[~mkf]]: [==]%0a* [[Sandbox.0dev]]  . . . November 11, 2021, at 01:45 AM by [[~dodocrypto]]: [==]%0a* [[Nsd.Configure]]  . . . November 10, 2021, at 11:58 AM by [[~Hawk]]: [==]%0a* [[Got.Mirror]]  . . . November 07, 2021, at 05:22 PM by [[~jrmu]]: [==]%0a* [[Vpn.OpenIKED]]  . . . November 07, 2021, at 03:45 PM by [[~gloNO]]: [==]%0a* [[Openbsd.Got]]  . . . November 07, 2021, at 03:16 PM by [[~jrmu]]: [==]%0a* [[Ircnow.Opsofliberty]]  . . . November 06, 2021, at 05:15 PM by [[~jrmu]]: [==]%0a* [[Emacs.Emacs]]  . . . November 06, 2021, at 04:39 PM by [[~LohanG]]: [==]%0a* [[ZNC.Support]]  . . . November 06, 2021, at 03:53 PM by [[~LohanG]]: [=added libera=]%0a* [[Vmm.Plan9]]  . . . November 05, 2021, at 09:31 PM by [[~mkf]]: [=???=]%0a* [[9.Stone]]  . . . November 04, 2021, at 04:09 PM by [[~meeekeeef]]: [==]%0a* [[9.Zuke]]  . . . November 04, 2021, at 04:01 PM by [[~meeekeeef]]: [==]%0a* [[Openbsd.Drawtermssh]]  . . . November 04, 2021, at 03:54 PM by [[~meeekeeef]]: [=ssh bad >:[=]%0a* [[Netcat.Http]]  . . . November 03, 2021, at 02:30 PM by [[~jrmu]]: [==]%0a* [[Telnet.Http]]  . . . November 03, 2021, at 02:18 PM by [[~jrmu]]: [==]%0a* [[Znc.Relayd]]  . . . November 03, 2021, at 10:18 AM by [[~jrmu]]: [==]%0a* [[ZNC.Admin]]  . . . November 02, 2021, at 05:44 PM by [[~jrmu]]: [==]%0a* [[Znc.Debug]]  . . . November 02, 2021, at 03:23 PM by [[~jrmu]]: [==]%0a* [[Znc.Usage]]  . . . November 02, 2021, at 03:09 PM by [[~jrmu]]: [==]%0a* [[Ambassador.Markets]]  . . . November 02, 2021, at 01:29 PM by [[~jrmu]]: [==]%0a* [[Almanack.Rewrite]]  . . . October 31, 2021, at 10:30 PM by [[~hydragyrum]]: [==]%0a* [[9.Sysupdate]]  . . . October 31, 2021, at 10:21 PM by [[~meeekeeef]]: [==]%0a* [[Debian.Debian]]  . . . October 31, 2021, at 12:34 PM by [[~monaco]]: [==]%0a* [[Ircnow.Victorycpus]]  . . . October 30, 2021, at 08:17 AM by [[~jrmu]]: [==]%0a* [[Gnus.Connect]]  . . . October 30, 2021, at 01:32 AM by [[~hydragyrum]]: [==]%0a* [[Ircnow.Settler]]  . . . October 29, 2021, at 04:03 PM by [[~jrmu]]: [==]%0a* [[Debian.Nginxphpfpm]]  . . . October 29, 2021, at 12:26 PM by [[~monaco]]: [==]%0a* [[Debian.Nginx]]  . . . October 29, 2021, at 12:18 PM by [[~monaco]]: [==]%0a* [[Vmm.Homerouter]]  . . . October 26, 2021, at 05:08 PM by [[~jrmu]]: [==]%0a* [[9.Netcat]]  . . . October 25, 2021, at 03:40 PM by [[~jrmu]]: [==]%0a* [[9.Plan9ini]]  . . . October 24, 2021, at 04:30 PM by [[~jrmu]]: [==]%0a* [[Iked.Newconfig]]  . . . October 24, 2021, at 03:49 PM by [[~tool]]: [==]%0a* [[Lua.Minetest-1]]  . . . October 24, 2021, at 10:30 AM by [[~debiankaios]]: [==]%0a* [[9.Links]]  . . . October 24, 2021, at 06:29 AM by [[~mkf]]: [==]%0a* [[9.Keybindings]]  . . . October 24, 2021, at 06:15 AM by [[~mkf]]: [=heheheheheh=]%0a* [[Xdefaults.Configure]]  . . . October 23, 2021, at 02:40 PM by [[~jrmu]]: [==]%0a* [[TigerVNC.SSH]]  . . . October 23, 2021, at 11:56 AM by [[~Hawk]]: [==]%0a* [[Rio.Customize]]  . . . October 22, 2021, at 09:22 AM by [[~jrmu]]: [==]%0a* [[9.Ssh]]  . . . October 22, 2021, at 12:54 AM by [[~jrmu]]: [==]%0a* [[Vmm.Devuan4Iso]]  . . . October 21, 2021, at 04:29 PM by [[~debiankaios]]: [=changed beowulf_3.1.1 to chimaera_4.0.0=]%0a* [[9.101]]  . . . October 20, 2021, at 04:53 PM by [[~jrmu]]: [==]%0a* [[Fvwm.Configure]]  . . . October 18, 2021, at 10:20 AM by [[~jrmu]]: [==]%0a* [[KISSmo.KISSmo]]  . . . October 18, 2021, at 09:58 AM by [[~monaco]]: [==]%0a* [[KISSmo.Download]]  . . . October 18, 2021, at 09:53 AM by [[~monaco]]: [==]%0a* [[KISSmo.About]]  . . . October 18, 2021, at 09:52 AM by [[~monaco]]: [==]%0a* [[KISSmo.Install]]  . . . October 18, 2021, at 09:44 AM by [[~monaco]]: [==]%0a* [[Cvs.Repo]]  . . . October 17, 2021, at 08:32 AM by [[~jrmu]]: [==]%0a* [[Cvs.Anoncvs]]  . . . October 17, 2021, at 04:00 AM by [[~jrmu]]: [==]%0a* [[Cvs.Commit]]  . . . October 17, 2021, at 03:58 AM by [[~jrmu]]: [==]%0a* [[Cvs.Cvsweb]]  . . . October 17, 2021, at 03:28 AM by [[~jrmu]]: [==]%0a* [[9.Cvsfs]]  . . . October 15, 2021, at 12:58 PM by [[~mkf]]: [==]%0a* [[Openbsd.Sysupgrade70]]  . . . October 15, 2021, at 11:02 AM by [[~mkf]]: [=humans are easily confused.=]%0a* [[Openbsd.Ilines]]  . . . October 15, 2021, at 02:36 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Pmwiki]]  . . . October 14, 2021, at 02:14 PM by [[~miniontoby]]: [=added credits =]%0a* [[Vmm.Devuan-ISO]]  . . . October 14, 2021, at 09:50 AM by [[~siva]]: [==]%0a* [[Vmm.Devuan-Simple]]  . . . October 14, 2021, at 09:48 AM by [[~siva]]: [=Tutorial Created=]%0a* [[Cvs.Intro]]  . . . October 13, 2021, at 03:49 PM by [[~jrmu]]: [==]%0a* [[Synapse.Install]]  . . . October 12, 2021, at 02:49 PM by [[~miniontoby]]: [=Created=]%0a* [[Ircnow.Oper]]  . . . October 12, 2021, at 03:02 AM by [[~jrmu]]: [==]%0a* [[Terms.Privacy]]  . . . October 11, 2021, at 11:48 AM by [[~jrmu]]: [==]%0a* [[Ircnow.Diversity]]  . . . October 09, 2021, at 02:56 AM by [[~jrmu]]: [==]%0a* [[Ircnow.Linux]]  . . . October 08, 2021, at 04:51 AM by [[~jrmu]]: [==]%0a* [[OpenBSD.ResetPassword]]  . . . October 07, 2021, at 03:56 AM by [[~jrmu]]: [==]%0a* [[Terms.Vps]]  . . . October 06, 2021, at 12:30 AM by [[~jrmu]]: [==]%0a* [[9.JSDrawterm]]  . . . September 30, 2021, at 06:06 PM by [[~jrmu]]: [==]%0a* [[9.Fonts]]  . . . September 28, 2021, at 05:13 PM by [[~jrmu]]: [==]%0a* [[Openbsd.Install69]]  . . . September 27, 2021, at 05:59 PM by [[~jrmu]]: [==]%0a* [[Cvs.Guide]]  . . . September 26, 2021, at 02:28 PM by [[~Miniontoby]]: [==]%0a* [[Openbsd.PFStable]]  . . . September 24, 2021, at 03:28 PM by [[~miniontoby]]: [==]%0a* [[License.IrcnowV2]]  . . . September 21, 2021, at 03:53 AM by [[~jrmu]]: [==]%0a* [[Dhcpd.Configure]]  . . . September 15, 2021, at 04:02 PM by [[~jrmu]]: [==]%0a* [[Vmm.Router]]  . . . September 14, 2021, at 12:11 PM by [[~jrmu]]: [==]%0a* [[Weechat.Relay]]  . . . September 11, 2021, at 05:46 PM by [[~mkf]]: [==]%0a* [[Gry.Bio]]  . . . September 11, 2021, at 02:49 AM by [[~jrmu]]: [==]%0a* [[Hopm.Telnet]]  . . . September 10, 2021, at 06:13 AM by [[~mkf]]: [==]%0a* [[Wraith.Chroot]]  . . . September 10, 2021, at 06:11 AM by [[~mkf]]: [==]%0a* [[Mutt.Connect]]  . . . September 10, 2021, at 06:01 AM by [[~mkf]]: [=6.8 -> 6.9=]%0a* [[ZNC.Skins]]  . . . September 06, 2021, at 07:58 AM by [[~mkf]]: [="Huh, pmwiki has a bug." no numbered list if use monospaced text. :(=]%0a* [[Seamonkey.Connect]]  . . . August 28, 2021, at 01:05 PM by [[~mkf]]: [==]%0a* [[Debate.Wikistyle]]  . . . August 27, 2021, at 03:29 PM by [[~mkf]]: [==]%0a* [[Email.EmailAndroidEmailApp]]  . . . August 27, 2021, at 02:37 PM by [[~mkf]]: [==]%0a* [[Tmux.Shortcuts]]  . . . August 27, 2021, at 12:56 PM by [[~mkf]]: [==]%0a* [[Vmm.Haiku]]  . . . August 27, 2021, at 12:53 PM by [[~mkf]]: [==]%0a* [[Openbsd.Mailopenproxy]]  . . . August 25, 2021, at 08:19 PM by [[~mkf]]: [==]%0a* [[Openbsd.Two-FactorAuth]]  . . . August 23, 2021, at 07:39 PM by [[~mkf]]: [=login.db compiling is no longer recommended.=]%0a* [[Vmm.DragonflyBSD]]  . . . August 23, 2021, at 07:31 PM by [[~mkf]]: [=logs=]%0a* [[Vmm.NetBSD]]  . . . August 23, 2021, at 07:01 PM by [[~mkf]]: [=better logs?=]%0a* [[Mariadb.Install]]  . . . August 23, 2021, at 04:42 PM by [[~wiz]]: [==]%0a* [[DNS.Ipv6rDNS]]  . . . August 23, 2021, at 11:55 AM by [[~jrmu]]: [==]%0a* [[Pipes.Redirection]]  . . . August 23, 2021, at 03:50 AM by [[~jrmu]]: [==]%0a* [[Ksh.Redirection]]  . . . August 23, 2021, at 03:50 AM by [[~jrmu]]: [==]%0a* [[DNS.RDNS]]  . . . August 22, 2021, at 11:20 PM by [[~jrmu]]: [==]%0a* [[Rbldnsd.Install]]  . . . August 22, 2021, at 07:58 PM by [[~mkf]]: [=wiki-ish.=]%0a* [[Netcat.Smtp]]  . . . August 22, 2021, at 06:58 PM by [[~mkf]]: [=byebye=]%0a* [[Vmm.UbuntuIso]]  . . . August 22, 2021, at 06:40 AM by [[~jrmu]]: [==]%0a* [[Vmm.DevuanIso]]  . . . August 22, 2021, at 05:44 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Npppd]]  . . . August 21, 2021, at 01:43 PM by [[~mkf]]: [==]%0a* [[Shell.Shell]]  . . . August 21, 2021, at 11:42 AM by [[~jrmu]]: [==]%0a* [[Tls.CA]]  . . . August 21, 2021, at 11:10 AM by [[~jrmu]]: [==]%0a* [[Openssl.Imap]]  . . . August 21, 2021, at 04:05 AM by [[~AncientWisdom]]: [==]%0a* [[Openbsd.FilePermissions]]  . . . August 20, 2021, at 02:20 AM by [[~Nate S]]: [==]%0a* [[Ircnow.Todo]]  . . . August 17, 2021, at 08:41 AM by [[~mkf]]: [==]%0a* [[Vmm.GuixIso]]  . . . August 16, 2021, at 05:12 PM by [[~jrmu]]: [==]%0a* [[Vmm.VoidIso]]  . . . August 16, 2021, at 06:19 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Gophernicus]]  . . . August 15, 2021, at 02:06 AM by [[~mkf]]: [==]%0a* [[Gazette.Gazette]]  . . . August 15, 2021, at 01:14 AM by [[~mkf]]: [=a bit polishing=]%0a* [[EmailTray.Connect]]  . . . August 15, 2021, at 12:11 AM by [[~mkf]]: [==]%0a* [[Bouncer.Konversation]]  . . . August 14, 2021, at 02:46 PM by [[~mkf]]: [==]%0a* [[Squirrelmail.Connect]]  . . . August 14, 2021, at 04:47 AM by [[~mkf]]: [==]%0a* [[Termius.Connect]]  . . . August 14, 2021, at 04:42 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Openhttpd]]  . . . August 13, 2021, at 07:29 AM by [[~jrmu]]: [==]%0a* [[ConnectBot.Keys]]  . . . August 12, 2021, at 06:58 AM by [[~jrmu]]: [==]%0a* [[Debate.Monopolydanger]]  . . . August 11, 2021, at 07:01 PM by [[~mkf]]: [==]%0a* [[ConnectBot.Connect]]  . . . August 11, 2021, at 04:34 PM by [[~jrmu]]: [==]%0a* [[Openbsd.ZNCModules]]  . . . August 11, 2021, at 03:06 PM by [[~wiz]]: [==]%0a* [[Termux.Connect]]  . . . August 11, 2021, at 05:28 AM by [[~jrmu]]: [==]%0a* [[Web101.Web101]]  . . . August 10, 2021, at 04:20 PM by [[~craziness]]: [=started web101=]%0a* [[Openbsd.Bitlbee]]  . . . August 10, 2021, at 12:03 PM by [[~mkf]]: [==]%0a* [[Openbsd.Pppoe]]  . . . August 10, 2021, at 11:56 AM by [[~mkf]]: [==]%0a* [[Sylpheed.Connect]]  . . . August 10, 2021, at 11:50 AM by [[~mkf]]: [=eh, forgot that "[" again=]%0a* [[MacTerminal.Connect]]  . . . August 10, 2021, at 10:33 AM by [[~jrmu]]: [==]%0a* [[OpenSSH.Connect]]  . . . August 10, 2021, at 10:19 AM by [[~jrmu]]: [==]%0a* [[Fdroid.Install]]  . . . August 10, 2021, at 09:05 AM by [[~jrmu]]: [==]%0a* [[Shell.Sshfingerprints]]  . . . August 10, 2021, at 08:55 AM by [[~jrmu]]: [==]%0a* [[OpenSSH.Keygen]]  . . . August 09, 2021, at 06:27 PM by [[~jrmu]]: [==]%0a* [[Openbsd.Sshkeys]]  . . . August 09, 2021, at 04:42 PM by [[~jrmu]]: [==]%0a* [[Vmm.9front]]  . . . August 09, 2021, at 06:16 AM by [[~mkf]]: [==]%0a* [[Bouncer.WinIRC]]  . . . August 09, 2021, at 06:03 AM by [[~mkf]]: [==]%0a* [[IP.Myaddress]]  . . . August 07, 2021, at 05:14 PM by [[~jrmu]]: [==]%0a* [[SerFISH.Connect]]  . . . August 06, 2021, at 05:05 PM by [[~jrmu]]: [==]%0a* [[Sshwifty.Connect]]  . . . August 06, 2021, at 05:00 PM by [[~jrmu]]: [==]%0a* [[Openbsd.Squirrelmail]]  . . . August 06, 2021, at 10:32 AM by [[~baytuch]]: [==]%0a* [[Eggdrop.NickServ]]  . . . August 05, 2021, at 07:27 AM by [[~jrmu]]: [==]%0a* [[Medals.Intro]]  . . . August 04, 2021, at 08:34 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Dnszones]]  . . . August 03, 2021, at 09:26 AM by [[~jrmu]]: [==]%0a* [[Dns.Zonefile]]  . . . August 03, 2021, at 09:21 AM by [[~jrmu]]: [==]%0a* [[Irc.Clients]]  . . . August 02, 2021, at 02:54 PM by [[~mkf]]: [==]%0a* [[Minutemin.Ifconfig]]  . . . August 02, 2021, at 12:59 PM by [[~mkf]]: [==]%0a* [[Openbsd.Matterbridge]]  . . . August 02, 2021, at 12:33 PM by [[~mkf]]: [==]%0a* [[Znc.I18n]]  . . . August 02, 2021, at 09:12 AM by [[~mkf]]: [==]%0a* [[Almanack.Alt]]  . . . August 02, 2021, at 07:52 AM by [[~jrmu]]: [==]%0a* [[Eggdrop.Simple]]  . . . August 02, 2021, at 07:49 AM by [[~jrmu]]: [==]%0a* [[Eggdrop.Install]]  . . . August 02, 2021, at 05:11 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Vhost]]  . . . August 02, 2021, at 02:32 AM by [[~jrmu]]: [==]%0a* [[Ircnow.Hardware]]  . . . August 01, 2021, at 01:48 PM by [[~jrmu]]: [==]%0a* [[Thunderirc.Hardware]]  . . . August 01, 2021, at 01:47 PM by [[~jrmu]]: [==]%0a* [[Planetofnix.Hardware]]  . . . August 01, 2021, at 01:46 PM by [[~jrmu]]: [==]%0a* [[Bsdforall.Hardware]]  . . . August 01, 2021, at 01:45 PM by [[~jrmu]]: [==]%0a* [[Oddprotocol.Hardware]]  . . . August 01, 2021, at 01:28 PM by [[~jrmu]]: [==]%0a* [[Lecturify.Hardware]]  . . . August 01, 2021, at 01:27 PM by [[~jrmu]]: [==]%0a* [[Eggdrop184.Install]]  . . . August 01, 2021, at 07:07 AM by [[~jrmu]]: [==]%0a* [[Congress.Procedure]]  . . . August 01, 2021, at 06:41 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Chroot]]  . . . July 31, 2021, at 02:47 AM by [[~jrmu]]: [==]%0a* [[Syslogd.Remote]]  . . . July 30, 2021, at 03:30 PM by [[~jrmu]]: [==]%0a* [[Openbsd.Vmmuser]]  . . . July 29, 2021, at 05:31 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Vmminstall]]  . . . July 29, 2021, at 05:28 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Vmm]]  . . . July 29, 2021, at 05:24 AM by [[~jrmu]]: [==]%0a* [[Openbsd.ZNCAdmin]]  . . . July 28, 2021, at 06:14 AM by [[~jrmu]]: [==]%0a* [[Openbsd.ZNCSupport]]  . . . July 28, 2021, at 06:14 AM by [[~jrmu]]: [==]%0a* [[ZNC.Troubleshoot]]  . . . July 28, 2021, at 06:12 AM by [[~jrmu]]: [==]%0a* [[Znc.Troubleshoot]]  . . . July 28, 2021, at 06:11 AM by [[~jrmu]]: [==]%0a* [[Kill.Usage]]  . . . July 28, 2021, at 03:42 AM by [[~jrmu]]: [==]%0a* [[Ps.Usage]]  . . . July 28, 2021, at 03:42 AM by [[~jrmu]]: [==]%0a* [[Dns.Vhost]]  . . . July 28, 2021, at 03:05 AM by [[~jrmu]]: [==]%0a* [[Host.Usage]]  . . . July 28, 2021, at 01:57 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Php]]  . . . July 27, 2021, at 02:53 PM by [[~jrmu]]: [==]%0a* [[UsersCategoryMirrory.IRCFreeHomesteadVPS]]  . . . July 26, 2021, at 06:12 AM by [[~category_mirror]]: [==]%0a* [[Ircnow.PioneerTldr]]  . . . July 26, 2021, at 06:04 AM by [[~jrmu]]: [==]%0a* [[UsersCategoryMirrory.Pioneer]]  . . . July 26, 2021, at 04:22 AM by [[~category_mirror]]: [==]%0a* [[Openbsd.Dig]]  . . . July 25, 2021, at 06:50 AM by [[~jrmu]]: [==]%0a* [[Openbsd.RDNS]]  . . . July 23, 2021, at 06:44 AM by [[~jrmu]]: [==]%0a* [[Wordpress.Install]]  . . . July 21, 2021, at 06:59 PM by [[~mkf]]: [==]%0a* [[Bouncer.All]]  . . . July 21, 2021, at 06:37 PM by [[~mkf]]: [==]%0a* [[Lemon.Todo]]  . . . July 21, 2021, at 06:21 PM by [[~mkf]]: [==]%0a* [[Irc.Guide]]  . . . July 21, 2021, at 06:02 PM by [[~mkf]]: [=client -> clients=]%0a* [[Openbsd.Sic]]  . . . July 21, 2021, at 05:57 PM by [[~mkf]]: [=first edit.=]%0a* [[Minutemin.Progress]]  . . . July 21, 2021, at 08:10 AM by [[~jrmu]]: [==]%0a* [[Openssl.Check]]  . . . July 20, 2021, at 01:27 PM by [[~jrmu]]: [==]%0a* [[Rsync.Usage]]  . . . July 19, 2021, at 02:30 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Openrsync]]  . . . July 18, 2021, at 02:01 PM by [[~jrmu]]: [==]%0a* [[Eggdrop.DuckHunt]]  . . . July 17, 2021, at 06:34 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Znc]]  . . . July 16, 2021, at 10:43 AM by [[~jrmu]]: [==]%0a* [[Netizen.Become]]  . . . July 14, 2021, at 09:47 AM by [[~jrmu]]: [==]%0a* [[Freedom.Bearcode]]  . . . July 14, 2021, at 09:42 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Staticnet]]  . . . July 12, 2021, at 05:48 PM by [[~jrmu]]: [==]%0a* [[Openbsd.Dovecot]]  . . . July 12, 2021, at 02:58 PM by [[~jrmu]]: [==]%0a* [[Openbsd.Relayd]]  . . . July 12, 2021, at 02:45 PM by [[~jrmu]]: [==]%0a* [[Openbsd.Spf]]  . . . July 12, 2021, at 03:08 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Eggdrop]]  . . . July 02, 2021, at 03:20 AM by [[~jrmu]]: [==]%0a* [[Openssl.Http]]  . . . June 30, 2021, at 04:44 AM by [[~mkf]]: [==]%0a* [[Debate.Oldsoftware]]  . . . June 29, 2021, at 03:56 PM by [[~mkf]]: [==]%0a* [[Debate.Xmlflaws]]  . . . June 29, 2021, at 03:54 PM by [[~mkf]]: [==]%0a* [[Debate.Wikipediadanger]]  . . . June 29, 2021, at 03:51 PM by [[~mkf]]: [==]%0a* [[Debate.DCC]]  . . . June 29, 2021, at 03:49 PM by [[~mkf]]: [==]%0a* [[Debate.Matrixflaws]]  . . . June 29, 2021, at 03:48 PM by [[~mkf]]: [==]%0a* [[Debate.Webirc]]  . . . June 29, 2021, at 03:48 PM by [[~mkf]]: [==]%0a* [[Debate.Nodejstrap]]  . . . June 29, 2021, at 03:48 PM by [[~mkf]]: [==]%0a* [[Debate.Ircv3defense]]  . . . June 29, 2021, at 03:45 PM by [[~mkf]]: [==]%0a* [[Openbsd.Newdisk]]  . . . June 29, 2021, at 03:23 PM by [[~jrmu]]: [==]%0a* [[AndroidEmail.AndroidEmail]]  . . . June 29, 2021, at 03:11 PM by [[~jrmu]]: [==]%0a* [[Openbsd.Ed]]  . . . June 28, 2021, at 04:04 PM by [[~mkf]]: [==]%0a* [[Openbsd.Unbound]]  . . . June 27, 2021, at 12:12 PM by [[~jrmu]]: [==]%0a* [[Freedom.Religion]]  . . . June 27, 2021, at 02:02 AM by [[~jrmu]]: [==]%0a* [[Tor.Hidden]]  . . . June 26, 2021, at 08:56 PM by [[~mkf]]: [==]%0a* [[Freedom.Union]]  . . . June 26, 2021, at 01:01 PM by [[~jrmu]]: [==]%0a* [[Freedom.Firstamendment]]  . . . June 26, 2021, at 11:45 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Dkimproxy]]  . . . June 25, 2021, at 12:56 PM by [[~jrmu]]: [==]%0a* [[MIF.Test]]  . . . June 25, 2021, at 12:42 PM by [[~nsturtz]]: [==]%0a* [[Openbsd.Sysupgrade69]]  . . . June 25, 2021, at 05:46 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Opensmtpd]]  . . . June 23, 2021, at 02:21 AM by [[~jrmu]]: [==]%0a* [[Openbsd.NgircdLink]]  . . . June 22, 2021, at 07:50 PM by [[~mkf]]: [=delete=]%0a* [[File.File]]  . . . June 22, 2021, at 07:43 PM by [[~mkf]]: [=linking=]%0a* [[Debate.Linuxflaws]]  . . . June 20, 2021, at 08:03 AM by [[~mkf]]: [=making hyperlinks=]%0a* [[Police.Intro]]  . . . June 19, 2021, at 11:42 AM by [[~jrmu]]: [==]%0a* [[Freedom.Destiny]]  . . . June 18, 2021, at 05:31 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Doas]]  . . . June 13, 2021, at 01:19 PM by [[~jrmu]]: [==]%0a* [[Freedom.Freedom]]  . . . June 13, 2021, at 09:13 AM by [[~jrmu]]: [==]%0a* [[Freedom.Press]]  . . . June 13, 2021, at 09:12 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Shell]]  . . . June 11, 2021, at 09:36 AM by [[~jrmu]]: [==]%0a* [[Ircnow.Constitution]]  . . . June 10, 2021, at 03:48 PM by [[~jrmu]]: [==]%0a* [[Netizen.Rights]]  . . . June 10, 2021, at 03:21 PM by [[~jrmu]]: [==]%0a* [[IPv4.Overview]]  . . . June 10, 2021, at 10:13 AM by [[~jrmu]]: [==]%0a* [[Ksh.Bash]]  . . . June 09, 2021, at 11:31 AM by [[~jrmu]]: [==]%0a* [[PowerShell.Connect]]  . . . June 09, 2021, at 11:10 AM by [[~jrmu]]: [==]%0a* [[Code.Code]]  . . . June 08, 2021, at 05:24 PM by [[~mkf]]: [=better formating=]%0a* [[Grape.DonateUs]]  . . . June 06, 2021, at 03:41 PM by [[~fizi]]: [==]%0a* [[Openbsd.Books]]  . . . June 06, 2021, at 12:46 PM by [[~jrmu]]: [==]%0a* [[Grape.Grape]]  . . . June 06, 2021, at 11:39 AM by [[~fizi]]: [==]%0a* [[Openbsd.Pfa]]  . . . June 06, 2021, at 03:49 AM by [[~navic]]: [==]%0a* [[Vmm.Debian]]  . . . June 04, 2021, at 07:48 PM by [[~mkf]]: [="LOL"=]%0a* [[DNS.Dnswl]]  . . . June 04, 2021, at 11:11 AM by [[~jrmu]]: [==]%0a* [[Netcat.SMTP]]  . . . June 04, 2021, at 09:59 AM by [[~jrmu]]: [==]%0a* [[Dkim.Dkimsign]]  . . . June 04, 2021, at 09:07 AM by [[~jrmu]]: [==]%0a* [[Tor.Torsocks]]  . . . June 04, 2021, at 06:16 AM by [[~jrmu]]: [==]%0a* [[Vpn.VpnIos]]  . . . June 04, 2021, at 05:52 AM by [[~jrmu]]: [==]%0a* [[Vpn.VpnMac]]  . . . June 04, 2021, at 05:40 AM by [[~jrmu]]: [==]%0a* [[Fdisk.Usage]]  . . . June 04, 2021, at 05:04 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Wordpress]]  . . . June 04, 2021, at 04:55 AM by [[~jrmu]]: [==]%0a* [[DNS.SPF]]  . . . June 03, 2021, at 01:27 PM by [[~jrmu]]: [==]%0a* [[Terms.Terms]]  . . . June 02, 2021, at 01:40 PM by [[~jrmu]]: [==]%0a* [[HostServ.Rules]]  . . . June 01, 2021, at 08:11 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Anope]]  . . . May 31, 2021, at 10:24 AM by [[~miniontoby]]: [=cp=]%0a* [[Openbsd.ACKFlood]]  . . . May 29, 2021, at 06:20 AM by [[~mkf]]: [==]%0a* [[Openbsd.SSDP]]  . . . May 29, 2021, at 06:18 AM by [[~mkf]]: [==]%0a* [[Openbsd.Anycast]]  . . . May 29, 2021, at 06:01 AM by [[~mkf]]: [==]%0a* [[Ambassador.Networks]]  . . . May 27, 2021, at 04:05 PM by [[~jrmu]]: [==]%0a* [[Marketing.Rules]]  . . . May 26, 2021, at 06:15 AM by [[~jrmu]]: [==]%0a* [[Freenode.Power]]  . . . May 26, 2021, at 04:38 AM by [[~jrmu]]: [==]%0a* [[Freenode.Money]]  . . . May 25, 2021, at 03:29 PM by [[~jrmu]]: [==]%0a* [[Freenode.Takeover]]  . . . May 25, 2021, at 05:28 AM by [[~jrmu]]: [==]%0a* [[Freedom.Freenode]]  . . . May 25, 2021, at 01:48 AM by [[~jrmu]]: [==]%0a* [[Bouncer.Atomic]]  . . . May 24, 2021, at 03:22 PM by [[~mkf]]: [=spacing=]%0a* [[Minetest.Updating]]  . . . May 24, 2021, at 08:10 AM by [[~mkf]]: [=monospaced commands=]%0a* [[Shell.Putty]]  . . . May 24, 2021, at 06:16 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Dmarc]]  . . . May 21, 2021, at 09:22 AM by [[~jrmu]]: [==]%0a* [[Vmm.Optimize]]  . . . May 19, 2021, at 04:04 AM by [[~jrmu]]: [==]%0a* [[Ircnow.Stable]]  . . . May 18, 2021, at 10:15 AM by [[~mkf]]: [==]%0a* [[Ircnow.VicePresident]]  . . . May 18, 2021, at 08:15 AM by [[~jrmu]]: [==]%0a* [[Ircnow.Sheriff]]  . . . May 18, 2021, at 08:00 AM by [[~jrmu]]: [==]%0a* [[Ircnow.Ambassador]]  . . . May 18, 2021, at 07:42 AM by [[~jrmu]]: [==]%0a* [[Pf.Guide]]  . . . May 17, 2021, at 03:37 AM by [[~bejelentkezni]]: [==]%0a* [[Openbsd.Disklabel]]  . . . May 17, 2021, at 03:33 AM by [[~bejelentkezni]]: [==]%0a* [[Openbsd.Fdisk]]  . . . May 17, 2021, at 03:27 AM by [[~bejelentkezni]]: [==]%0a* [[NewsNow.Install]]  . . . May 16, 2021, at 06:49 AM by [[~mkf]]: [="$"=]%0a* [[Tmux.Share]]  . . . May 15, 2021, at 02:27 AM by [[~mistera]]: [==]%0a* [[Openbsd.Security]]  . . . May 14, 2021, at 03:14 AM by [[~caesar]]: [==]%0a* [[Bouncer.Vision]]  . . . May 13, 2021, at 09:47 AM by [[~mkf]]: [=added home page, removed "..."s=]%0a* [[Minetest.Worldbackup]]  . . . May 12, 2021, at 11:02 AM by [[~AES]]: [==]%0a* [[Minetest.Texturestyle]]  . . . May 12, 2021, at 11:00 AM by [[~AES]]: [==]%0a* [[Minetest.Serverlocations]]  . . . May 12, 2021, at 10:59 AM by [[~AES]]: [==]%0a* [[Minetest.Addingarenas]]  . . . May 12, 2021, at 10:58 AM by [[~jrmu]]: [==]%0a* [[Relay.Relay]]  . . . May 12, 2021, at 09:10 AM by [[~jrmu]]: [==]%0a* [[Ngircd.Install-bej]]  . . . May 11, 2021, at 05:26 AM by [[~bejelentkezni]]: [==]%0a* [[Botnow.Botnow]]  . . . May 08, 2021, at 09:44 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Hopm-Arthur]]  . . . May 07, 2021, at 12:28 PM by [[~Arthur]]: [==]%0a* [[Znc.Chroot69]]  . . . May 06, 2021, at 03:36 AM by [[~bejelentkezni]]: [=back to 6.9 to see real changes=]%0a* [[Dig.Usage]]  . . . May 04, 2021, at 02:36 AM by [[~sarah]]: [==]%0a* [[Bgpd.Configure]]  . . . May 03, 2021, at 06:26 AM by [[~jrmu]]: [==]%0a* [[Cherry.Cherry]]  . . . May 02, 2021, at 01:43 PM by [[~Oz]]: [==]%0a* [[Freedom.Unix]]  . . . April 29, 2021, at 03:39 PM by [[~jrmu]]: [==]%0a* [[Pmwiki.Simpleurl]]  . . . April 29, 2021, at 02:46 PM by [[~punk]]: [==]%0a* [[Gpl.Flaws]]  . . . April 24, 2021, at 04:56 PM by [[~jrmu]]: [==]%0a* [[Iked.Windows]]  . . . April 18, 2021, at 07:38 PM by [[~st13g]]: [==]%0a* [[Freedom.Libertyordeath]]  . . . April 17, 2021, at 12:35 PM by [[~jrmu]]: [==]%0a* [[Minetest.Economy]]  . . . April 15, 2021, at 02:32 PM by [[~jrmu]]: [==]%0a* [[Vim.Vim]]  . . . April 11, 2021, at 11:14 PM by [[~monaco]]: [==]%0a* [[Minutemin.Duty]]  . . . April 11, 2021, at 04:53 AM by [[~jrmu]]: [==]%0a* [[License.License]]  . . . April 04, 2021, at 02:00 AM by [[~jrmu]]: [==]%0a* [[EthicalSource.HolierThanThou]]  . . . April 04, 2021, at 01:56 AM by [[~jrmu]]: [==]%0a* [[Jrmu.Rmsboycott]]  . . . April 03, 2021, at 01:36 AM by [[~jrmu]]: [==]%0a* [[Jrmu.Libertyordeath]]  . . . April 02, 2021, at 12:56 PM by [[~jrmu]]: [==]%0a* [[Fig.Fig]]  . . . March 31, 2021, at 10:15 AM by [[~chewy]]: [==]%0a* [[Coconut.Coconut]]  . . . March 29, 2021, at 12:28 PM by [[~jrmu]]: [==]%0a* [[Ircnow.CodeForce]]  . . . March 29, 2021, at 12:04 PM by [[~jrmu]]: [==]%0a* [[ClawsMail.Connect]]  . . . March 29, 2021, at 08:42 AM by [[~miniontoby]]: [==]%0a* [[Freedom.Madeonirc]]  . . . March 27, 2021, at 11:48 AM by [[~jrmu]]: [==]%0a* [[Third.Devs]]  . . . March 27, 2021, at 11:41 AM by [[~jrmu]]: [==]%0a* [[Minutemin.Code]]  . . . March 24, 2021, at 03:26 AM by [[~jrmu]]: [==]%0a* [[Cherry.Todo]]  . . . March 23, 2021, at 03:23 PM by [[~Oz]]: [==]%0a* [[Freedom.Independence]]  . . . March 22, 2021, at 01:13 PM by [[~wiz]]: [==]%0a* [[Ifconfig.Change]]  . . . March 20, 2021, at 11:15 AM by [[~jrmu]]: [==]%0a* [[Marketing.Founders]]  . . . March 20, 2021, at 01:40 AM by [[~jrmu]]: [==]%0a* [[NewsNow.Teams]]  . . . March 18, 2021, at 09:47 AM by [[~miniontoby]]: [=banana=]%0a* [[NewsNow.NewsNow]]  . . . March 17, 2021, at 04:33 PM by [[~miniontoby]]: [=more ways=]%0a* [[Vhost.Freedns]]  . . . March 16, 2021, at 12:22 PM by [[~wiz]]: [==]%0a* [[Marketing.Freedom]]  . . . March 15, 2021, at 01:30 PM by [[~jrmu]]: [==]%0a* [[Bsd.Labor]]  . . . March 15, 2021, at 06:12 AM by [[~jrmu]]: [==]%0a* [[License.Discriminatory]]  . . . March 15, 2021, at 06:12 AM by [[~jrmu]]: [==]%0a* [[Bsd.Hope]]  . . . March 14, 2021, at 11:05 PM by [[~jrmu]]: [==]%0a* [[License.Publicdomain]]  . . . March 14, 2021, at 10:02 AM by [[~jrmu]]: [==]%0a* [[Linux.Flaws]]  . . . March 14, 2021, at 05:13 AM by [[~jrmu]]: [==]%0a* [[NewsNow.Browser]]  . . . March 12, 2021, at 08:00 AM by [[~miniontoby]]: [==]%0a* [[Abuse.Code]]  . . . March 09, 2021, at 03:44 PM by [[~jrmu]]: [==]%0a* [[Congress.Documents]]  . . . March 07, 2021, at 04:50 AM by [[~jrmu]]: [==]%0a* [[Ircnow.Goals]]  . . . March 06, 2021, at 09:33 AM by [[~jrmu]]: [==]%0a* [[Ircnow.Chatforce]]  . . . March 05, 2021, at 02:15 PM by [[~jrmu]]: [==]%0a* [[Shell.Bash]]  . . . March 05, 2021, at 10:19 AM by [[~jrmu]]: [==]%0a* [[User.Welcome]]  . . . March 05, 2021, at 07:34 AM by [[~jrmu]]: [==]%0a* [[Immigrant.Welcome]]  . . . March 05, 2021, at 06:59 AM by [[~jrmu]]: [==]%0a* [[Mail.Openrelay]]  . . . March 04, 2021, at 03:20 PM by [[~jrmu]]: [==]%0a* [[Mail.Test]]  . . . March 04, 2021, at 03:07 PM by [[~jrmu]]: [==]%0a* [[Minutemin.Game]]  . . . March 04, 2021, at 10:16 AM by [[~jrmu]]: [==]%0a* [[Marketing.Recruit]]  . . . March 04, 2021, at 09:39 AM by [[~jrmu]]: [==]%0a* [[Ircnow.Howtoask]]  . . . March 03, 2021, at 12:35 PM by [[~jrmu]]: [==]%0a* [[Ircnow.Netizen]]  . . . February 28, 2021, at 03:18 PM by [[~jrmu]]: [==]%0a* [[Servers.Rights]]  . . . February 28, 2021, at 12:37 PM by [[~jrmu]]: [==]%0a* [[Marketing.Enterprise]]  . . . February 28, 2021, at 11:52 AM by [[~jrmu]]: [==]%0a* [[Minutemin.Creed]]  . . . February 28, 2021, at 03:21 AM by [[~jrmu]]: [==]%0a* [[Ln.Intro]]  . . . February 25, 2021, at 12:20 PM by [[~jrmu]]: [==]%0a* [[Leafnode.Install]]  . . . February 25, 2021, at 10:56 AM by [[~jrmu]]: [==]%0a* [[Guava.Todo]]  . . . February 23, 2021, at 10:47 AM by [[~quofan]]: [==]%0a* [[Relays.Relays]]  . . . February 22, 2021, at 04:22 PM by [[~jrmu]]: [==]%0a* [[Jujube.Jujube]]  . . . February 21, 2021, at 04:22 PM by [[~fizi]]: [==]%0a* [[PSFTP.Connect]]  . . . February 21, 2021, at 03:57 PM by [[~jrmu]]: [==]%0a* [[Outlook.Connect]]  . . . February 21, 2021, at 03:23 PM by [[~jrmu]]: [==]%0a* [[AppleMail.Connect]]  . . . February 20, 2021, at 04:38 PM by [[~jrmu]]: [==]%0a* [[Thunderbird.Pgp]]  . . . February 19, 2021, at 04:44 PM by [[~jrmu]]: [==]%0a* [[License.Ircnow]]  . . . February 19, 2021, at 09:45 AM by [[~miniontoby]]: [=2021=]%0a* [[Thunderbird.Connect]]  . . . February 19, 2021, at 09:36 AM by [[~jrmu]]: [==]%0a* [[Shell.Mac]]  . . . February 19, 2021, at 09:14 AM by [[~jrmu]]: [==]%0a* [[Minutemin.Training]]  . . . February 18, 2021, at 06:42 AM by [[~jrmu]]: [==]%0a* [[Freedom.Openforeveryone]]  . . . February 16, 2021, at 04:33 AM by [[~jrmu]]: [==]%0a* [[Ircnow.IRCitizen]]  . . . February 15, 2021, at 05:32 AM by [[~jrmu]]: [==]%0a* [[IPv6.Overview]]  . . . February 14, 2021, at 11:09 AM by [[~jrmu]]: [==]%0a* [[Tcpip.Overview]]  . . . February 14, 2021, at 11:02 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Syspatch]]  . . . February 14, 2021, at 11:00 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Netadmin]]  . . . February 14, 2021, at 10:56 AM by [[~jrmu]]: [==]%0a* [[Marketing.Religion]]  . . . February 14, 2021, at 10:37 AM by [[~jrmu]]: [==]%0a* [[Marketing.Independence]]  . . . February 13, 2021, at 04:59 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Leafnode]]  . . . February 12, 2021, at 01:40 PM by [[~chewy]]: [==]%0a* [[Oidentd.Pylink]]  . . . February 12, 2021, at 01:25 PM by [[~jrmu]]: [==]%0a* [[Marketing.Opportunity]]  . . . February 11, 2021, at 12:58 PM by [[~jrmu]]: [==]%0a* [[Marketing.Republic]]  . . . February 11, 2021, at 06:45 AM by [[~jrmu]]: [==]%0a* [[Achurch.Install]]  . . . February 10, 2021, at 04:33 PM by [[~jrmu]]: [==]%0a* [[Openbsd.Pylink]]  . . . February 08, 2021, at 08:33 AM by [[~jrmu]]: [==]%0a* [[Ircnow.OpofLiberty]]  . . . February 06, 2021, at 12:53 PM by [[~jrmu]]: [==]%0a* [[Ircnow.Allies]]  . . . February 06, 2021, at 12:47 PM by [[~jrmu]]: [==]%0a* [[Freedom.Dueprocess]]  . . . February 06, 2021, at 12:25 PM by [[~jrmu]]: [==]%0a* [[Freedom.Checks]]  . . . February 06, 2021, at 12:21 PM by [[~jrmu]]: [==]%0a* [[Freedom.Rulebylaw]]  . . . February 06, 2021, at 12:12 PM by [[~jrmu]]: [==]%0a* [[Freedom.Startupdream]]  . . . February 06, 2021, at 12:12 PM by [[~jrmu]]: [==]%0a* [[Freedom.Federation]]  . . . February 06, 2021, at 11:44 AM by [[~jrmu]]: [==]%0a* [[Freedom.Selfadmin]]  . . . February 06, 2021, at 11:26 AM by [[~jrmu]]: [==]%0a* [[Ircnow.OpsofLiberty]]  . . . February 06, 2021, at 02:13 AM by [[~jrmu]]: [==]%0a* [[Freedom.Homestead]]  . . . February 05, 2021, at 12:49 PM by [[~jrmu]]: [==]%0a* [[Freedom.Software]]  . . . February 05, 2021, at 11:31 AM by [[~jrmu]]: [==]%0a* [[Freedom.Opportunity]]  . . . February 05, 2021, at 08:55 AM by [[~jrmu]]: [==]%0a* [[Unix.Workethic]]  . . . February 05, 2021, at 08:49 AM by [[~jrmu]]: [==]%0a* [[Unix.Ethic]]  . . . February 05, 2021, at 08:48 AM by [[~jrmu]]: [==]%0a* [[Freedom.Privacy]]  . . . February 05, 2021, at 07:26 AM by [[~jrmu]]: [==]%0a* [[Debate.Privacy]]  . . . February 05, 2021, at 07:05 AM by [[~jrmu]]: [==]%0a* [[Team.Policy]]  . . . February 04, 2021, at 04:08 PM by [[~jrmu]]: [==]%0a* [[Freedom.Serversrights]]  . . . February 04, 2021, at 02:43 PM by [[~jrmu]]: [==]%0a* [[Freedom.Serverrights]]  . . . February 04, 2021, at 02:42 PM by [[~jrmu]]: [==]%0a* [[Freedom.Fork]]  . . . February 04, 2021, at 02:39 PM by [[~jrmu]]: [==]%0a* [[Freedom.Lanofopportunity]]  . . . February 04, 2021, at 01:24 PM by [[~jrmu]]: [==]%0a* [[Freedom.Opentoall]]  . . . February 04, 2021, at 01:17 PM by [[~jrmu]]: [==]%0a* [[Freedom.Refuge]]  . . . February 04, 2021, at 09:31 AM by [[~jrmu]]: [==]%0a* [[Dns.Providers]]  . . . February 04, 2021, at 04:27 AM by [[~jrmu]]: [==]%0a* [[Guava.Guava]]  . . . February 03, 2021, at 02:30 AM by [[~st13g]]: [==]%0a* [[Openbsd.Stable]]  . . . February 02, 2021, at 02:25 PM by [[~jrmu]]: [==]%0a* [[Openbsd.Base64]]  . . . February 02, 2021, at 06:37 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Unboundadblock]]  . . . February 02, 2021, at 04:29 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Pfbadhost]]  . . . February 02, 2021, at 04:29 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Wraith]]  . . . February 02, 2021, at 04:22 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Delphinusdnsd]]  . . . February 02, 2021, at 01:51 AM by [[~jrmu]]: [==]%0a* [[Mango.Mango]]  . . . January 31, 2021, at 12:01 PM by [[~nix]]: [==]%0a* [[Openbsd.Abuse]]  . . . January 31, 2021, at 05:33 AM by [[~jrmu]]: [==]%0a* [[Freedom.Censorship]]  . . . January 31, 2021, at 05:23 AM by [[~jrmu]]: [==]%0a* [[Debate.Firstamendment]]  . . . January 31, 2021, at 05:20 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Phishing]]  . . . January 31, 2021, at 05:02 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Audit]]  . . . January 31, 2021, at 04:46 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Ongoing]]  . . . January 31, 2021, at 01:19 AM by [[~jrmu]]: [==]%0a* [[Ircnow.Partners]]  . . . January 31, 2021, at 12:32 AM by [[~jrmu]]: [==]%0a* [[Orange.Todo]]  . . . January 30, 2021, at 11:31 AM by [[~jrmu]]: [==]%0a* [[Pear.Pear]]  . . . January 29, 2021, at 06:09 PM by [[~dennis]]: [==]%0a* [[Openbsd.Httpopenproxy]]  . . . January 29, 2021, at 11:01 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Zncadmin]]  . . . January 29, 2021, at 10:00 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Rbldns]]  . . . January 29, 2021, at 05:45 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Setuid]]  . . . January 28, 2021, at 06:53 AM by [[~jrmu]]: [==]%0a* [[Openbsd.PFTesting]]  . . . January 25, 2021, at 03:28 PM by [[~jrmu]]: [==]%0a* [[Openbsd.ZNCDaily]]  . . . January 25, 2021, at 11:35 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Irssi]]  . . . January 25, 2021, at 07:08 AM by [[~jrmu]]: [==]%0a* [[Ircnow.Sysadmins]]  . . . January 24, 2021, at 10:36 AM by [[~jrmu]]: [==]%0a* [[Debate.UnixPhilosophy]]  . . . January 18, 2021, at 05:05 AM by [[~category_mirror]]: [==]%0a* [[Openbsd.XTerm]]  . . . January 17, 2021, at 01:48 PM by [[~miniontoby]]: [=copyright=]%0a* [[UsersCategoryMirrory.Statement]]  . . . January 17, 2021, at 02:44 AM by [[~category_mirror]]: [==]%0a* [[Email.Outlook]]  . . . January 16, 2021, at 05:13 PM by [[~Zouheir]]: [==]%0a* [[Plum.Todo]]  . . . January 16, 2021, at 12:09 AM by [[~st13g]]: [==]%0a* [[Debate.Ipsec]]  . . . January 13, 2021, at 10:39 AM by [[~jrmu]]: [==]%0a* [[Plum.Plum]]  . . . January 12, 2021, at 03:02 PM by [[~wiz]]: [==]%0a* [[Openbsd.Slrn]]  . . . January 12, 2021, at 02:40 PM by [[~Noxturnix]]: [==]%0a* [[OpenBSD.CPAN]]  . . . January 12, 2021, at 01:48 PM by [[~Dima]]: [==]%0a* [[Jujube.Todo]]  . . . January 11, 2021, at 05:13 PM by [[~fizi]]: [==]%0a* [[Ircnow.Ilines]]  . . . January 11, 2021, at 09:55 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Netcat]]  . . . January 09, 2021, at 02:20 PM by [[~jrmu]]: [==]%0a* [[OpenBSD.Perl]]  . . . January 09, 2021, at 02:04 PM by [[~dima]]: [==]%0a* [[Openbsd.Perl]]  . . . January 09, 2021, at 01:52 PM by [[~jrmu]]: [==]%0a* [[Fig.Log]]  . . . January 07, 2021, at 11:23 AM by [[~dima]]: [=test=]%0a* [[Fig.Todo]]  . . . January 06, 2021, at 01:06 PM by [[~jrmu]]: [==]%0a* [[Grape.Todo]]  . . . January 06, 2021, at 01:05 PM by [[~jrmu]]: [==]%0a* [[Pear.Todo]]  . . . January 06, 2021, at 01:05 PM by [[~jrmu]]: [==]%0a* [[Jujube.Team]]  . . . January 06, 2021, at 01:04 PM by [[~jrmu]]: [==]%0a* [[Mango.Todo]]  . . . January 06, 2021, at 01:04 PM by [[~jrmu]]: [==]%0a* [[Ircnow.Censorship]]  . . . January 06, 2021, at 03:01 AM by [[~jrmu]]: [==]%0a* [[Ircnow.Pentesters]]  . . . January 05, 2021, at 11:17 AM by [[~jrmu]]: [==]%0a* [[Ircnow.Coders]]  . . . January 05, 2021, at 11:11 AM by [[~jrmu]]: [==]%0a* [[Banana.Todo]]  . . . January 04, 2021, at 09:41 AM by [[~miniontoby]]: [=znc=]%0a* [[Users.CategoryMirrory]]  . . . January 04, 2021, at 01:10 AM by [[~category_mirror]]: [==]%0a* [[UsersCategoryMirrory.Test]]  . . . January 03, 2021, at 08:17 PM by [[~category_mirrory]]: [==]%0a* [[Users.Categorymirrory]]  . . . January 03, 2021, at 08:12 PM by [[~category_mirrory]]: [=wrong caps=]%0a* [[Banana.Banana]]  . . . January 03, 2021, at 02:39 PM by [[~miniontoby]]: [==]%0a* [[Orange.Orange]]  . . . January 03, 2021, at 02:10 PM by [[~jrmu]]: [==]%0a* [[Openbsd.Backup]]  . . . January 03, 2021, at 01:46 PM by [[~jrmu]]: [==]%0a* [[Openbsd.Backups]]  . . . January 02, 2021, at 11:44 AM by [[~jrmu]]: [==]%0a* [[Debate.Appledanger]]  . . . January 02, 2021, at 01:35 AM by [[~jrmu]]: [==]%0a* [[Grape.Tasks]]  . . . January 01, 2021, at 07:52 PM by [[~fizi]]: [==]%0a* [[Ircnow.Helpers]]  . . . January 01, 2021, at 04:36 AM by [[~jrmu]]: [==]%0a* [[Ircnow.Finances]]  . . . January 01, 2021, at 04:15 AM by [[~jrmu]]: [==]%0a* [[Tutorial.Tutorial]]  . . . January 01, 2021, at 03:25 AM by [[~jrmu]]: [==]%0a* [[Ircnow.Testing]]  . . . December 30, 2020, at 12:58 PM by [[~jrmu]]: [==]%0a* [[Openbsd.Sshbackdoor]]  . . . December 30, 2020, at 12:14 PM by [[~jrmu]]: [==]%0a* [[Mango.Packages]]  . . . December 30, 2020, at 10:48 AM by [[~nix]]: [==]%0a* [[Ircnow.Contact]]  . . . December 30, 2020, at 03:18 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Pf-bnc]]  . . . December 29, 2020, at 06:30 PM by [[~jrmu]]: [==]%0a* [[Ircnow.Partners2]]  . . . December 29, 2020, at 02:52 PM by [[~jrmu]]: [==]%0a* [[Openbsd.Tcltls]]  . . . December 29, 2020, at 09:53 AM by [[~jrmu]]: [==]%0a* [[Debate.Mozilladanger]]  . . . December 27, 2020, at 03:05 AM by [[~jrmu]]: [==]%0a* [[Debate.Controlcomputer]]  . . . December 27, 2020, at 03:02 AM by [[~jrmu]]: [==]%0a* [[Debate.Facebookdanger]]  . . . December 27, 2020, at 03:01 AM by [[~jrmu]]: [==]%0a* [[Debate.Slackdanger]]  . . . December 27, 2020, at 02:56 AM by [[~jrmu]]: [==]%0a* [[Debate.Freespeech]]  . . . December 27, 2020, at 02:36 AM by [[~jrmu]]: [==]%0a* [[Debate.Ethicalflaws]]  . . . December 27, 2020, at 02:31 AM by [[~jrmu]]: [==]%0a* [[Debate.Hatespeech]]  . . . December 27, 2020, at 02:20 AM by [[~jrmu]]: [==]%0a* [[Debate.Monero]]  . . . December 27, 2020, at 02:02 AM by [[~jrmu]]: [==]%0a* [[Debate.WhyNotC]]  . . . December 26, 2020, at 06:43 PM by [[~searchsocial]]: [==]%0a* [[Debate.Python]]  . . . December 26, 2020, at 06:21 PM by [[~jrmu]]: [==]%0a* [[Debate.Cash]]  . . . December 26, 2020, at 06:18 PM by [[~jrmu]]: [==]%0a* [[Debate.Uberdanger]]  . . . December 26, 2020, at 06:16 PM by [[~jrmu]]: [==]%0a* [[Debate.Microsoftdanger]]  . . . December 26, 2020, at 06:15 PM by [[~jrmu]]: [==]%0a* [[Debate.Accessibility]]  . . . December 26, 2020, at 06:14 PM by [[~jrmu]]: [==]%0a* [[Debate.Zoomdanger]]  . . . December 26, 2020, at 06:08 PM by [[~jrmu]]: [==]%0a* [[Shell.Applications]]  . . . December 19, 2020, at 06:21 PM by [[~fizi]]: [==]%0a* [[Third.Dillo]]  . . . December 19, 2020, at 01:52 PM by [[~jrmu]]: [==]%0a* [[Third.Basilisk]]  . . . December 19, 2020, at 01:38 PM by [[~jrmu]]: [==]%0a* [[Third.Directory]]  . . . December 19, 2020, at 01:35 PM by [[~jrmu]]: [==]%0a* [[Guava.Packages]]  . . . December 19, 2020, at 06:14 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Amplification]]  . . . December 19, 2020, at 05:42 AM by [[~jrmu]]: [==]%0a* [[Openbsd.UDPFlood]]  . . . December 18, 2020, at 10:39 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Tcpdump]]  . . . December 18, 2020, at 09:12 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Tcpackflood]]  . . . December 17, 2020, at 10:36 AM by [[~jrmu]]: [==]%0a* [[Openbsd.RSTFlood]]  . . . December 17, 2020, at 10:34 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Tcpresetflood]]  . . . December 17, 2020, at 10:34 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Ssdp]]  . . . December 15, 2020, at 12:59 PM by [[~jrmu]]: [==]%0a* [[Bouncer.Igloo]]  . . . December 14, 2020, at 09:39 AM by [[~Noxturnix]]: [==]%0a* [[Main.Terms]]  . . . December 13, 2020, at 01:35 PM by [[~jrmu]]: [==]%0a* [[Openbsd.Pf]]  . . . December 13, 2020, at 12:03 PM by [[~jrmu]]: [==]%0a* [[Openbsd.Upgrade68]]  . . . December 13, 2020, at 11:12 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Install68]]  . . . December 13, 2020, at 10:13 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Upgrade67]]  . . . December 13, 2020, at 04:02 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Sysupgrade68]]  . . . December 11, 2020, at 10:27 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Dokuwiki]]  . . . December 10, 2020, at 02:23 PM by [[~miniontoby]]: [=code blocks fixed=]%0a* [[Openbsd.Acme-client]]  . . . December 09, 2020, at 06:47 PM by [[~miniontoby]]: [=fixed troubleshooting links=]%0a* [[Freedom.Christian]]  . . . December 08, 2020, at 01:12 AM by [[~jrmu]]: [==]%0a* [[Freedom.Finances]]  . . . December 08, 2020, at 01:04 AM by [[~jrmu]]: [==]%0a* [[Shell.Sshkeys]]  . . . December 07, 2020, at 10:36 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Install67]]  . . . December 06, 2020, at 11:03 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Buyvm]]  . . . December 06, 2020, at 02:42 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Install]]  . . . December 04, 2020, at 04:15 PM by [[~jrmu]]: [==]%0a* [[Opernbsd.Buyvm]]  . . . December 04, 2020, at 12:06 PM by [[~jrmu]]: [==]%0a* [[Bouncer.WeeChat]]  . . . December 02, 2020, at 12:43 PM by [[~jrmu]]: [==]%0a* [[Bouncer.SimpleIRC]]  . . . December 02, 2020, at 12:31 PM by [[~jrmu]]: [==]%0a* [[Freedom.Militia]]  . . . December 02, 2020, at 04:18 AM by [[~jrmu]]: [==]%0a* [[Third.Third]]  . . . December 01, 2020, at 01:49 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Oidentd]]  . . . November 30, 2020, at 11:42 PM by [[~jrmu]]: [==]%0a* [[Ircnow.Helper]]  . . . November 28, 2020, at 02:21 AM by [[~jrmu]]: [==]%0a* [[Bouncer.Hexchat]]  . . . November 27, 2020, at 12:52 PM by [[~jrmu]]: [==]%0a* [[Bouncer.IRCCloud]]  . . . November 24, 2020, at 11:53 AM by [[~jrmu]]: [==]%0a* [[Bouncer.AdiIRC]]  . . . November 24, 2020, at 11:42 AM by [[~jrmu]]: [==]%0a* [[Bouncer.RevolutionIRC]]  . . . November 24, 2020, at 11:35 AM by [[~jrmu]]: [==]%0a* [[Bouncer.KiwiIRC]]  . . . November 24, 2020, at 11:34 AM by [[~jrmu]]: [==]%0a* [[Bouncer.KVIrc]]  . . . November 24, 2020, at 11:33 AM by [[~jrmu]]: [==]%0a* [[Bouncer.IceChat]]  . . . November 24, 2020, at 11:27 AM by [[~jrmu]]: [==]%0a* [[Bouncer.IRCCloudiOS]]  . . . November 24, 2020, at 11:20 AM by [[~jrmu]]: [==]%0a* [[Bouncer.IRCCloudAndroid]]  . . . November 24, 2020, at 11:20 AM by [[~jrmu]]: [==]%0a* [[Bouncer.IRCCloudWeb]]  . . . November 24, 2020, at 11:19 AM by [[~jrmu]]: [==]%0a* [[Third.Catalog]]  . . . November 23, 2020, at 07:52 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Checklist]]  . . . November 20, 2020, at 12:44 AM by [[~gry]]: [=+=]%0a* [[Openbsd.Acopm]]  . . . November 04, 2020, at 03:32 PM by [[~jrmu]]: [==]%0a* [[Openbsd.Achurch]]  . . . November 04, 2020, at 02:25 PM by [[~jrmu]]: [==]%0a* [[Openbsd.Vi]]  . . . November 04, 2020, at 12:51 PM by [[~jrmu]]: [==]%0a* [[Openbsd.Sudo]]  . . . November 04, 2020, at 12:38 PM by [[~jrmu]]: [==]%0a* [[Freedom.Denomination]]  . . . October 23, 2020, at 09:20 AM by [[~jrmu]]: [==]%0a* [[Vps.Intro]]  . . . October 10, 2020, at 08:22 AM by [[~jrmu]]: [==]%0a* [[Ircweb.Ircweb]]  . . . October 05, 2020, at 01:10 AM by [[~jrmu]]: [==]%0a* [[Http2irc.Http2irc]]  . . . October 05, 2020, at 01:04 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Easyapp]]  . . . September 29, 2020, at 12:13 PM by [[~jrmu]]: [==]%0a* [[Orange.Nl]]  . . . September 17, 2020, at 08:43 AM by [[~miniontoby]]: [=Dutch correct page=]%0a* [[Grape.Guide]]  . . . September 16, 2020, at 08:42 AM by [[~baytuch]]: [==]%0a* [[Orange.Id]]  . . . September 08, 2020, at 09:51 AM by [[~gry]]: [=+=]%0a* [[Orange.Ru]]  . . . September 07, 2020, at 11:29 PM by [[~gry]]: [=+=]%0a* [[Bouncer.MIRC]]  . . . September 06, 2020, at 03:59 AM by [[~jrmu]]: [==]%0a* [[Debate.Bncnow]]  . . . September 04, 2020, at 04:36 AM by [[~jrmu]]: [==]%0a* [[Openbsd.Cgit]]  . . . September 01, 2020, at 05:51 PM by [[~baytuch]]: [==]%0a* [[Orange.Notes]]  . . . August 27, 2020, at 03:38 AM by [[~gry]]: [=expanded=]%0a* [[Shell.ShellSSHKEYS]]  . . . August 25, 2020, at 10:00 PM by [[~gry]]: [=permissions added=]%0a* [[Bots.Bots]]  . . . August 25, 2020, at 12:02 PM by [[~jrmu]]: [==]%0a* [[Bouncer.Irccloud]]  . . . August 24, 2020, at 12:20 PM by [[~jrmu]]: [==]%0a* [[GrapeTeam.Tracker]]  . . . August 24, 2020, at 10:16 AM by [[~gry]]: [=+=]%0a* [[GrapeTeam.GrapeTeam]]  . . . August 24, 2020, at 10:13 AM by [[~jrmu]]: [==]%0a* [[Ircnow.Course]]  . . . August 21, 2020, at 05:01 AM by [[~gry]]: [==]%0a* [[Openbsd.Bchs]]  . . . August 20, 2020, at 07:11 AM by [[~jrmu]]: [==]%0a* [[Ircnow.Todo]]  . . . August 20, 2020, at 06:48 AM by [[~jrmu]]: on_is_active php_session_active squirrelmailing sqsession_start troubleshooting authentication session_status config_default webmail_access modifications configuration unfortunately accessibility administrator webmail_error compatibility acceleration default_pref organization replacement disposition alternative information sourceforge permissions certificate interactive configuring preferences letsencrypt development compatible javascript configtest connection additional nameserver configured afterwards extracting attempting installing documents complains openhttpd functions localhost opensmtpd challenge supported subdomain receiving databases recommend necessary following languages delimiter directory debugging fusername essential addresses installed chrooted smtphost projects browsers normally location provides tlsmulti 26214400 required remember original security listener optional settings sendmail properly software specific licensed messages brackets instance writable services browsing defaults drawback continue opening control dovecot fastcgi already contact defines example initial unbound folders unusual request plugins general command servers defined private options however records contrib include restart because nologin disable exiting keypair baytuch strings misused charset appears content instead openbsd release sending mt_rand another subject version tarball warning charlie without changes resolve foxtrot uploads written client relayd needed return logout syntax longer cannot latest htdocs braces rather offset typing before themes ircnow frames across making should switch please detect secure invert readme global create update system locale report serial delete femail myname daemon lookup socket number errors trying issues actual stable inline attach master reload touch could color chown check chmod needs first intro shell rcctl php74 mkdir books hosts write above https there false using might every ascii happy delta curly array fatal bravo query where since which setup exist works notes saved files press alpha enter means class block title index chain strip lines known worry based ifend about zones this doas 2001 imap will well page your real acme make sure that aaaa ipv4 does fccf want 1008 2602 than sbin chsh help bind body some copy runs both must logs like when ctrl type echo xvzf find uses html many wiki easy fees more exec text once were have made mime done next move into ipv6 pop3 menu sign quit full motd hide give edit time www ssl etc var 127 day see has 162 bad gpl 451 fix ksh 644 zip its 755 ftp net way crt 634 usr 403 src nsd fpm dns max few db8 143 via by gz 22 cd rx 38 87 mv 80 9
+time=1678134050
 Relayd.TLSMulti:1628325508: Relayd.Acceleration Openhttpd.Hosting Acme-client.Configure Pf.Guide Openssl.Http : troubleshooting acknowledgments configuration acceleration dramatically remote_addr server_port permissions server_addr connections simpletable certificate commentary configured especially consulting forwarding foreground plaintext correctly debugging fullchain openhttpd available forwarded verbosity splitting listening challenge following selective remaining instances directory stacksize newsyslog openfiles service1 service2 searches increase database disabled protocol symlinks starting services tlsmulti sortable requests complete template filtered properly networks rotation addition location listener expanded multiple messages concepts example keypair listens finally backlog running private www6tls warning openbsd respond content produce provide verbose replace hosting devices android earlier maximum inspect enabled another domains openssl syslogd reverse headers td76656 without archive default already missing labeled records address option actual relayd handle relays create nabble wwwtls define packet turned before client please border append serves common public errors either cannot number blocks syntax bottom daemon assume entire typing failed simply sample second notice output https certs class there check rcctl first pfctl width guide login fails queue where names large which value match avoid above ports using based wrong entry lines close title below doesn three users index known third proxy while strip 8020 sure 8001 8002 icmp 4096 have make 2001 need will both that ipv6 them this want acme they ipv4 your edit what sack time doas then must logs html 7691 into send busy wish from real upon look test like stop ones auto when well root load last says also ddos etc 443 crt sub see are any ip4 ios tcp org man cur 96m 128 its won var may nsd set dns how pem 100 dvv 127 168 192 ip6 db8 of n7 by ln=
 Relayd.Acceleration:1628324627: Pf.Guide Leafnode.Install Tcpip.Sockets Openbsd.Znc Openhttpd.Configure Openhttpd.Hosting Telnet.Http Znc.Chroot Openbsd.Netcat Acme-client.Configure Openssl.Http : troubleshooting acknowledgments eavesdropping configuration dramatically introduction acceleration permissions server_addr connections simpletable server_port remote_addr certificate integration application transparent forwarding encryption webhosting configured foreground indication afterwards especially commentary splitting openhttpd plaintext challenge openfiles forwarded stacksize listening selective necessary directory fullchain providing debugging correctly sometimes following newsyslog verbosity available instances location service1 service2 symlinks protocol possible searches template requests listener filtered bouncers sortable database rotation addition increase messages balancer networks properly features plumbing normally exposing leafnode starting disabled complete private example produce keypair openbsd missing warning running replace address labeled default records openssl sockets install android devices verbose td76656 archiv=
blob - 646d5f0fdeeb8f77e1d7bfd85569d83ca912cbbc
blob + 2ec5104e4d43c5ad751cf61556786ec5f90285bc
--- wiki.d/SiteAdmin.Blocklist-MoinMaster
+++ wiki.d/SiteAdmin.Blocklist-MoinMaster
@@ -1,10 +1,10 @@
-version=pmwiki-2.2.130 ordered=1 urlencoded=1
-agent=Mozilla/5.0 (Linux; Android 7.0; MI MAX) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Mobile Safari/537.36
+version=pmwiki-2.3.20 ordered=1 urlencoded=1
+agent=NetSurf/3.11 (Plan9)
 charset=UTF-8
 ctime=1596101899
-host=2001:448a:1022:2580:19f7:77df:8fc0:8232
+host=2.178.200.45
 name=SiteAdmin.Blocklist-MoinMaster
 passwdread=@lock
-rev=617
+rev=618
 text=%0a  [@%0a## blocklist-note:   NOTE: This page is automatically generated by blocklist.php%0a## blocklist-note:   NOTE: Any edits to this page may be lost!%0a## blocklist-url:    http://moinmo.in/BadContent?action=raw%0a## blocklist-when:   2020-07-30T09:38:19%0a#  blocklist-format: regex%0a#### Unable to download blocklist (allow_url_fopen=)%0a  @]%0a
-time=1677994348
+time=1678122018