├── .drone.yml ├── .github └── FUNDING.yml ├── .gitignore ├── .well-known ├── apple-developer-merchantid-domain-association ├── autoconfig │ └── mail │ │ └── config-v1.1.xml └── brave-rewards-verification.txt ├── 50x.html ├── LICENSE ├── README.md ├── SECURITY.md ├── clubbanner.png ├── errors ├── 400.php ├── 403.php ├── 404.php ├── 405.php ├── 408.php ├── 413.php ├── 500.php └── 502.php ├── favicon.png ├── footer.php ├── gen_tdp ├── header.php ├── header24h.php ├── icons └── poweredby.png ├── images └── rss.png ├── index.php ├── nav.html ├── news ├── news.json ├── news.php ├── polls ├── admin.php ├── api.php ├── db.php ├── index.php └── setup.php ├── robots.txt ├── signup ├── email │ ├── Net │ │ └── DNS2.php │ ├── ipaddr.php │ ├── smtp.php │ └── utf8.php ├── index.php └── signup-handler.php ├── style.css ├── supporters.json ├── tilde.ico ├── tildeclub.png ├── updateonline-users ├── users └── index.php ├── webring.php └── wiki ├── .gitignore ├── Makefile ├── README.md ├── custom.theme ├── gophermap ├── header-permalinks.lua ├── index.php ├── link_footnote.lua ├── source ├── 2fa.md ├── archive.org.md ├── bashblog.md ├── bbj.md ├── cgi.md ├── cgit.md ├── cli-for-beginners.md ├── code-of-conduct.md ├── dcss.md ├── donate.md ├── edit_index.md ├── emacs.md ├── email.md ├── error404.md ├── faq.md ├── finding_index.md ├── git.md ├── gopher.md ├── help_system.md ├── irc.md ├── json.md ├── leafnode.md ├── multiplexers.md ├── netiquette.md ├── pagecounter.md ├── quilt.md ├── safe-scripting-the-tilde-way.md ├── security.md ├── slrn.md ├── ssh.md ├── sshfs.md ├── tildeverse.md ├── time-zone.md ├── tin.md ├── ttbp.md ├── tunnelblick.md ├── usenet-news.md ├── vimrc.md ├── vpn-gate.md ├── vpnwhy.md ├── wiki.md └── winscp.md ├── txtlist.sh └── wiki.tmpl /.drone.yml: -------------------------------------------------------------------------------- 1 | --- 2 | kind: pipeline 3 | type: ssh 4 | name: deploy 5 | 6 | server: 7 | host: 8 | from_secret: host 9 | user: 10 | from_secret: username 11 | ssh_key: 12 | from_secret: ssh_key 13 | 14 | clone: 15 | disable: true 16 | 17 | trigger: 18 | branch: 19 | - master 20 | 21 | steps: 22 | - name: deploy 23 | commands: 24 | - git -C /usr/share/nginx/html pull --rebase origin master 25 | - name: build-wiki 26 | commands: 27 | - make -C /usr/share/nginx/html/wiki 28 | 29 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | liberapay: tilde.club # Replace with a single Liberapay username 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .gitignore 2 | header24h.php 3 | nginx-logo.png 4 | pkglist.txt 5 | poweredby.png 6 | social.html 7 | tilde.24h* 8 | tilde.json 9 | online-users.json 10 | changes.rss 11 | news/ 12 | icons/ 13 | stats/ 14 | cache/ 15 | polls/polls.db 16 | -------------------------------------------------------------------------------- /.well-known/apple-developer-merchantid-domain-association: -------------------------------------------------------------------------------- 1 | 7B227073704964223A2239373943394538343346343131343044463144313834343232393232313734313034353044314339464446394437384337313531303944334643463542433731222C2276657273696F6E223A312C22637265617465644F6E223A313536363233343735303036312C227369676E6174757265223A22333038303036303932613836343838366637306430313037303261303830333038303032303130313331306633303064303630393630383634383031363530333034303230313035303033303830303630393261383634383836663730643031303730313030303061303830333038323033653333303832303338386130303330323031303230323038346333303431343935313964353433363330306130363038326138363438636533643034303330323330376133313265333032633036303335353034303330633235343137303730366336353230343137303730366336393633363137343639366636653230343936653734363536373732363137343639366636653230343334313230326432303437333333313236333032343036303335353034306230633164343137303730366336353230343336353732373436393636363936333631373436393666366532303431373537343638366637323639373437393331313333303131303630333535303430613063306134313730373036633635323034393665363332653331306233303039303630333535303430363133303235353533333031653137306433313339333033353331333833303331333333323335333735613137306433323334333033353331333633303331333333323335333735613330356633313235333032333036303335353034303330633163363536333633326437333664373032643632373236663662363537323264373336393637366535663535343333343264353035323466343433313134333031323036303335353034306230633062363934663533323035333739373337343635366437333331313333303131303630333535303430613063306134313730373036633635323034393665363332653331306233303039303630333535303430363133303235353533333035393330313330363037326138363438636533643032303130363038326138363438636533643033303130373033343230303034633231353737656465626436633762323231386636386464373039306131323138646337623062643666326332383364383436303935643934616634613534313162383334323065643831316633343037653833333331663163353463336637656233323230643662616435643465666634393238393839336537633066313361333832303231313330383230323064333030633036303335353164313330313031666630343032333030303330316630363033353531643233303431383330313638303134323366323439633434663933653465663237653663346636323836633366613262626664326534623330343530363038326230363031303530353037303130313034333933303337333033353036303832623036303130353035303733303031383632393638373437343730336132663266366636333733373032653631373037303663363532653633366636643266366636333733373033303334326436313730373036633635363136393633363133333330333233303832303131643036303335353164323030343832303131343330383230313130333038323031306330363039326138363438383666373633363430353031333038316665333038316333303630383262303630313035303530373032303233303831623630633831623335323635366336393631366536333635323036663665323037343638363937333230363336353732373436393636363936333631373436353230363237393230363136653739323037303631373237343739323036313733373337353664363537333230363136333633363537303734363136653633363532303666363632303734363836353230373436383635366532303631373037303663363936333631363236633635323037333734363136653634363137323634323037343635373236643733323036313665363432303633366636653634363937343639366636653733323036663636323037353733363532633230363336353732373436393636363936333631373436353230373036663663363936333739323036313665363432303633363537323734363936363639363336313734363936663665323037303732363136333734363936333635323037333734363137343635366436353665373437333265333033363036303832623036303130353035303730323031313632613638373437343730336132663266373737373737326536313730373036633635326536333666366432663633363537323734363936363639363336313734363536313735373436383666373236393734373932663330333430363033353531643166303432643330326233303239613032376130323538363233363837343734373033613266326636333732366332653631373037303663363532653633366636643266363137303730366336353631363936333631333332653633373236633330316430363033353531643065303431363034313439343537646236666435373438313836383938393736326637653537383530376537396235383234333030653036303335353164306630313031666630343034303330323037383033303066303630393261383634383836663736333634303631643034303230353030333030613036303832613836343863653364303430333032303334393030333034363032323130306265303935373166653731653165373335623535653561666163623463373266656234343566333031383532323263373235313030326236316562643666353530323231303064313862333530613564643664643665623137343630333562313165623263653837636661336536616636636264383338303839306463383263646461613633333038323032656533303832303237356130303330323031303230323038343936643266626633613938646139373330306130363038326138363438636533643034303330323330363733313162333031393036303335353034303330633132343137303730366336353230353236663666373432303433343132303264323034373333333132363330323430363033353530343062306331643431373037303663363532303433363537323734363936363639363336313734363936663665323034313735373436383666373236393734373933313133333031313036303335353034306130633061343137303730366336353230343936653633326533313062333030393036303335353034303631333032353535333330316531373064333133343330333533303336333233333334333633333330356131373064333233393330333533303336333233333334333633333330356133303761333132653330326330363033353530343033306332353431373037303663363532303431373037303663363936333631373436393666366532303439366537343635363737323631373436393666366532303433343132303264323034373333333132363330323430363033353530343062306331643431373037303663363532303433363537323734363936363639363336313734363936663665323034313735373436383666373236393734373933313133333031313036303335353034306130633061343137303730366336353230343936653633326533313062333030393036303335353034303631333032353535333330353933303133303630373261383634386365336430323031303630383261383634386365336430333031303730333432303030346630313731313834313964373634383564353161356532353831303737366538383061326566646537626165346465303864666334623933653133333536643536363562333561653232643039373736306432323465376262613038666437363137636538386362373662623636373062656338653832393834666635343435613338316637333038316634333034363036303832623036303130353035303730313031303433613330333833303336303630383262303630313035303530373330303138363261363837343734373033613266326636663633373337303265363137303730366336353265363336663664326636663633373337303330333432643631373037303663363537323666366637343633363136373333333031643036303335353164306530343136303431343233663234396334346639336534656632376536633466363238366333666132626266643265346233303066303630333535316431333031303166663034303533303033303130316666333031663036303335353164323330343138333031363830313462626230646561313538333338383961613438613939646562656264656261666461636232346162333033373036303335353164316630343330333032653330326361303261613032383836323636383734373437303361326632663633373236633265363137303730366336353265363336663664326636313730373036633635373236663666373436333631363733333265363337323663333030653036303335353164306630313031666630343034303330323031303633303130303630613261383634383836663736333634303630323065303430323035303033303061303630383261383634386365336430343033303230333637303033303634303233303361636637323833353131363939623138366662333563333536636136326266663431376564643930663735346461323865626566313963383135653432623738396638393866373962353939663938643534313064386639646539633266653032333033323264643534343231623061333035373736633564663333383362393036376664313737633263323136643936346663363732363938323132366635346638376137643162393963623962303938393231363130363939306630393932316430303030333138323031386233303832303138373032303130313330383138363330376133313265333032633036303335353034303330633235343137303730366336353230343137303730366336393633363137343639366636653230343936653734363536373732363137343639366636653230343334313230326432303437333333313236333032343036303335353034306230633164343137303730366336353230343336353732373436393636363936333631373436393666366532303431373537343638366637323639373437393331313333303131303630333535303430613063306134313730373036633635323034393665363332653331306233303039303630333535303430363133303235353533303230383463333034313439353139643534333633303064303630393630383634383031363530333034303230313035303061303831393533303138303630393261383634383836663730643031303930333331306230363039326138363438383666373064303130373031333031633036303932613836343838366637306430313039303533313066313730643331333933303338333133393331333733313332333333303561333032613036303932613836343838366637306430313039333433313164333031623330306430363039363038363438303136353033303430323031303530306131306130363038326138363438636533643034303330323330326630363039326138363438383666373064303130393034333132323034323062303731303365313430613462386231376262613230316130336163643036396234653431366232613263383066383661383338313435633239373566633131333030613036303832613836343863653364303430333032303434363330343430323230343639306264636637626461663833636466343934396534633035313039656463663334373665303564373261313264376335666538633033303033343464663032323032363764353863393365626233353031333836363062353730373938613064643731313734316262353864626436613138363633353038353431656565393035303030303030303030303030227D -------------------------------------------------------------------------------- /.well-known/autoconfig/mail/config-v1.1.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | tilde.club 5 | TildeClub EMail 6 | club 7 | 8 | imap.tilde.club 9 | 993 10 | SSL 11 | password-cleartext 12 | %EMAILLOCALPART% 13 | 14 | 15 | smtp.tilde.club 16 | 587 17 | STARTTLS 18 | password-cleartext 19 | %EMAILLOCALPART% 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /.well-known/brave-rewards-verification.txt: -------------------------------------------------------------------------------- 1 | This is a Brave Rewards publisher verification file. 2 | 3 | Domain: tilde.club 4 | Token: 9c786faeb68dcbed2a1c7ce23ed1674e1bc910765da27327c53bbf58bcf812fc 5 | -------------------------------------------------------------------------------- /50x.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Error 5 | 10 | 11 | 12 |

An error occurred.

13 |

Sorry, the page you are looking for is currently unavailable.
14 | Please try again later.

15 |

If you are the system administrator of this resource then you should check 16 | the error log for details.

17 |

Faithfully yours, nginx.

18 | 19 | 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # site 2 | tilde.club site source 3 | 4 | # Help Wanted 5 | Tilde.club is moving very quickly and is 100% volunteer led. 6 | 7 | ## 1. optimal: pull requests and bug reports 8 | - There is a lot of great work going on around config, FAQ, basic docs. 9 | - Jump in if you want. Literally everyone here said "I am ready to help, what can I do." 10 | - We need non-coders (writers, editors, communicators, artists, project managers) as much as we need tech folks. 11 | - Most of the coding work is done for us by the Unix operating system. We're celebrating that. 12 | - A lot of the basic docs are in the [wiki](https://github.com/tildeclub/tilde.club/wiki) which you (yes, you) can edit. 13 | 14 | ## 2. suboptimal: open ended feature requests and broad discussion 15 | - We love philosophy, just not in our issue tracker! 16 | 17 | 18 | signup code from [https://tildegit.org/team/site/src/branch/master/signup](https://tildegit.org/team/site/src/branch/master/signup) 19 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | ## Reporting a Vulnerability 4 | 5 | Please report (suspected) security vulnerabilities to security@tilde.club. You will receive a response from us within 48 hours. 6 | If the issue is confirmed, we will release a patch as soon as possible depending on complexity. 7 | -------------------------------------------------------------------------------- /clubbanner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tildeclub/site/49081bb620726ba62e44a787f606388e6b61b3b6/clubbanner.png -------------------------------------------------------------------------------- /errors/400.php: -------------------------------------------------------------------------------- 1 | 2 | 3 |

ERROR 400 Bad Request

4 | 5 |
6 | 7 |
8 | 9 |
10 |

A 400 error status implies The request sent to the server was invalid or malformed. This could happen if there is a mistake in the request parameters or syntax.

11 |
12 |

If you're a site visitor

13 |

Please use your browser's back button and check that you're in the right place. If you need immediate assistance, please send us an email instead.

14 |

If you're the site owner

15 |

Please check that you're in the right place and get in touch with your website provider if you believe this to be an error.

16 | 17 | 18 |
19 |
20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /errors/403.php: -------------------------------------------------------------------------------- 1 | 2 | 3 |

ERROR 403 Forbidden

4 | 5 |
6 | 7 |
8 | 9 |
10 |

A 403 error status implies You don’t have permission to access the requested resource. This usually occurs when access to the resource is restricted.

11 |
12 |

If you're a site visitor

13 |

Please use your browser's back button and check that you're in the right place. If you need immediate assistance, please send us an email instead.

14 |

If you're the site owner

15 |

Please check that you're in the right place and get in touch with your website provider if you believe this to be an error.

16 | 17 | 18 |
19 |
20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /errors/404.php: -------------------------------------------------------------------------------- 1 | 2 | 3 |

ERROR 404 Not Found

4 | 5 |
6 | 7 |
8 | 9 |
10 |

A 404 error status implies that the file or page that you're looking for could not be found.

11 |
12 |

If you're a site visitor

13 |

Please use your browser's back button and check that you're in the right place. If you need immediate assistance, please send us an email instead.

14 |

If you're the site owner

15 |

Please check that you're in the right place and get in touch with your website provider if you believe this to be an error.

16 | 17 | 18 |
19 |
20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /errors/405.php: -------------------------------------------------------------------------------- 1 | 2 | 3 |

ERROR 405 Method Not Allowed

4 | 5 |
6 | 7 |
8 | 9 |
10 |

A 405 error implies the method used in the request (such as GET, POST, PUT, etc.) is not allowed for the requested resource.

11 |
12 |

If you're a site visitor

13 |

Please use your browser's back button and check that you're in the right place. If you need immediate assistance, please send us an email instead.

14 |

If you're the site owner

15 |

Please check that you're in the right place and get in touch with your website provider if you believe this to be an error.

16 | 17 | 18 |
19 |
20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /errors/408.php: -------------------------------------------------------------------------------- 1 | 2 | 3 |

ERROR 408 Request Timeout

4 | 5 |
6 | 7 |
8 | 9 |
10 |

A 408 error implies the server timed out while waiting for the client’s request. This usually happens when the request takes too long to complete.

11 |
12 |

If you're a site visitor

13 |

Please use your browser's back button and check that you're in the right place. If you need immediate assistance, please send us an email instead.

14 |

If you're the site owner

15 |

Please check that you're in the right place and get in touch with your website provider if you believe this to be an error.

16 | 17 | 18 |
19 |
20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /errors/413.php: -------------------------------------------------------------------------------- 1 | 2 | 3 |

ERROR 413 Payload Too Large

4 | 5 |
6 | 7 |
8 | 9 |
10 |

A 413 error implies the server is refusing to process the request because the payload (body of the request) is too large.

11 |
12 |

If you're a site visitor

13 |

Please use your browser's back button and check that you're in the right place. If you need immediate assistance, please send us an email instead.

14 |

If you're the site owner

15 |

Please check that you're in the right place and get in touch with your website provider if you believe this to be an error.

16 | 17 | 18 |
19 |
20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /errors/500.php: -------------------------------------------------------------------------------- 1 | 2 | 3 |

ERROR 500 Internal Server Error

4 | 5 |
6 | 7 |
8 | 9 |
10 |

A 500 error implies the server encountered an internal error or misconfiguration and was unable to complete the request.

11 |
12 |

If you're a site visitor

13 |

Please use your browser's back button and check that you're in the right place. If you need immediate assistance, please send us an email instead.

14 |

If you're the site owner

15 |

Please check that you're in the right place and get in touch with your website provider if you believe this to be an error.

16 | 17 | 18 |
19 |
20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /errors/502.php: -------------------------------------------------------------------------------- 1 | 2 | 3 |

ERROR 502 Bad Gateway

4 | 5 |
6 | 7 |
8 | 9 |
10 |

A 502 error implies the server, while acting as a gateway or proxy, received an invalid response from the upstream server.

11 |
12 |

If you're a site visitor

13 |

Please use your browser's back button and check that you're in the right place. If you need immediate assistance, please send us an email instead.

14 |

If you're the site owner

15 |

Please check that you're in the right place and get in touch with your website provider if you believe this to be an error.

16 | 17 | 18 |
19 |
20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tildeclub/site/49081bb620726ba62e44a787f606388e6b61b3b6/favicon.png -------------------------------------------------------------------------------- /footer.php: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /gen_tdp: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import glob, subprocess, json, os.path, requests 3 | from bs4 import BeautifulSoup as bs 4 | 5 | tdp = {} 6 | tdp["name"] = "tilde.club" 7 | tdp["url"] = "https://tilde.club" 8 | tdp["signup_url"] = tdp["url"] + "/signup/" 9 | users = sorted([u[len("/home/"):] for u in glob.glob("/home/*", recursive=False)]) 10 | tdp["user_count"] = len(users) 11 | tdp["want_users"] = True 12 | tdp["admin_email"] = "root@tilde.club" 13 | tdp["description"] = "the original 'tilde': tilde.club is not a social network it is one tiny totally standard unix computer that people respectfully use together in their shared quest to build awesome web pages" 14 | 15 | tdpusers = [] 16 | for user in users: 17 | tdpuser = dict(username=user) 18 | 19 | try: 20 | title = bs( 21 | requests.get(f"http://tilde.club/~{user}/", allow_redirects=False).text, 22 | "lxml", features='xml' 23 | ).title.text 24 | except: 25 | title = "No title" 26 | tdpuser["title"] = title 27 | 28 | if os.path.exists(f"/home/{user}/public_html/index.html"): 29 | tdpuser["mtime"] = os.path.getmtime(f"/home/{user}/public_html/index.html") 30 | elif os.path.exists(f"/home/{user}/public_html/index.php"): 31 | tdpuser["mtime"] = os.path.getmtime(f"/home/{user}/public_html/index.php") 32 | 33 | tdpusers.append(tdpuser) 34 | 35 | tdp["users"] = tdpusers 36 | 37 | with open("tilde.json", "w") as f: 38 | json.dump(tdp, f) 39 | -------------------------------------------------------------------------------- /header.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | <?=isset($title) ? $title : "Welcome to ~tilde.club~"?> 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | RSS icon 22 | 23 | -------------------------------------------------------------------------------- /header24h.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | <?=isset($title) ? $title : "Welcome to ~tilde.club~"?> 7 | 8 | 9 | 10 | 11 | 20 | 21 |
22 | 23 |

recently updated

24 | 25 |
26 |
27 | 28 |
29 | 30 |

tilde.club home pages updated in last 24 hours

31 | 32 | There's also a JSON version of this data; it's all updated once a minute, so hold yer damn horses, people. Also, times are in the server's time zone (GMT, it appears).
33 |
34 | This script is by ~delfuego 35 | 36 | -------------------------------------------------------------------------------- /icons/poweredby.png: -------------------------------------------------------------------------------- 1 | ../../../pixmaps/poweredby.png -------------------------------------------------------------------------------- /images/rss.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tildeclub/site/49081bb620726ba62e44a787f606388e6b61b3b6/images/rss.png -------------------------------------------------------------------------------- /nav.html: -------------------------------------------------------------------------------- 1 | 10 | -------------------------------------------------------------------------------- /news: -------------------------------------------------------------------------------- 1 | /var/lib/news/http -------------------------------------------------------------------------------- /news.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "date": "2024-09-30", 4 | "title": "UPDATE: September 2024", 5 | "heading": "Happy 10th Birthday, Tilde.Club!", 6 | "content": "Tilde.Club turned 10! This cozy corner of the internet has become a haven for creativity and community. Members have crafted quirky personal pages, shared knowledge through the wiki, and supported each other in countless projects. It's a space where everyone's unique contributions shine, making it truly special. Here's to a decade of fun and friendship, and many more to come!" 7 | }, 8 | { 9 | "date": "2024-08-01", 10 | "title": "UPDATE: August 2024", 11 | "heading": "Hey Everyone, Disk Quotas are Here!", 12 | "content": "Just a heads up: we've rolled out disk quotas to keep things running smoothly for everyone. This will help us share space fairly and make sure the system stays in good shape. Here's the scoop:", 13 | "details": [ 14 | "Soft Limit: 1 GB – You’ll get a nudge if you go over this, but no worries, you can still go up to the hard limit.", 15 | "Hard Limit: 3 GB – This is the max. Once you hit this, you won’t be able to save more files until you clean up.", 16 | "Grace Period: 1 week – If you go over the soft limit, you’ll have a week to get back under before things get strict." 17 | ], 18 | "additional_content": "You can check your usage and see how much space you’ve got left by running the resources-used script in your home directory. It’s easy!" 19 | }, 20 | { 21 | "date": "2024-03-01", 22 | "title": "UPDATE: March 2024", 23 | "heading": "Hey everyone, we've leveled up to Fedora 39!", 24 | "content": "Big shoutout to all of you who've been part of this journey with tilde.club. Your contributions, big and small, have really made a difference. We couldn't keep this going without all of you. Fedora 39 is here, and it's packed with cool updates and features. Just a heads-up for those of you working with PHP, there's been an update, so you might want to check your scripts to make sure everything's still running smoothly.", 25 | "details": [ 26 | "Looking forward, 2024 is shaping up to be an exciting year, and we're just getting started. We're all about fostering a community that's innovative, supportive, and fun. Together, we're not just keeping tilde.club alive; we're making it thrive.", 27 | "Thanks again to every single one of you. Your creativity, support, and collaboration are what make this community special. Here's to more adventures and achievements together in 2024 and beyond!" 28 | ] 29 | }, 30 | { 31 | "date": "2022-09-01", 32 | "title": "UPDATE: September 2022", 33 | "heading": "OS Upgrade to Fedora 36", 34 | "content": "Fedora 36 has been installed and things should be back to normal.", 35 | "note": "**NOTE** SSH client requires SHA2 support since SHA1 support is now disabled." 36 | }, 37 | { 38 | "date": "2021-11-01", 39 | "title": "UPDATE: November 2021", 40 | "heading": "OS Upgrade to Fedora 35", 41 | "content": "We have upgraded our OS to Fedora 35. All updates installed without error or any issues. If you encounter any issues please let ben or deepend know. One notable update that may affect your programs is php is now version 8. Please check your php scripts to ensure they still work.", 42 | "additional_content": "Webmail has also been upgraded as well and we have enabled the ability for our users to use 2-Factor Authentication with it. You can find 2-Factor Authentication inside webmail/settings/security." 43 | }, 44 | { 45 | "date": "2020-03-01", 46 | "title": "UPDATE: March 2020", 47 | "heading": "", 48 | "content": "Things at tilde.club are going well, Thank you to all our new and existing users. Let's make 2020 a great one for ~club and the wider tildeverse!", 49 | "details": [ 50 | "We have reached 1985 users! and many more signing up daily. Welcome everyone.", 51 | "Users can now utilize more to make their pages unique, such as PHP.", 52 | "~club now has a Mastodon page you can follow us at https://tilde.zone/@tildeclub.", 53 | "Users can now setup Two-Factor Authentication (2FA) to use for SSH logins instead of only public key auth." 54 | ] 55 | } 56 | ] 57 | -------------------------------------------------------------------------------- /news.php: -------------------------------------------------------------------------------- 1 | 2 | 3 |

welcome to tilde.club

4 | 5 |

Questions? See the official FAQ.

6 | 7 | 8 | 9 |
10 |

Currently Active Users:

11 |
12 |
    13 | $username"; 20 | } 21 | // Repeat the list for seamless scrolling 22 | foreach ($activeUsers as $user) { 23 | $username = htmlspecialchars($user); 24 | echo "
  • $username
  • "; 25 | } 26 | } else { 27 | echo "
  • No active users at the moment.
  • "; 28 | } 29 | ?> 30 |
31 |
32 |
33 | loadHTML($html); 41 | libxml_clear_errors(); 42 | 43 | // Extract the content inside the
 tag
44 | $preTags = $dom->getElementsByTagName('pre');
45 | $innStatus = '';
46 | if ($preTags->length > 0) {
47 |     $innStatus = $preTags->item(0)->nodeValue;
48 | }
49 | 
50 | ?>
51 | 
52 | 
53 | 
54 |     
55 |     
56 |     
57 |     INN Status
58 |     
59 | 
60 | 
61 | 
62 | 
63 |

INN Status

64 |
65 |
66 | 67 | 68 | 69 | 70 | -------------------------------------------------------------------------------- /polls/api.php: -------------------------------------------------------------------------------- 1 | query("SELECT id, question_text FROM poll_questions ORDER BY id DESC"); 21 | $polls = $stmt->fetchAll(PDO::FETCH_ASSOC); 22 | sendJson(['success' => true, 'polls' => $polls]); 23 | } catch (Exception $e) { 24 | sendJson(['success' => false, 'error' => $e->getMessage()], 500); 25 | } 26 | break; 27 | 28 | // -------------------------------------------------- 29 | // 2) Get a single poll (question + options) 30 | // -------------------------------------------------- 31 | case 'get_poll': 32 | $pollId = (int)($_GET['poll_id'] ?? 0); 33 | if ($pollId <= 0) { 34 | sendJson(['success' => false, 'error' => 'Invalid poll_id'], 400); 35 | } 36 | try { 37 | // Fetch poll question 38 | $stmt = $db->prepare("SELECT id, question_text FROM poll_questions WHERE id = :id"); 39 | $stmt->execute([':id' => $pollId]); 40 | $poll = $stmt->fetch(PDO::FETCH_ASSOC); 41 | 42 | if (!$poll) { 43 | sendJson(['success' => false, 'error' => 'Poll not found'], 404); 44 | } 45 | 46 | // Fetch options 47 | $optionsStmt = $db->prepare(" 48 | SELECT po.id AS option_id, po.option_text, 49 | IFNULL(pr.vote_count, 0) AS vote_count 50 | FROM poll_options po 51 | LEFT JOIN poll_results pr ON po.id = pr.option_id 52 | WHERE po.question_id = :question_id 53 | ORDER BY po.id ASC 54 | "); 55 | $optionsStmt->execute([':question_id' => $pollId]); 56 | $options = $optionsStmt->fetchAll(PDO::FETCH_ASSOC); 57 | 58 | sendJson([ 59 | 'success' => true, 60 | 'poll' => [ 61 | 'id' => $poll['id'], 62 | 'question_text' => $poll['question_text'], 63 | 'options' => $options 64 | ] 65 | ]); 66 | } catch (Exception $e) { 67 | sendJson(['success' => false, 'error' => $e->getMessage()], 500); 68 | } 69 | break; 70 | 71 | // -------------------------------------------------- 72 | // 3) Cast a vote 73 | // Expects: poll_id, option_id, username 74 | // -------------------------------------------------- 75 | case 'vote': 76 | // This can come from POST or GET. We'll assume POST for clarity. 77 | $pollId = (int)($_POST['poll_id'] ?? 0); 78 | $optionId = (int)($_POST['option_id'] ?? 0); 79 | $username = trim($_POST['username'] ?? ''); 80 | 81 | if ($pollId <= 0 || $optionId <= 0 || empty($username)) { 82 | sendJson(['success' => false, 'error' => 'Missing or invalid parameters'], 400); 83 | } 84 | 85 | // Check if user already voted on this poll 86 | try { 87 | // 1) Ensure poll & option exist 88 | $checkOption = $db->prepare(" 89 | SELECT COUNT(*) 90 | FROM poll_options 91 | WHERE id = :option_id 92 | AND question_id = :poll_id 93 | "); 94 | $checkOption->execute([ 95 | ':option_id' => $optionId, 96 | ':poll_id' => $pollId 97 | ]); 98 | if (!$checkOption->fetchColumn()) { 99 | sendJson(['success' => false, 'error' => 'Option does not belong to poll or does not exist'], 400); 100 | } 101 | 102 | // 2) Check if user already voted 103 | $checkVote = $db->prepare(" 104 | SELECT COUNT(*) 105 | FROM user_votes 106 | WHERE question_id = :poll_id 107 | AND user_name = :username 108 | "); 109 | $checkVote->execute([ 110 | ':poll_id' => $pollId, 111 | ':username' => $username 112 | ]); 113 | if ($checkVote->fetchColumn() > 0) { 114 | // Already voted 115 | sendJson(['success' => false, 'error' => 'Already voted'], 403); 116 | } 117 | 118 | // 3) Cast the vote (increment poll_results) 119 | $updateStmt = $db->prepare(" 120 | UPDATE poll_results 121 | SET vote_count = vote_count + 1 122 | WHERE question_id = :poll_id 123 | AND option_id = :option_id 124 | "); 125 | $updateStmt->execute([ 126 | ':poll_id' => $pollId, 127 | ':option_id' => $optionId 128 | ]); 129 | 130 | // 4) Record the user vote 131 | // Ensure user_votes table is created: 132 | // CREATE TABLE IF NOT EXISTS user_votes ( 133 | // id INTEGER PRIMARY KEY AUTOINCREMENT, 134 | // question_id INTEGER NOT NULL, 135 | // option_id INTEGER NOT NULL, 136 | // user_name TEXT NOT NULL, 137 | // voted_at DATETIME DEFAULT CURRENT_TIMESTAMP 138 | // ); 139 | $insertVote = $db->prepare(" 140 | INSERT INTO user_votes (question_id, option_id, user_name) 141 | VALUES (:poll_id, :option_id, :username) 142 | "); 143 | $insertVote->execute([ 144 | ':poll_id' => $pollId, 145 | ':option_id' => $optionId, 146 | ':username' => $username 147 | ]); 148 | 149 | sendJson(['success' => true, 'message' => 'Vote cast successfully']); 150 | } catch (Exception $e) { 151 | sendJson(['success' => false, 'error' => $e->getMessage()], 500); 152 | } 153 | break; 154 | 155 | // -------------------------------------------------- 156 | // 4) Unknown / default 157 | // -------------------------------------------------- 158 | default: 159 | sendJson(['success' => false, 'error' => 'Unknown action'], 400); 160 | break; 161 | } 162 | -------------------------------------------------------------------------------- /polls/db.php: -------------------------------------------------------------------------------- 1 | setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 22 | 23 | // If the DB didn't exist before, create the required tables 24 | if (!$dbExists) { 25 | // Create 'users' table 26 | $db->exec(" 27 | CREATE TABLE IF NOT EXISTS users ( 28 | id INTEGER PRIMARY KEY AUTOINCREMENT, 29 | username TEXT UNIQUE NOT NULL, 30 | password TEXT NOT NULL 31 | ); 32 | "); 33 | 34 | // Create 'poll_questions' table 35 | $db->exec(" 36 | CREATE TABLE IF NOT EXISTS poll_questions ( 37 | id INTEGER PRIMARY KEY AUTOINCREMENT, 38 | question_text TEXT NOT NULL, 39 | created_at DATETIME DEFAULT CURRENT_TIMESTAMP 40 | ); 41 | "); 42 | 43 | // Create 'poll_options' table 44 | $db->exec(" 45 | CREATE TABLE IF NOT EXISTS poll_options ( 46 | id INTEGER PRIMARY KEY AUTOINCREMENT, 47 | question_id INTEGER NOT NULL, 48 | option_text TEXT NOT NULL, 49 | FOREIGN KEY (question_id) REFERENCES poll_questions(id) 50 | ); 51 | "); 52 | 53 | // Create 'poll_results' table 54 | $db->exec(" 55 | CREATE TABLE IF NOT EXISTS poll_results ( 56 | id INTEGER PRIMARY KEY AUTOINCREMENT, 57 | question_id INTEGER NOT NULL, 58 | option_id INTEGER NOT NULL, 59 | vote_count INTEGER NOT NULL DEFAULT 0, 60 | FOREIGN KEY (question_id) REFERENCES poll_questions(id), 61 | FOREIGN KEY (option_id) REFERENCES poll_options(id) 62 | ); 63 | "); 64 | 65 | // Create a default admin user with a hashed password 66 | // NOTE: In production, you should not hardcode these credentials. 67 | // Instead, store them outside of your code or set them up once. 68 | $adminUsername = 'admin'; 69 | $adminPlainPassword = 'password'; // Change this in production 70 | $adminHashedPassword = password_hash($adminPlainPassword, PASSWORD_DEFAULT); 71 | 72 | $insertUser = $db->prepare(" 73 | INSERT INTO users (username, password) 74 | VALUES (:username, :password) 75 | "); 76 | $insertUser->bindValue(':username', $adminUsername, PDO::PARAM_STR); 77 | $insertUser->bindValue(':password', $adminHashedPassword, PDO::PARAM_STR); 78 | $insertUser->execute(); 79 | } 80 | 81 | // Optionally, you can return $db or leave it globally accessible 82 | // for other parts of your application. 83 | // Example: 84 | // return $db; 85 | 86 | } catch (PDOException $e) { 87 | echo "Database error: " . $e->getMessage(); 88 | exit; 89 | } 90 | ?> 91 | -------------------------------------------------------------------------------- /polls/index.php: -------------------------------------------------------------------------------- 1 | prepare("SELECT * FROM poll_questions WHERE id = :id LIMIT 1"); 13 | $stmt->bindValue(':id', $pollId, PDO::PARAM_INT); 14 | $stmt->execute(); 15 | return $stmt->fetch(PDO::FETCH_ASSOC); 16 | } 17 | 18 | // Helper function: Fetch poll options (and their results) by poll ID 19 | function getPollOptions($db, $pollId) { 20 | $stmt = $db->prepare(" 21 | SELECT 22 | po.id AS option_id, 23 | po.option_text, 24 | IFNULL(pr.vote_count, 0) AS vote_count 25 | FROM poll_options po 26 | LEFT JOIN poll_results pr ON po.id = pr.option_id 27 | WHERE po.question_id = :question_id 28 | ORDER BY po.id ASC 29 | "); 30 | $stmt->bindValue(':question_id', $pollId, PDO::PARAM_INT); 31 | $stmt->execute(); 32 | return $stmt->fetchAll(PDO::FETCH_ASSOC); 33 | } 34 | 35 | // If a vote is being cast 36 | if (isset($_POST['vote']) && isset($_POST['option_id']) && isset($_POST['poll_id'])) { 37 | $pollId = (int)$_POST['poll_id']; 38 | $optionId = (int)$_POST['option_id']; 39 | 40 | // Ensure this user hasn't already voted on this poll in this session 41 | if (!in_array($pollId, $_SESSION['voted_polls'], true)) { 42 | // Update the vote count 43 | $updateStmt = $db->prepare(" 44 | UPDATE poll_results 45 | SET vote_count = vote_count + 1 46 | WHERE question_id = :question_id 47 | AND option_id = :option_id 48 | "); 49 | $updateStmt->bindValue(':question_id', $pollId, PDO::PARAM_INT); 50 | $updateStmt->bindValue(':option_id', $optionId, PDO::PARAM_INT); 51 | $updateStmt->execute(); 52 | 53 | // Mark the user as having voted 54 | $_SESSION['voted_polls'][] = $pollId; 55 | } 56 | 57 | // Redirect back to the same poll to show results 58 | header("Location: index.php?poll_id=" . $pollId); 59 | exit; 60 | } 61 | 62 | // Check if a specific poll is requested 63 | $pollId = isset($_GET['poll_id']) ? (int)$_GET['poll_id'] : null; 64 | ?> 65 | 66 | 67 | 68 | 69 | Poll Application 70 | 89 | 90 | 91 | 92 | 96 |
97 |

Available Polls

98 | query("SELECT id, question_text, created_at FROM poll_questions ORDER BY id DESC"); 101 | $allPolls = $allPollsStmt->fetchAll(PDO::FETCH_ASSOC); 102 | 103 | if ($allPolls) { 104 | foreach ($allPolls as $poll) { 105 | ?> 106 |
107 | Question:
108 | Created at:
109 | View Poll 110 |
111 | 115 |

No polls available.

116 | 119 |
120 | 126 |
127 | Poll not found.

"; 130 | } else { 131 | $options = getPollOptions($db, $pollId); 132 | $hasVoted = in_array($pollId, $_SESSION['voted_polls'], true); 133 | ?> 134 |

135 | 136 | 141 |
142 |
143 |
    144 | 145 |
  • 146 | 152 |
  • 153 | 154 |
155 |
156 | 157 | 158 |
159 | No options available for this poll.

"; 162 | } 163 | } else { 164 | // Show the results if user has already voted 165 | ?> 166 |

Results

167 |
168 |
    169 | 0) ? ($voteCount / $totalVotes) * 100 : 0; 178 | ?> 179 |
  • 180 | : 181 | votes 182 | (%) 183 |
  • 184 | 187 |
188 |

Total votes:

189 |
190 | 194 | Back to Poll List 195 |
196 | 199 | 200 | 201 | 202 | -------------------------------------------------------------------------------- /polls/setup.php: -------------------------------------------------------------------------------- 1 | query("SELECT COUNT(*) FROM users")->fetchColumn(); 13 | 14 | // If at least one user exists, show a message and no form 15 | if ($checkTotal > 0) { 16 | ?> 17 | 18 | 19 | 20 | 21 | Setup Admin User 22 | 39 | 40 | 41 |
42 |

Admin User Already Exists

43 |

44 | An admin user has already been created. No additional admins can be set up here. 45 |

46 |

47 | Go back to the Polls site. 48 |

49 |
50 | 51 | 52 | prepare(" 71 | INSERT INTO users (username, password) 72 | VALUES (:username, :password) 73 | "); 74 | $insertStmt->bindValue(':username', $username, PDO::PARAM_STR); 75 | $insertStmt->bindValue(':password', $hashedPassword, PDO::PARAM_STR); 76 | $insertStmt->execute(); 77 | 78 | $success = "Admin user '$username' created successfully."; 79 | } 80 | } 81 | ?> 82 | 83 | 84 | 85 | 86 | Setup Admin User 87 | 115 | 116 | 117 |
118 |

Setup Admin User

119 | 120 | 121 |
122 | 123 | 124 |
125 |

You can now go to the Admin page to log in.

126 | 127 |
128 |
129 | 130 | 137 |
138 | 139 |
140 | 141 | 147 |
148 | 149 |
150 | 151 | 157 |
158 | 159 |
160 | 161 |
162 |
163 | 164 |
165 | 166 | 167 | -------------------------------------------------------------------------------- /robots.txt: -------------------------------------------------------------------------------- 1 | User-Agent: MojeekBot 2 | Allow: /~xwindows/ 3 | 4 | User-Agent: Qwantify 5 | Allow: /~xwindows/ 6 | 7 | User-Agent: Wibybot 8 | Allow: /~xwindows/ 9 | 10 | User-Agent: search.marginalia.nu 11 | Allow: /~xwindows/ 12 | 13 | User-Agent: SearchMySiteBot 14 | Allow: /~xwindows/ 15 | 16 | User-Agent: Duckduckbot 17 | Allow: /~xwindows/ 18 | 19 | User-Agent: ia_archiver 20 | Allow: /~xwindows/ 21 | 22 | User-Agent: Googlebot 23 | Allow: /~xwindows/$ 24 | Allow: /~xwindows/index.html$ 25 | Disallow: /~xwindows/ 26 | 27 | User-Agent: bingbot 28 | Allow: /~xwindows/$ 29 | Allow: /~xwindows/index.html$ 30 | Disallow: /~xwindows/ 31 | 32 | User-Agent: YandexBot 33 | Allow: /~xwindows/$ 34 | Allow: /~xwindows/index.html$ 35 | Disallow: /~xwindows/ 36 | 37 | User-Agent: YandexFavicons 38 | Disallow: /~xwindows/ 39 | 40 | User-Agent: MegaIndex.ru 41 | Disallow: /~xwindows/ 42 | 43 | User-Agent: Amazonbot 44 | Disallow: /~xwindows/ 45 | 46 | User-Agent: Linespider 47 | Disallow: /~xwindows/ 48 | 49 | User-Agent: Bytespider 50 | Disallow: /~xwindows/ 51 | 52 | User-Agent: CCBot 53 | Disallow: /~xwindows/ 54 | 55 | User-Agent: Neevabot 56 | Disallow: /~xwindows/ 57 | 58 | User-Agent: PetalBot 59 | Disallow: /~xwindows/ 60 | 61 | User-Agent: SemrushBot 62 | Disallow: /~xwindows/ 63 | 64 | User-Agent: AhrefsBot 65 | Disallow: /~xwindows/ 66 | 67 | User-Agent: DataForSeoBot 68 | Disallow: /~xwindows/ 69 | 70 | User-Agent: dotbot 71 | Disallow: /~xwindows/ 72 | 73 | User-Agent: Barkrowler 74 | Disallow: /~xwindows/ 75 | 76 | User-Agent: MJ12bot 77 | Disallow: /~xwindows/ 78 | 79 | User-Agent: BuiltWith 80 | Disallow: /~xwindows/ 81 | 82 | User-Agent: webprosbot 83 | Disallow: /~xwindows/ 84 | 85 | User-Agent: Dataprovider 86 | Disallow: /~xwindows/ 87 | 88 | User-Agent: * 89 | Allow: /~xwindows/$ 90 | Allow: /~xwindows/index.html$ 91 | Disallow: /~xwindows/ 92 | -------------------------------------------------------------------------------- /signup/email/ipaddr.php: -------------------------------------------------------------------------------- 1 | $segment) 19 | { 20 | $segment = trim($segment); 21 | if ($segment != "") $ipaddr2[] = $segment; 22 | else if ($foundpos === false && count($ipaddr) > $num + 1 && $ipaddr[$num + 1] != "") 23 | { 24 | $foundpos = count($ipaddr2); 25 | $ipaddr2[] = "0000"; 26 | } 27 | } 28 | // Convert ::ffff:123.123.123.123 format. 29 | if (str_contains($ipaddr2[count($ipaddr2) - 1], ".")) 30 | { 31 | $x = count($ipaddr2) - 1; 32 | if ($ipaddr2[count($ipaddr2) - 2] != "ffff") $ipaddr2[$x] = "0"; 33 | else 34 | { 35 | $ipaddr = explode(".", $ipaddr2[$x]); 36 | if (count($ipaddr) != 4) $ipaddr2[$x] = "0"; 37 | else 38 | { 39 | $ipaddr2[$x] = str_pad(strtolower(dechex($ipaddr[0])), 2, "0", STR_PAD_LEFT) . str_pad(strtolower(dechex($ipaddr[1])), 2, "0", STR_PAD_LEFT); 40 | $ipaddr2[] = str_pad(strtolower(dechex($ipaddr[2])), 2, "0", STR_PAD_LEFT) . str_pad(strtolower(dechex($ipaddr[3])), 2, "0", STR_PAD_LEFT); 41 | } 42 | } 43 | } 44 | $ipaddr = array_slice($ipaddr2, 0, 8); 45 | if ($foundpos !== false && count($ipaddr) < 8) array_splice($ipaddr, $foundpos, 0, array_fill(0, 8 - count($ipaddr), "0000")); 46 | foreach ($ipaddr as $num => $segment) 47 | { 48 | $ipaddr[$num] = substr(str_pad(strtolower(dechex(hexdec($segment))), 4, "0", STR_PAD_LEFT), -4); 49 | } 50 | $ipv6addr = implode(":", $ipaddr); 51 | 52 | // Extract IPv4 address. 53 | if (str_starts_with($ipv6addr, "0000:0000:0000:0000:0000:ffff:")) $ipv4addr = hexdec(substr($ipv6addr, 30, 2)) . "." . hexdec(substr($ipv6addr, 32, 2)) . "." . hexdec(substr($ipv6addr, 35, 2)) . "." . hexdec(substr($ipv6addr, 37, 2)); 54 | 55 | // Make a short IPv6 address. 56 | $shortipv6 = $ipv6addr; 57 | $pattern = "0000:0000:0000:0000:0000:0000:0000"; 58 | do 59 | { 60 | $shortipv6 = str_replace($pattern, ":", $shortipv6); 61 | $pattern = substr($pattern, 5); 62 | } while (strlen($shortipv6) == 39 && $pattern != ""); 63 | $shortipv6 = explode(":", $shortipv6); 64 | foreach ($shortipv6 as $num => $segment) 65 | { 66 | if ($segment != "") $shortipv6[$num] = strtolower(dechex(hexdec($segment))); 67 | } 68 | $shortipv6 = implode(":", $shortipv6); 69 | 70 | return array("ipv6" => $ipv6addr, "shortipv6" => $shortipv6, "ipv4" => $ipv4addr); 71 | } 72 | 73 | static function GetRemoteIP($proxies = array()) 74 | { 75 | $ipaddr = self::NormalizeIP($_SERVER["REMOTE_ADDR"] ?? "127.0.0.1"); 76 | 77 | // Check for trusted proxies. Stop at first untrusted IP in the chain. 78 | if (isset($proxies[$ipaddr["ipv6"]]) || ($ipaddr["ipv4"] != "" && isset($proxies[$ipaddr["ipv4"]]))) 79 | { 80 | $xforward = (isset($_SERVER["HTTP_X_FORWARDED_FOR"]) ? explode(",", $_SERVER["HTTP_X_FORWARDED_FOR"]) : array()); 81 | $clientip = (isset($_SERVER["HTTP_CLIENT_IP"]) ? explode(",", $_SERVER["HTTP_CLIENT_IP"]) : array()); 82 | 83 | do 84 | { 85 | $found = false; 86 | 87 | $header = $proxies[$ipaddr["ipv6"]] ?? $proxies[$ipaddr["ipv4"]]; 88 | 89 | $header = strtolower($header); 90 | if ($header == "xforward" && count($xforward) > 0) 91 | { 92 | $ipaddr = self::NormalizeIP(array_pop($xforward)); 93 | $found = true; 94 | } 95 | else if ($header == "clientip" && count($clientip) > 0) 96 | { 97 | $ipaddr = self::NormalizeIP(array_pop($clientip)); 98 | $found = true; 99 | } 100 | } while ($found && (isset($proxies[$ipaddr["ipv6"]]) || ($ipaddr["ipv4"] != "" && isset($proxies[$ipaddr["ipv4"]])))); 101 | } 102 | 103 | return $ipaddr; 104 | } 105 | 106 | static function IsMatch($pattern, $ipaddr) 107 | { 108 | if (is_string($ipaddr)) $ipaddr = self::NormalizeIP($ipaddr); 109 | 110 | if (str_contains($pattern, ":")) 111 | { 112 | // Pattern is IPv6. 113 | $pattern = explode(":", strtolower($pattern)); 114 | $ipaddr = explode(":", $ipaddr["ipv6"]); 115 | if (count($pattern) != 8 || count($ipaddr) != 8) return false; 116 | foreach ($pattern as $num => $segment) 117 | { 118 | $found = false; 119 | $pieces = explode(",", $segment); 120 | foreach ($pieces as $piece) 121 | { 122 | $piece = trim($piece); 123 | $piece = explode(".", $piece); 124 | if (count($piece) == 1) 125 | { 126 | $piece = $piece[0]; 127 | 128 | if ($piece == "*") $found = true; 129 | else if (str_contains($piece, "-")) 130 | { 131 | $range = explode("-", $piece); 132 | $range[0] = hexdec($range[0]); 133 | $range[1] = hexdec($range[1]); 134 | $val = hexdec($ipaddr[$num]); 135 | if ($range[0] > $range[1]) $range[0] = $range[1]; 136 | if ($val >= $range[0] && $val <= $range[1]) $found = true; 137 | } 138 | else if ($piece === $ipaddr[$num]) $found = true; 139 | } 140 | else if (count($piece) == 2) 141 | { 142 | // Special IPv4-like notation. 143 | $found2 = false; 144 | $found3 = false; 145 | $val = hexdec(substr($ipaddr[$num], 0, 2)); 146 | $val2 = hexdec(substr($ipaddr[$num], 2, 2)); 147 | 148 | if ($piece[0] == "*") $found2 = true; 149 | else if (str_contains($piece[0], "-")) 150 | { 151 | $range = explode("-", $piece[0]); 152 | if ($range[0] > $range[1]) $range[0] = $range[1]; 153 | if ($val >= $range[0] && $val <= $range[1]) $found2 = true; 154 | } 155 | else if ($piece[0] == $val) $found2 = true; 156 | 157 | if ($piece[1] == "*") $found3 = true; 158 | else if (str_contains($piece[1], "-")) 159 | { 160 | $range = explode("-", $piece[1]); 161 | if ($range[0] > $range[1]) $range[0] = $range[1]; 162 | if ($val >= $range[0] && $val <= $range[1]) $found3 = true; 163 | } 164 | else if ($piece[1] == $val2) $found3 = true; 165 | 166 | if ($found2 && $found3) $found = true; 167 | } 168 | 169 | if ($found) break; 170 | } 171 | 172 | if (!$found) return false; 173 | } 174 | } 175 | else 176 | { 177 | // Pattern is IPv4. 178 | $pattern = explode(".", strtolower($pattern)); 179 | $ipaddr = explode(".", $ipaddr["ipv4"]); 180 | if (count($pattern) != 4 || count($ipaddr) != 4) return false; 181 | foreach ($pattern as $num => $segment) 182 | { 183 | $found = false; 184 | $pieces = explode(",", $segment); 185 | foreach ($pieces as $piece) 186 | { 187 | $piece = trim($piece); 188 | 189 | if ($piece == "*") $found = true; 190 | else if (str_contains($piece, "-")) 191 | { 192 | $range = explode("-", $piece); 193 | if ($range[0] > $range[1]) $range[0] = $range[1]; 194 | if ($ipaddr[$num] >= $range[0] && $ipaddr[$num] <= $range[1]) $found = true; 195 | } 196 | else if ($piece == $ipaddr[$num]) $found = true; 197 | 198 | if ($found) break; 199 | } 200 | 201 | if (!$found) return false; 202 | } 203 | } 204 | 205 | return true; 206 | } 207 | } 208 | -------------------------------------------------------------------------------- /signup/email/utf8.php: -------------------------------------------------------------------------------- 1 | 1) $tempchr2 = ord($data[$x + 1]); 18 | else $tempchr2 = 0x00; 19 | if ($y - $x > 2) $tempchr3 = ord($data[$x + 2]); 20 | else $tempchr3 = 0x00; 21 | if ($y - $x > 3) $tempchr4 = ord($data[$x + 3]); 22 | else $tempchr4 = 0x00; 23 | if ($tempchr == 0x09 || $tempchr == 0x0A || $tempchr == 0x0D || ($tempchr >= 0x20 && $tempchr <= 0x7E)) 24 | { 25 | // ASCII minus control and special characters. 26 | $result .= chr($tempchr); 27 | $x++; 28 | } 29 | else if (($tempchr >= 0xC2 && $tempchr <= 0xDF) && ($tempchr2 >= 0x80 && $tempchr2 <= 0xBF)) 30 | { 31 | // Non-overlong (2 bytes). 32 | $result .= chr($tempchr); 33 | $result .= chr($tempchr2); 34 | $x += 2; 35 | } 36 | else if ($tempchr == 0xE0 && ($tempchr2 >= 0xA0 && $tempchr2 <= 0xBF) && ($tempchr3 >= 0x80 && $tempchr3 <= 0xBF)) 37 | { 38 | // Non-overlong (3 bytes). 39 | $result .= chr($tempchr); 40 | $result .= chr($tempchr2); 41 | $result .= chr($tempchr3); 42 | $x += 3; 43 | } 44 | else if ((($tempchr >= 0xE1 && $tempchr <= 0xEC) || $tempchr == 0xEE || $tempchr == 0xEF) && ($tempchr2 >= 0x80 && $tempchr2 <= 0xBF) && ($tempchr3 >= 0x80 && $tempchr3 <= 0xBF)) 45 | { 46 | // Normal/straight (3 bytes). 47 | $result .= chr($tempchr); 48 | $result .= chr($tempchr2); 49 | $result .= chr($tempchr3); 50 | $x += 3; 51 | } 52 | else if ($tempchr == 0xED && ($tempchr2 >= 0x80 && $tempchr2 <= 0x9F) && ($tempchr3 >= 0x80 && $tempchr3 <= 0xBF)) 53 | { 54 | // Non-surrogates (3 bytes). 55 | $result .= chr($tempchr); 56 | $result .= chr($tempchr2); 57 | $result .= chr($tempchr3); 58 | $x += 3; 59 | } 60 | else if ($tempchr == 0xF0 && ($tempchr2 >= 0x90 && $tempchr2 <= 0xBF) && ($tempchr3 >= 0x80 && $tempchr3 <= 0xBF) && ($tempchr4 >= 0x80 && $tempchr4 <= 0xBF)) 61 | { 62 | // Planes 1-3 (4 bytes). 63 | $result .= chr($tempchr); 64 | $result .= chr($tempchr2); 65 | $result .= chr($tempchr3); 66 | $result .= chr($tempchr4); 67 | $x += 4; 68 | } 69 | else if (($tempchr >= 0xF1 && $tempchr <= 0xF3) && ($tempchr2 >= 0x80 && $tempchr2 <= 0xBF) && ($tempchr3 >= 0x80 && $tempchr3 <= 0xBF) && ($tempchr4 >= 0x80 && $tempchr4 <= 0xBF)) 70 | { 71 | // Planes 4-15 (4 bytes). 72 | $result .= chr($tempchr); 73 | $result .= chr($tempchr2); 74 | $result .= chr($tempchr3); 75 | $result .= chr($tempchr4); 76 | $x += 4; 77 | } 78 | else if ($tempchr == 0xF4 && ($tempchr2 >= 0x80 && $tempchr2 <= 0x8F) && ($tempchr3 >= 0x80 && $tempchr3 <= 0xBF) && ($tempchr4 >= 0x80 && $tempchr4 <= 0xBF)) 79 | { 80 | // Plane 16 (4 bytes). 81 | $result .= chr($tempchr); 82 | $result .= chr($tempchr2); 83 | $result .= chr($tempchr3); 84 | $result .= chr($tempchr4); 85 | $x += 4; 86 | } 87 | else $x++; 88 | } 89 | 90 | return $result; 91 | } 92 | 93 | public static function IsValid($data) 94 | { 95 | $x = 0; 96 | $y = strlen($data); 97 | while ($x < $y) 98 | { 99 | $tempchr = ord($data[$x]); 100 | if ($y - $x > 1) $tempchr2 = ord($data[$x + 1]); 101 | else $tempchr2 = 0x00; 102 | if ($y - $x > 2) $tempchr3 = ord($data[$x + 2]); 103 | else $tempchr3 = 0x00; 104 | if ($y - $x > 3) $tempchr4 = ord($data[$x + 3]); 105 | else $tempchr4 = 0x00; 106 | if ($tempchr == 0x09 || $tempchr == 0x0A || $tempchr == 0x0D || ($tempchr >= 0x20 && $tempchr <= 0x7E)) $x++; 107 | else if (($tempchr >= 0xC2 && $tempchr <= 0xDF) && ($tempchr2 >= 0x80 && $tempchr2 <= 0xBF)) $x += 2; 108 | else if ($tempchr == 0xE0 && ($tempchr2 >= 0xA0 && $tempchr2 <= 0xBF) && ($tempchr3 >= 0x80 && $tempchr3 <= 0xBF)) $x += 3; 109 | else if ((($tempchr >= 0xE1 && $tempchr <= 0xEC) || $tempchr == 0xEE || $tempchr == 0xEF) && ($tempchr2 >= 0x80 && $tempchr2 <= 0xBF) && ($tempchr3 >= 0x80 && $tempchr3 <= 0xBF)) $x += 3; 110 | else if ($tempchr == 0xED && ($tempchr2 >= 0x80 && $tempchr2 <= 0x9F) && ($tempchr3 >= 0x80 && $tempchr3 <= 0xBF)) $x += 3; 111 | else if ($tempchr == 0xF0 && ($tempchr2 >= 0x90 && $tempchr2 <= 0xBF) && ($tempchr3 >= 0x80 && $tempchr3 <= 0xBF) && ($tempchr4 >= 0x80 && $tempchr4 <= 0xBF)) $x += 4; 112 | else if (($tempchr >= 0xF1 && $tempchr <= 0xF3) && ($tempchr2 >= 0x80 && $tempchr2 <= 0xBF) && ($tempchr3 >= 0x80 && $tempchr3 <= 0xBF) && ($tempchr4 >= 0x80 && $tempchr4 <= 0xBF)) $x += 4; 113 | else if ($tempchr == 0xF4 && ($tempchr2 >= 0x80 && $tempchr2 <= 0x8F) && ($tempchr3 >= 0x80 && $tempchr3 <= 0xBF) && ($tempchr4 >= 0x80 && $tempchr4 <= 0xBF)) $x += 4; 114 | else return false; 115 | } 116 | 117 | return true; 118 | } 119 | 120 | // Locates the next UTF8 character in a UTF8 string. 121 | // Set Pos and Size to 0 to start at the beginning. 122 | // Returns false at the end of the string or bad UTF8 character. Otherwise, returns true. 123 | public static function NextChrPos(&$data, $datalen, &$pos, &$size) 124 | { 125 | $pos += $size; 126 | $size = 0; 127 | $x = $pos; 128 | $y = $datalen; 129 | if ($x >= $y) return false; 130 | 131 | $tempchr = ord($data[$x]); 132 | if ($y - $x > 1) $tempchr2 = ord($data[$x + 1]); 133 | else $tempchr2 = 0x00; 134 | if ($y - $x > 2) $tempchr3 = ord($data[$x + 2]); 135 | else $tempchr3 = 0x00; 136 | if ($y - $x > 3) $tempchr4 = ord($data[$x + 3]); 137 | else $tempchr4 = 0x00; 138 | if ($tempchr == 0x09 || $tempchr == 0x0A || $tempchr == 0x0D || ($tempchr >= 0x20 && $tempchr <= 0x7E)) $size = 1; 139 | else if (($tempchr >= 0xC2 && $tempchr <= 0xDF) && ($tempchr2 >= 0x80 && $tempchr2 <= 0xBF)) $size = 2; 140 | else if ($tempchr == 0xE0 && ($tempchr2 >= 0xA0 && $tempchr2 <= 0xBF) && ($tempchr3 >= 0x80 && $tempchr3 <= 0xBF)) $size = 3; 141 | else if ((($tempchr >= 0xE1 && $tempchr <= 0xEC) || $tempchr == 0xEE || $tempchr == 0xEF) && ($tempchr2 >= 0x80 && $tempchr2 <= 0xBF) && ($tempchr3 >= 0x80 && $tempchr3 <= 0xBF)) $size = 3; 142 | else if ($tempchr == 0xED && ($tempchr2 >= 0x80 && $tempchr2 <= 0x9F) && ($tempchr3 >= 0x80 && $tempchr3 <= 0xBF)) $size = 3; 143 | else if ($tempchr == 0xF0 && ($tempchr2 >= 0x90 && $tempchr2 <= 0xBF) && ($tempchr3 >= 0x80 && $tempchr3 <= 0xBF) && ($tempchr4 >= 0x80 && $tempchr4 <= 0xBF)) $size = 4; 144 | else if (($tempchr >= 0xF1 && $tempchr <= 0xF3) && ($tempchr2 >= 0x80 && $tempchr2 <= 0xBF) && ($tempchr3 >= 0x80 && $tempchr3 <= 0xBF) && ($tempchr4 >= 0x80 && $tempchr4 <= 0xBF)) $size = 4; 145 | else if ($tempchr == 0xF4 && ($tempchr2 >= 0x80 && $tempchr2 <= 0x8F) && ($tempchr3 >= 0x80 && $tempchr3 <= 0xBF) && ($tempchr4 >= 0x80 && $tempchr4 <= 0xBF)) $size = 4; 146 | else return false; 147 | 148 | return true; 149 | } 150 | 151 | // Determines if a UTF8 string can also be viewed as ASCII. 152 | public static function IsASCII($data) 153 | { 154 | $pos = 0; 155 | $size = 0; 156 | $y = strlen($data); 157 | while (self::NextChrPos($data, $y, $pos, $size) && $size == 1) {} 158 | if ($pos < $y || $size > 1) return false; 159 | 160 | return true; 161 | } 162 | 163 | // Returns the number of characters in a UTF8 string. 164 | public static function strlen($data) 165 | { 166 | $num = 0; 167 | $pos = 0; 168 | $size = 0; 169 | $y = strlen($data); 170 | while (self::NextChrPos($data, $y, $pos, $size)) $num++; 171 | 172 | return $num; 173 | } 174 | 175 | // Converts a UTF8 string to ASCII and drops bad UTF8 and non-ASCII characters in the process. 176 | public static function ConvertToASCII($data) 177 | { 178 | $result = ""; 179 | 180 | $pos = 0; 181 | $size = 0; 182 | $y = strlen($data); 183 | while ($pos < $y) 184 | { 185 | if (self::NextChrPos($data, $y, $pos, $size) && $size == 1) $result .= $data[$pos]; 186 | else if (!$size) $size = 1; 187 | } 188 | 189 | return $result; 190 | } 191 | 192 | // Converts UTF8 characters in a string to HTML entities. 193 | public static function ConvertToHTML($data) 194 | { 195 | return preg_replace_callback('/([\xC0-\xF7]{1,1}[\x80-\xBF]+)/', 'UTF8::ConvertToHTML__Callback', $data); 196 | } 197 | 198 | private static function ConvertToHTML__Callback($data) 199 | { 200 | $data = $data[1]; 201 | $num = 0; 202 | $data = str_split(strrev(chr((ord(substr($data, 0, 1)) % 252 % 248 % 240 % 224 % 192) + 128) . substr($data, 1))); 203 | foreach ($data as $k => $v) $num += (ord($v) % 128) * pow(64, $k); 204 | 205 | return "&#" . $num . ";"; 206 | } 207 | } 208 | ?> -------------------------------------------------------------------------------- /signup/index.php: -------------------------------------------------------------------------------- 1 | 23 | 24 |
25 | We don't accept Gmail addresses due to Google not allowing emails to go through due to a recent spam issue.
26 | 27 | 28 |

sign up to join tilde.club

29 | 30 |
31 |
32 |
33 |

We're excited you're here! Let's get you signed up!

34 |

Fill out this form and we'll get back to you with account info

35 |
36 |
37 |

your desired username (numbers and lowercase letters only, no spaces)

38 | " type="text" required> 39 |
40 | 41 |
42 |

email to contact you with account info

43 | " type="text" required> 44 |
45 | 46 |
47 |

what interests you about tilde.club? we want to make sure you're a real human being :)

48 | 49 |
50 | 51 |
52 |

SSH public key

53 | 54 |

if you don't have a key, don't worry! check out our guide to ssh keys and make sure that you only put your pubkey here

55 |
56 | 57 |

58 | signing up implies that you agree to abide by our code of conduct 59 |
60 | no drama. be respectful. have fun. we're all trying, and we're all in this together :) 61 |

62 |

you must be at least 13 years or older to sign up and use tilde.club.

63 | 64 | 65 | 66 |
67 | 68 | 69 | 70 | 71 | 72 |
73 |
74 | 75 | fill in your desired username\n"; 140 | else { 141 | if (strlen($name) < 2) 142 | $message .= "
  • username is too short (2 character min)
  • \n"; 143 | 144 | if (strlen($name) > 32) 145 | $message .= "
  • username too long (32 character max)
  • \n"; 146 | 147 | if (strlen($name) > 1 && !preg_match('/^[a-z][a-z0-9]{1,31}$/', $name)) 148 | $message .= "
  • username contains invalid characters (lowercase only, must start with a letter).
  • \n"; 149 | 150 | if (posix_getpwnam($name) || forbidden_name($name)) 151 | $message .= "
  • sorry, the username $name is unavailable
  • \n"; 152 | } 153 | 154 | // Check the e-mail address. 155 | $email = trim($_REQUEST["email"]); 156 | if ($email == "") 157 | $message .= "
  • please fill in your email address
  • "; 158 | else { 159 | $result = SMTP::MakeValidEmailAddress($_REQUEST["email"]); 160 | if (!$result["success"]) 161 | $message .= "
  • invalid email address: " . htmlspecialchars($result["error"]) . "
  • "; 162 | elseif ($result["email"] != $email) 163 | $message .= "
  • invalid email address. did you mean: " . htmlspecialchars($result["email"]) . "
  • "; 164 | 165 | elseif ($name != "" && forbidden_email($email)) { 166 | $message .= "
  • your email is banned!

  • "; 167 | add_ban_info($name, $email); 168 | } 169 | } 170 | 171 | if ($_REQUEST["interest"] == "") 172 | $message .= "
  • please explain why you're interested so we can make sure you're a real human being
  • "; 173 | 174 | $sshkey = trim($_REQUEST["sshkey"]); 175 | if ($sshkey == "" || !is_ssh_pubkey($sshkey)) 176 | $message .= '
  • ssh key required: please create one and submit the public key. ' 177 | . 'see our ssh wiki or ' 178 | . 'hop on irc and ask for help
  • '; 179 | else { 180 | if ($name != "" && $email != "") { 181 | if (forbidden_sshkey($sshkey)) { 182 | $message .= "
  • your sshkey is banned!
  • \n"; 183 | add_ban_info($name, $email); 184 | } 185 | } 186 | } 187 | 188 | 189 | // no validation errors 190 | if ($message == "") { 191 | $makeuser = "makeuser {$_REQUEST["username"]} {$_REQUEST["email"]} \"$sshkey\""; 192 | 193 | $msgbody = " 194 | username: {$_REQUEST["username"]} 195 | email: {$_REQUEST["email"]} 196 | reason: {$_REQUEST["interest"]} 197 | 198 | $makeuser 199 | "; 200 | 201 | if (mail('root', 'new tilde.club signup', $msgbody)) { 202 | echo ''; 205 | // temp. add to forbidden to prevent double signups (cleanup after user creation) 206 | file_put_contents("/var/signups_current", $name.PHP_EOL, FILE_APPEND); 207 | file_put_contents("/var/signups", $makeuser.PHP_EOL, FILE_APPEND); 208 | // clear form fields 209 | $_REQUEST["email"] = $_REQUEST["username"] = $_REQUEST["sshkey"] = $_REQUEST["interest"] = ""; 210 | } else { 211 | echo ''; 214 | } 215 | 216 | } else { 217 | ?> 218 | 222 | 226 | -------------------------------------------------------------------------------- /style.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: 'Liberation Monospace'; 3 | font-style: normal; 4 | font-weight: normal; 5 | src: local('Liberation Monospace'), url('https://fonts.cdnfonts.com/s/276/LiberationMono-Regular.woff') format('woff'); 6 | } 7 | 8 | @font-face { 9 | font-family: 'Liberation Monospace'; 10 | font-style: normal; 11 | font-weight: bold; 12 | src: local('Liberation Monospace'), url('https://fonts.cdnfonts.com/s/276/LiberationMono-Bold.woff') format('woff'); 13 | } 14 | 15 | body { 16 | margin: auto; 17 | padding: 1em; 18 | max-width: 1024px; 19 | font-family: 'Liberation Monospace', 'Courier New', monospace, sans-serif; 20 | color: #fb5; 21 | background: #111; 22 | word-wrap: break-word; 23 | } 24 | 25 | a { 26 | text-decoration: none; 27 | color: #f70; 28 | font-weight: bold; 29 | padding-right: 0.25em; 30 | } 31 | 32 | a:hover { 33 | color: #f20; 34 | } 35 | 36 | hr { 37 | border-color: #fb5; 38 | } 39 | 40 | .text-center { 41 | text-align: center 42 | } 43 | 44 | .advisory { 45 | background: #fc4; 46 | color: #222; 47 | font-weight: bold; 48 | padding: 1em; 49 | border-radius: 0.25em; 50 | } 51 | 52 | h1 { 53 | font-size:1.6rem; 54 | text-transform: uppercase; 55 | letter-spacing:-.75px; 56 | color: #fb5; 57 | padding-top:.5rem; 58 | } 59 | 60 | .grid { 61 | border-collapse: collapse; 62 | } 63 | .col { 64 | border: 6px double #fb5; 65 | padding: 1em; 66 | flex-grow: 1; 67 | } 68 | 69 | /* THEGOODS */ 70 | #fancyboi::before { 71 | content: "$ "; 72 | } 73 | 74 | @media (prefers-reduced-motion: no-preference) { 75 | @keyframes flash { 76 | 50% { opacity: 0; } 77 | } 78 | 79 | @keyframes reveal { 80 | from { max-width: 2em; } /* Width of ::before */ 81 | to { max-width: 100%; } 82 | } 83 | 84 | #fancyboi { 85 | overflow: hidden; 86 | white-space: nowrap; 87 | animation: reveal 4s linear; 88 | text-overflow: "█"; 89 | } 90 | 91 | #fancyboi::after { 92 | content: "█"; 93 | animation: flash 0.5s step-end infinite; 94 | position: relative; 95 | top: -2px; 96 | margin-left: 3px; 97 | } 98 | } 99 | /* SDOOGEHT */ 100 | 101 | .sourceCode { 102 | color:#008000; 103 | } 104 | 105 | code > span.fl { 106 | color: #008000; 107 | } 108 | 109 | /* Style the navbar */ 110 | #navbar { 111 | overflow: hidden; 112 | background-color: #fb5; 113 | color: #222; 114 | z-index: 99; 115 | position: relative; 116 | top: 0; 117 | left: 0; 118 | width: 100%; 119 | border-radius: 0.25em; 120 | } 121 | 122 | #navbar a:hover { 123 | background-color: #f93; 124 | } 125 | 126 | /* Navbar links */ 127 | #navbar a { 128 | float: left; 129 | display: block; 130 | color: black; 131 | text-align: center; 132 | padding: 14px; 133 | text-decoration: none; 134 | } 135 | 136 | /* RSS Icon Styles */ 137 | .rss-icon { 138 | float: right; 139 | margin-top:5px; 140 | } 141 | 142 | /* Page content */ 143 | .user-list { 144 | display: grid; 145 | grid-template-columns: repeat(auto-fill, minmax(195px, 1fr)); 146 | } 147 | 148 | .user-list a { 149 | overflow: hidden; 150 | text-overflow: ellipsis; 151 | white-space: nowrap; 152 | flex: 10em; 153 | } 154 | 155 | .user-list a:before { 156 | content:"~"; 157 | } 158 | 159 | [data-op="5"] { opacity:5%; } 160 | [data-op="10"] { opacity:10%; } 161 | [data-op="15"] { opacity:15%; } 162 | [data-op="20"] { opacity:20%; } 163 | [data-op="25"] { opacity:25%; } 164 | [data-op="30"] { opacity:30%; } 165 | [data-op="35"] { opacity:35%; } 166 | [data-op="40"] { opacity:40%; } 167 | [data-op="45"] { opacity:45%; } 168 | [data-op="50"] { opacity:50%; } 169 | [data-op="55"] { opacity:55%; } 170 | [data-op="60"] { opacity:60%; } 171 | [data-op="65"] { opacity:65%; } 172 | [data-op="70"] { opacity:70%; } 173 | [data-op="75"] { opacity:75%; } 174 | [data-op="80"] { opacity:80%; } 175 | [data-op="85"] { opacity:85%; } 176 | [data-op="90"] { opacity:90%; } 177 | [data-op="95"] { opacity:95%; } 178 | [data-op="100"] { opacity:100%; } 179 | 180 | .user-list a:hover { 181 | text-decoration:underline; 182 | color:#f70; 183 | } 184 | 185 | .user-list b { 186 | background-color: #fb5; 187 | color:#000; 188 | } 189 | 190 | input[type="text"], 191 | textarea { 192 | background-color: #333; 193 | color: darkorange; 194 | } 195 | 196 | div.alert-warning { 197 | background-color: darkred; 198 | } 199 | div.alert-success { 200 | background-color: darkgreen; 201 | } 202 | 203 | .notice-message { 204 | background-color: #f93; 205 | color: #222; 206 | font-weight: bold; 207 | padding: 0.75em; 208 | border-radius: 0.25em; 209 | margin: 1em 0; 210 | text-align: center; 211 | border: 2px solid #fb5; 212 | box-shadow: 0 0 10px rgba(255, 187, 85, 0.5); 213 | } 214 | 215 | blockquote { 216 | border-left: 2px solid #fb5; 217 | background-color: rgba(255, 187, 85, 5%); 218 | padding: 0.5em; 219 | } 220 | 221 | @media (min-width: 768px) { 222 | .row { 223 | display: flex; 224 | flex-wrap: nowrap; 225 | flex-direction: row-reverse; 226 | } 227 | } 228 | 229 | @media (max-width: 768px) { 230 | td { 231 | display: block; 232 | } 233 | } 234 | 235 | /* Ensure the user-list displays items in a single column */ 236 | .single-column { 237 | display: block; 238 | } 239 | .single-column li { 240 | display: block; 241 | overflow: hidden; 242 | text-overflow: ellipsis; 243 | white-space: nowrap; 244 | } 245 | 246 | /* Style for the article content */ 247 | .article-headers { 248 | background-color: #333; 249 | color: #fb5; 250 | padding: 1em; 251 | border: 1px solid #fb5; 252 | border-radius: 0.25em; 253 | margin-bottom: 1em; 254 | } 255 | 256 | .article-headers p { 257 | margin: 0.5em 0; 258 | } 259 | 260 | pre { 261 | background-color: #333; 262 | color: #fb5; 263 | padding: 1em; 264 | border: 1px solid #fb5; 265 | border-radius: 0.25em; 266 | } 267 | 268 | /* Style for error messages */ 269 | .alert-warning { 270 | background-color: darkred; 271 | color: #fb5; 272 | padding: 1em; 273 | border-radius: 0.25em; 274 | font-weight: bold; 275 | } 276 | /* Ensure the user-list displays items in a single column */ 277 | .single-column { 278 | display: block; 279 | } 280 | .single-column li { 281 | display: block; 282 | overflow: hidden; 283 | text-overflow: ellipsis; 284 | white-space: nowrap; 285 | } 286 | 287 | /* Tree structure styles */ 288 | .tree, .tree ul { 289 | padding: 0; 290 | list-style: none; 291 | position: relative; 292 | } 293 | 294 | .tree ul { 295 | margin-left: 1em; /* indentation for nested lists */ 296 | } 297 | 298 | .tree ul:before { 299 | content: ""; 300 | display: block; 301 | width: 0; 302 | position: absolute; 303 | top: 0; 304 | bottom: 0; 305 | left: 0; 306 | border-left: 1px solid #fb5; 307 | } 308 | 309 | .tree li { 310 | margin: 0; 311 | padding: 0.5em 0 0.5em 1em; /* space between items */ 312 | position: relative; 313 | } 314 | 315 | .tree li:before { 316 | content: ""; 317 | display: inline-block; 318 | width: 1em; /* horizontal space for the branch line */ 319 | height: 0; 320 | border-top: 1px solid #fb5; 321 | position: absolute; 322 | top: 1.2em; /* adjust as needed */ 323 | left: 0; 324 | } 325 | 326 | .tree li:after { 327 | content: ""; 328 | position: absolute; 329 | top: 0; 330 | bottom: 0; 331 | left: -0.5em; /* adjust to align with the branch */ 332 | border-left: 1px solid #fb5; 333 | } 334 | 335 | .tree li:last-child:after { 336 | display: none; /* hide the line for the last child */ 337 | } 338 | 339 | /* Style for timestamps */ 340 | .timestamp { 341 | color: #999; 342 | font-size: 0.9em; 343 | margin-left: 0.5em; 344 | } 345 | /* Highlighted item */ 346 | .highlighted { 347 | background-color: #333; /* Dark background to fit the page colorscheme */ 348 | border: 1px solid #fb5; /* Matching border color */ 349 | border-radius: 0.25em; /* Slight border radius for better appearance */ 350 | padding: 0.5em; /* Padding for better readability */ 351 | } 352 | 353 | #active-users { 354 | margin-top: 20px; 355 | display: flex; 356 | align-items: center; 357 | gap:10px; 358 | } 359 | 360 | #active-users h2 { 361 | flex-shrink:0; 362 | font-size: 1.25rem; 363 | } 364 | 365 | #active-users a { 366 | color: #fb5; 367 | text-decoration: none; 368 | } 369 | 370 | #active-users a:hover { 371 | color: #f70; 372 | } 373 | 374 | -------------------------------------------------------------------------------- /supporters.json: -------------------------------------------------------------------------------- 1 | [ 2 | {"date": "05/06/2025", "name": "mlot", "url": "/~mlot"}, 3 | {"date": "05/03/2025", "name": "ve3zsh", "url": "/~ve3zsh"}, 4 | {"date": "02/26/2025", "name": "djhsu", "url": "/~djhsu"}, 5 | {"date": "11/11/2024", "name": "litemotiv", "url": "/~litemotiv"}, 6 | {"date": "10/12/2024", "name": "subarctic", "url": "/~subarctic"}, 7 | {"date": "09/25/2024", "name": "thumos", "url": "/~thumos"}, 8 | {"date": "09/21/2024", "name": "jpurnell", "url": "/~jpurnell"}, 9 | {"date": "09/09/2024", "name": "barnold", "url": "/~barnold"}, 10 | {"date": "08/29/2024", "name": "crivic", "url": "/~crivic"}, 11 | {"date": "08/20/2024", "name": "speedygo55", "url": "/~speedygo55"}, 12 | {"date": "05/08/2024", "name": "whitcomb", "url": "/~whitcomb"}, 13 | {"date": "03/14/2024", "name": "alcor", "url": "/~alcor"}, 14 | {"date": "02/17/2024", "name": "dddaaannn", "url": "/~dddaaannn"}, 15 | {"date": "12/19/2023", "name": "passthejoe", "url": "/~passthejoe"}, 16 | {"date": "12/16/2023", "name": "lake", "url": "/~lake"}, 17 | {"date": "11/18/2023", "name": "serge", "url": "/~serge"}, 18 | {"date": "08/17/2023", "name": "amr", "url": "/~amr"}, 19 | {"date": "04/08/2023", "name": "corwin", "url": "/~corwin"}, 20 | {"date": "05/15/2022", "name": "hifikuno", "url": "/~hifikuno"}, 21 | {"date": "12/20/2022", "name": "rajiv", "url": "/~rajiv"}, 22 | {"date": "09/27/2022", "name": "tubbo", "url": "/~tubbo"}, 23 | {"date": "09/08/2022", "name": "cyrus", "url": "/~cyrus"}, 24 | {"date": "08/17/2023", "name": "ranguli", "url": "/~ranguli"}, 25 | {"date": "06/08/2022", "name": "barnold", "url": "/~barnold"}, 26 | {"date": "05/12/2022", "name": "hifikuno", "url": "/~hifikuno"}, 27 | {"date": "04/27/2022", "name": "mhd", "url": "/~mhd"}, 28 | {"date": "02/29/2022", "name": "neildaemond", "url": "/~neildaemond"}, 29 | {"date": "02/15/2022", "name": "alex1138", "url": "/~alex1138"}, 30 | {"date": "02/15/2022", "name": "amr", "url": "/~amr"}, 31 | {"date": "01/27/2022", "name": "whitcomb", "url": "/~whitcomb"}, 32 | {"date": "12/15/2021", "name": "dctrud", "url": "/~dctrud"}, 33 | {"date": "10/10/2021", "name": "dmi3", "url": "/~dmi3"}, 34 | {"date": "03/08/2021", "name": "webwiz", "url": "/~webwiz"}, 35 | {"date": "02/13/2021", "name": "whitcomb", "url": "/~whitcomb"}, 36 | {"date": "11/30/2020", "name": "dethelor", "url": "/~dethelor"}, 37 | {"date": "11/26/2020", "name": "waffles", "url": "/~waffles"}, 38 | {"date": "11/20/2020", "name": "buttstuf", "url": "/~buttstuf"}, 39 | {"date": "09/03/2020", "name": "northernlights", "url": "/~northernlights"}, 40 | {"date": "08/16/2020", "name": "dctrud", "url": "/~dctrud"}, 41 | {"date": "07/21/2020", "name": "offdutypirate", "url": "/~offdutypirate"}, 42 | {"date": "07/15/2020", "name": "necrotechno", "url": "/~necrotechno"}, 43 | {"date": "07/10/2020", "name": "snowdusk", "url": "/~snowdusk"}, 44 | {"date": "05/31/2020", "name": "melyanna", "url": "/~melyanna"}, 45 | {"date": "05/15/2020", "name": "wgreenhouse", "url": "/~wgreenhouse"}, 46 | {"date": "04/21/2020", "name": "cano", "url": "/~cano"}, 47 | {"date": "11/09/2019", "name": "sneak", "url": "/~sneak"}, 48 | {"date": "10/05/2014", "name": "beau", "url": "/~beau"}, 49 | {"date": "10/05/2014", "name": "skk", "url": "/~skk"}, 50 | {"date": "10/05/2014", "name": "joeld", "url": "/~joeld"}, 51 | {"date": "10/05/2014", "name": "john", "url": "/~john"}, 52 | {"date": "10/05/2014", "name": "brendn", "url": "/~brendn"}, 53 | {"date": "10/05/2014", "name": "droob", "url": "/~droob"}, 54 | {"date": "10/05/2014", "name": "delfuego", "url": "/~delfuego"}, 55 | {"date": "10/05/2014", "name": "jonathan", "url": "/~jonathan"}, 56 | {"date": "10/05/2014", "name": "coldmode", "url": "/~coldmode"}, 57 | {"date": "10/05/2014", "name": "jemal", "url": "/~jemal"}, 58 | {"date": "10/05/2014", "name": "jonbell", "url": "/~jonbell"}, 59 | {"date": "10/05/2014", "name": "_", "url": "/~_"}, 60 | {"date": "10/05/2014", "name": "dvd", "url": "/~dvd"}, 61 | {"date": "10/05/2014", "name": "whitneymcn", "url": "/~whitneymcn"}, 62 | {"date": "10/05/2014", "name": "jimray", "url": "/~jimray"}, 63 | {"date": "10/05/2014", "name": "schussat", "url": "/~schussat"}, 64 | {"date": "10/05/2014", "name": "macdiva", "url": "/~macdiva"}, 65 | {"date": "10/03/2014", "name": "extraface", "url": "/~extraface"}, 66 | {"date": "10/03/2014", "name": "joshuag", "url": "/~joshuag"}, 67 | {"date": "10/03/2014", "name": "zarate", "url": "/~zarate"}, 68 | {"date": "10/03/2014", "name": "englishm", "url": "/~englishm"}, 69 | {"date": "10/03/2014", "name": "danbri", "url": "/~danbri"} 70 | ] 71 | -------------------------------------------------------------------------------- /tilde.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tildeclub/site/49081bb620726ba62e44a787f606388e6b61b3b6/tilde.ico -------------------------------------------------------------------------------- /tildeclub.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tildeclub/site/49081bb620726ba62e44a787f606388e6b61b3b6/tildeclub.png -------------------------------------------------------------------------------- /updateonline-users: -------------------------------------------------------------------------------- 1 | #!/usr/bin/php 2 | 18 | -------------------------------------------------------------------------------- /users/index.php: -------------------------------------------------------------------------------- 1 | 5 |

    Tilde.club user list

    6 |
    7 |
    8 |
    9 |

    Here is a full list of users (including those who haven't updated their page from the default)

    10 |

    Also see users who have updated their page in the last 24 hours

    11 |
    12 |
    13 | '.$user.''; 18 | } 19 | ?> 20 |
    21 |
    22 |
    23 |
    24 | 2 |
    3 | 4 |

    5 |
    6 |

    7 |
    8 |
    9 | Click for the [ 10 | Random page ] 11 |
    12 | Want to join the ring? Click here for 13 | info. 14 |
    15 | 16 | 17 | 18 | 19 | 20 |
    21 | 22 | -------------------------------------------------------------------------------- /wiki/.gitignore: -------------------------------------------------------------------------------- 1 | *.html 2 | *.txt 3 | -------------------------------------------------------------------------------- /wiki/Makefile: -------------------------------------------------------------------------------- 1 | SRC_MD_FILES != find source -name '*.md' 2 | DST_HTML_FILES := $(SRC_MD_FILES:source/%.md=%.html) 3 | DST_TXT_FILES := $(SRC_MD_FILES:source/%.md=%.txt) 4 | PANDOC != command -v pandoc 2> /dev/null 5 | PHP != command -v php 2> /dev/null 6 | 7 | all: dep-pandoc $(DST_HTML_FILES) $(DST_TXT_FILES) index 8 | 9 | index: dep-php index.html 10 | %.html: %.php 11 | php $< > $@ 12 | 13 | %.html: source/%.md wiki.tmpl custom.theme 14 | $(info building $@) 15 | @$(PANDOC) \ 16 | --from markdown+backtick_code_blocks \ 17 | --include-before-body=../nav.html \ 18 | --template wiki.tmpl \ 19 | --lua-filter header-permalinks.lua \ 20 | --highlight-style=custom.theme \ 21 | --title-prefix "tilde.club wiki" \ 22 | --variable toc-title:"table of contents" \ 23 | --standalone \ 24 | --table-of-contents \ 25 | --output $@ \ 26 | $< 27 | 28 | %.txt: source/%.md link_footnote.lua 29 | $(info building $@) 30 | @$(PANDOC) \ 31 | --from markdown+backtick_code_blocks \ 32 | --to plain \ 33 | --lua-filter ./link_footnote.lua \ 34 | --standalone \ 35 | --output $@ \ 36 | $< 37 | 38 | clean: 39 | $(info removing generated files) 40 | -rm *.html *.txt 41 | 42 | dep-pandoc:: 43 | ifndef PANDOC 44 | $(error missing dependency 'pandoc'. please install and try again) 45 | endif 46 | 47 | dep-php:: 48 | ifndef PHP 49 | $(error missing dependency 'php'. please install and try again) 50 | endif 51 | 52 | .PHONY: clean dep-pandoc 53 | 54 | -------------------------------------------------------------------------------- /wiki/README.md: -------------------------------------------------------------------------------- 1 | # tilde.club wiki 2 | 3 | to write an article, make a markdown file in source/ and fill out the 4 | appropriate metadata keys. only title and author are required. 5 | 6 | to build the wiki pages, just run `make`. the resulting html files will 7 | not be tracked in this repo. 8 | 9 | open a PR with your changes! feel free to send a patch with 10 | [git-send-email(1)](https://git-send-email.io) to root@tilde.club if you prefer 11 | that workflow. 12 | 13 | -------------------------------------------------------------------------------- /wiki/custom.theme: -------------------------------------------------------------------------------- 1 | { 2 | "text-color": "#cfcfc2", 3 | "background-color": null, 4 | "line-number-color": "#7a7c7d", 5 | "line-number-background-color": "#232629", 6 | "text-styles": { 7 | "Other": { 8 | "text-color": "#27ae60", 9 | "background-color": null, 10 | "bold": false, 11 | "italic": false, 12 | "underline": false 13 | }, 14 | "Attribute": { 15 | "text-color": "#2980b9", 16 | "background-color": null, 17 | "bold": false, 18 | "italic": false, 19 | "underline": false 20 | }, 21 | "SpecialString": { 22 | "text-color": "#da4453", 23 | "background-color": null, 24 | "bold": false, 25 | "italic": false, 26 | "underline": false 27 | }, 28 | "Annotation": { 29 | "text-color": "#3f8058", 30 | "background-color": null, 31 | "bold": false, 32 | "italic": false, 33 | "underline": false 34 | }, 35 | "RegionMarker": { 36 | "text-color": "#2980b9", 37 | "background-color": "#153042", 38 | "bold": false, 39 | "italic": false, 40 | "underline": false 41 | }, 42 | "Function": { 43 | "text-color": "#8e44ad", 44 | "background-color": null, 45 | "bold": false, 46 | "italic": false, 47 | "underline": false 48 | }, 49 | "String": { 50 | "text-color": "#f44f4f", 51 | "background-color": null, 52 | "bold": false, 53 | "italic": false, 54 | "underline": false 55 | }, 56 | "ControlFlow": { 57 | "text-color": "#fdbc4b", 58 | "background-color": null, 59 | "bold": true, 60 | "italic": false, 61 | "underline": false 62 | }, 63 | "Operator": { 64 | "text-color": "#cfcfc2", 65 | "background-color": null, 66 | "bold": false, 67 | "italic": false, 68 | "underline": false 69 | }, 70 | "Error": { 71 | "text-color": "#da4453", 72 | "background-color": null, 73 | "bold": false, 74 | "italic": false, 75 | "underline": true 76 | }, 77 | "Normal": { 78 | "text-color": "#cfcfc2", 79 | "background-color": null, 80 | "bold": false, 81 | "italic": false, 82 | "underline": false 83 | }, 84 | "BaseN": { 85 | "text-color": "#f67400", 86 | "background-color": null, 87 | "bold": false, 88 | "italic": false, 89 | "underline": false 90 | }, 91 | "Alert": { 92 | "text-color": "#95da4c", 93 | "background-color": "#4d1f24", 94 | "bold": true, 95 | "italic": false, 96 | "underline": false 97 | }, 98 | "Variable": { 99 | "text-color": "#27aeae", 100 | "background-color": null, 101 | "bold": false, 102 | "italic": false, 103 | "underline": false 104 | }, 105 | "BuiltIn": { 106 | "text-color": "#7f8c8d", 107 | "background-color": null, 108 | "bold": false, 109 | "italic": false, 110 | "underline": false 111 | }, 112 | "Extension": { 113 | "text-color": "#0099ff", 114 | "background-color": null, 115 | "bold": true, 116 | "italic": false, 117 | "underline": false 118 | }, 119 | "Preprocessor": { 120 | "text-color": "#27ae60", 121 | "background-color": null, 122 | "bold": false, 123 | "italic": false, 124 | "underline": false 125 | }, 126 | "Information": { 127 | "text-color": "#c45b00", 128 | "background-color": null, 129 | "bold": false, 130 | "italic": false, 131 | "underline": false 132 | }, 133 | "VerbatimString": { 134 | "text-color": "#da4453", 135 | "background-color": null, 136 | "bold": false, 137 | "italic": false, 138 | "underline": false 139 | }, 140 | "Warning": { 141 | "text-color": "#da4453", 142 | "background-color": null, 143 | "bold": false, 144 | "italic": false, 145 | "underline": false 146 | }, 147 | "Documentation": { 148 | "text-color": "#a43340", 149 | "background-color": null, 150 | "bold": false, 151 | "italic": false, 152 | "underline": false 153 | }, 154 | "Import": { 155 | "text-color": "#27ae60", 156 | "background-color": null, 157 | "bold": false, 158 | "italic": false, 159 | "underline": false 160 | }, 161 | "Char": { 162 | "text-color": "#3daee9", 163 | "background-color": null, 164 | "bold": false, 165 | "italic": false, 166 | "underline": false 167 | }, 168 | "DataType": { 169 | "text-color": "#2980b9", 170 | "background-color": null, 171 | "bold": false, 172 | "italic": false, 173 | "underline": false 174 | }, 175 | "Float": { 176 | "text-color": "#f67400", 177 | "background-color": null, 178 | "bold": false, 179 | "italic": false, 180 | "underline": false 181 | }, 182 | "Comment": { 183 | "text-color": "#7a7c7d", 184 | "background-color": null, 185 | "bold": false, 186 | "italic": false, 187 | "underline": false 188 | }, 189 | "CommentVar": { 190 | "text-color": "#7f8c8d", 191 | "background-color": null, 192 | "bold": false, 193 | "italic": false, 194 | "underline": false 195 | }, 196 | "Constant": { 197 | "text-color": "#27aeae", 198 | "background-color": null, 199 | "bold": true, 200 | "italic": false, 201 | "underline": false 202 | }, 203 | "SpecialChar": { 204 | "text-color": "#3daee9", 205 | "background-color": null, 206 | "bold": false, 207 | "italic": false, 208 | "underline": false 209 | }, 210 | "DecVal": { 211 | "text-color": "#f67400", 212 | "background-color": null, 213 | "bold": false, 214 | "italic": false, 215 | "underline": false 216 | }, 217 | "Keyword": { 218 | "text-color": "#cfcfc2", 219 | "background-color": null, 220 | "bold": true, 221 | "italic": false, 222 | "underline": false 223 | } 224 | } 225 | } 226 | -------------------------------------------------------------------------------- /wiki/gophermap: -------------------------------------------------------------------------------- 1 | !tilde.club wiki 2 | 3 | welcome to the gopher portal of the tilde.club wiki 4 | 5 | it's also available on the web at https://tilde.club/wiki/ 6 | 7 | here are the articles: 8 | 9 | =./txtlist.sh 10 | 11 | 1back to tilde.club / 12 | -------------------------------------------------------------------------------- /wiki/header-permalinks.lua: -------------------------------------------------------------------------------- 1 | function Header(elem) 2 | table.insert(elem.content, pandoc.Space()) 3 | table.insert(elem.content, pandoc.Link("§", "#" .. elem.identifier)) 4 | return elem 5 | end 6 | 7 | -------------------------------------------------------------------------------- /wiki/index.php: -------------------------------------------------------------------------------- 1 | 5 |

    the tilde.club wiki

    6 |
    7 |
    8 |
    9 |

    Here's the articles on our wiki:

    10 |
      11 | '.ucwords($category).''; 36 | echo '
        '; 37 | 38 | $article_titles = []; 39 | $article_names = []; 40 | 41 | foreach ($category_to_articles[$category] as $article) 42 | { 43 | array_push($article_names, $article[0]); 44 | array_push($article_titles, $article[1]); 45 | } 46 | 47 | $name_to_title = array_combine($article_names, $article_titles); 48 | asort($name_to_title); 49 | 50 | foreach ($name_to_title as $name => $title) 51 | echo '
      • '.$title.'
      • '; 52 | 53 | echo '

      '; 54 | 55 | } 56 | ?> 57 |
    58 |
    59 |
    60 | /git/ 12 | ``` 13 | 14 | Below is the quick‑start plus a few tips. 15 | 16 | --- 17 | 18 | ## 1  Create the **public\_git** directory (once) 19 | 20 | ```bash 21 | $ mkdir -p ~/public_git 22 | ``` 23 | 24 | The web server is already allowed to traverse `~/public_git`, so you do **not** have to chmod anything manually. 25 | 26 | --- 27 | 28 | ## 2  Add a repository 29 | 30 | Only **bare** repos are accepted (they have no working tree inside them). 31 | 32 | ```bash 33 | # create a brand‑new bare repository 34 | $ cd ~/public_git 35 | $ git init --bare hello.git 36 | ``` 37 | 38 | or push an existing project: 39 | 40 | ```bash 41 | $ cd ~/my/project 42 | # add tilde as a remote and mirror‑push everything 43 | $ git remote add tilde ssh://@tilde.club/~/public_git/project.git 44 | $ git push --mirror tilde 45 | ``` 46 | 47 | You can repeat for as many repos as you like; just keep each one directly in 48 | `~/public_git/` and make sure the name ends with `.git`. 49 | 50 | --- 51 | 52 | ## 3  Browse your repos 53 | 54 | ``` 55 | Index page : https://tilde.club/~/git/ 56 | Single repo : https://tilde.club/~/git/.git/ 57 | ``` 58 | 59 | Example for user **deepend**: 60 | 61 | ``` 62 | https://tilde.club/~deepend/git/ # lists everything 63 | https://tilde.club/~deepend/git/hello.git/ # specific repo 64 | ``` 65 | 66 | The header will say `~deepend Git Repositories`, commits are clickable, diffs 67 | are highlighted, and the cloning URL is shown near the top right. 68 | 69 | --- 70 | 71 | ## 4  Update a repository 72 | 73 | Because the repo is bare you **push** into it; cgit shows the new state 74 | immediately. 75 | 76 | ```bash 77 | $ git push tilde main # normal 78 | $ git push --mirror tilde # full mirror (branches + tags) 79 | ``` 80 | 81 | --- 82 | 83 | ## 5  Remove a repository 84 | 85 | Simply delete or rename the directory: 86 | 87 | ```bash 88 | $ rm -rf ~/public_git/oldstuff.git 89 | ``` 90 | 91 | The entry disappears from the index on the next page load. 92 | 93 | --- 94 | 95 | ## FAQ 96 | 97 | ### Can I hide a repo from the list? 98 | 99 | Move it somewhere else in your home directory or make it non‑bare. 100 | `cgit` only scans `~/public_git/*.git`. 101 | 102 | ### Why bare repos only? 103 | 104 | Internal `.git/` directories inside non‑bare repos confuse cgit’s scanner and 105 | produce broken links like `/repo.git/.git/`. 106 | Bare repos avoid that and are the normal way to publish Git over HTTP. 107 | 108 | ### Clone / pull URL? 109 | 110 | Use SSH for write access: 111 | 112 | ``` 113 | ssh://@tilde.club/~/public_git/.git 114 | ``` 115 | 116 | or plain HTTPS for read‑only: 117 | 118 | ``` 119 | https://tilde.club/~/git/.git 120 | ``` 121 | 122 | --- 123 | 124 | Happy hacking, and show off your code! 125 | Questions? `#club` on irc.newnet.net or mail **[root@tilde.club](mailto:root@tilde.club)**. 126 | -------------------------------------------------------------------------------- /wiki/source/code-of-conduct.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: code of conduct 3 | author: benharri 4 | category: tilde.club 5 | --- 6 | 7 | > **tl;dr** learn by doing and helping. be excellent to each other. have fun! 8 | 9 | 10 | ## 1. purpose 11 | 12 | a primary goal of tilde.club is to be inclusive to the largest number of 13 | contributors, with the most varied and diverse backgrounds possible. as such, 14 | we are committed to providing a friendly, safe and welcoming environment 15 | for all. 16 | 17 | this code of conduct outlines our expectations for all those who participate 18 | in our community, as well as the consequences for unacceptable behavior. 19 | 20 | we invite all those who participate in tilde.club to help us create safe 21 | and positive experiences for everyone. 22 | 23 | 24 | ## 2. tilde.club mission 25 | 26 | **tilde.club exists to foster an engaged community for socializing, learning, 27 | and making cool stuff** 28 | 29 | in a mass-media age, it is up to small, intentional communities to gather 30 | and work together to provide a space outside of the advertising-laden, 31 | profit-seeking, corporate-owned world of social media. 32 | 33 | to that end, tilde.club strives to be a radically inclusive community where 34 | people of all backgrounds and all technological experience levels can come 35 | together to learn, to teach, and to delight in one another's creations. 36 | 37 | 38 | ## 3. expected behavior 39 | 40 | the following behaviors are expected and requested of all community members: 41 | 42 | * participate in an authentic and active way. in doing so, you contribute 43 | to the health and longevity of this community. 44 | * exercise consideration and 45 | respect in your speech and actions. 46 | * attempt collaboration before conflict. 47 | * refrain from demeaning, discriminatory, or harassing behavior and speech. 48 | * be mindful of your surroundings and of your fellow participants. 49 | * teach when people need help. don't do it for them. 50 | 51 | 52 | ## 4. unacceptable behavior 53 | 54 | the following behaviors are considered harassment and are unacceptable within 55 | our community: 56 | 57 | * violence, threats of violence or violent language directed against another 58 | person. 59 | * sexist, racist, homophobic, transphobic, ableist or otherwise 60 | discriminatory jokes and language. 61 | * posting or displaying sexually explicit or violent material. 62 | * posting or threatening to post other people's personally identifying 63 | information ("doxing"). 64 | * personal insults, particularly those related to gender, sexual orientation, 65 | race, religion, or disability. 66 | * unwelcome sexual attention. this includes sexualized comments or jokes. 67 | * deliberate intimidation, stalking or following. 68 | 69 | 70 | ## 5. consequences of unacceptable behavior 71 | 72 | unacceptable behavior from any community member, including sponsors and 73 | those with decision-making authority (sudo), will not be tolerated. 74 | 75 | anyone asked to stop unacceptable behavior is expected to comply immediately. 76 | 77 | if a community member engages in unacceptable behavior, the community 78 | organizers may take any action they deem appropriate, up to and including 79 | a temporary ban or permanent expulsion from tilde.club without warning 80 | (meaning your account will be terminated and all user data deleted). 81 | 82 | 83 | ## 6. reporting guidelines 84 | 85 | if you are subject to or witness unacceptable behavior, or have any other 86 | concerns, please contact an admin (see info below). 87 | 88 | additionally, help engaging with law enforcement is available. 89 | 90 | 91 | ## 7. addressing grievances 92 | 93 | if you feel you have been falsely or unfairly accused of violating this 94 | code of conduct, use the contact info below to send a concise description 95 | of your grievance. 96 | 97 | 98 | ## 8. scope 99 | 100 | we expect all tilde.club members to abide by this code of conduct while: 101 | 102 | * engaging with other members 103 | * publishing content on tilde.club 104 | 105 | 106 | ## 9. contact info 107 | 108 | tilde.club admins: 109 | 110 | you can also send a mail to [root@tilde.club](mailto:root@tilde.club) to 111 | make sure we all get it. 112 | 113 | * [benharri](https://tilde.club/~benharri/): 114 | - [benharri@tilde.club](mailto:benharri@tilde.club) 115 | - on irc `/query 116 | ben hello` 117 | * [deepend](https://tilde.club/~deepend/): 118 | - [deepend@tilde.club](mailto:deepend@tilde.club) 119 | - on irc `/query deepend hello` 120 | 121 | 122 | ## 10. license and attribution 123 | 124 | this code of conduct is based on 125 | [citizencodeofconduct.org](http://citizencodeofconduct.org/) 126 | and [tilde.town coc](http://tilde.town/wiki/conduct.html) 127 | under the terms of the [creative commons attribution-sharealike 128 | license](http://creativecommons.org/licenses/by-sa/3.0/). 129 | 130 | -------------------------------------------------------------------------------- /wiki/source/dcss.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: dcss (dungeon crawl stone soup) 3 | author: audiodude 4 | category: software 5 | --- 6 | connect to [crawl.tildeverse.org](https://crawl.tildeverse.org) to play dungeon 7 | crawl stone soup, a roguelike game with leaderboards and the ability to 8 | spectate other players. Also available with full images on the web! -------------------------------------------------------------------------------- /wiki/source/donate.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: donate to tilde.club 3 | author: deepend 4 | category: tilde.club 5 | --- 6 | 7 | ***NOTICE: Tilde Club is not a registered legal entity or charity, so any donations made cannot be claimed as tax-deductible contributions. *** 8 | 9 | If you like what tilde.club does and would like to contribute to the costs of running such a service, feel free to make a donation. If you can, we appreciate it, if you can't, we also appreciate you being here. 10 | 11 | ## Methods you can donate to tilde.club. 12 | 13 | There are currently two (2) methods you can donate financially to tilde.club. (All money is used towards paying hosting costs (domains, servers) 14 | 15 | [Liberapay](https://liberapay.com/tilde.club/donate) 16 | 17 | 18 | [Paypal](https://www.paypal.com/donate?hosted_button_id=DWHSADKJ26HZ8) Direct contribution. 19 | 20 | [Vultr](https://www.vultr.com/?ref=9732299-9J) Signing up to Vultr using this link gives you $300 credit and it benefits tilde.club ($300 Credit is Limited Time). 21 | 22 | [DigitalOcean](https://www.digitalocean.com/?refcode=be3f8510bfe9&utm_campaign=Referral_Invite&utm_medium=Referral_Program&utm_source=badge) Signing up gets your $200 Credit and helps tilde.club. 23 | 24 | [Web Hosting Canada](https://clients.whc.ca/aff.php?aff=7560) Buying any service/domain helps tilde.club. 25 | 26 | [Voip.ms](https://voip.ms/en/invite/MTEyMDM5) Buying Voip Services gives me credit so I will be able to offer more tilde.tel features in the future. 27 | 28 | **NOTE: Please E-Mail root@tilde.club to notify that you have donated so we can add you to the gold star supporters list. 29 | 30 | ## Be Involved! 31 | 32 | Best thing to do is be involved in the community. 33 | Eg. Create a PR on tilde.club's github, Chat on IRC, create awesome webpages, 34 | develop software using the many tools available to you on tilde.club. 35 | 36 | Tilde.club does cost money to run, however it all makes it worth it if the community is active and enjoying what we offer. 37 | 38 | ask on irc if you have questions! 39 | -------------------------------------------------------------------------------- /wiki/source/edit_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Editing your index.html file 3 | author: vielmetti 4 | category: tutorials 5 | --- 6 | 7 | Type: `nano` index.html to open your index.html file and begin editing 8 | 9 | ![screenshot of the nano editor](https://tilde.club/~annika/static/nano.png) 10 | 11 | Edit your file, willy nilly 12 | 13 | When done editing, use `CTRL+X` to close the file 14 | 15 | You'll be asked if you want to save; say y and [return] to return to the command line 16 | 17 | Refresh your tilde page in your browser to see your new website 18 | 19 | Note: If at any time you feel you made a mistake in editing, you can exit and n to not save. 20 | 21 | There's more info here about the nano editor; if you're familiar with 22 | emacs or vim they are here too. 23 | 24 | -------------------------------------------------------------------------------- /wiki/source/emacs.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Editing with Emacs 3 | author: 4 | - ohnoitsnoah 5 | - xwindows 6 | - keyboardan 7 | category: tutorials 8 | --- 9 | 10 | 11 | Emacs in tilde.club 12 | =================== 13 | 14 | [Emacs](https://www.gnu.org/software/emacs/) is a text-editor that is very capable, but also can be confusing to new users, so here's a basic guide to working with Emacs. 15 | 16 | Opening Emacs 17 | ------------- 18 | 19 | You can open Emacs by typing `emacs` in the shell. This then opens Emacs :D. 20 | 21 | Basic Elements of the Screen/Terminology 22 | ---------------------------------------- 23 | 24 | ![Emacs running in a text-console](https://upload.wikimedia.org/wikipedia/commons/thumb/3/36/Emacs-linux-console.png/440px-Emacs-linux-console.png) 25 | 26 | When first starting Emacs, there are a few elements of the screen that you should know: 27 | 28 | ### Buffer 29 | 30 | A "Buffer" is basically a container that holds the contents of whatever file you're editing. 31 | 32 | > "Buffers in Emacs editing are objects that have distinct names and hold text that can be edited." 33 | > 34 | > -[GNU Emacs 28.2 Manual](https://www.gnu.org/software/emacs/manual/html_node/emacs/index.html) 35 | 36 | ### Window 37 | 38 | Unlike what Microsoft Windows and other common-place OS' consider "windows", a window in Emacs is more like a window "pane", as where a buffer contains content, a *window* contains a buffer. 39 | 40 | > "In Emacs terminology, a "window" is a container in which a buffer is displayed. This may be confusing at first; if so, think "pane" whenever you see "window" in an Emacs context until you get used to it." 41 | > 42 | > -[WikEmacs](https://wikemacs.org/wiki/Emacs_Terminology) 43 | 44 | ### Modeline 45 | 46 | The Modeline is the strip of details towards the bottom of an instance in Emacs. This shows the file/buffer name, file type, any active modes/extensions, line and column numbers, and more. 47 | 48 | ### Mini-Buffer 49 | 50 | The Mini-Buffer is the small area under the Modeline. It acts as a prompt, telling you when you've hit the beginning/ending of a buffer, allowing/alerting you to type/confirm commands, and more. 51 | 52 | ### Menu Bar 53 | 54 | The Menu Bar is the series of drop-down menus at the top of an Emacs instance. It gives all the available commands in the current buffer, and shows their corresponding key-bindings. 55 | 56 | Emacs Command Key 57 | ----------------- 58 | 59 | 60 | 61 | Emacs has some weird, complex commands, that may not make sense to new users. While this tutorial will mostly be based around using the drop-down menus, it's still good to know how to read command's key-bindings, as using them is the more effective/productive route. 62 | 63 | * `C-` means the Control/Ctrl key 64 | * `M-` means the Meta key 65 | * While not common on modern hardware, the Meta key can be typed by using either the Escape/ESC key, or the Alt key in some cases 66 | 67 | Key-bindings in Emacs are typically longer than normal key-bindings used outside of Emacs, usually being a combination of what would be two "normal" key-bindings. For example; to exit Emacs, you can type `C-x C-c`. That means you press both of these key-bindings in series to complete the Emacs key-binding of exiting Emacs. It's somewhat weird, but is easy to adjust to after using it for a while. 68 | 69 | Interactive Learning 70 | -------------------- 71 | 72 | The best way to begin learning, is the interactive way. GNU Emacs has a built-in command that is specifically to learning the basic of GNU Emacs. To access it, you can press `C-h t`, or execute the GNU Emacs command named `help-with-tutorial` (pressing `M-x help-with-tutorial`). 73 | 74 | To close the tutorial, use `C-x k` to kill the buffer. 75 | 76 | Navigating Emacs with the Drop-Down Menus 77 | ----------------------------------------- 78 | 79 | 80 | 81 | The way you accsess the drop-downs are by pressing the `F10` key, then using the arrow keys to navigate through the menus. You can press the `F10` key again to exit the menus, or the global "quit" command, `C-g`. As easy as these menus are, I reccommend slowly learning the key-bindings, as they make it faster and easier to navigate through Emacs as a whole. On that note, *I will be putting each commands corresponding key-binding next to their respective section title.* 82 | 83 | ### Switching Buffers (C-x b) 84 | 85 | When you start Emacs using `emacs` in the shell, you'll be greeted with a welcome screen, along with two other buffers titled `*scratch*` and `Messages`. 86 | You can switch between these buffers by going to the Buffers drop-down and selecting which buffer to go to. 87 | 88 | ### Visting a New File (C-x C-f) 89 | 90 | To visit a new or existing file, simply go to the File menu and select "Visit New File". You may also select "Open file...", however this does the same thing as "Visit New File", just without the ability to create a new file. 91 | 92 | ### Save and Save As (C-x C-s, C-x C-w) 93 | 94 | To save the current buffer, select "Save" from the File menu. If you need to save the buffer as something else, you can select "Save As", which is also in the File menu. 95 | 96 | ### Killing a Buffer (C-x k) 97 | 98 | Whenever you are finished working on a file, and no longer need the buffer, you can kill the current buffer by selecting "Close" from the File menu. 99 | 100 | ### Cut, Copy, Paste (C-w, M-w, C-y) 101 | 102 | Cut, Copy, and Paste are all available in the Edit menu. 103 | 104 | Emacs is Self-Documented 105 | ------------------------ 106 | 107 | GNU Emacs is a very big program, and to master it, it takes a lot of time. GNU Emacs is an LISP environment, where you can *grow* a lot. Which makes learning GNU Emacs, a great investment of time; because you can do basically everything, related to text, and, with time, you will master GNU Emacs flexibility. Which means you will be able to do anything with GNU Emacs. 108 | 109 | But you don't need to know everything that GNU Emacs has to offer (is there anyone that does know?).... The most important thing to know, is how to seek for help. And GNU Emacs is there to help you. 110 | 111 | To access the main help menu of GNU Emacs, you press `C-h C-h`. This will open a new buffer, where you can interact. In this buffer, there is, for example, " b Show all keybindings" entry. This means that if you now press "b" it will show all the keybindings of the buffer. 112 | 113 | And, if you are in any other buffer, and want to know all the keybindings quickly, you may, instead, press `C-h b` (mind that this "b", after the `C-h`, has the same effect as pressing "b" in the main menu help). `C-h` in GNU Emacs, means exactly, I want help. Then follow it with a keystroke that say the type of help you want. 114 | 115 | ### Common Help Keybindings 116 | 117 | #### C-h t (help-with-tutorial) 118 | 119 | Select the Emacs learn-by-doing tutorial. 120 | 121 | #### C-h k (describe-key) 122 | 123 | Display documentation of the function invoked by a key sequence. 124 | 125 | #### C-h f (describe-function) 126 | 127 | Display the full documentation of function. 128 | 129 | #### C-h v (describe-variable) 130 | 131 | Display the full documentation of variable. 132 | 133 | #### C-h a (apropos-command) 134 | 135 | Show commands that match a certain pattern. 136 | 137 | #### C-h m (describe-mode) 138 | 139 | Display documentation of current major mode and minor modes. 140 | 141 | #### C-h i (info) 142 | 143 | Enter Info, the documentation browser. It shows a complete documentation of your installed operating system's commands. 144 | -------------------------------------------------------------------------------- /wiki/source/email.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: email 3 | author: 4 | - benharri 5 | - xwindows 6 | category: tutorials 7 | --- 8 | 9 | Your shiny, new tilde.club account comes with an email account. `alpine` is a command-line email application to use it, as is `mutt`. [Good old-fashioned `mail` works too](#using-traditional-unix-mail-program), once configured properly; although it's a little cryptic. 10 | 11 | `alpine` is menu driven, and the menus are self-explanatory; it's surprisingly easy to learn, and surprisingly powerful when you want to customize it. 12 | 13 | From the command line (after logged in via SSH), type: `pine` and `[return]` 14 | Follow instructions and use the menus at the bottom and top. (Note: When you see the ^ in front of the letter it means you need to use CTRL, otherwise just use the letter.) 15 | 16 | ## non-cli options 17 | 18 | alternatively, you can use the [webmail](https://webmail.tilde.club/) or standard imap/smtp. 19 | 20 | some clients will automatically detect the right settings (tested with thunderbird). 21 | 22 | connection settings: 23 | 24 | - imap.tilde.club port 993 with ssl 25 | - pop3.tilde.club port 995 with ssl 26 | - smtp.tilde.club port 587 with starttls 27 | 28 | please remember to use only your tilde username as the login name, excluding the `@tilde.club`; for example `invalid` instead of `invalid@tilde.club` 29 | 30 | if you'd like your @tilde.club mail forwarded elsewhere, you can put an email 31 | address in a file called `~/.forward` 32 | 33 | ## sieve filtering 34 | 35 | our dovecot configuration supports [sieve](http://sieve.info/) and 36 | [managesieve](https://wiki1.dovecot.org/ManageSieve). 37 | 38 | this means that you should put your scripts in a `~/sieve/` directory, 39 | symlink the active script to `~/.dovecot.sieve`, and make sure to compile it 40 | with `sievec ~/.dovecot.sieve`. 41 | 42 | you can find some example sieve scripts [here]( 43 | https://doc.dovecot.org/configuration_manual/sieve/examples/). 44 | 45 | alternately, you can use webmail's [filter settings]( 46 | https://webmail.tilde.club/#/settings/filters) to configure your filters. 47 | 48 | ## mailing list 49 | 50 | we now have an official mailing list! 51 | 52 | if your account is old (pre sept 2019), you should be subscribed with the email 53 | you originally signed up with. if your account is newer (post sept 2019), then 54 | you should be subscribed with your @tilde.club address. if you don't fit either 55 | of those categories, you can subscribe by visiting the [web portal]( 56 | https://lists.tildeverse.org/postorius/lists/tildeclub.lists.tildeverse.org/) 57 | or by sending a mail to tildeclub-subscribe@lists.tildeverse.org with "subscribe" 58 | in the subject line. in either case, you can change the email you're subscribed 59 | with on the web portal or by unsubscribing and re-subscribing from the other 60 | address. 61 | 62 | list archives are available [on the web here]( 63 | https://lists.tildeverse.org/hyperkitty/list/tildeclub@lists.tildeverse.org/). 64 | 65 | as of september 17, 2019, we're still seeing quite a few pending mails to 66 | gmail, yahoo, and fastmail. help get our list delivered by making sure to 67 | mark list messages as not spam and adding the list address to your contacts. 68 | if you're feeling especially motivated, please reach out to the support on 69 | your mail provider and ask them to look into why you're not receiving the 70 | messages. 71 | 72 | ## Login-Time New Mail Notification 73 | 74 | If you use an on-server email client to handle your Tilde.club inbox 75 | and have ever received any email there, 76 | you probably noticed that there was no incoming mail notification 77 | (You have new mail. or similar message) 78 | appearing at login time. 79 | This is due to the [mailbox format](#mailbox-format) used in Tilde.club 80 | not being the traditional centralized-folder MBOX; 81 | but fret not: 82 | if you wish to bring back this old-timey function, 83 | it can still be done by a one-line script. 84 | 85 | To add this notification, 86 | add the following one-line Bourne shell snippet 87 | to your _login script_: 88 | 89 | ls -U ~/.mail/new | grep -F -q "" && echo "You got mail." 90 | 91 | If you are using Bash (default) as your login shell, 92 | your _login script_ file would be `~/.bash_profile`; 93 | but if you are using Dash, 94 | your _login script_ would be the traditional `~/.profile`. 95 | (For other shells, 96 | check your manual) 97 | 98 | However, 99 | if you arranged for a terminal multiplexer to start automatically 100 | at the login time, 101 | you would not see the notification added this way. 102 | So in this case, 103 | you would rather want this notification 104 | to be shown at each start of your shell: 105 | instead of adding the snippet to your login script, 106 | you would have to add it to your shell's startup script: 107 | in case of Bash (default shell), 108 | your startup script would be `~/.bashrc`. 109 | (For other shells, 110 | check your manual) 111 | 112 | Note that this code snippet 113 | only checks your main inbox folder. 114 | So, 115 | if you have explicitly written some [Sieve](#sieve-filtering) 116 | or webmail filtering rules 117 | to deliver some of the incoming emails into specific folder 118 | other than the main inbox, 119 | those emails would not produce notification. 120 | (This can be a desirable outcome in most cases, 121 | where people write Sieve filter 122 | to redirect unsolicited emails into Junk folder) 123 | 124 | ## Using Traditional Unix Mail Program 125 | 126 | A traditional Unix `mail` program provided on Tilde.club 127 | is [Heirloom Mailx](https://heirloom.sourceforge.net/mailx.html). 128 | In its default configuration, 129 | it works for sending emails, 130 | but not receiving; 131 | due to the incoming [mailbox format](#mailbox-format) 132 | used in Tilde.club 133 | not being the old style system-wide centralized inbox folders 134 | used in the olden days, 135 | which the program expects by default. 136 | 137 | However, 138 | for anyone who are soughting for a traditional Unix mail experience, 139 | or is experimenting with Tilde.club using a real teleprinter; 140 | Heirloom Mailx could be configured 141 | to operate directly on your Tilde.club mailbox, 142 | with some quirks, 143 | by adding the following lines to your `~/.mailrc` 144 | or create it with the following lines if not already existing 145 | (substitute `USERNAME` part with your Tilde.club username): 146 | 147 | set MAIL=/home/USERNAME/.mail 148 | set folder=.mail 149 | set emptybox 150 | set newfolders=maildir 151 | set record=+.sent-mail 152 | 153 | Once you did so, 154 | running `mail` would now show the list your emails 155 | if you have any in your inbox. 156 | (Type `q` and press Enter to quit) 157 | 158 | Tips: 159 | 160 | - Set your `PAGER` and `EDITOR` environment variables properly; 161 | unless you really want to view your emails through `more` 162 | and/or compose your emails through `ed`. 163 | (Even if you are really using a teleprinter, 164 | it is still a good idea to set these explicitly however) 165 | - Type `?` and press Enter for in-program help. 166 | Also read a manual 167 | (`man mail` from the main system command line). 168 | - Heirloom Mailx does not understand the Maildir++ subfolder structure; 169 | so you will have to type the name of subdirectory 170 | as seen in the filesystem 171 | (including its dot prefix) 172 | when changing folder. 173 | For example, 174 | use command: 175 | 176 | folder +.sent-mail 177 | 178 | to view the emails you have sent. 179 | (See [mailbox format](#mailbox-format) 180 | below for the default folders available) 181 | - When changing to view mail folder other than inbox, 182 | you nearly always want to prefix it with `+`; 183 | which means the folder is a subdirectory of the main email folder. 184 | - When changing to view the main inbox folder, 185 | simply use `%` as folder name 186 | without any prefix. 187 | - Marking email as junk here 188 | does not do a thing you would normally expect 189 | from modern email clients 190 | or webmails; 191 | so don't do it. 192 | 193 | ## Mailbox Format 194 | 195 | Tilde.club uses [Dovecot](https://www.dovecot.org/) as a local mail delivery agent 196 | as well as an IMAP server. 197 | It is configured to deliver your emails 198 | into a `.mail/` subdirectory 199 | within your home directory on the server, 200 | structured in [Courier MTA's Maildir++ format](https://www.courier-mta.org/imap/README.maildirquota.html). 201 | 202 | Maildir++ format is essentially the same as Maildir mailbox format, 203 | but with a concept of subfolders added in: 204 | apart from the usual `cur/`, 205 | `new/`, 206 | and `tmp/` subdirectories for normal Maildir operations; 207 | there would now also be dot-subdirectories 208 | which are email subfolders. 209 | Each dot-subdirectory 210 | would contain usual Maildir subdirectories, 211 | but not any more dot-subdirectory inside it. 212 | 213 | In Tilde.club, 214 | the default layout of your Maildir++ folder hierarchy 215 | would be as the following: 216 | 217 | | Email Folder | Filesystem Directory | 218 | |:-------------|:----------------------| 219 | | _(Inbox)_ | `~/.mail/` | 220 | | _(Sent)_ | `~/.mail/.sent-mail/` | 221 | | Junk | `~/.mail/.Junk/` | 222 | | Drafts | `~/.mail/.Drafts/` | 223 | | Trash | `~/.mail/.Trash/` | 224 | 225 | So, 226 | if you would like to use command line tools 227 | to tinker with your mailbox, 228 | then more power to you. 229 | Also, 230 | note that email access via IMAP and webmail 231 | actually read/write emails directly onto these directories; 232 | so now you know where to grab a copy of all your emails data 233 | if you ever need a backup as well. 234 | -------------------------------------------------------------------------------- /wiki/source/error404.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: custom 404 error page 3 | author: deepend 4 | category: tutorials 5 | --- 6 | 7 | All users can now setup their own custom 404 error page. Just add a file named `404.html` in `~/public_html` 8 | 9 | An example of one user's custom 404: [~benharri](http://tilde.club/~benharri/not_here). 10 | 11 | 12 | -------------------------------------------------------------------------------- /wiki/source/faq.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: faq 3 | author: ford (updated by deepend) 4 | category: tilde.club 5 | --- 6 | 7 | _______________________________________ 8 | / WELCOME TO TILDE.CLUB A place for web \ 9 | \ pages / 10 | --------------------------------------- 11 | \ ^__^ 12 | \ (oo)\_______ 13 | (__)\ )\/\ 14 | ||----w | 15 | || || 16 | 17 | Looking to join? We can\'t wait to meet you! 18 | -------------------------------------------- 19 | 20 | Sign up on our main page [https://tilde.club/signup](https://tilde.club/signup)! 21 | 22 | [Several alternate sites have sprouted 23 | up](http://tilde.club/%7Epfhawkins/othertildes.html) 24 | 25 | How did this accidentally awesome thing get started? 26 | ---------------------------------------------------- 27 | 28 | [Paul wrote an explanation on 29 | Medium](https://medium.com/message/tilde-club-i-had-a-couple-drinks-and-woke-up-with-1-000-nerds-a8904f0a2ebf) 30 | and you can follow along with his thinking [on his tilde 31 | blog](http://tilde.club/~ford/). 32 | 33 | I\'m on Tilde, now what? 34 | ------------------------ 35 | 36 | Tilde has a great community culture and we\'re trying hard to keep it 37 | that way. We\'re working on some netiquette outlines for people who are 38 | new to all of this. In the meantime\... 39 | 40 | - DON\'T HACK THE GIBSON. 41 | - no drama. be respectful. have fun. we\'re all trying, and we\'re all 42 | in this together :) 43 | 44 | Got it, don\'t be a jerk. But how do I, like, do things? 45 | -------------------------------------------------------- 46 | 47 | Here are some good places to start 48 | 49 | - [the unofficial official tilde 50 | primer](http://tilde.club/~anthonydpaul/primer.html) 51 | - [some more quick 52 | tips](http://tilde.club/~pfhawkins/tipsntricks.html) 53 | - [how do I usenet in 54 | tilde.club](http://tilde.club/wiki/usenet-news.html)? 55 | - [help me understand \'screen\'](http://tilde.club/~jonathan/screen/) 56 | 57 | Who are all these folks and what are they up to? 58 | ------------------------------------------------ 59 | 60 | - [tell me some lore](http://tilde.club/~joeld/tildelore.html)? 61 | - [who is online right 62 | now](http://tilde.club/~whitneymcn/whoville.shtml)? 63 | - [who updated their websites 64 | recently](http://tilde.club/tilde.24h.php)? 65 | - [can you give me a blogroll](http://tilde.club/~_/)? 66 | 67 | Disk Quotas Now Enforced 68 | ------------------------ 69 | 70 | To help keep tilde.club running smoothly, we've introduced disk quotas. This helps make sure everyone gets their fair share of space and keeps the system in good shape. 71 | 72 | **Here's what you need to know:** 73 | 74 | - **Soft Limit:** 1 GB – You'll get a heads-up if you go over this, but you can still use more space up to the hard limit. 75 | - **Hard Limit:** 3 GB – This is the max. If you hit this limit, you'll need to clear some space before adding more files. 76 | - **Grace Period:** 1 week – If you exceed the soft limit, you have 7 days to get back under it before the hard limit kicks in. 77 | 78 | You can check your usage and see how much space you have left by running the `resources-used` script in your home directory. 79 | 80 | If you have any questions or run into any issues, just reach out. We're all in this together! 81 | 82 | My function keys don't work in byobu! (using Windows PuTTY) 83 | ------------------------------------------------------------------ 84 | 85 | **TL;DR** 86 | 87 | Change your Terminal->Keyboard->"The Function keys and keypad" setting to "XTerm R6". 88 | 89 | **Details** 90 | 91 | I am using PuTTY 0.73 Windows 11, and could not get byobu hotkeys to work. Instead of creating or changing windows with F2, F3, and F4, the byobu command line would display a ~ every time I hit a a function key. The solution was to change my PuTTY settings for "XTerm R6" emulation. Now the Function keys work great, including F8! Note there are other articles out there that suggest using "VT100+" instead of "XTerm R6". Althought VT100+ helped out F2, F3, and F4, it *did not help F8* and some of the higher keys--that is where "XTerm R6" solved the rest. 92 | 93 | **References** 94 | 95 | - [Function Key Fix at codeyarns.com](https://codeyarns.com/tech/2013-01-21-byobu-function-keys-do-not-work-in-putty.html) 96 | - [Byobu Keybindings Cheat Sheet at cheatography.com](https://cheatography.com/mikemikk/cheat-sheets/byobu-keybindings/)) 97 | 98 | Other links 99 | ----------- 100 | 101 | - [Github](https://github.com/tildeclub/tilde.club) 102 | - [Webring](http://tilde.club/~harper/link.html?action=join) 103 | - [TildeClub Badge](http://tilde.club/~zarate/badge.html) 104 | - [TildeRadio](https://tilderadio.org/) 105 | 106 | How do you pronounce \"tilde\"? 107 | ------------------------------- 108 | 109 | Tilde the word is pronounced TIL-duh. Tilde the community is pronounced 110 | TIL-dee. 111 | 112 | We can\'t wait to meet you. Seriously. 113 | 114 | __ .' '. 115 | _/__) . . . 116 | (8|)_}}- . . . 117 | `\__) '. . ' ' . . ' 118 | -------------------------------------------------------------------------------- /wiki/source/finding_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: finding your index.html 3 | category: tutorials 4 | --- 5 | 6 | There are some basic command line commands you'll want to Google and learn, but for this tutorial you only need a few: 7 | 8 | `ls` = list files and folders in current directory 9 | 10 | `cd` = change directories 11 | 12 | `vim`, `emacs`, `nano` = a text editor 13 | 14 | Type: `ls` to see where you are; you should see a directory called "public_html" 15 | 16 | Type: `cd public_html` to browse into that folder 17 | 18 | Type: `ls` to see where you are; you should see your index.html file 19 | -------------------------------------------------------------------------------- /wiki/source/git.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: how to use git 3 | category: tutorials 4 | --- 5 | 6 | `git` is a version control system. It's pretty confusing at first, but 7 | once you sort out what it can do and can't do, it starts to get better. 8 | 9 | This tutorial is pretty good: [http://git-scm.com/docs/gittutorial](http://git-scm.com/docs/gittutorial) 10 | 11 | The best way to learn `git` is to find someone who knows `git` really 12 | well and sort out issues with them. Ask on [IRC](chat.html) if you get 13 | stuck. (There should be a better buddy system for this, but until there 14 | is, we do what we can.) 15 | 16 | A good introduction to `git` is to create a repository for your 17 | `public_html` directory. This will allow you to back up your public web 18 | directory. 19 | 20 | First thing you will want to do is set up git. 21 | 22 | If you don't have a [GitHub](http://github.com) account, you will want 23 | one for this exercise. If you choose another Git host, you will need to 24 | work out some parts of this setup on your own. 25 | 26 | Once you have a git account, you will want to set up `git` for your 27 | tilde.club account. Use the email address that you used to create your 28 | GitHub account. You can register multiple accounts with GitHub if 29 | needed. 30 | 31 | git config --global user.name "Your Name Here" 32 | git config --global user.email youremail@example.org 33 | 34 | You will also want to create a `.gitignore` file. This file defines what 35 | things you want git to ignore, such as editor temporary files or 36 | directories you may not want to keep in `git` such as generated files or 37 | private files you upload to a public repository. The `.gitignore` file 38 | can be created in your home directory, but I like to create it in the 39 | project directory. 40 | 41 | Here is an example `.gitignore` file: 42 | 43 | # files being edited 44 | *~ 45 | *swp 46 | # Generated files 47 | tilde_graphs 48 | # Private files 49 | diary.txt 50 | 51 | Now go create a repository on GitHub. In our examples we are using 52 | mytildeweb as the repo name, but you can choose whatever name works for 53 | you. If you do change the repository name be sure to update the commands 54 | with the proper one. 55 | 56 | Now we should be ready to create and upload the repository. 57 | 58 | cd public_html/ 59 | # This will initialize public_html as a repository 60 | git init 61 | # Adds all files to the repo. "." means "the current directory" (public_html, in this case) 62 | # Note: you can also add files one at a time 63 | git add . 64 | # Commits files to local repo 65 | git commit -m "first commit of tildeweb" 66 | # Tells git where your remote repo is 67 | git remote add origin https://github.com//mytildeweb.git 68 | # Uploads to the remote repo 69 | git push -u origin master 70 | 71 | Your files should now be on GitHub. If you make a change and you want to 72 | update, do the following after making your edits: 73 | 74 | git add index.html 75 | git commit -m "updated blog" 76 | git push origin master 77 | -------------------------------------------------------------------------------- /wiki/source/gopher.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: gopher 3 | author: benharri 4 | category: tutorials 5 | --- 6 | 7 | tilde.club now serves gopher! we're using 8 | [gophernicus](https://github.com/gophernicus/gophernicus) as our 9 | gopherd. 10 | 11 | user pages are served from your `~/public_gopher` dirs and can be 12 | accessed at `gopher://tilde.club/1/~username`. note that the itemtype 13 | `1` is required. 14 | 15 | ## basic gophermap syntax 16 | 17 | files named `gophermap` are the gopher equivalent to index.html. each 18 | line in a gophermap consists of the following parts separated by literal 19 | tab characters: 20 | 21 | - item type 22 | - display name 23 | - selector 24 | - host 25 | - port 26 | 27 | for example: 28 | 29 | `1tildeclub/tilde.club70` 30 | 31 | basic item types include: 32 | 33 | - `0` - text file 34 | - `1` - directory 35 | - `7` - search query 36 | - `9` - binary file 37 | - `g` - gif image 38 | - `h` - html file 39 | - `i` - info text 40 | - `I` - generic image file (not a gif) 41 | 42 | gophernicus also supports the following special types: 43 | 44 | - `#` - comment 45 | - `!title` - only valid on the first line 46 | - `-file` - hide file from listings 47 | - `:ext=type` - change filetype 48 | - `~` - include a list of users with a valid `~/public_gopher` 49 | - `=mapfile` - include or execute a script or gophermap 50 | - `-` - stop processing gophermap and include file listing 51 | 52 | - `.` - stop processing gophermap (default) 53 | 54 | ## additional resources 55 | 56 | see [gophernicus' gophermap 57 | documentation](https://github.com/gophernicus/gophernicus/blob/master/README.gophermap) 58 | for more info on available item types and other special selectors. 59 | 60 | if you're completely new to gopher, check out the [gopher zone](https://gopher.zone)! 61 | -------------------------------------------------------------------------------- /wiki/source/help_system.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Tilde.club Help Desk Guide 3 | category: tilde.club 4 | author: deepend 5 | --- 6 | 7 | # Tilde.club Help Desk Guide 8 | 9 | Welcome! This Help Desk system provides a quick, self-serve way to: 10 | 11 | 1. **Request or redeem a new SSH key** for your tilde account. 12 | 2. **Reset your account password** (if you've forgotten it). 13 | 14 | Below you’ll find step-by-step instructions on how to use the help desk system when you **SSH** into the `help` user. 15 | 16 | --- 17 | 18 | ## Accessing the Help Desk 19 | 20 | 1. Open a terminal on your local machine. 21 | 2. **SSH** into the **help** account (adjust the hostname to your actual tilde server name): 22 | ```bash 23 | ssh help@tilde.club 24 | ``` 25 | 3. You’ll see a welcome message and a **main menu** with numbered options. 26 | 27 | --- 28 | 29 | ## Main Menu Overview 30 | 31 | After logging in, you’ll see three main options: 32 | 33 | 1. **SSH Key Help** 34 | 2. **Password Help** 35 | 3. **Exit** 36 | 37 | Select the option that applies by typing its corresponding number and pressing **Enter**. 38 | 39 | --- 40 | 41 | ## 1. SSH Key Help 42 | 43 | When you choose **SSH Key Help** at the main menu, you’ll see another menu: 44 | 45 | 1. **Request a new SSH key** 46 | 2. **Redeem a code** for a new SSH key 47 | 3. **Return** to the previous menu 48 | 49 | ### 1.1 Request a New SSH Key 50 | 51 | 1. Pick **“I want to request a new SSH key”** (option 1). 52 | 2. **Enter the email** you registered with your tilde account. The system does a simple check to ensure it’s valid. 53 | 3. If the email matches an existing account, you’ll receive a **“request code”** at that address. 54 | 4. After receiving that code, **log out** or press **Enter** to return to the main menu. 55 | 56 | ### 1.2 Redeem a New SSH Key 57 | 58 | 1. Back in the **SSH Key Help** menu, choose **“I have a code from my email and need to redeem it.”** 59 | 2. Paste in the **request code** you received. 60 | 3. The system confirms your username. 61 | 4. When prompted, **paste your new public SSH key** (the part that starts with `ssh-ed25519` or `ssh-rsa` or similar). 62 | 5. The system appends your key to your `~/.ssh/authorized_keys`. 63 | 6. You’ll see a success message, and you can then **log in** to your tilde with that new key. 64 | 65 | --- 66 | 67 | ## 2. Password Help 68 | 69 | At the main menu, choosing **Password Help** displays: 70 | 71 | 1. **Request a password reset code** 72 | 2. **Redeem a password reset code** 73 | 3. **Return** to the previous menu 74 | 75 | ### 2.1 Request a Password Reset Code 76 | 77 | 1. Choose **“Request a password reset code.”** 78 | 2. **Enter your email** address. 79 | 3. The system sends a **reset code** to your email if the account matches. 80 | 4. Exit or return to the menu once you have the code. 81 | 82 | ### 2.2 Redeem a Password Reset Code 83 | 84 | 1. Choose **“Redeem a password reset code.”** 85 | 2. **Paste in** the code from your email. 86 | 3. Enter a **new password** for your tilde account, then **confirm** it. 87 | 4. Upon success, the system updates your account’s password immediately. 88 | 89 | --- 90 | 91 | ## 3. Exiting the Help Desk 92 | 93 | Simply choose **“I’d like to leave this help desk”** (option 3 in the main menu) or press Ctrl+D (end of file) to disconnect. 94 | 95 | --- 96 | 97 | ## Tips & Troubleshooting 98 | 99 | - **Time Limit**: Each prompt has a 2-minute inactivity timer. If you wait too long, the help desk **exits** automatically. Just log in again to resume. 100 | - **Email Didn’t Arrive?** Check your spam folder. If you still don’t see it, contact root@tilde.club. 101 | - **Invalid Email**: If you mistype an email or use an unrecognized domain, you’ll see an error. Double-check your address. 102 | - **Incorrect Code**: If the code was typed incorrectly or expired, the system will refuse it. Request a new one if needed. 103 | 104 | --- 105 | -------------------------------------------------------------------------------- /wiki/source/irc.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Socializing and chat 3 | author: 4 | - emv 5 | - benharri 6 | - deepend 7 | category: tutorials 8 | --- 9 | 10 | ## irc 11 | 12 | Our main channel is on the [Newnet IRC Network](https://newnet.net). the official 13 | channel for ~club is `#club`. Stop by and say hello! 14 | 15 | run `chat` to open [weechat](https://weechat.org) auto-connected to our irc 16 | server. try launching [tmux](tmux.html), [byobu](https://superuser.com/a/423397) 17 | or [screen](screen.html) to keep your chat session running. 18 | 19 | other clients like irssi are available as well! just connect to irc.newnet.net on 20 | port 6697 TLS and `/join #club`. 21 | 22 | feel free to use Newnet's [webchat](https://web.newnet.net/?join=club) if 23 | you prefer. 24 | 25 | some channels might require you to register your nickname with NickServ to post in them (e.g. #meta). NickServ acts like a regular user, so you communicate with it through `/msg`. steps: 26 | 27 | 1. [optional] set nickname: `/nick YourNick` - not necessary with weechat, since it connects you under your tilde.club username 28 | 2. register: `/msg NickServ REGISTER YourPassword youremail@example.com` - you can use your tilde.club e-mail address for this 29 | 3. wait for registration email with confirmation code 30 | 4. confirm: `/msg NickServ CONFIRM someCode` 31 | 32 | after this, every time you reconnect to irc you will have to identify with nickserv again: `/msg NickServ IDENTIFY YourPassword`. 33 | 34 | weechat tip: NickServ replies and error messages appear in the first buffer `tilde weechat` (use Alt + up/down to switch). 35 | 36 | ## Weechat relays 37 | 38 | weechat introduced [unix socket relays]( 39 | https://weechat.org/files/doc/stable/weechat_user.en.html#relay_unix_socket) 40 | in version 2.5 which is a much easier way to offer per-user relay access. 41 | 42 | tilde.club/~username/weechat is configured to proxy to the default unix relay socket 43 | location (`~/.weechat/relay_socket`). to get started using it, follow these steps. 44 | 45 | 1. in weechat: 46 | * `/relay add unix.weechat %h/relay_socket` 47 | * `/set relay.network.password mysupersecretpassword` - don't use this password 48 | of course. note that you might already have this set. 49 | 50 | 2. at your shell: 51 | * `chmod o+rw ~/.weechat/relay_socket` - note that other members of the club group 52 | are not included in the granted permissions. this allows nginx to connect 53 | to your socket on your behalf. you will need to do this every time you start 54 | weechat as the socket doesn't exist until weechat starts up. 55 | 56 | 3. in your relay client: 57 | * [glowing-bear](https://glowingbear.tilde.club/): 58 | - relay hostname: tilde.club:443/~username/weechat 59 | - relay port: 443 60 | - your relay password 61 | 62 | * [weechat-android](https://github.com/ubergeek42/weechat-android) and [lith](https://github.com/lithapp/lith): 63 | - connection type: websocket (ssl) 64 | - websocket path: ~username/weechat 65 | - relay host: tilde.club 66 | - relay port: 443 67 | - your relay password 68 | 69 | - (if you get "Error: Could not connect using WebSocket", check to be sure 70 | ~/ and ~/.weechat have at least o+rx permissions so nginx can reach 71 | ~/.weechat/relay_socket) 72 | 73 | ## IRC Bouncer (ZNC) 74 | NOTE: Email deepend or message him on IRC if you require ZNC access. 75 | 76 | You can find a ZNC IRC Bouncer by going to: [https://services.tilde.club/znc](https://services.tilde.club/znc). 77 | Use your tilde.club username and password for login. 78 | To connect to your ZNC its at services.tilde.club Port: 6699(SSL) 79 | 80 | NOTE: long passwords fail to authenticate with the ZNC server. 81 | -------------------------------------------------------------------------------- /wiki/source/json.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: JSON 3 | category: software 4 | --- 5 | 6 | JSON is the "Javascript Object Notation", basically a file format for 7 | data that's suitable for easy processing by most modern web-based tools. 8 | 9 | Several tilde.club programs expose APIs essentially by spitting out 10 | JSON as their output, including e.g. the list of recently updated home 11 | pages at 12 | 13 | [http://tilde.club/~delfuego/tilde.24h.json](http://tilde.club/~delfuego/tilde.24h.json) 14 | 15 | If you're looking to parse JSON from the command line with a minimum of 16 | code, the `jq` program may be your thing. `jq` is a filter that takes 17 | JSON on standard input and produces JSON on standard output. Along the 18 | way in the middle you can do various standard sorts of file munging on 19 | a field by field basis. 20 | 21 | [Documentation for `jq` is in its manual.](http://stedolan.github.io/jq/manual/) 22 | -------------------------------------------------------------------------------- /wiki/source/leafnode.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Leafnode 3 | category: links 4 | --- 5 | 6 | `leafnode` is a news client suitable for "leaf" nodes, that is nodes that have no downstream feeds. 7 | 8 | [http://leafnode.sourceforge.net/](http://leafnode.sourceforge.net/) -------------------------------------------------------------------------------- /wiki/source/multiplexers.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Byobu, TMUX & Screen (terminal multiplexers) 3 | author: rudi 4 | category: software 5 | --- 6 | 7 | # Terminal Muiltiplexers 8 | Terminal multiplexers are programs that will keep your session running, even if you disconnect from the server. They also allow you to 'multiplex' your terminals, spawning multiple shells in one local terminal. The three multiplexers on tilde.club are [byobu](https://linux.die.net/man/1/byobu), [tmux](https://linux.die.net/man/1/tmux), and [screen](https://linux.die.net/man/1/screen). 9 | 10 | # Byobu 11 | byobu is the default mutliplexer for tilde.club. It was originally designed to provide elegant enhancements to the otherwise functional, plain, practical [GNU Screen](http://www.gnu.org/software/screen/), for the [Ubuntu](https://ubuntu.com/) server distribution. Byobu now includes an enhanced profiles, convenient keybindings, configuration utilities, and toggle-able system status notifications for both the GNU Screen window manager and the more modern [Tmux](https://github.com/tmux/tmux) terminal multiplexer, and works on most Linux, BSD, and Mac distributions. 12 | 13 | In the spirit of the former tmux page, here is a super basic primer: 14 | The basic keys to know are f2, f3, f4, f6, f8, and f9 15 | f2 - spawn new tab 16 | f3 - move to previous (left) tab 17 | f4 - move to next (right) tab 18 | f6 - disconnect from byobu (and the server) 19 | f8 - rename a tab 20 | f9 - configuration menu (also has a basic help guide) 21 | 22 | With those keys, you can do a lot. However tmux shortcuts will work here in byobu (but unless you configure it differently, the escape sequence isn't ctrl-b, it's ctrl-a) 23 | You can even configure byobu to run automatically when you connect, using `byobu-enable` (`byobu-disable` to undo). 24 | For a more in depth overview, you can go to [byobu's documentation](https://www.byobu.org/documentation) or `man byobu`. 25 | 26 | # Tmux 27 | Here's a super basic primer. 28 | 29 | to start a new session, type `tmux new -s tildemux`. 30 | 31 | A yellow bar will appear at the bottom of your terminal. You're now in TMUX! 32 | 33 | TMUX has sessions, windows, and panes. Each of these things will have a terminal in it. If you actually typed what I told you to earlier, you'll be in a session named `tildemux`. That session has one window, `0`. That window has one pane, also named `0`. (Computers start counting at 0, not 1.) 34 | 35 | ## windows 36 | 37 | Your tmux bar should look like: 38 | 39 | `[tildemux] 0:bash*` 40 | 41 | …which means that you're in a session named `tildemux`, which has a window `0`, running the command `bash`. `*` means that window 0 is active, and the pane running bash is currently active. 42 | 43 | To create a new window within this session, type `PREFIX c`. PREFIX?!? By default, it's `control-b`. Now you should see: 44 | 45 | `[tildemux] 0:bash- 1:bash*` 46 | 47 | `1:bash*` means you're in a pane running `bash` inside window 1. To change back to pane 0, type `PREFIX 0`. The `*` should be back on `0:bash`. 48 | 49 | Run a cool interactive command, such as `htop` (to see how many of system resources we're eating up) or `vim` (to write some awesome webpages). Your tmux status bar should update to `0:`. So now instead of saying `bash` it will say `htop` or `vim`. 50 | 51 | ## panes 52 | 53 | Panes are great. TMUX panes let you run more than one terminal inside your one, actual terminal. To "split" a new pane, `PREFIX "`. That makes a horizontal split. You'll notice there are now two panes open one on top of the other. `PREFIX %` makes a vertical split, for side-by-side panes. Did I mention that panes are great? 54 | 55 | To move between panes in the current window, use `PREFIX `. That's right, the arrow keys. 56 | 57 | ## more 58 | 59 | I'm not the best writer or teacher. Just google anything that doesn't make sense. 60 | 61 | [Or take a look at this tmux guide](http://robots.thoughtbot.com/a-tmux-crash-course) 62 | 63 | But definitely use tmux or byobu. 64 | 65 | Or, if you don't like it - try [screen](screen.html) 66 | 67 | # screen 68 | 69 | `screen` is a unix utility that lets you manage multiple shells from within a single window. You switch between them with a few keystrokes. When you disconnect it keeps the processes alive, and you can reconnect from another login. 70 | 71 | It's pretty handy. [tmux](tmux.html) does a similar set of things. 72 | 73 | a nice [screen tutorial](http://tilde.club/~jonathan/screen/) from ~jonathan will walk you through it. 74 | 75 | -------------------------------------------------------------------------------- /wiki/source/netiquette.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: tilde.club netiquette 3 | category: tilde.club 4 | --- 5 | 6 | ## Two phrases we use a lot 7 | 8 | * DON'T HACK THE GIBSON 9 | * No drama. Be respectful. Have fun. We're all trying, and we're all in this together :) 10 | 11 | ## Details 12 | 13 | First things first, explore and have fun! But remember, this is a single linux server trying to support the weight of several hundred nerds. Don't host servers, don't run heavy processes, don't host giant files. In short, be gentle. 14 | 15 | More about [scripting netiquette here](http://tilde.club/wiki/safe-scripting-the-tilde-way.html) 16 | 17 | Now let's talk about drama. There is a Mary J. Blige song called "No More Drama." If Mary J. Blige would think it was drama, it is drama. No flamewars about emacs/vi, no matter how historically accurate they may be. No guilting people, shaming them, or making them feel bad. More benefit of the doubt and less "are you kidding me?" 18 | -------------------------------------------------------------------------------- /wiki/source/pagecounter.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Adding a web counter to your page 3 | author: deepend 4 | category: tutorials 5 | --- 6 | 7 | To display a visit counter on your webpage, you'll need to edit your `index.html` file and insert a ` 15 | ``` 16 | 17 | - Replace `homepage` with any identifier for the page you're tracking. 18 | - Replace `yourname` with your username or something unique to your site. 19 | - Replace `57chevy` with a different style if you'd like. 20 | 21 | Here’s an example: 22 | 23 | ```html 24 |

    Visitor count: 25 | 26 |

    27 | ``` 28 | 29 | Once you’ve added the line, save and close the file using `CTRL+X`, then press `y` and `[Enter]`. 30 | 31 | Refresh your site in your browser to see the counter. 32 | 33 | ### Available Styles 34 | 35 | You can use any of these style names in the `style=` parameter: 36 | 37 | - `57chevy` 38 | - `7seg` 39 | - `bbldotg` 40 | - `bellbtm` 41 | - `blgrv` 42 | - `cntdwn` 43 | - `computer` 44 | - `ds9` 45 | - `fdb` 46 | - `led` 47 | - `links` 48 | - `marsil` 49 | - `sbgs` 50 | - `web1` 51 | 52 | Try different styles to see which one fits your site best. 53 | 54 | Note: The counter uses sessions and cookies to count *unique* visits per user every 24 hours (or whatever time is configured). Page refreshes won’t increase the count unless unique mode is off. 55 | 56 | If you need help or want a custom style added, reach out to the site admin. 57 | ``` 58 | -------------------------------------------------------------------------------- /wiki/source/quilt.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: tilde quilt 3 | author: lab6 4 | category: links 5 | --- 6 | 7 | ## 2-dimensional anonymous collaborative microblogging 8 | 9 | [Visit the tilde quilt](https://tilde.club/~lab6/quilt.html) to read messages from other tilde users. 10 | 11 | Add your own messages (up to 150 printable ASCII characters) by running a command like the following: 12 | 13 | `echo "Hi!" > /home/lab6/quilt` 14 | 15 | Each message has an id in the top left corner, which you can use to influence where your message is placed. 16 | You can prefix your message with <id><compassdirection>, where direction is one of N, E, W, or S, like this: 17 | 18 | `echo "2EThis message goes to the east of the message with id 2" > /home/lab6/quilt` 19 | `echo "3NThis message goes to the north of message 3" > /home/lab6/quilt` 20 | `echo "4SThis message goes to the south of message 4" > /home/lab6/quilt` 21 | `echo "5WAnd this message goes to the west of message 5" > /home/lab6/quilt` 22 | 23 | If you don't use a prefix like this, your message will be placed randomly. 24 | 25 | Rate-limiting is in effect. If your write blocks, just wait. If your write fails, or your message fails to appear on the quilt, 26 | wait a minute or so and try again. The rate-limiting is intended to keep the quilt slow and human-scale. Please don't pipe in 27 | massive streams of data - it will clog the pipe for other users. 28 | 29 | Have fun and be kind! 30 | 31 | ## What's going on? 32 | 33 | We are building a patchwork quilt with the aid of POSIX named pipes. Any user able to execute a command on tilde.club 34 | can pipe their message to `/home/lab6/quilt`. Messages are anonymous - there is no way to detect which user sent data into the pipe. 35 | Users from outside the tilde.club server can [read the quilt](https://tilde.club/~lab6/quilt.html) but cannot add to it. 36 | 37 | Backups will be taken regularly and the quilt will never be reset. The quilt is strictly 38 | append-only. Old messages are never edited or overwritten (spam and nastiness may be spray-painted over but I trust you folk to be better than this). 39 | The quilt grows without bound in all four directions. 40 | 41 | Be creative. Use your 150 characters wisely. If you didn't use them wisely, try again. Hold a conversation. Vent a thought. 42 | Play correspondence chess. Golf some perl. Branch off into the void. 43 | 44 | Early adopters who snag the low messages IDs will be venerated by the generations to come. 45 | 46 | Contact ~lab6 if it's broken. Contact ~lab6 if it's not broken - he loves getting postcards. 47 | 48 | ## Roadmap 49 | 50 | * Unicode 51 | * 2D blockchain 52 | * z-axis 53 | -------------------------------------------------------------------------------- /wiki/source/safe-scripting-the-tilde-way.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: safe scripting the tilde way 3 | author: michaelcoyote 4 | category: tutorials 5 | --- 6 | 7 | Welcome to tilde.club. For many of you this may be your first multi-user host and for even more of you this may be your *first* host. Welcome to all of you. 8 | 9 | Whether you are used to Unix, Linux and programming or a complete beginner please consider this an invitation to create and build new things. 10 | 11 | It's important when creating however that we respect the shared environment and that we respect the boundaries of others. 12 | 13 | As Paul says: 14 | 15 | > no drama. be respectful. have fun. 16 | 17 | What does that mean with respect to scripting and programming on a shared host? 18 | 19 | - DOs 20 | - Respect shared CPU/Disk/Network resources 21 | - Keep things that require a tilde.club login local to the server (don't post publicly), like home directory files: 22 | - Note that exceptions could include an opt-in file or special permissions from the user. 23 | - Respect `robots.txt` when writing web crawlers 24 | 25 | In short use your common sense and consider how your actions may affect others. 26 | 27 | If you are unsure if something is a good idea or not, head to irc or message using the `wall` command and ask others what they think. 28 | 29 | If you want a conclusive answer, contact one of the system operators. 30 | 31 | ##### Thinking privacy 32 | 33 | Consider the source of the data. 34 | 35 | E.g. We know that finger data might contain personal data such as phone numbers, and other identifying information and is not generally available without a tilde.club login. 36 | 37 | Before exposing data such as this to the world, it should check for an opt in file such as the .public file file test before presenting info to the outside world. 38 | 39 | #### Shared Resources 40 | 41 | - In general 42 | - Consider executing long running processes during overnight hours when fewer users are on the system 43 | - CPU 44 | - Use the `nice` command to keep intensive processes from affecting others 45 | - The `nice -n19 -p$$` placed in a script will make sure it runs at the lowest priority. 46 | - Run a long command at the lowest CPU priority: `nice -n 19 ~/bin/command` 47 | - Change the priority of process 923 (also known as "re-nicing a process") : `renice -17 -p923` 48 | - Disk 49 | - On any commands that will heavily use disk, consider using the `ionice` command so that scripts will not affect interactive users 50 | - By adding the `ionice -c3 -p$$` command to any script, it will only use disk when idle. 51 | - You can also run a command or script: `ionice -c3 -t ~/bin/command` 52 | -------------------------------------------------------------------------------- /wiki/source/security.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Editing Basic UNIX Security the Tilde way 3 | author: michaelcoyote 4 | category: tutorials 5 | --- 6 | 7 | 8 | > "Unix is public by default. This means that other people who use the server can see your files. You can change that on a file-by-file basis. You can also change the default behavior for you. It is totally okay to keep your stuff private. Let us show you how." 9 | 10 | Unix was built with a fairly open security policy. It's the kind of system you might expect a bunch of Berkley hippies to design. That said, if it bugs you that someone might be able to look the files in your home directory and you don't want to read any more of this document then run these commands: 11 | 12 | cd ~ 13 | chmod 711 . 14 | 15 | Those will keep anyone on the system from looking at your directory while still allowing your `~youruser` site to work. If you want to have more control over who can view what in your directory, then please read on. You can even come back and read this later, we'll be here. 16 | 17 | ### Users and Groups 18 | 19 | What is a user? For starters, you are a user and so is every other person on the system. Sometimes special user accounts are used for running specific processes (such as the web server) or for handling special administrative tasks. 20 | 21 | There are several attributes that define a user. 22 | 23 | - username 24 | This is your login id and the name of your homedir 25 | - user id (or uid) 26 | This is your unique numerical id number on the system. This is how the system keeps track of you, your processes, and your files. 27 | - group id (or gid) 28 | This is a unique numerical id number for your primary user group on the system. User groups are the traditional way that users would colaberate on large projects. 29 | 30 | For now we only need to know about the username. 31 | 32 | #### Welcome to tilde.club, your new home (and homedir) 33 | When you registered for the system, you got an email that contained many things. One of those things was a username, and another was a password. When you logged into the server you were presented with what we call a prompt, and it looked a bit like this: 34 | 35 | sh-4.1$ 36 | 37 | That's boring so type the command `ls -l public_html/index.html` 38 | 39 | sh-4.1$ ls -l public_html/index.html 40 | rw-rw-r-- 1 youruser youruser 177 Oct 13 04:51 public_html/index.html 41 | 42 | You'll notice that your login shows up, but what does this actually show us? 43 | 44 | First of all `ls` is a command to list files and directories. We've given it the command line switch `-l` that tells the `ls` command that we want a long listing of the file or directory attributes, and finally we've given it the filename `my_file` so that we can see its file attributes. 45 | 46 | What does this long file listing of `my_file` show us? 47 | 48 | -rw-rw-r-- 1 youruser youruser 177 Oct 13 04:51 my_file 49 | ---------- --- ------- -------- ----- ------------ ------------- 50 | | | | | | | | 51 | | | | | | | File Name 52 | | | | | | +--- Modification Time 53 | | | | | +------------- Size (in bytes) 54 | | | | +----------------------- Group owner 55 | | | +-------------------------------- User owner 56 | | +-------------------------------------- Number of links 57 | +---------------------------------------------- File Permissions 58 | 59 | This seems like a lot to take in, but for the purpose of talking about files and security, we'll only need three things: the file permissions, the group owner and the user owner. 60 | 61 | - Homework 62 | - Run `ls -la` in your home directory and note the users and permissions of the various files 63 | - Run `ls -l /etc/passwd` and `ls -l /var/log/messages` and compare the permissions and ownership to that of your homedir 64 | 65 | 66 | ### Basics about file and directory permissions 67 | 68 | -rwxrwxrwx 69 | ---------- 70 | | | | | 71 | | | | +--- Other Read/Write/Execute permissions 72 | | | +------ Group Read/Write/Execute permissions 73 | | +--------- User Read/Write/Execute permissions 74 | +----------- Directory/Special flag 75 | 76 | The first column at first glance looks like a bunch of alphabet soup, however if you look over a few of them, a pattern begins to emerge. Some lines begin with `d` and there are repeating instances of `r`, `w` and `x`. You might notice that the lines beginning with `d` refer to directories and that many files have `rw-` at the start of the column and `r--` or even `---` at the end of the column. These are important and indicate to the computer and to users how that file can be accessed. 77 | 78 | #### Types of permissions 79 | 80 | There are three major types of permissions (and a hand full of others) 81 | - Read 82 | Read permission is represented as an `r` and will allow a listing of a directory and reading a file. 83 | - Write 84 | Write permission is represented with a `w` and allows a file or directory to be written to or deleted. 85 | - Execute 86 | Execute permission is represented as an `x` and allows a file (such as a script) to be executed and it allows for a directory to be "traversed" 87 | 88 | - Other special permissions and notations in `ls -l` 89 | - `-` means that the permission for that place isn't set. If it's at the beginning of the line, it means it's a normal file. 90 | - `d` at the start of a line isn't a permission really. It just denotes a directory. 91 | - `b` or `c` isn't a permission either, it probably means you did an `ls -l` of the `/dev` directory as those indicate block or character devices. 92 | - `s` is a setuid/setgid permission. It's a special setting that allows you to run a script file or program as a user or a group. It can be used on a directory to make sure files are written as a user/group. It's rare to see, and in general should be used only if the proper precautions are taken. Serious consequences can come about if a shell script/program is poorly written and given setuid permissions, as it could lead to an escalation to root privileges or a more privileged user. 93 | 94 | #### Three classes of access permissions 95 | 96 | - User permissions 97 | This set of access controls define what an owner can do to her own files or directories. These controls are most often useful to set on a script file you want to run or a file you want to protect from deletion or overwriting. 98 | 99 | - Group permissions 100 | This set of access controls define what the group can do to a file or directory. This tends not to matter much in your homedir, but it can matter a lot when working with other users on shared projects. 101 | 102 | - Others 103 | These access controls are what you use to allow and others who are not listed as an owner or group member to do to a file or directory. For example, if you remove read permissions from others on your ~/public_html/index.html`, the webserver process will be unable to read your web page. 104 | 105 | #### Changing file and directory permissions using `chmod` 106 | 107 | Examples 108 | 109 | - Homework 110 | - `mkdir -p test/01` and then try the following `chmod` commands 111 | chmod u+rwx test 112 | echo "hello world" > test/a_file 113 | ls -l test 114 | chmod ugo-rw test 115 | ls -l test 116 | ls -l test/a_file 117 | 118 | 119 | 120 | #### Basics about the `finger` and `chfn` commands 121 | 122 | How to see others in the system using `finger` 123 | 124 | Type the command `finger` 125 | 126 | Type the command `finger $USER` 127 | 128 | How others see you. 129 | 130 | Changing the information people see about you using `chfn` 131 | 132 | creating a `~/.plan` and `~/.project` file that's readable 133 | 134 | 135 | #### More advanced topics 136 | 137 | Let's look at the `/etc/passwd` file. What is it? It's a file that contains most of the information about users in the system. 138 | 139 | - Homework 140 | - `head -10 /etc/passwd` 141 | - `grep $USER /etc/passwd` 142 | - Note the columns in the `/etc/passwd` file. Note the columns and the `:` separator between them. 143 | 144 | Back at our command line, lets type the command `id`: 145 | 146 | sh-4.1$ id 147 | uid=501(youruser) gid=501(youruser) groups=501(youruser)` 148 | 149 | The `id` command is a tool to show us how the system keeps track of us. From this we can see that according to the system, our user ID (or uid) is 501, and our group id is also 501. 150 | 151 | - Homework 152 | - Run `id` in your own directory, then run 153 | - Run `id -u root` 154 | - use the `grep` command to find your uid in the `/etc/passwd` file 155 | 156 | As noted above, we can obtain our group id using the `id` command. Try locating your group in `/etc/group` using the commands that were specified above; your group name will probably be the same as your user (although at times this might not be true depending on the configuration of the system). 157 | -------------------------------------------------------------------------------- /wiki/source/slrn.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: slrn 3 | category: links 4 | --- 5 | 6 | ``slrn`` is a news reader for [Usenet](usenet-news.html). 7 | 8 | Documentation for slrn can be found at [http://slrn.sourceforge.net](http://slrn.sourceforge.net) 9 | 10 | Tilde-specific slrn info is on [http://tilde.club/~joeld/slrn.html](http://tilde.club/~joeld/slrn.html) 11 | 12 | -------------------------------------------------------------------------------- /wiki/source/ssh.md: -------------------------------------------------------------------------------- 1 | --- 2 | author: benharri 3 | title: How to connect using SSH (secure shell) 4 | category: tutorials 5 | --- 6 | 7 | 8 | _or, how to tell other computers to do cool things_ 9 | 10 | --- 11 | 12 | > all users are required to use an ssh keypair for login, or will be required 13 | > to proceed with manual account recovery. 14 | > you can also set up [two-factor authentication](2fa.html) to log in without your 15 | > keypair. 16 | 17 | ## tilde.club details 18 | 19 | for example, to connect to tilde.club, you can do: 20 | 21 | ``` 22 | ssh user@tilde.club 23 | mosh user@tilde.club 24 | ``` 25 | 26 | ssh is also available on port 443 using the address `ssh.tilde.club`: 27 | 28 | ssh -p 443 user@ssh.tilde.club 29 | 30 | this is useful if you're on a limited public network that blocks non-http 31 | ports. 32 | 33 | if you are prompted for a verification code, it's for [2fa](2fa.html). 34 | it will not work if you haven't set it up. be sure you're using the right ssh keypair. 35 | 36 | --- 37 | 38 | ## intro 39 | 40 | ** if you just want to get right to a tutorial you can 41 | [skip over this background info](#how-to-make-an-ssh-key)** 42 | 43 | while [tilde.club](https://tilde.club) is accessible on the web and features 44 | lovely web pages written by its users, most interaction with tilde.club takes 45 | place **inside the machine** that runs tilde.club as opposed to via web forms 46 | that have an effect from **outside** tilde.club's computer. 47 | 48 | this is what sets tilde.club apart from most other online communities. you 49 | connect directly to another computer from yours alongside other people and then 50 | write your web pages, chat, and play games all via text-based interfaces right 51 | on tilde.club's computer. 52 | 53 | prior to the web (which debuted in 1995) this is how pretty much all computer 54 | stuff got done. you connected directly to a machine (usually over a direct, 55 | physical phone line) and did your work there. 56 | 57 | for a long time, people used a tool called 58 | [`telnet`](https://en.wikipedia.org/wiki/telnet) to connect to other computers. 59 | these days we use a tool called **ssh**. 60 | 61 | `ssh` is a text-based tool that provides a direct connection from your computer 62 | to another. ssh is an acronym that stands for secure shell. the _shell_ part 63 | refers to the fact that it's a text-based tool; we use the word shell to refer 64 | to a text-based interface that you give commands to. the _secure_ part refers 65 | to the fact that, when you're using ssh, no one can spy on your connection to 66 | another computer (unlike the old `telnet` command). 67 | 68 | **why bother with all of this?** passwords are really insecure and hard to manage. 69 | using keys makes life easier for you, fair user (your account is less likely to 70 | be hacked) and for me, your humble sysadmin (less administration than passwords). 71 | 72 | --- 73 | 74 | ## how to make an ssh key 75 | 76 | SSH supports a handful of types of cryptographic keys. The most used are [RSA]( 77 | ) and the more modern [Ed25519]( 78 | https://en.wikipedia.org/wiki/EdDSA#Ed25519). 79 | 80 | RSA is the de-facto standard and is supported everywhere (just choose a big 81 | enough key like 4096 bits to be secure). Ed25519 is designed to be faster and 82 | smaller withouth sacrificing security, so is best suited for embedded devices 83 | or machines with low resources. It's supported on tilde (and really on any 84 | modern system) but you may find older systems which do not support it. 85 | 86 | Below you'll find instructions to generate either type (or both if you want). 87 | 88 | Keep in mind that these instructions leave your private keys unencrypted in 89 | your local hard disk. So keep them private; never share them. A good solution 90 | is to provide a password for them at creation time, but this implies entering 91 | a password any time you used them (impractical) or use something like [ssh-agent]( 92 | https://man.openbsd.org/ssh-agent.1) (a bit more complex) 93 | 94 | pick your fighter: [[mac](#mac)] | [[windows](#windows)] | [[linux](#linux)] 95 | 96 | --- 97 | 98 | ### mac 99 | 100 | #### generating your keypair 101 | 102 | 1. open terminal (it's in `/Applications/Utilities`) 103 | 104 | 2. create your .ssh directory: 105 | 106 | ```bash 107 | mkdir -m 700 ~/.ssh 108 | ``` 109 | 110 | 3. create your keypair: 111 | 112 | ```bash 113 | ssh-keygen -t ed25519 -a 100 114 | ``` 115 | 116 | 4. if you press enter to accept the defaults, your public and private key will 117 | be located at `~/.ssh/id_ed25519.pub` and `~/.ssh/id_ed25519` 118 | 119 | `cat ~/.ssh/id_ed25519.pub` 120 | 121 | 5. copy the output of the last command and paste it in the sshkey field on the 122 | signup form (or email it to [~root](mailto:root@tilde.club) if you already have an account) 123 | 124 | #### using your keypair 125 | 126 | once an admin approves your signup, you can join the tilde.club 127 | 128 | 6. open terminal (it's in `/Applications/Utilities`) 129 | 130 | 7. `ssh` to tilde.club: 131 | 132 | ```bash 133 | ssh username@tilde.club 134 | ``` 135 | 136 | where username is your username (~benharri would use `ssh benharri@tilde.club`) 137 | 138 | 8. profit??? 139 | 140 | --- 141 | 142 | ### windows 143 | 144 | #### Ensure OpenSSH is installed 145 | 146 | 1. Open Settings, select Apps, then select Optional Features 147 | 1. Scan the list to see if the OpenSSH is already installed. If not, at the top of the page, select Add a feature, then... 148 | 1. Find OpenSSH Client, then select Install 149 | 150 | #### generating your keypair 151 | 152 | 1. open your command prompt (Start -> Search -> type "cmd") 153 | 154 | 2. create your keypair: 155 | 156 | ```cmd 157 | ssh-keygen -t ed25519 -a 100 158 | ``` 159 | 160 | 3. If you press enter to accept the defaults, your public and private key will be located at %USERPROFILE%\\.ssh\\id_ed25519.pub and %USERPROFILE%\\.ssh\\id_ed25519 respectively. 161 | 162 | Note: %USERPROFILE% is a short code that the computer expands to mean C:\\Users\\your_name\\, or whatever the relevant path is to your user's main folder. 163 | 164 | Next we will open up the public key so we can copy its contents. 165 | 166 | ```cmd 167 | notepad %USERPROFILE%\.ssh\id_ed25519.pub 168 | ``` 169 | 170 | 4. Copy the text of the pubkey that opens in Notepad and paste it in the sshkey field on the signup form or email it to the relevant sign-up address for the tilde you are joining. 171 | 172 | #### using your keypair 173 | 174 | once an admin approves your signup, you can join the tilde.club 175 | 176 | 5. open command prompt (Start -> Search -> type "cmd") 177 | 178 | 6. `ssh` to tilde.club: 179 | 180 | ```cmd 181 | ssh username@tilde.club 182 | ``` 183 | 184 | where username is your username (~benharri would use `ssh benharri@tilde.club`) 185 | 186 | 7. profit??? 187 | 188 | --- 189 | 190 | ### linux 191 | 192 | there are a lot of linux distros, but `ssh` and `ssh-keygen` should be available 193 | in almost all cases. if they're not, look up how to install ssh for your distro. 194 | 195 | #### generating your keypair 196 | 197 | 1. make sure you have a `~/.ssh` directory 198 | 199 | ```bash 200 | mkdir -m 700 ~/.ssh 201 | ``` 202 | 203 | 2. create your keypair 204 | 205 | ```bash 206 | ssh-keygen -t ed25519 -a 100 207 | ``` 208 | 209 | 3. if you press enter to accept the defaults, your public and private key will 210 | be located at `~/.ssh/id_ed25519.pub` and `~/.ssh/id_ed25519` 211 | 212 | ```bash 213 | cat ~/.ssh/id_ed25519.pub 214 | ``` 215 | 216 | 4. copy the output of the last command and paste it in the sshkey field on the 217 | signup form (or email it to [root@tilde.club](mailto:root@tilde.club) if you already have an account) 218 | 219 | #### using your keypair 220 | 221 | once an admin approves your signup, you can join the tilde.club 222 | 223 | 5. open a terminal (this depends on your distro) 224 | 225 | 6. `ssh` to tilde.club: 226 | 227 | where username is your username (~benharri would use `ssh benharri@tilde.club`) 228 | 229 | ```bash 230 | ssh username@tilde.club 231 | ``` 232 | 233 | Note: If you generated your key to the location above (%USERPROFILE%\\.ssh\\...) then you will be able to SSH to your tilde server without having to specify the location of the key. That folder is the default used by SSH and it will be found automatically. If you generated your keys in a different location or moved them, you will need to specify the full path to the private key. 234 | 235 | ```cmd 236 | ssh -i c:\path\to\my\private\key username@your.tilde 237 | ``` 238 | 239 | 7. profit??? 240 | 241 | --- 242 | 243 | this tutorial is based on and uses parts of [the tilde.club ssh primer](https://github.com/tildeclub/tilde.club/blob/master/docs/ssh.md) and [the tilde.town ssh guide](https://tilde.town/wiki/getting-started/ssh.html). 244 | -------------------------------------------------------------------------------- /wiki/source/sshfs.md: -------------------------------------------------------------------------------- 1 | --- 2 | author: jeffbonhag 3 | title: SSHFS (SSH Filesystem) 4 | category: software 5 | --- 6 | 7 | On OS X: 8 | 9 | - Download the lastest version of OSXFUSE: [http://osxfuse.github.io/](http://osxfuse.github.io/) 10 | - `brew install sshfs` 11 | 12 | 13 | Now you can mount a ssh server by issuing the following commands: 14 | 15 | mkdir tilde.club 16 | sshfs jeffbonhag@tilde.club:/home/jeffbonhag tilde.club 17 | 18 | If you're on Linux and want to make an entry in your fstab: 19 | 20 | mkdir -p /mnt/tilde.club 21 | 22 | Put an entry in your `/etc/fstab` like this: 23 | 24 | jeffbonhag@tilde.club:/home/jeffbonhag /mnt/tilde.club fuse.sshfs _netdev,user,idmap=user,transform_symlinks,allow_other,default_permissions,uid=jeff,gid=jeff,umask=0 0 0 25 | 26 | then you can do 27 | 28 | mount /mnt/tilde.club 29 | 30 | If you want to use an identity file to mount instead of a password, this may 31 | work (untested): 32 | 33 | jeffbonhag@tilde.club:/home/jeffbonhag /mnt/tilde.club fuse.sshfs _netdev,user,idmap=user,transform_symlinks,identityfile=/home/USER_C/.ssh/id_rsa,allow_other,default_permissions,uid=USER_C_ID,gid=GROUP_C_ID,umask=0 0 0 34 | 35 | Although -- do you really need to do this? It just occurred to me that the 36 | first command is just as easy, and probably makes more sense. 37 | -------------------------------------------------------------------------------- /wiki/source/tildeverse.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: tildeverse 3 | author: audiodude 4 | category: links 5 | --- 6 | From the website at [https://tildeverse.org/](https://tildeverse.org/): 7 | 8 | > we're a loose association of like-minded tilde communities. if you're 9 | > interested in learning about *nix (linux, unix, bsd, etc) come check out our 10 | > [member tildes](https://tildeverse.org/members/) and sign up! 11 | -------------------------------------------------------------------------------- /wiki/source/time-zone.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: time zones 3 | category: tutorials 4 | --- 5 | 6 | The timezone by default on the server is UTC. 7 | 8 | If you want to make it so that your shell prints out dates in localtime for you, run `tzselect` 9 | to find the correct timezone name that you'll need to export as the `TZ` environment variable. 10 | 11 | for example, if you're in eastern time, add something like this 12 | `export TZ="America/Detroit"` 13 | 14 | to your `.bashrc` 15 | 16 | -------------------------------------------------------------------------------- /wiki/source/tin.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: tin (UseNet reader) 3 | category: software 4 | --- 5 | 6 | tin is a threaded NNTP and spool based [UseNet](usenet-news.html) newsreader for a variety of platforms. 7 | 8 | [http://www.tin.org/](http://www.tin.org/) 9 | 10 | it is an actively maintained project, and is installed on ``tilde.club``. `tin` should be invoked as `tin -r` to read from the remote news spool. Use to go to the next unread article and `w` to write a new article. 11 | 12 | if you have `tin` on your local box and can do [[ssh port forwarding]], you can read news using it. (details forthcoming). 13 | -------------------------------------------------------------------------------- /wiki/source/tunnelblick.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Tunnelblick 3 | category: links 4 | --- 5 | 6 | `tunnelblick` is an application for your Mac that allows you to configure 7 | and manage VPN sessions. You can use this e.g. if you are connecting to 8 | tilde.club via a network that does not allow high UDP ports; with a properly 9 | configured tunnel, you can still run [[mosh]] as your shell and keep on 10 | truckin. 11 | 12 | [https://tunnelblick.net/](https://tunnelblick.net/) 13 | 14 | To find a VPN endpoint, see the [VPN Gate](vpn-gate.html) project. 15 | -------------------------------------------------------------------------------- /wiki/source/usenet-news.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: usenet news 3 | category: tutorials 4 | author: 5 | - deepend 6 | - audiodude 7 | - xwindows 8 | --- 9 | 10 | ## As of 2020-04-14 news is back up! 11 | 12 | You'll need a news (NNTP) client to read news. 13 | The address to use inside of Tilde.club 14 | is `localhost` port 119. 15 | The address to use outside is `news.tilde.club` port 119 (plain), 16 | or port 563 (with TLS, 17 | available since 2023-02-17). 18 | If you connect from outside of Tilde servers, 19 | e.g. from home, 20 | you would have to use TLS 21 | and authenticate using your Tilde.club username and password, 22 | to be able to post. 23 | 24 | This netnews service is brought to you by [~deepend](../~deepend) (administrator) 25 | and [~xwindows](/~xwindows/) (technical troubleshooter). 26 | 27 | ## News clients 28 | 29 | ### slrn 30 | [slrn](slrn.html) is a newsreader; see [http://slrn.sourceforge.net/](http://slrn.sourceforge.net/) for details. 31 | 32 | First, add `export NNTPSERVER="localhost"` to your shellrc (`.bashrc`, `.zshrc`) 33 | and source it (`source path/to/.shellrc`). 34 | 35 | Then run `slrn --create` to create the slrn config file, and lastly `slrn -d` to 36 | populate group names. 37 | 38 | You're now ready to run `slrn`! If the list is empty, press `L` (for list-groups) and enter `*` in the field for all groups. You might need to enter each group (pressing `space`) to get a proper count for how many (if any) unread messages there are. 39 | 40 | ### pine/alpine 41 | 42 | Pine can read news; this 43 | [tutorial](http://www.chebucto.ns.ca/Help/News/PineNews.html) might help. 44 | You can also read the [FAQ from U Washington](http://www.washington.edu/pine/faq/news.html). 45 | 46 | If you use Pine from inside Tilde.club, 47 | configure it by: 48 | 49 | 1. 'S' for setup, 'C' for config, then 50 | 1. set 'NNTP Server (for news)' to `localhost` 51 | 1. Then go back to the main menu, and pick Folder List, 52 | 1. A for add, ^t for list 53 | 54 | ### Emacs 55 | 56 | `M-x gnus` in emacs can read news, but you better know [emacs](emacs.html) first before you start. 57 | 58 | ### lynx 59 | 60 | Lynx reads news, a la `lynx nntp://news.tilde.club/local.general`. It can even post news, but you have to design your own headers. 61 | 62 | ### tin 63 | There is also [tin](tin.html). 64 | 65 | ### Thunderbird 66 | If you are a Tilde.club member and already using Thunderbird for email; 67 | it can also be configured for news. 68 | 69 | 1. Go to the `Tools` menu 70 | (`Edit` menu in case of Unix-like system) -> `Account Settings`. 71 | Or in versions without a menu bar: 72 | hamburger menu -> `Preferences` -> `Account Settings`. 73 | 1. Under `Account Actions` click `Add Other Account...` 74 | 1. Select "Newsgroup Account" 75 | 1. Type in the name you and email address you want associated with your posts. 76 | This can be your real name and tilde.club email address, or any other name 77 | (like your tilde username) and any other email address. 78 | 1. For the "Newsgroup Server" type `news.tilde.club`. Give it a name 79 | ("news.tilde.club" works fine), confirm a couple of times, 80 | and you should see a new entry for news.tilde.club 81 | in the left panel of the Account Settings dialog. 82 | 1. Select `Server Settings` under it, 83 | and change `Connection security` to "SSL/TLS"; 84 | you would see that the `Port` setting above it changed to 563. 85 | (If it doesn't do that automatically, 86 | make it so) 87 | 1. Press OK to close the Account Settings dialog. 88 | 1. Right click on "news.tilde.club" in your accounts list and click 89 | `Subscribe...` 90 | 1. You should see a dialog with a tree of news topics. Click one and click 91 | `Subscribe` to subscribe to the topic. When Thunderbird is running, it will 92 | periodically check for new messages to each of these topics. You will also 93 | see a list of topics in your accounts list with unread counts. 94 | 1. To post to a topic, open the topic and click the "Write" button. 95 | 1. When you click `Send` on your new post, 96 | Thunderbird would ask for your Tilde.club username and password 97 | (which is the same as the one you use on your [Tilde.club email](email.html)). 98 | -------------------------------------------------------------------------------- /wiki/source/vimrc.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Vim (editor) .vimrc file 3 | category: software 4 | --- 5 | 6 | The file `.vimrc` in your home directory has instructions for [[vim]] 7 | to load every time it runs. Customizations go there. 8 | 9 | For instance, you might want to use [[Markdown]] to edit files that 10 | end in `.md`. The system default for some reason is to treat these as 11 | [[Modula-2]] files, though we don't have a Modula-2 compiler running 12 | (yet). So the contents of `.vimrc` should read 13 | 14 | `` 15 | au BufRead,BufNewFile *.md set filetype=markdown 16 | `` 17 | 18 | For more suggestions in deep depth on how to set up your `.vimrc` please read 19 | [this tutorial from Doug Black](https://web.archive.org/web/20161224112739/https://dougblack.io/words/a-good-vimrc.html). (The website's no longer up, it's on the 'net archive. 20 | -------------------------------------------------------------------------------- /wiki/source/vpn-gate.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: VPN Gate 3 | category: links 4 | --- 5 | 6 | `VPN Gate` is a project from U Tsukuba in Japan that allows you to 7 | evade censorship and filtering by setting up VPN tunnels. It was 8 | designed with the Great Firewall of China in mind. 9 | 10 | [http://www.vpngate.net/en/](http://www.vpngate.net/en/) 11 | 12 | You may need client side software to make this work; [tunnelblick](tunnelblick.html) is one 13 | such service on the Mac. 14 | -------------------------------------------------------------------------------- /wiki/source/vpnwhy.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Don't use VPN services 3 | author: joepie91 on github 4 | category: tutorials 5 | --- 6 | 7 | # Don't use VPN services. 8 | 9 | No, seriously, don't. You're probably reading this because you've asked what VPN service to use, and this is the answer. 10 | 11 | *Note: The content in this post does not apply to using VPN for their intended purpose; that is, as a virtual private (internal) network. It only applies to using it as a glorified proxy, which is what every third-party "VPN provider" does.* 12 | 13 | - A Russian translation of this article can be found [here](https://tdemin.github.io/posts/2017-08-13-dont-use-vpn-services_ru), contributed by Timur Demin. 14 | - A Turkish translation can be found [here](https://write.as/nwz9t04yfjwlv0yj.md), contributed by agyild. 15 | - There's also [this article](https://schub.io/blog/2019/04/08/very-precarious-narrative.html) about VPN services, which is honestly better written (and has more cat pictures!) than my article. 16 | 17 | ## Why not? 18 | 19 | Because a VPN in this sense is just a glorified proxy. The VPN provider can see all your traffic, and do with it what they want - including logging. 20 | 21 | ## But my provider doesn't log! 22 | 23 | There is no way for you to verify that, and of course this is what a malicious VPN provider would claim as well. In short: the only safe assumption is that *every* VPN provider logs. 24 | 25 | And remember that it is in a VPN provider's best interest to log their users - it lets them deflect blame to the customer, if they ever were to get into legal trouble. The $10/month that you're paying for your VPN service doesn't even pay for the lawyer's *coffee*, so expect them to hand you over. 26 | 27 | ## But a provider would lose business if they did that! 28 | 29 | I'll believe that when HideMyAss goes out of business. They gave up their users years ago, and [this was widely publicized](http://www.theregister.co.uk/2011/09/26/hidemyass_lulzsec_controversy/). The reality is that most of their customers will either not care or not even be aware of it. 30 | 31 | ## But I pay anonymously, using Bitcoin/PaysafeCard/Cash/drugs! 32 | 33 | Doesn't matter. You're still connecting to their service from your own IP, and they can log that. 34 | 35 | ## But I want more security! 36 | 37 | VPNs don't provide security. They are just a glorified proxy. 38 | 39 | ## But I want more privacy! 40 | 41 | VPNs don't provide privacy, with a few exceptions (detailed below). They are just a proxy. If somebody wants to tap your connection, they can still do so - they just have to do so at a different point (ie. when your traffic leaves the VPN server). 42 | 43 | ## But I want more encryption! 44 | 45 | Use SSL/TLS and HTTPS (for centralized services), or end-to-end encryption (for social or P2P applications). VPNs can't magically encrypt your traffic - it's simply not technically possible. If the endpoint expects plaintext, there is *nothing* you can do about that. 46 | 47 | When using a VPN, the *only* encrypted part of the connection is from you to the VPN provider. From the VPN provider onwards, it is the same as it would have been without a VPN. And remember, __the VPN provider can see and mess with all your traffic.__ 48 | 49 | ## But I want to confuse trackers by sharing an IP address! 50 | 51 | Your IP address is a largely irrelevant metric in modern tracking systems. Marketers have gotten wise to these kind of tactics, and combined with increased adoption of [CGNAT](https://en.wikipedia.org/wiki/Carrier-grade_NAT) and an ever-increasing amount of devices per household, it just isn't a reliable data point anymore. 52 | 53 | Marketers will almost always use some kind of other metric to identify and distinguish you. That can be anything from a useragent to a [fingerprinting profile](https://panopticlick.eff.org/). A VPN cannot prevent this. 54 | 55 | ## So when should I use a VPN? 56 | 57 | There are roughly two usecases where you might want to use a VPN: 58 | 59 | 1. You are on a known-hostile network (eg. a public airport WiFi access point, or an ISP that is known to use MITM), and you want to work around that. 60 | 2. You want to hide your IP from a very specific set of non-government-sanctioned adversaries - for example, circumventing a ban in a chatroom or preventing anti-piracy scareletters. 61 | 62 | In the second case, you'd probably just want a regular proxy *specifically* for that traffic - sending *all* of your traffic over a VPN provider (like is the default with almost every VPN client) will still result in the provider being able to snoop on and mess with your traffic. 63 | 64 | However, in practice, __just don't use a VPN provider at all, even for these cases.__ 65 | 66 | ## So, then... what? 67 | 68 | If you absolutely need a VPN, and you understand what its limitations are, purchase a VPS and set up your own (either using something like [Streisand](https://github.com/StreisandEffect/streisand) or manually - I recommend using Wireguard). I will not recommend any specific providers (diversity is good!), but there are plenty of cheap ones to be found on [LowEndTalk](https://www.lowendtalk.com/categories/offers). 69 | 70 | ## But how is that any better than a VPN service? 71 | 72 | A VPN provider *specifically seeks out* those who are looking for privacy, and who may thus have interesting traffic. Statistically speaking, it is more likely that a VPN provider will be malicious or a honeypot, than that an arbitrary generic VPS provider will be. 73 | 74 | ## So why do VPN services exist? Surely they must serve some purpose? 75 | 76 | Because it's easy money. You just set up OpenVPN on a few servers, and essentially start reselling bandwidth with a markup. You can make every promise in the world, because nobody can verify them. You don't even have to know what you're doing, because again, nobody can verify what you say. It is 100% snake-oil. 77 | 78 | So yes, VPN services do serve a purpose - it's just one that benefits the provider, not you. 79 | 80 | ---- 81 | 82 | __This post is licensed under the [WTFPL](http://cryto.net/~joepie91/blog/LICENSE.txt) or [CC0](https://creativecommons.org/publicdomain/zero/1.0/), at your choice.__ You may distribute, use, modify, translate, and license it in any way. 83 | 84 | ---- 85 | -------------------------------------------------------------------------------- /wiki/source/winscp.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Editing your tilde.club site with WinSCP 3 | author: vincenz00 4 | category: tutorials 5 | --- 6 | 7 | ![](https://user-images.githubusercontent.com/57832/132138979-3c05c6fa-f0fd-4332-9c55-8a00260effb0.PNG) 8 | 9 | ## Stuff you'll need:- 10 | 11 | 1. tilde.club sign up confirmation email 12 | 1. WinSCP ([download](https://winscp.net/eng/index.php)) 13 | 1. Public and private keys you used for signing up to tilde.club 14 | 1. Decent knowledge in HTML(why are you even here otherwise?) 15 | 16 | ## Steps to follow:- 17 | 18 | 1. Hopefully by now you've got your sign up confirmation by email and are 19 | looking forward to creating your own page, keep the password provided in 20 | the back of your head, it comes into play later. 21 | 1. Download and install WinSCP 22 | 1. Now when you open WinSCP, you'll meet with the login page. 23 | 1. Enter the following here:- 24 | - Host name: tilde.club 25 | - Username: username you used to sign up to tilde.club 26 | - Password: the password given in the sign up confirmation email 27 | 1. Now the final step before you go ahead and login. Go to 28 | advanced=>SSH=>Authentication and under authentication parameters, add your 29 | private key by locating it by using the file browser. 30 | 1. Add your public key in the same tab by copying it from the file and 31 | adding it to the “Display public key” button. 32 | 1. Close that tab and now save your preferences for making logging in 33 | easier. 34 | 1. Login and after logging in you can find your index.html file present 35 | there. 36 | 1. ??? 37 | 1. profit 38 | -------------------------------------------------------------------------------- /wiki/txtlist.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | for txt in ./*.txt; do 4 | printf "0%s\t%s\ttilde.club\t70\n" "$(head -n1 $txt)" "/wiki/${txt#"./"}" 5 | done 6 | 7 | -------------------------------------------------------------------------------- /wiki/wiki.tmpl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | $for(author-meta)$ 8 | 9 | $endfor$ 10 | $if(date-meta)$ 11 | 12 | $endif$ 13 | $if(keywords)$ 14 | 15 | $endif$ 16 | $if(title-prefix)$$title-prefix$ – $endif$$pagetitle$ 17 | 18 | 19 | 29 | $if(highlighting-css)$ 30 | 33 | $endif$ 34 | $for(css)$ 35 | 36 | $endfor$ 37 | $if(math)$ 38 | $math$ 39 | $endif$ 40 | 43 | $for(header-includes)$ 44 | $header-includes$ 45 | $endfor$ 46 | 47 | 48 | $for(include-before)$ 49 | $include-before$ 50 | $endfor$ 51 |
    52 | $if(title)$ 53 |
    54 |

    $title$

    55 | 56 | $if(subtitle)$ 57 |

    $subtitle$

    58 | $endif$ 59 | 60 | $if(author)$ 61 |

    authors:

    62 | $for(author)$ 63 |

    ~$author$

    64 | $endfor$ 65 | $endif$ 66 | 67 | $if(date)$ 68 |

    $date$

    69 | $endif$ 70 |
    71 | $endif$ 72 |
    73 |
    74 |
    75 | 76 |
    77 | 78 | $if(toc)$ 79 | $if(toc-title)$ 80 |

    $toc-title$

    81 | $endif$ 82 | 85 |
    86 | $endif$ 87 | 89 | $body$ 90 | $for(include-after)$ 91 | $include-after$ 92 | $endfor$ 93 |
    94 |
    95 |
    96 |
    97 |
    98 | 102 | 103 | 104 | --------------------------------------------------------------------------------