├── .gitignore
├── www
├── alert.mp3
├── ohsnap.js
├── status.js
├── shared.js
├── js.cookie.js
├── status.html
├── files.js
├── files.html
├── numeral.min.js
├── md5.js
├── style.css
├── normalize.css
├── index.html
├── skeleton.css
├── chat.js
└── messages.js
├── package
├── meshchat
│ ├── prerm
│ ├── control
│ ├── preinst
│ └── postinst
├── meshchat-api
│ └── control
├── populate-meshchat-api-fs.sh
├── populate-meshchat-fs.sh
├── update-version.sh
└── ipk-build.sh
├── support
├── meshchatsync-init.d
└── meshchatsync
├── README.md
├── .release-it.yaml
├── .github
├── workflows
│ ├── build-packages.yaml
│ ├── workflow-meshchat-api-package.yaml
│ ├── workflow-meshchat-package.yaml
│ ├── publish-docs.yaml
│ └── release-meshchat.yaml
└── ISSUE_TEMPLATE
│ ├── Feature Request.yml
│ └── Bug Report.yml
├── luadox.conf
├── docs
├── History.md
├── Install.md
└── Troubleshooting.md
├── api
└── meshchat
├── CHANGELOG.md
├── meshchatconfig.lua
├── meshchatlib.lua
└── meshchat
/.gitignore:
--------------------------------------------------------------------------------
1 | docs/.markupserve_index
2 |
--------------------------------------------------------------------------------
/www/alert.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hickey/meshchat/HEAD/www/alert.mp3
--------------------------------------------------------------------------------
/package/meshchat/prerm:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | /etc/init.d/meshchatsync disable
4 | /etc/init.d/meshchatsync stop
5 |
6 | rm -rf /tmp/meshchat
7 |
8 | exit 0
9 |
--------------------------------------------------------------------------------
/package/meshchat/control:
--------------------------------------------------------------------------------
1 | Package: meshchat
2 | Version:
3 | Depends: curl lua
4 | Provides:
5 | Source: package/meshchat
6 | Section: net
7 | Priority: optional
8 | Maintainer: Tim Wilkinson (KN6PLV) and Trevor Paskett (K7FPV)
9 | Architecture: all
10 | Description: P2P distributed chat for mesh networks
11 |
--------------------------------------------------------------------------------
/support/meshchatsync-init.d:
--------------------------------------------------------------------------------
1 | #!/bin/sh /etc/rc.common
2 |
3 | START=99
4 | APP=meshchatsync
5 | SERVICE_WRITE_PID=1
6 | SERVICE_DAEMONIZE=1
7 |
8 | start() {
9 | service_start /usr/local/bin/meshchatsync
10 | }
11 | stop() {
12 | service_stop /usr/local/bin/meshchatsync
13 | killall meshchatsync
14 | }
15 |
--------------------------------------------------------------------------------
/package/meshchat-api/control:
--------------------------------------------------------------------------------
1 | Package: meshchat-api
2 | Version:
3 | Depends: lua
4 | Provides:
5 | Source: $GITHUB_SERVER_URL/$GITHUB_REPOSITORY
6 | Section: net
7 | Priority: optional
8 | Maintainer: Tim Wilkinson (KN6PLV) and Trevor Paskett (K7FPV)
9 | Architecture: all
10 | Description: P2P distributed chat for mesh networks
11 |
--------------------------------------------------------------------------------
/package/populate-meshchat-api-fs.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # This script runs from the top of the project directory and
4 | # creates the filesystem image for the MeshChat API package.
5 |
6 | IPK_DIR=$1
7 |
8 | # Populate the CONTROL portion of the package
9 | mkdir -p $IPK_DIR/CONTROL
10 | cp -p package/meshchat-api/* $IPK_DIR/CONTROL/
11 | sed -i "s%\$GITHUB_SERVER_URL%$GITHUB_SERVER_URL%" $IPK_DIR/CONTROL/control
12 | sed -i "s%\$GITHUB_REPOSITORY%$GITHUB_REPOSITORY%" $IPK_DIR/CONTROL/control
13 |
14 | # Populate the filesystem image for the package
15 | install -D api/meshchat -m 755 $IPK_DIR/www/cgi-bin/meshchat
16 |
--------------------------------------------------------------------------------
/package/meshchat/preinst:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | /etc/init.d/meshchatsync stop > /dev/null 2> /dev/null
4 |
5 | mkdir -p /www/meshchat
6 |
7 | # if there is not a meshchat_local.lua, then prepare one
8 | if [ ! -f /www/cgi-bin/meshchat_local.lua ]; then
9 | if [ -f /www/cgi-bin/meshchatconfig.lua ]; then
10 | cp /www/cgi-bin/meshchatconfig.lua /www/cgi-bin/meshchat_local.lua
11 |
12 | # remove vars that should not be in meshchat_local.lua
13 | sed -i "/^protocol_version/d; /^app_version/d" /www/cgi-bin/meshchat_local.lua
14 | else
15 | touch /www/cgi-bin/meshchat_local.lua
16 | fi
17 | fi
18 |
19 | exit 0
20 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # MeshChat
2 |
3 | MeshChat for AREDN (in Lua). MeshChat has become the defacto standard
4 | chat application for AREDN networks. A number of features make it easy
5 | to implement and use:
6 |
7 | * Installable on AREDN firmware and most any Linux distribution
8 | * Automatic synchronization between nodes using the same service name
9 | * No account creation necessary--users access using call sign
10 | * Simple user interface
11 |
12 | If you are looking for a feature to be implemented or find a bug, please
13 | be sure to [create an issue](https://github.com/hickey/meshchat/issues/new)
14 | in the project so that it can be prioritized.
15 |
16 | Current documentation for MeshChat can be found at:
17 |
18 | https://hickey.github.io/meshchat
19 |
--------------------------------------------------------------------------------
/.release-it.yaml:
--------------------------------------------------------------------------------
1 | git:
2 | commit: true
3 | commitMessage: "chore(release): ${version}"
4 | commitArgs: ""
5 | tag: true
6 | tagName: "v${version}"
7 | tagAnnotation: "Automated release: ${version}"
8 | push: true
9 | requireBranch: release
10 | requireCommits: true
11 | changelog: "npx auto-changelog --stdout --commit-limit false"
12 |
13 | github:
14 | release: true
15 | releaseName: "v${version}"
16 |
17 | npm:
18 | publish: false
19 |
20 | plugins:
21 | "@release-it/conventional-changelog":
22 | infile: CHANGELOG.md
23 | preset:
24 | name: conventionalcommits
25 | types:
26 | - type: feat
27 | section: Features
28 | - type: fix
29 | section: Bug Fixes
30 | - tyep: docs
31 | section: Documentation
32 |
--------------------------------------------------------------------------------
/package/populate-meshchat-fs.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # This script runs from the top of the project directory and
4 | # creates the filesystem image for the MeshChat API package.
5 |
6 | IPK_DIR=$1
7 |
8 | # Populate the CONTROL portion of the package
9 | mkdir -p $IPK_DIR/CONTROL
10 | cp -p package/meshchat/* $IPK_DIR/CONTROL/
11 | sed -i "s%\$GITHUB_SERVER_URL%$GITHUB_SERVER_URL%" $IPK_DIR/CONTROL/control
12 | sed -i "s%\$GITHUB_REPOSITORY%$GITHUB_REPOSITORY%" $IPK_DIR/CONTROL/control
13 |
14 | # Populate the filesystem image for the package
15 | install -d $IPK_DIR/www/meshchat
16 | install www/* $IPK_DIR/www/meshchat
17 | install -d $IPK_DIR/www/cgi-bin
18 | install -m 755 meshchat $IPK_DIR/www/cgi-bin
19 | install -m 644 meshchatlib.lua $IPK_DIR/www/cgi-bin
20 | install -m 644 meshchatconfig.lua $IPK_DIR/www/cgi-bin
21 | install -D support/meshchatsync-init.d -m 755 $IPK_DIR/etc/init.d/meshchatsync
22 | install -D support/meshchatsync -m 755 $IPK_DIR/usr/local/bin/meshchatsync
23 |
--------------------------------------------------------------------------------
/.github/workflows/build-packages.yaml:
--------------------------------------------------------------------------------
1 | name: Build MeshChat Packages
2 | on: push
3 |
4 | jobs:
5 | calculate-version:
6 | runs-on: ubuntu-latest
7 | outputs:
8 | build_version: ${{ steps.build-version-slug.outputs.build_version }}
9 | steps:
10 | - uses: actions/checkout@v4
11 | with:
12 | fetch-depth: 0
13 | - id: build-version-slug
14 | run: |
15 | date=$(date +%Y%m%d)
16 | branch="${GITHUB_REF_NAME}"
17 | commit=$(git rev-parse --short HEAD)
18 | version="${date}-${branch}-${commit}"
19 |
20 | echo "build_version=$version" >> $GITHUB_OUTPUT
21 |
22 | build-meshchat-package:
23 | needs: calculate-version
24 | uses:
25 | ./.github/workflows/workflow-meshchat-package.yaml
26 | with:
27 | build_version: ${{ needs.calculate-version.outputs.build_version }}
28 | build_dir: package/meshchat-ipkg
29 |
30 | build-meshchat-api-package:
31 | needs: calculate-version
32 | uses:
33 | ./.github/workflows/workflow-meshchat-api-package.yaml
34 | with:
35 | build_version: ${{ needs.calculate-version.outputs.build_version }}
36 | build_dir: package/meshchat-ipkg
37 |
--------------------------------------------------------------------------------
/luadox.conf:
--------------------------------------------------------------------------------
1 | [project]
2 | # Project name that is displayed on the top bar of each page
3 | name = MeshChat
4 | # HTML title that is appended to every page. If not defined, name is used.
5 | title = MeshChat (master)
6 | # A list of files or directories for LuaDox to parse. Globs are supported.
7 | # This can be spread across multiple lines if you want, as long as the
8 | # other lines are indented.
9 | files = meshchat*
10 | #files = /data/src/data/www/cgi-bin/meshchat.lua /data/src/data/www/cgi-bin/meshchatlib.lua
11 | # The directory containing the rendered output files, which will be created
12 | # if necessary.
13 | outdir = _site
14 | # Path to a custom css file that will be included on every page. This will
15 | # be copied into the outdir.
16 | # css = custom.css
17 | # Path to a custom favicon. This will be copied into the outdir.
18 | # favicon = img/favicon.png
19 | # If require()d files discovered in source should also be parsed.
20 | follow = false
21 | # Character encoding for input files, which defaults to the current system
22 | # locale. Output files are always utf8.
23 | encoding = utf8
24 |
25 | [manual]
26 | index = README.md
27 | history = docs/History.md
28 | install = docs/Install.md
29 | troubleshoot = docs/Troubleshooting.md
30 |
--------------------------------------------------------------------------------
/package/meshchat/postinst:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | grep "|8080|meshchat" /etc/config.mesh/_setup.services.dmz &> /dev/null
4 | DMZPRESENT=$?
5 | grep "|8080|meshchat" /etc/config.mesh/_setup.services.nat &> /dev/null
6 | NATPRESENT=$?
7 | NODEMODE=$(uci -q -c /etc/local/uci/ get hsmmmesh.settings.config)
8 | RAND=$(awk 'BEGIN{srand();print int(rand()*10000) }')
9 | RESTART=0
10 |
11 | if [ "$DMZPRESENT" != 0 ]; then
12 | echo "MeshChat-$RAND|1|http|$(uname -n)|8080|meshchat" >> /etc/config.mesh/_setup.services.dmz
13 | RESTART=1
14 | fi
15 |
16 | if [ "$NATPRESENT" != 0 ]; then
17 | echo "MeshChat-$RAND|1|http|$(uname -n)|8080|meshchat" >> /etc/config.mesh/_setup.services.nat
18 | RESTART=1
19 | fi
20 |
21 | if [ "$NODEMODE" = "mesh" -a "$RESTART" = "1" ]; then
22 | echo "Applying service announcement"
23 | /usr/local/bin/node-setup -a -p mesh &> /dev/null
24 | /etc/init.d/olsrd restart &> /dev/null
25 | fi
26 |
27 | /etc/init.d/meshchatsync enable
28 | /etc/init.d/meshchatsync start
29 |
30 | echo " "
31 |
32 | echo "Mesh Chat has been setup at http://$(uname -n):8080/meshchat"
33 | echo " "
34 | if [ "$RESTART" = "1" ]; then
35 | echo "An advertised service has been added for Mesh Chat on the Services configuration page"
36 | fi
37 |
38 | exit 0
39 |
--------------------------------------------------------------------------------
/.github/workflows/workflow-meshchat-api-package.yaml:
--------------------------------------------------------------------------------
1 | name: Build MeshChat API Package
2 | on:
3 | workflow_call:
4 | inputs:
5 | build_version:
6 | required: true
7 | type: string
8 | build_dir:
9 | required: true
10 | type: string
11 | ref:
12 | required: false
13 | type: string
14 | default: ${{ github.ref_name }}
15 |
16 | jobs:
17 | create-meshchat-api-package:
18 | runs-on: ubuntu-latest
19 | # container:
20 | # image: registry.gitlab.com/wt0f/gitlab-runner-images/shell:latest
21 | steps:
22 | - uses: actions/checkout@v4
23 | with:
24 | fetch-depth: 0
25 | ref: ${{ inputs.ref }}
26 | - run: echo ${{ inputs.build_version }} > VERSION
27 | - run: package/populate-meshchat-api-fs.sh ${{ inputs.build_dir }}
28 | - run: package/update-version.sh ${{ inputs.build_dir }}
29 | - run: package/ipk-build.sh ${{ inputs.build_dir }}
30 | - id: detect-package-file
31 | run: echo "file=$(ls -1 meshchat-api_*.ipk)" >> $GITHUB_OUTPUT
32 | - run: echo "${{ steps.detect-package-file.outputs.file }}"
33 | - uses: actions/upload-artifact@v4
34 | with:
35 | name: ${{ steps.detect-package-file.outputs.file }}
36 | path: ${{ steps.detect-package-file.outputs.file }}
37 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/Feature Request.yml:
--------------------------------------------------------------------------------
1 | name: Feature Request
2 | description: Looking to add an enhancement to the MeshChat project
3 | title: "[Feature]: "
4 | labels:
5 | - enhancement
6 | assignees:
7 | - hickey
8 | body:
9 | - type: markdown
10 | attributes:
11 | value: |
12 | Thank you for taking the time to let us know about your idea. Please
13 | attempt to fill in as much information as you are able to.
14 | - type: input
15 | id: contact
16 | attributes:
17 | label: Contact Details
18 | description: How can we get in touch with you if we need more info?
19 | placeholder: ex. email@example.com
20 | validations:
21 | required: false
22 | - type: dropdown
23 | id: enhancement_type
24 | attributes:
25 | label: Enhancement Type
26 | description: What sort of enhancement is this?
27 | options:
28 | - Graphical interface
29 | - Message formatting
30 | - File sharing
31 | - API improvements
32 | - Documentation
33 | - Installation method
34 | - Other
35 | default: 0
36 | validations:
37 | required: true
38 | - type: textarea
39 | id: description
40 | attributes:
41 | label: What is your idea or what can be improved?
42 | description: Please be descriptive so that we can better understand the enhancement.
43 | placeholder: Tell us your idea.
44 | validations:
45 | required: true
46 |
47 |
--------------------------------------------------------------------------------
/.github/workflows/workflow-meshchat-package.yaml:
--------------------------------------------------------------------------------
1 | name: Build MeshChat Package
2 | on:
3 | workflow_call:
4 | inputs:
5 | build_version:
6 | required: true
7 | type: string
8 | build_dir:
9 | required: true
10 | type: string
11 | ref:
12 | required: false
13 | type: string
14 | default: ${{ github.ref_name }}
15 |
16 | jobs:
17 | create-meshchat-package:
18 | runs-on: ubuntu-latest
19 | # container:
20 | # image: registry.gitlab.com/wt0f/gitlab-runner-images/shell:latest
21 | outputs:
22 | package_file: ${{ steps.detect-package-file.outputs.file }}
23 | steps:
24 | - uses: actions/checkout@v4
25 | with:
26 | fetch-depth: 0
27 | ref: ${{ inputs.ref }}
28 | # - run: info "Populating the filesystem with MeshChat files"
29 | - run: echo ${{ inputs.build_version }} > VERSION
30 | - run: package/populate-meshchat-fs.sh ${{ inputs.build_dir }}
31 | # - run: info "Updating version numbers to "
32 | - run: package/update-version.sh ${{ inputs.build_dir }}
33 | # - run: info "Packing up MeshChat files"
34 | - run: package/ipk-build.sh ${{ inputs.build_dir }}
35 | - id: detect-package-file
36 | run: echo "file=$(ls -1 meshchat_*.ipk)" >> $GITHUB_OUTPUT
37 | - run: echo "${{ steps.detect-package-file.outputs.file }}"
38 | - uses: actions/upload-artifact@v4
39 | with:
40 | name: ${{ steps.detect-package-file.outputs.file }}
41 | path: ${{ steps.detect-package-file.outputs.file }}
42 |
--------------------------------------------------------------------------------
/www/ohsnap.js:
--------------------------------------------------------------------------------
1 | /**
2 | * == OhSnap!.js ==
3 | * A simple jQuery/Zepto notification library designed to be used in mobile apps
4 | *
5 | * author: Justin Domingue
6 | * date: september 18, 2015
7 | * version: 0.1.4
8 | * copyright - nice copyright over here
9 | */
10 |
11 | /* Shows a toast on the page
12 | * Params:
13 | * text: text to show
14 | * color: color of the toast. one of red, green, blue, orange, yellow or custom
15 | */
16 | function ohSnap(text, color, icon) {
17 | var icon_markup = "",
18 | html,
19 | time = '5000',
20 | $container = $('#ohsnap');
21 |
22 | if (icon) {
23 | icon_markup = " ";
24 | }
25 |
26 | // Generate the HTML
27 | html = $('
' + icon_markup + text + '
').fadeIn('fast');
28 |
29 | // Append the label to the container
30 | $container.append(html);
31 |
32 | // Remove the notification on click
33 | html.on('click', function() {
34 | ohSnapX($(this));
35 | });
36 |
37 | // After 'time' seconds, the animation fades out
38 | setTimeout(function() {
39 | ohSnapX(html);
40 | }, time);
41 | }
42 |
43 | function ohSnapX(element) {
44 | // Called without argument, the function removes all alerts
45 | // element must be a jQuery object
46 |
47 | if (typeof element !== "undefined") {
48 | element.fadeOut('fast', function() {
49 | $(this).remove();
50 | });
51 | } else {
52 | $('.alert').fadeOut('fast', function() {
53 | $(this).remove();
54 | });
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/www/status.js:
--------------------------------------------------------------------------------
1 | var last_update = epoch();
2 |
3 | $(function() {
4 | load_status();
5 | setInterval(function(){ load_status() }, 5000);
6 | setInterval(function() { monitor_last_update() }, 2500);
7 | });
8 |
9 | function monitor_last_update() {
10 | var secs = epoch() - last_update;
11 | $('#last-update').html('Updated: ' + secs + ' seconds ago');
12 | }
13 |
14 | function load_status() {
15 | $.getJSON('/cgi-bin/meshchat?action=sync_status', function(data) {
16 | var html = '';
17 | var count = 0;
18 |
19 | for (var i = 0; i < data.length; i++) {
20 | var date = new Date(0);
21 | date.setUTCSeconds(data[i].epoch);
22 |
23 | //if ((epoch() - data[i].epoch) > 60 * 60) continue;
24 |
25 | html += '
';
26 | html += '
' + data[i].node + '
';
27 | html += '
' + format_date(date) + '
';
28 | html += '
';
29 |
30 | count++;
31 | }
32 |
33 | $('#sync-table').html(html);
34 | $('#sync-count').html(count);
35 |
36 | last_update = epoch();
37 | });
38 |
39 | $.getJSON('/cgi-bin/meshchat?action=action_log', function(data) {
40 | var html = '';
41 |
42 | for (var i = 0; i < data.length; i++) {
43 | var date = new Date(0);
44 | date.setUTCSeconds(data[i].action_epoch);
45 |
46 | html += '
';
47 | html += '
' + format_date(date) + '
';
48 | html += '
' + data[i].script + '
';
49 | html += '
' + data[i].result + '
';
50 | html += '
' + data[i].message + '
';
51 | html += '
';
52 | }
53 |
54 | $('#log-table').html(html);
55 |
56 | last_update = epoch();
57 | });
58 | }
59 |
--------------------------------------------------------------------------------
/www/shared.js:
--------------------------------------------------------------------------------
1 | var config;
2 |
3 | $(function() {
4 | $('#logout').on('click', function(e){
5 | e.preventDefault();
6 | Cookies.remove('meshchat_call_sign');
7 | window.location = '/meshchat';
8 | });
9 | });
10 |
11 | function node_name() {
12 | return config.node;
13 | }
14 |
15 | function platform() {
16 | return config.platform || 'node'; // TODO temp patch until config API is updated
17 | }
18 |
19 | function epoch() {
20 | return Math.floor(new Date() / 1000);
21 | }
22 |
23 | function format_date(date) {
24 | var string;
25 |
26 | var year = String(date.getFullYear());
27 |
28 | string = (date.getMonth()+1) + '/' + date.getDate() + '/' + year.slice(-2);
29 | string += ' ';
30 |
31 | var hours = date.getHours();
32 | var minutes = date.getMinutes();
33 | var ampm = hours >= 12 ? 'PM' : 'AM';
34 |
35 | hours = hours % 12;
36 | hours = hours ? hours : 12; // the hour '0' should be '12'
37 | minutes = minutes < 10 ? '0'+minutes : minutes;
38 |
39 | string += hours + ':' + minutes + ' ' + ampm;
40 |
41 | return string;
42 | }
43 |
44 | function make_id()
45 | {
46 | var text = "";
47 | var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
48 |
49 | for( var i=0; i < 5; i++ )
50 | text += possible.charAt(Math.floor(Math.random() * possible.length));
51 |
52 | return text;
53 | }
54 |
55 | function aredn_domain(host) {
56 | if (host.indexOf(".") !== -1) {
57 | return host;
58 | }
59 | host = host.split(":")
60 | return host[0] + ".local.mesh" + (host[1] ? ":" + host[1] : "");
61 | }
62 |
63 | function debug(msg) {
64 | context.debug && console.debug(msg);
65 | }
66 |
67 | function error(msg) {
68 | console.error(msg);
69 | }
70 |
--------------------------------------------------------------------------------
/package/update-version.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # This script runs from the top of the project directory and
4 | # updates the version number in the control file for the package
5 | # being built.
6 |
7 | IPK_DIR=$1
8 |
9 | if [[ -f VERSION ]]; then
10 | version=$(cat VERSION)
11 | else
12 | if [[ "${GITHUB_REF_TYPE}" == 'tag' ]]; then
13 | # ideally should only get version tags (i.e. 'v' followed by a number)
14 | if [[ "${GITHUB_REF_NAME}" =~ ^v[0-9].* ]]; then
15 | version="${GITHUB_REF_NAME#v}"
16 | fi
17 | elif [[ -n "${CI_COMMIT_TAG}" ]]; then
18 | # ideally should only get version tags (i.e. 'v' followed by a number)
19 | if [[ "${CI_COMMIT_TAG}" =~ ^v[0-9].* ]]; then
20 | version="${CI_COMMIT_TAG#v}"
21 | fi
22 | else
23 | # branch gets date code-branch_name-commit
24 | date=$(date +%Y%m%d)
25 | branch=$(git rev-parse --abbrev-ref HEAD)
26 | # maybe a detached head, so check common vars for branch name
27 | if [[ -n "${CI_COMMIT_REF_NAME}" ]]; then
28 | branch="${CI_COMMIT_REF_NAME}"
29 | elif [[ -n "${GITHUB_REF_NAME}" ]]; then
30 | branch="${GITHUB_REF_NAME}"
31 | fi
32 | commit=$(git rev-parse --short HEAD)
33 | version="${date}-${branch}-${commit}"
34 | fi
35 | fi
36 |
37 | # write the version to a VERSION file
38 | echo "${version}" > VERSION
39 | echo "Updating code references to version ${version}"
40 |
41 | sed -i "s/^Version:.*/Version: $version/" $IPK_DIR/CONTROL/control
42 |
43 | # Update the version in meshchatconfig.lua if present
44 | if [[ -f $IPK_DIR/www/cgi-bin/meshchatconfig.lua ]]; then
45 | sed -i "s/^app_version.*$/app_version = \"${version}\"/" $IPK_DIR/www/cgi-bin/meshchatconfig.lua
46 | fi
47 |
--------------------------------------------------------------------------------
/docs/History.md:
--------------------------------------------------------------------------------
1 | # History of MeshChat
2 |
3 | This is the history of the various MeshChat versions that have existed--at
4 | least to the best of my knowledge.
5 |
6 | ## MeshChat v0.4 - v1.02
7 |
8 | This was the original version of MeshChat written by Trevor Paskett (K7FPV)
9 | around 2015. It was written in Perl and worked well on the limited resources
10 | of the AREDN nodes. Around 2018 Trevor was not able to or not interested
11 | in supporting MeshChat any longer, it is unclear which but the project
12 | became stagnant at version v1.01 in August of 2018. There was a final
13 | release of v1.02 in September 2022 that mostly added a few patches and
14 | support for Debian Stretch.
15 |
16 | The K7FPV code base still exists at https://github.com/tpaskett/meshchat.
17 |
18 | In addition Trevor wrote a good amount of documentation for his versions
19 | which is still pretty well covers the current versions of MeshChat.
20 | The documentation can be found over at his blog, https://github.com/tpaskett/meshchat.
21 |
22 | ## MeshChat v2.0 - v2.10
23 |
24 | When AREDN firmware v3.22.6.0 was released in June 2022, the AREDN development
25 | team stopped including Perl in the distribution in favor of LUA. In preparation
26 | of this change Tim Wilkinson (KN6PLV) started rewriting MeshChat in LUA
27 | March 2022 with the first release of the new code base in April 2022. The
28 | new MeshChat code continued to receive bug fixes for a year. At which
29 | time Tim's involvement on the AREDN development team prevented him from
30 | continuing to maintain MeshChat.
31 |
32 | ## Future of MeshChat
33 |
34 | That brings the story upto the current time, September 2023, where I,
35 | Gerard Hickey (WT0F), have started to be the maintainer of the MeshChat
36 | code base. There has already been work to restructure the repository to
37 | make working with the code more effective and to automatically build
38 | packages when a release occurs.
39 |
--------------------------------------------------------------------------------
/.github/workflows/publish-docs.yaml:
--------------------------------------------------------------------------------
1 | name: Publish MeshChat Documentation
2 | on:
3 | workflow_call:
4 | inputs:
5 | build_version:
6 | required: true
7 | type: string
8 |
9 | jobs:
10 | build:
11 | runs-on: ubuntu-latest
12 | container:
13 | image: jtackaberry/luadox:latest
14 | steps:
15 | - uses: actions/checkout@v4
16 | with:
17 | fetch-depth: 0
18 | ref: release
19 | - run: luadox -c luadox.conf
20 | - name: Fix permissions
21 | run: |
22 | chmod -c -R +rX "_site/" | while read line; do
23 | echo "::warning title=Invalid file permissions automatically fixed::$line"
24 | done
25 | - name: Update version strings
26 | run: |
27 | find docs -type f -exec sed -i "s/%VERSION%/${{ inputs.build_version }}/" {} \;
28 | - run: |
29 | echo ::group::Archive artifact
30 | tar -C "_site" \
31 | -cvf "$RUNNER_TEMP/artifact.tar" \
32 | --exclude=.git \
33 | --exclude=.github \
34 | .
35 | echo ::endgroup::
36 | - name: Upload artifact
37 | id: upload-artifact
38 | uses: actions/upload-artifact@v4
39 | with:
40 | name: github-pages
41 | path: ${{ runner.temp }}/artifact.tar
42 | retention-days: 1
43 | if-no-files-found: error
44 |
45 | # Deploy job
46 | deploy:
47 | needs: build
48 |
49 | # Grant GITHUB_TOKEN the permissions required to make a Pages deployment
50 | permissions:
51 | pages: write # to deploy to Pages
52 | id-token: write # to verify the deployment originates from an appropriate source
53 |
54 | # Deploy to the github-pages environment
55 | environment:
56 | name: github-pages
57 | url: ${{ steps.deployment.outputs.page_url }}
58 |
59 | # Specify runner + deployment step
60 | runs-on: ubuntu-latest
61 | steps:
62 | - name: Deploy to GitHub Pages
63 | id: deployment
64 | uses: actions/deploy-pages@v4 # or specific "vX.X.X" version tag for this action
65 |
--------------------------------------------------------------------------------
/docs/Install.md:
--------------------------------------------------------------------------------
1 | # Installing MeshChat
2 |
3 | MeshChat is distributed as an Itsy package (IPK file) to be installed on an
4 | AREDN node. This is the simplest way to install MeshChat.
5 |
6 | Simply download the MeshChat package to your compute and then access the
7 | Administration panel in the AREDN's node setup. Under Package Management
8 | you will have the option to upload a package. Once uploaded the MeshChat
9 | system will be started within a couple of seconds.
10 |
11 | Usually there is not really any configuration that needs to be done, but
12 | review of the [configuration settings](../module/meshchatconfig.html) is
13 | suggested.
14 |
15 | Starting with `v2.12.0` the configuration of MeshChat occurs in the file
16 | `/www/cgi-bin/meshchat_local.lua`. Any configuration settings that need
17 | to be modified need to be entered into the `meshchat_local.lua` file and
18 | not in the `meshchatconfig.lua` file that previous version used to
19 | configure MeshChat. Making changes to `meshchatconfig.lua` will be lost
20 | when MeshChat is upgraded or downgraded. Making changes to the configuration
21 | still requires one to SSH into the node and edit `meshchat_local.lua`
22 | directly.
23 |
24 | ## Setting the MeshChat Zone Name
25 |
26 | MeshChat uses a zone name to locate other MeshChat servers running with
27 | the same zone name. Once servers are added to the same zone name, they
28 | will automatically synchronize their message databases with one another.
29 | Setting the zone name is done in the AREDN node adminstration settings
30 | under the advertised services.
31 |
32 | After a new install of MeshChat the installation will randomly generate
33 | a zone name and register it with the AREDN node. The service name
34 | (i.e. zone name) can be changed to the desired zone name used by other
35 | MeshChat servers. Once the service name has been saved, it is best to
36 | reboot the AREDN node to insure that MeshChat is restarted with the
37 | correct zone name.
38 |
39 | ## Installing MeshChat on Linux
40 |
41 | The current distribution of MeshChat does not currently support Linux. In
42 | order to run MeshChat on a Linux machine, one needs to download MeshChat
43 | v1.0.2 and install it on the Linux machine. Once installed, the configuration
44 | need to be updated to set the `api_host` setting to the hostname or IP
45 | of an AREDN node that has the MeshChat API package installed.
46 |
--------------------------------------------------------------------------------
/api/meshchat:
--------------------------------------------------------------------------------
1 | #!/usr/bin/lua
2 | --[[
3 |
4 | Part of AREDN -- Used for creating Amateur Radio Emergency Data Networks
5 | Copyright (C) 2022 Tim Wilkinson
6 | Base on code (C) Trevor Paskett (see https://github.com/tpaskett)
7 | See Contributors file for additional contributors
8 |
9 | This program is free software: you can redistribute it and/or modify
10 | it under the terms of the GNU General Public License as published by
11 | the Free Software Foundation version 3 of the License.
12 |
13 | This program is distributed in the hope that it will be useful,
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | GNU General Public License for more details.
17 |
18 | You should have received a copy of the GNU General Public License
19 | along with this program. If not, see .
20 |
21 | Additional Terms:
22 |
23 | Additional use restrictions exist on the AREDN(TM) trademark and logo.
24 | See AREDNLicense.txt for more info.
25 |
26 | Attributions to the AREDN Project must be retained in the source code.
27 | If importing this code into a new or existing project attribution
28 | to the AREDN project must be added to the source code.
29 |
30 | You must not misrepresent the origin of the material contained within.
31 |
32 | Modified versions must be modified to attribute to the original source
33 | and be marked in reasonable ways as differentiate it from the original
34 | version
35 |
36 | --]]
37 |
38 | require('nixio')
39 | require('luci.http')
40 |
41 | function str_escape(str)
42 | return str:gsub("%(", "%%("):gsub("%)", "%%)"):gsub("%%", "%%%%"):gsub("%.", "%%."):gsub("%+", "%%+"):gsub("-", "%%-"):gsub("%*", "%%*"):gsub("%[", "%%["):gsub("%?", "%%?"):gsub("%^", "%%^"):gsub("%$", "%%$")
43 | end
44 |
45 | local query = {}
46 | if os.getenv("QUERY_STRING") ~= "" then
47 | query = luci.http.Request(nixio.getenv()):formvalue()
48 | end
49 |
50 | print("Content-type: text/plain\r")
51 | print("\r")
52 | if query.action == "meshchat_nodes" then
53 | local pattern = "http://(%S+):(%d+)/meshchat|tcp|" .. str_escape(query.zone_name) .. "%s"
54 | for line in io.lines("/var/run/services_olsr")
55 | do
56 | local node, port = line:match(pattern)
57 | if node and port then
58 | print(node .. "\t" .. port)
59 | end
60 | end
61 | else
62 | print("error no action")
63 | end
64 |
--------------------------------------------------------------------------------
/.github/workflows/release-meshchat.yaml:
--------------------------------------------------------------------------------
1 | name: Release MeshChat Package
2 | on: workflow_dispatch
3 |
4 | jobs:
5 | create-release:
6 | runs-on: ubuntu-latest
7 | # container:
8 | # image: registry.gitlab.com/wt0f/gitlab-runner-images/node:latest
9 | outputs:
10 | build_version: ${{ steps.detect_version.outputs.build_version }}
11 | env:
12 | GITHUB_TOKEN: ${{ secrets.RELEASE_IT_TOKEN }}
13 | steps:
14 | - uses: actions/checkout@v4
15 | with:
16 | fetch-depth: 0
17 | ref: release
18 | - name: git config
19 | run: |
20 | git config user.name "${GITHUB_ACTOR}"
21 | git config user.email "${GITHUB_ACTOR}@users.noreply.github.com"
22 | - run: npm install -g release-it @release-it/conventional-changelog @commitlint/config-conventional @commitlint/cli auto-changelog
23 | - id: detect_version
24 | run: echo "build_version=$(npx release-it --release-version)" >> $GITHUB_OUTPUT
25 | - run: npx release-it -VV --ci
26 | # - run: git checkout master
27 | # - run: git rebase release
28 | # - run: git push
29 |
30 | build-meshchat-package:
31 | needs: create-release
32 | uses:
33 | ./.github/workflows/workflow-meshchat-package.yaml
34 | with:
35 | ref: release
36 | build_version: ${{ needs.create-release.outputs.build_version }}
37 | build_dir: package/meshchat-ipkg
38 |
39 | build-meshchat-api-package:
40 | needs: create-release
41 | uses:
42 | ./.github/workflows/workflow-meshchat-api-package.yaml
43 | with:
44 | build_version: ${{ needs.create-release.outputs.build_version }}
45 | build_dir: package/meshchat-ipkg
46 |
47 | add-meshchat-package-to-release:
48 | needs:
49 | - build-meshchat-package
50 | - build-meshchat-api-package
51 | # container:
52 | # image: registry.gitlab.com/wt0f/gitlab-runner-images/node:latest
53 | runs-on: ubuntu-latest
54 | steps:
55 | - uses: actions/checkout@v4
56 | with:
57 | fetch-depth: 0
58 | fetch-tags: true
59 | - run: git pull
60 | - run: npm install -g release-it @release-it/conventional-changelog @commitlint/config-conventional @commitlint/cli auto-changelog
61 | - uses: actions/download-artifact@v4
62 | with:
63 | name: ${{ needs.release_meshchat_package.outputs.package_file }}
64 | path: ${{ needs.release_meshchat_package.outputs.package_file }}
65 | - run: |
66 | for file in *.ipk; do
67 | echo "uploading $file"
68 | npx release-it --ci --no-increment --no-git --no-npm --github.update=true --github.assets=$file
69 | done
70 | env:
71 | GITHUB_TOKEN: ${{ secrets.RELEASE_IT_TOKEN }}
72 |
73 | update-documentation:
74 | needs: create-release
75 | uses:
76 | ./.github/workflows/publish-docs.yaml
77 | with:
78 | build_version: ${{ needs.create-release.outputs.build_version }}
79 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | ## [2.12.1](https://github.com/hickey/meshchat/compare/v2.12.0...v2.12.1) (2024-08-20)
4 |
5 |
6 | ### Bug Fixes
7 |
8 | * Update zone name discovery to ignore icon metadata ([#52](https://github.com/hickey/meshchat/issues/52)) ([5c3f03a](https://github.com/hickey/meshchat/commit/5c3f03a31ad0d7b96f9e01d9785a7ebef2bd64f2))
9 |
10 | ## [2.12.0](https://github.com/hickey/meshchat/compare/v2.11.2...v2.12.0) (2024-03-03)
11 |
12 |
13 | ### Features
14 |
15 | * add message class abstracting message handling ([#23](https://github.com/hickey/meshchat/issues/23)) ([28d1759](https://github.com/hickey/meshchat/commit/28d17592f7ee1a778fdd0bc740f451646493f9dd))
16 | * Add support for meshchat_local.lua ([#47](https://github.com/hickey/meshchat/issues/47)) ([b51bb16](https://github.com/hickey/meshchat/commit/b51bb16baa0abf7f72a895471712e0bdb6d7a44d))
17 | * allow admin to set default channel ([#19](https://github.com/hickey/meshchat/issues/19)) ([d90fc33](https://github.com/hickey/meshchat/commit/d90fc33eafecd31fec2dc825d8388f8e98ae8fd0))
18 | * Set send channel when channel filter changed ([f26130b](https://github.com/hickey/meshchat/commit/f26130ba5f06f9b4fbd26257be8d967a61e531bc))
19 |
20 |
21 | ### Bug Fixes
22 |
23 | * recover code lost from bad merges ([9ad1637](https://github.com/hickey/meshchat/commit/9ad163784ba66b1b42ec0b695a37104c3d8a348d))
24 | * remove duplicate config definitions ([57d2766](https://github.com/hickey/meshchat/commit/57d2766d1bece87138ff4b76053e3316955454a0))
25 | * Set caller to unknown_caller for notified functions ([7856502](https://github.com/hickey/meshchat/commit/78565026aae76dee20751e483f38f0bc7bfb94ad))
26 | * set epoch in send_message API even if not specified ([bfadccb](https://github.com/hickey/meshchat/commit/bfadccb3f8010c51374e206d78585b22ac86848a))
27 |
28 | ## [2.11.2](https://github.com/hickey/meshchat/compare/v2.11.1...v2.11.2) (2024-03-02)
29 |
30 |
31 | ### Bug Fixes
32 |
33 | * recover code lost from bad merges ([05c8dff](https://github.com/hickey/meshchat/commit/05c8dff7192941651145a4423916de46797adf3e))
34 | * remove duplicate config definitions ([53dd0c6](https://github.com/hickey/meshchat/commit/53dd0c6785167537430e592e0d6d895499ac3ce7))
35 |
36 | ## [2.11.1](https://github.com/hickey/meshchat/compare/v2.11.0...v2.11.1) (2024-03-02)
37 |
38 |
39 | ### Bug Fixes
40 |
41 | * remove duplicate config definitions ([#46](https://github.com/hickey/meshchat/issues/46)) ([a6cb468](https://github.com/hickey/meshchat/commit/a6cb468ca0fa594629a1bae0e22781dfc0bf074e))
42 |
43 | ## [2.11.0](https://github.com/hickey/meshchat/compare/v2.10.0...v2.11.0) (2024-03-01)
44 |
45 |
46 | ### Features
47 |
48 | * allow admin to set default channel ([#19](https://github.com/hickey/meshchat/issues/19)) ([a1374f0](https://github.com/hickey/meshchat/commit/a1374f03da7d6cad218bee3e8486c707141f184c))
49 | * Add documentation (#44)
50 | * Add message class abstracting message handling (#23)
51 | * Set send channel when channel filter changed
52 |
53 | ### Bug fixes
54 |
55 | * Discover zone name from /etc/config.mesh (#36)
56 | * set epoch in send_message API even if not specified
57 |
--------------------------------------------------------------------------------
/docs/Troubleshooting.md:
--------------------------------------------------------------------------------
1 | # Troubleshooting
2 |
3 | This is a "living" document. It is attempted to keep it up to date with
4 | any new problems and troubleshooting techniques. If you find something
5 | missing, please create an [Issue](https://github.com/hickey/meshchat/issues/new/choose)
6 | do describe what problem or issue is missing. Better yet is to fork the
7 | MeshChat repository, update the documentation in the forked repository
8 | and then generate a PR back to the official MeshChat repository. Your
9 | efforts will be greatly appreciated.
10 |
11 | It is important to realize that MeshChat is effectively two separate
12 | programs: one that runs in your browser (the frontend code) and one that
13 | runs on the AREDN node (the backend code or API). While it may not be
14 | obvious which piece of code is having the problem, it generally can be
15 | broken down as if there is an issue with the format of a message or it
16 | being displayed in the browser then the frontend code should be investigated.
17 | Otherwise the API should be investigated.
18 |
19 | ## Installation Issues
20 |
21 | There is a known issue that if an older AREDN firmware is being upgraded,
22 | any additional packages will need to be reinstalled after the node has
23 | completed the firmware upgrade. This should not be the case for AREDN
24 | firmware 3.23.8.0 or greater.
25 |
26 | If it appears that the installation of the package did not completely
27 | install or is not fully functional, check the node to determine how much
28 | disk space is available. Generally one should plan on a minimum of 100 KB
29 | of disk space for MeshChat to operate.
30 |
31 | Package installation failures also generally have an error message displayed
32 | above the upload button when there is a failure. This can help indicate
33 | what the failure type was, so it should be reported back as a project
34 | issue using the link above.
35 |
36 | ## Message Synchronization Issues
37 |
38 | In order for messages to be synchronized between MeshChat instances, the
39 | `meshchatsync` process needs to be running. Log into the node and execute
40 | `ps | grep meshchatsync` to see if the process exists. If it is not
41 | running, then one can start it with executing `/usr/local/bin/meshchatsync`.
42 | Doing so will keep the process attached to the current terminal and any
43 | error output will be displayed in the terminal. Once the terminal is
44 | exited, the `meshchatsync` process will terminate. So after determining
45 | that there are no errors being generated, it is best to reboot the node.
46 | This will allow `meshchatsync` to startup normally with no manual
47 | intervention.
48 |
49 | If it appears that `meshchatsync` is operating correctly, then the next
50 | item to check is that the message database exists and messages are being
51 | written to it. On an AREDN node, the message database is normally located
52 | in `/tmp/meshchat`. Check for a `messages.`. If the message
53 | database does exist, post a new message in the MeshChat instance on the
54 | node and insure that the message gets written to the message database.
55 |
56 | Also insure that the message database has write permissions on the file.
57 |
58 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/Bug Report.yml:
--------------------------------------------------------------------------------
1 | name: Bug Report
2 | description: File a bug for the MeshChat project
3 | title: "[Bug]: "
4 | labels:
5 | - bug
6 | - needs triage
7 | assignees:
8 | - hickey
9 | body:
10 | - type: markdown
11 | attributes:
12 | value: |
13 | Thank you for taking the time to create a bug report. Please
14 | attempt to fill in as much information as you are able to.
15 | - type: input
16 | id: contact
17 | attributes:
18 | label: Contact Details
19 | description: How can we get in touch with you if we need more info?
20 | placeholder: ex. email@example.com
21 | validations:
22 | required: false
23 | - type: dropdown
24 | id: version
25 | attributes:
26 | label: Version
27 | description: Version of MeshChat?
28 | options:
29 | - v1.x
30 | - v2.0 - v2.8
31 | - v2.9
32 | - v2.10
33 | - v2.12.0
34 | - development build (include version in what happened)
35 | default: 0
36 | validations:
37 | required: true
38 | - type: dropdown
39 | id: system_type
40 | attributes:
41 | label: System Type
42 | description: What type of system is MeshChat installed on?
43 | options:
44 | - AREDN node
45 | - Linux
46 | - Unknown
47 | default: 0
48 | validations:
49 | required: true
50 | - type: textarea
51 | id: what-happened
52 | attributes:
53 | label: What happened?
54 | description: Also tell us, what did you expect to happen?
55 | placeholder: |
56 | Describe to the best of your ability what happened or what you
57 | did to trigger the problem.
58 | validations:
59 | required: true
60 | - type: textarea
61 | id: config
62 | attributes:
63 | label: MeshChat configuration
64 | description: |
65 | If you are the admin of the MeshChat instance, it is asked that
66 | you past your MeshChat configuration file between the back ticks
67 | to aid in troubleshooting.
68 | value: |
69 | ```
70 |
71 | ```
72 | - type: dropdown
73 | id: connection_type
74 | attributes:
75 | label: Connection type
76 | multiple: false
77 | description: |
78 | How is the node that is running the MeshChat instance connected?
79 | If you know the mesh network that the node is connected to please
80 | indicate the name of the mesh network below in the node name field.
81 | options:
82 | - Non-connected mesh network
83 | - Mesh network connected through IP tunnel
84 | - Mesh network connected through a supernode
85 | - I don't know
86 | - type: input
87 | id: node_name
88 | attributes:
89 | label: Node name
90 | description: Please specify the node name where MeshChat runs.
91 | - type: dropdown
92 | id: browsers
93 | attributes:
94 | label: What browsers are you seeing the problem on?
95 | multiple: true
96 | options:
97 | - Firefox
98 | - Chrome
99 | - Safari
100 | - Microsoft Edge
101 | - Brave
102 | - Vivialdi
103 | - Other
104 |
--------------------------------------------------------------------------------
/package/ipk-build.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # ipkg-build -- construct a .ipk from a directory
3 | # Carl Worth
4 | # based on a script by Steve Redler IV, steve@sr-tech.com 5-21-2001
5 | set -e
6 |
7 | ipkg_extract_value() {
8 | sed -e "s/^[^:]*:[[:space:]]*//"
9 | }
10 |
11 | required_field() {
12 | field=$1
13 |
14 | value=`grep "^$field:" < $CONTROL/control | ipkg_extract_value`
15 | if [ -z "$value" ]; then
16 | echo "ipkg-build: Error: $CONTROL/control is missing field $field" ;
17 | PKG_ERROR=1
18 | fi
19 | echo $value
20 | }
21 |
22 | pkg_appears_sane() {
23 | local pkg_dir=$1
24 |
25 | local owd=`pwd`
26 | cd $pkg_dir
27 |
28 | PKG_ERROR=0
29 | if [ ! -f "$CONTROL/control" ]; then
30 | echo "ipkg-build: Error: Control file $pkg_dir/$CONTROL/control not found."
31 | cd $owd
32 | return 1
33 | fi
34 |
35 | pkg=`required_field Package`
36 | version=`required_field Version`
37 | arch=`required_field Architecture`
38 | required_field Maintainer >/dev/null
39 | required_field Description >/dev/null
40 |
41 | if echo $pkg | grep '[^a-z0-9.+-]'; then
42 | echo "ipkg-build: Error: Package name $name contains illegal characters, (other than [a-z0-9.+-])"
43 | PKG_ERROR=1;
44 | fi
45 |
46 | local bad_fields=`sed -ne 's/^\([^[:space:]][^:[:space:]]\+[[:space:]]\+\)[^:].*/\1/p' < $CONTROL/control | sed -e 's/\\n//'`
47 | if [ -n "$bad_fields" ]; then
48 | bad_fields=`echo $bad_fields`
49 | echo "ipkg-build: Error: The following fields in $CONTROL/control are missing a ':'"
50 | echo " $bad_fields"
51 | echo "ipkg-build: This may be due to a missing initial space for a multi-line field value"
52 | PKG_ERROR=1
53 | fi
54 |
55 | for script in $CONTROL/preinst $CONTROL/postinst $CONTROL/prerm $CONTROL/postrm; do
56 | if [ -f $script -a ! -x $script ]; then
57 | echo "ipkg-build: Error: package script $script is not executable"
58 | PKG_ERROR=1
59 | fi
60 | done
61 |
62 | if [ -f $CONTROL/conffiles ]; then
63 | for cf in `cat $CONTROL/conffiles`; do
64 | if [ ! -f ./$cf ]; then
65 | echo "ipkg-build: Error: $CONTROL/conffiles mentions conffile $cf which does not exist"
66 | PKG_ERROR=1
67 | fi
68 | done
69 | fi
70 |
71 | cd $owd
72 | return $PKG_ERROR
73 | }
74 |
75 | ###
76 | # ipkg-build "main"
77 | ###
78 |
79 | case $# in
80 | 1)
81 | dest_dir=.
82 | ;;
83 | 2)
84 | dest_dir=$2
85 | ;;
86 | *)
87 | echo "Usage: ipkg-build []" ;
88 | exit 1
89 | ;;
90 | esac
91 |
92 | pkg_dir=$1
93 |
94 | if [ ! -d $pkg_dir ]; then
95 | echo "ipkg-build: Error: Directory $pkg_dir does not exist"
96 | exit 1
97 | fi
98 |
99 | # CONTROL is second so that it takes precedence
100 | CONTROL=
101 | [ -d $pkg_dir/DEBIAN ] && CONTROL=DEBIAN
102 | [ -d $pkg_dir/CONTROL ] && CONTROL=CONTROL
103 | if [ -z "$CONTROL" ]; then
104 | echo "ipkg-build: Error: Directory $pkg_dir has no CONTROL subdirectory."
105 | exit 1
106 | fi
107 |
108 | if ! pkg_appears_sane $pkg_dir; then
109 | echo "Please fix the above errors and try again."
110 | exit 1
111 | fi
112 |
113 | tmp_dir=$dest_dir/IPKG_BUILD.$$
114 | mkdir $tmp_dir
115 |
116 | tar -C $pkg_dir --exclude=$CONTROL -czf $tmp_dir/data.tar.gz .
117 | tar -C $pkg_dir/$CONTROL -czf $tmp_dir/control.tar.gz .
118 |
119 | echo "2.0" > $tmp_dir/debian-binary
120 |
121 | pkg_file=$dest_dir/${pkg}_${version}_${arch}.ipk
122 | tar -C $tmp_dir -czf $pkg_file debian-binary data.tar.gz control.tar.gz
123 | rm $tmp_dir/debian-binary $tmp_dir/data.tar.gz $tmp_dir/control.tar.gz
124 | rmdir $tmp_dir
125 |
126 | echo "Packaged contents of $pkg_dir into $pkg_file"
127 |
--------------------------------------------------------------------------------
/meshchatconfig.lua:
--------------------------------------------------------------------------------
1 | --[[
2 | STOP STOP STOP DO NOT EDIT THIS FILE
3 |
4 | This file is used to set default values for MeshChat and should NOT
5 | be edited. Edits made to this file WILL BE LOST when upgrading or
6 | downgrading MeshChat. All the values below can be overridden by
7 | adding them to the meshchat_local.lua file located in the same
8 | directory as this file.
9 |
10 | EDIT THIS FILE AT YOUR PERIL. YOU HAVE BEEN WARNED.
11 |
12 |
13 | Part of AREDN -- Used for creating Amateur Radio Emergency Data Networks
14 | Copyright (C) 2022 Tim Wilkinson
15 | Base on code (C) Trevor Paskett (see https://github.com/tpaskett)
16 | See Contributors file for additional contributors
17 |
18 | This program is free software: you can redistribute it and/or modify
19 | it under the terms of the GNU General Public License as published by
20 | the Free Software Foundation version 3 of the License.
21 |
22 | This program is distributed in the hope that it will be useful,
23 | but WITHOUT ANY WARRANTY; without even the implied warranty of
24 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 | GNU General Public License for more details.
26 |
27 | You should have received a copy of the GNU General Public License
28 | along with this program. If not, see .
29 |
30 | Additional Terms:
31 |
32 | Additional use restrictions exist on the AREDN(TM) trademark and logo.
33 | See AREDNLicense.txt for more info.
34 |
35 | Attributions to the AREDN Project must be retained in the source code.
36 | If importing this code into a new or existing project attribution
37 | to the AREDN project must be added to the source code.
38 |
39 | You must not misrepresent the origin of the material contained within.
40 |
41 | Modified versions must be modified to attribute to the original source
42 | and be marked in reasonable ways as differentiate it from the original
43 | version
44 |
45 | --]]
46 |
47 | ---
48 | -- @module meshchatconfig
49 | -- @section MeshChat Configuration
50 |
51 | --- Base directory to store all MeshChat generated files
52 | -- @type string
53 | meshchat_path = "/tmp/meshchat"
54 | --- Maximum number of messages in the database
55 | -- @type int
56 | max_messages_db_size = 500
57 | --- Maximum amount of filesystem space for storing files
58 | -- @type int
59 | max_file_storage = 512 * 1024
60 | lock_file = meshchat_path .. "/lock"
61 | messages_db_file = meshchat_path .. "/messages"
62 | messages_db_file_orig = meshchat_path .. "/messages"
63 | sync_status_file = meshchat_path .. "/sync_status"
64 | local_users_status_file = meshchat_path .. "/users_local"
65 | remote_users_status_file = meshchat_path .. "/users_remote"
66 | remote_files_file = meshchat_path .. "/files_remote"
67 | messages_version_file = meshchat_path .. "/messages_version"
68 | local_files_dir = meshchat_path .. "/files"
69 | tmp_upload_dir = "/tmp/web/upload"
70 | --- How often to check for new messages
71 | -- @type int
72 | poll_interval = 10
73 | non_meshchat_poll_interval = 600
74 | valid_future_message_time = 30 * 24 * 60 * 60
75 | connect_timeout = 5
76 | speed_time = 10
77 | speed_limit = 1000
78 | --- Type of node that MeshChat is installed on ("node" or "pi")
79 | -- @type string
80 | platform = "node"
81 | --- Turn debug message on
82 | -- @type bool
83 | debug = 0
84 | extra_nodes = {}
85 | --- MeshChat protocol version
86 | -- @type string
87 | protocol_version = "1.02"
88 | app_version = "master"
89 | default_channel = ""
90 |
91 | require("meshchat_local")
92 |
--------------------------------------------------------------------------------
/www/js.cookie.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * JavaScript Cookie v2.0.4
3 | * https://github.com/js-cookie/js-cookie
4 | *
5 | * Copyright 2006, 2015 Klaus Hartl & Fagner Brack
6 | * Released under the MIT license
7 | */
8 | (function (factory) {
9 | if (typeof define === 'function' && define.amd) {
10 | define(factory);
11 | } else if (typeof exports === 'object') {
12 | module.exports = factory();
13 | } else {
14 | var _OldCookies = window.Cookies;
15 | var api = window.Cookies = factory();
16 | api.noConflict = function () {
17 | window.Cookies = _OldCookies;
18 | return api;
19 | };
20 | }
21 | }(function () {
22 | function extend () {
23 | var i = 0;
24 | var result = {};
25 | for (; i < arguments.length; i++) {
26 | var attributes = arguments[ i ];
27 | for (var key in attributes) {
28 | result[key] = attributes[key];
29 | }
30 | }
31 | return result;
32 | }
33 |
34 | function init (converter) {
35 | function api (key, value, attributes) {
36 | var result;
37 |
38 | // Write
39 |
40 | if (arguments.length > 1) {
41 | attributes = extend({
42 | path: '/'
43 | }, api.defaults, attributes);
44 |
45 | if (typeof attributes.expires === 'number') {
46 | var expires = new Date();
47 | expires.setMilliseconds(expires.getMilliseconds() + attributes.expires * 864e+5);
48 | attributes.expires = expires;
49 | }
50 |
51 | try {
52 | result = JSON.stringify(value);
53 | if (/^[\{\[]/.test(result)) {
54 | value = result;
55 | }
56 | } catch (e) {}
57 |
58 | if (!converter.write) {
59 | value = encodeURIComponent(String(value))
60 | .replace(/%(23|24|26|2B|3A|3C|3E|3D|2F|3F|40|5B|5D|5E|60|7B|7D|7C)/g, decodeURIComponent);
61 | } else {
62 | value = converter.write(value, key);
63 | }
64 |
65 | key = encodeURIComponent(String(key));
66 | key = key.replace(/%(23|24|26|2B|5E|60|7C)/g, decodeURIComponent);
67 | key = key.replace(/[\(\)]/g, escape);
68 |
69 | return (document.cookie = [
70 | key, '=', value,
71 | attributes.expires && '; expires=' + attributes.expires.toUTCString(), // use expires attribute, max-age is not supported by IE
72 | attributes.path && '; path=' + attributes.path,
73 | attributes.domain && '; domain=' + attributes.domain,
74 | attributes.secure ? '; secure' : ''
75 | ].join(''));
76 | }
77 |
78 | // Read
79 |
80 | if (!key) {
81 | result = {};
82 | }
83 |
84 | // To prevent the for loop in the first place assign an empty array
85 | // in case there are no cookies at all. Also prevents odd result when
86 | // calling "get()"
87 | var cookies = document.cookie ? document.cookie.split('; ') : [];
88 | var rdecode = /(%[0-9A-Z]{2})+/g;
89 | var i = 0;
90 |
91 | for (; i < cookies.length; i++) {
92 | var parts = cookies[i].split('=');
93 | var name = parts[0].replace(rdecode, decodeURIComponent);
94 | var cookie = parts.slice(1).join('=');
95 |
96 | if (cookie.charAt(0) === '"') {
97 | cookie = cookie.slice(1, -1);
98 | }
99 |
100 | try {
101 | cookie = converter.read ?
102 | converter.read(cookie, name) : converter(cookie, name) ||
103 | cookie.replace(rdecode, decodeURIComponent);
104 |
105 | if (this.json) {
106 | try {
107 | cookie = JSON.parse(cookie);
108 | } catch (e) {}
109 | }
110 |
111 | if (key === name) {
112 | result = cookie;
113 | break;
114 | }
115 |
116 | if (!key) {
117 | result[name] = cookie;
118 | }
119 | } catch (e) {}
120 | }
121 |
122 | return result;
123 | }
124 |
125 | api.get = api.set = api;
126 | api.getJSON = function () {
127 | return api.apply({
128 | json: true
129 | }, [].slice.call(arguments));
130 | };
131 | api.defaults = {};
132 |
133 | api.remove = function (key, attributes) {
134 | api(key, '', extend(attributes, {
135 | expires: -1
136 | }));
137 | };
138 |
139 | api.withConverter = init;
140 |
141 | return api;
142 | }
143 |
144 | return init(function () {});
145 | }));
146 |
--------------------------------------------------------------------------------
/www/status.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | Mesh Chat
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |