diff --git a/.idea/.idea.CloudflareDDNS.dir/.idea/.gitignore b/.idea/.idea.CloudflareDDNS.dir/.idea/.gitignore
new file mode 100644
index 0000000..9a9048f
--- /dev/null
+++ b/.idea/.idea.CloudflareDDNS.dir/.idea/.gitignore
@@ -0,0 +1,13 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Rider ignored files
+/contentModel.xml
+/modules.xml
+/projectSettingsUpdater.xml
+/.idea.CloudflareDDNS.iml
+# Datasource local storage ignored files
+/../../../../../../../../../:\Redirected\Asif\Documents\RiderProjects\CloudflareDDNS\.idea\.idea.CloudflareDDNS.dir\.idea/dataSources/
+/dataSources.local.xml
+# Editor-based HTTP Client requests
+/httpRequests/
diff --git a/.idea/.idea.CloudflareDDNS.dir/.idea/indexLayout.xml b/.idea/.idea.CloudflareDDNS.dir/.idea/indexLayout.xml
new file mode 100644
index 0000000..27ba142
--- /dev/null
+++ b/.idea/.idea.CloudflareDDNS.dir/.idea/indexLayout.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/.idea.CloudflareDDNS.dir/.idea/riderModule.iml b/.idea/.idea.CloudflareDDNS.dir/.idea/riderModule.iml
new file mode 100644
index 0000000..1a4e0d9
--- /dev/null
+++ b/.idea/.idea.CloudflareDDNS.dir/.idea/riderModule.iml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/.idea.CloudflareDDNS.dir/.idea/vcs.xml b/.idea/.idea.CloudflareDDNS.dir/.idea/vcs.xml
new file mode 100644
index 0000000..45577ff
--- /dev/null
+++ b/.idea/.idea.CloudflareDDNS.dir/.idea/vcs.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/cfddns.posix.sh b/cfddns.posix.sh
new file mode 100644
index 0000000..5315ab4
--- /dev/null
+++ b/cfddns.posix.sh
@@ -0,0 +1,172 @@
+#!/bin/sh
+
+#
+# update CloudFlare DNS records with current (dynamic) IP address
+# Script by Asif Bacchus
+# Last modified: May 7, 2021
+#
+
+### text formatting presets using tput
+if command -v tput >/dev/null; then
+ bold=$(tput bold)
+ cyan=$(tput setaf 6)
+ err=$(tput bold)$(tput setaf 1)
+ magenta=$(tput setaf 5)
+ norm=$(tput sgr0)
+ ok=$(tput setaf 2)
+ warn=$(tput bold)$(tput setaf 3)
+ yellow=$(tput setaf 3)
+ width=$(tput cols)
+else
+ bold=""
+ cyan=""
+ err=""
+ magenta=""
+ norm=""
+ ok=""
+ warn=""
+ yellow=""
+ width=80
+fi
+
+### functions
+badParam() {
+ if [ "$1" = "null" ]; then
+ printf "\n%sERROR: '%s' cannot have a NULL (empty) value.\n" "$err" "$2"
+ printf "%sPlease use '--help' for assistance.%s\n\n" "$cyan" "$norm"
+ exit 1
+ elif [ "$1" = "dne" ]; then
+ printf "\n%sERROR: '%s %s'\n" "$err" "$2" "$3"
+ printf "file or directory does not exist or is empty.%s\n\n" "$norm"
+ exit 1
+ elif [ "$1" = "errMsg" ]; then
+ printf "\n%sERROR: %s%s\n\n" "$err" "$2" "$norm"
+ exit 1
+ fi
+}
+
+stamp() {
+ (date +%F" "%T)
+}
+
+scriptHelp() {
+ printf "\nEventually an in-script help will be here...\n\n"
+ exit 0
+}
+
+quit() {
+ if [ -z "$1" ]; then
+ # exit gracefully
+ printf "\n%s%s -- %s completed --%s\n\n" "$ok" "$(stamp)" "$scriptName" "$norm" >>"$logFile"
+ exit 0
+ fi
+}
+
+### default variable values
+scriptPath="$(CDPATH='' \cd -- "$(dirname -- "$0")" && pwd -P)"
+scriptName="$(basename "$0")"
+logFile="$scriptPath/${scriptName%.*}.log"
+accountFile="$scriptPath/cloudflare.credentials"
+colourizeLogFile=1
+dnsRecords=""
+dnsSeparator=","
+ipAddress="$(hostname -i)"
+ip4=1
+ip6=0
+errCount=0
+warnCount=0
+
+### process startup parameters
+if [ -z "$1" ]; then
+ scriptHelp
+fi
+while [ $# -gt 0 ]; do
+ case "$1" in
+ -h | -\? | --help)
+ # display help
+ scriptHelp
+ ;;
+ -l | --log)
+ # set log file location
+ if [ -n "$2" ]; then
+ logFile="${2%/}"
+ shift
+ else
+ badParam null "$@"
+ fi
+ ;;
+ --nc | --no-color | --no-colour)
+ # do not colourize log file
+ colourizeLogFile=0
+ ;;
+ -c | --cred* | -f)
+ # path to CloudFlare credentials file
+ if [ -n "$2" ]; then
+ if [ -f "$2" ] && [ -s "$2" ]; then
+ accountFile="${2%/}"
+ shift
+ else
+ badParam dne "$@"
+ fi
+ else
+ badParam null "$@"
+ fi
+ ;;
+ -r | --record | --records)
+ # DNS records to update
+ if [ -n "$2" ]; then
+ dnsRecords=$(printf "%s" "$2" | sed -e 's/ //g')
+ shift
+ else
+ badParam null "$@"
+ fi
+ ;;
+ -i | --ip | --ip-address | -a | --address)
+ # IP address to use (not parsed for correctness)
+ if [ -n "$2" ]; then
+ ipAddress="$2"
+ shift
+ else
+ badParam null "$@"
+ fi
+ ;;
+ -4 | --ip4 | --ipv4)
+ # operate in IP4 mode (default)
+ ip4=1
+ ;;
+ -6 | --ip6 | --ipv6)
+ # operate in IP6 mode
+ ip6=1
+ ;;
+ *)
+ printf "\n%sUnknown option: %s\n" "$err" "$1"
+ printf "%sUse '--help' for valid options.%s\n\n" "$cyan" "$norm"
+ exit 1
+ ;;
+ esac
+ shift
+done
+
+### pre-flight checks
+[ -z "$dnsRecords" ] && badParam errMsg "You must specify at least one DNS record to update. Exiting."
+[ "$ip4" -eq 1 ] && [ "$ip6" -eq 1 ] && badParam errMsg "Cannot operate in IP4 and IP6 modes simultaneously. Exiting."
+
+printf "\nscript: %s\n" "$scriptPath/$scriptName"
+printf "accountFile: %s\n" "$accountFile"
+printf "colourize: %s\n" "$colourizeLogFile"
+if [ "$ip4" = 1 ]; then
+ printf "mode: IP4\n"
+elif [ "$ip6" = 1 ]; then
+ printf "mode: IP6\n"
+fi
+printf "ip address: %s\n" "$ipAddress"
+
+# iterate DNS records to update
+dnsRecordsToUpdate="$dnsRecords$dnsSeparator"
+while [ "$dnsRecordsToUpdate" != "${dnsRecordsToUpdate#*${dnsSeparator}}" ] && { [ -n "${dnsRecordsToUpdate%%${dnsSeparator}*}" ] || [ -n "${dnsRecordsToUpdate#*${dnsSeparator}}" ]; }; do
+ record="${dnsRecordsToUpdate%%${dnsSeparator}*}"
+ dnsRecordsToUpdate="${dnsRecordsToUpdate#*${dnsSeparator}}"
+ printf "update record: %s\n" "$record"
+done
+
+exit 0