#!/bin/bash

# Simple SRIF compatible FREQ processor
# © Copyleft Stas Degteff 2:5080/102@fidonet
# Modified by Jay Harris 1:229/664@fidonet
# Added additional comments/safeguards from Bjorn Wiberg 2:201/137@fidonet
version=1.1

##### Configuration
# NOTE: Should have a TRAILING SLASH (to avoid symlink traversal)!
PUB=/home/ubuntu/fido/fileechoes/

declare -A ALIASES
# Put your Magic Names here
ALIASES=(
 [FILES]=/home/ubuntu/fido/binkd/ALLFILES.TXT
 [ALLFILES]=/home/ubuntu/fido/binkd/ALLFILES.TXT
 [NODELIST]=/home/ubuntu/fido/binkd/NODELIST.ZIP
 [NODEDIFF]=/home/ubuntu/fido/binkd/NODEDIFF.ARC
 [DAILYLIST]=/home/ubuntu/fido/binkd/Z1DAILY.ZIP
 [MININFO]=/home/ubuntu/fido/fileechoes/min_info/MININFO.ZIP
 [MINLIST]=/home/ubuntu/fido/binkd/MINLIST.ZIP
 [MINDIFF]=/home/ubuntu/fido/binkd/MINDIFF.ZIP
)

logfacilityinfo=local1.notice
logfacilityerror=local1.err
logstderr= #-s

##### Implementation

function usage
{
 echo "Simple SRIF compatible Fidonet File Request processor v$version"
 echo -e "© copyleft Stas Degteff 2:5080/102\n"
 echo "Aliases are supported"
 echo "Usage: `basename $0` <SRIF-file>"
}

function getSrifFile
# read information from SRIF file
# Parameters: $1 = SRIF file name
{
 local token value error

 logger -p "$logfacilityinfo" $logstderr -t "srifreq[$$]" "parse SRIF file: $1"
 { while read -u 4 token value; do
   # remove special characters
   token=${token//[\'\"\`\$]/}
   value=${value//[\'\"\`\$]/}

   case "$token" in
    [Ss][yY][sS][oO][pP])
     sysop=$value
     logger -p "$logfacilityinfo" $logstderr -t "srifreq[$$]" "sysop: $sysop"
    ;;
    [Aa][Kk][Aa])
     aka=$value
     logger -p "$logfacilityinfo" $logstderr -t "srifreq[$$]" "aka: $aka"
    ;;
    [Rr][eE][qQ][uU][eE][sS][tT][Ll][iI][sS][tT])
     # remove any directory traversals (../)
     # NOTE: Probably unnecessary, as the RequestList path is created by the receiving (local) mailer, which should be trusted!
     requestlist=${value//\.\.\/}
     logger -p "$logfacilityinfo" $logstderr -t "srifreq[$$]" "requestlist: $requestlist"
     if [ ! -s "$requestlist" ]; then
      error=1
      logger -p "$logfacilityerror" $logstderr -t "srifreq[$$]" "broken SRIF file: RequestList $requestlist does not exist or empty!"
     else
      if [ ! -r "$requestlist" ]; then
       error=1
       logger -p "$logfacilityerror" $logstderr -t "srifreq[$$]" "Error: RequestList $requestlist is not readable!"
      fi
     fi
    ;;
    [Rr][eE][sS][pP][oO][nN][sS][eE][Ll][iI][sS][tT])
     # remove any directory traversals (../)
     # NOTE: Probably unnecessary, as the ResponseList path is created by the receiving (local) mailer, which should be trusted!
     responselist=${value//\.\.\/}
     logger -p "$logfacilityinfo" $logstderr -t "srifreq[$$]" "responselist: $responselist"
     if [ ! -w `dirname "$responselist"` ]; then
      error=1
      logger -p "$logfacilityerror" $logstderr -t "srifreq[$$]" "responselist $responselist is not writable"
     fi
    ;;
   esac
 done
  } 4<"$1"
  if [ -z "$responselist" -o -z "$requestlist" ]; then
   logger -p "$logfacilityerror" $logstderr -t "srifreq[$$]" "broken SRIF file: ResponseList or RequestList is not specified"
   error=1
  fi
  if [ "$error" ] ; then exit $error ; fi
}

function processrequest
# Process requested file list
# Parameters: $1 = request file (one requesting file in line)
#             $2 = responce file (found files prefixed with "+")
{ local fname
  while read -u4 fname; do
   # remove special characters
   fname=${fname//[\'\"\`\$]}
   fname=${fname//$'\r'}

   # extract basename
   fname=`basename "$fname"`

   # ignore empty lines/names
   [ ! "$fname" ] && continue

   logger -p "$logfacilityinfo" $logstderr -t "srifreq[$$]" "Find file $fname"

   for key in "${!ALIASES[@]}"; do
    if [ "$fname" = "$key" ]; then
     echo "+${ALIASES[${fname}]}" >> "$2"
    fi
   done

   find "$PUB" -name "$fname" -printf "+%p\n" 2>/dev/null >> "$2"
  done
} 4<"$1"

#### main code
if [ $# != 1  -o ! -f "$1" ]; then
 usage
 exit 1
fi

getSrifFile "$1"
processrequest "$requestlist" "$responselist"
exit 0
