#!/bin/ash
# *********************************************************************
# ldaptolist: turns selected LDAP entries into a NoSQL list.
#	      Requires the OpenLDAP utility 'ldapsearch'.
#
# Copyright (c) 2004,2006,2007,2009 Carlo Strozzi
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; version 2 dated June, 1991.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
# *********************************************************************

# Get local settings and apply defaults.
: ${TMPDIR:=/tmp} ${NOSQL_CHARSET:=utf-8}
: ${NOSQL_INSTALL:=@NOSQL_INSTALL@}
: ${SWU_INSTALL:=@SWU_INSTALL@}
: ${PATH:=@LOCAL_PATH@}

export NOSQL_INSTALL SWU_INSTALL PATH TMPDIR NOSQL_CHARSET

EUSAGE='Usage: ldaptolist [options] attr [attr ...] -- [ldapsearch options] filter(s)'

[ $# = 0 ] && { echo "$EUSAGE"; exit 1; }

while :
do
  case $1 in
    -o|--output)	shift; o_file="$1" ;;
    -c|--charset)	shift; NOSQL_CHARSET="$1" ;;
    -h|--help)
       grep -v '^#' $NOSQL_INSTALL/help/ldaptolist.txt
       exit 1
    ;;
    --show-copying)
       cat $NOSQL_INSTALL/doc/COPYING
       exit 1
    ;;
    --show-warranty)
       cat $NOSQL_INSTALL/doc/WARRANTY
       exit 1
    ;;
    --)		shift; break ;;
    *)		attlist="$attlist $1" ;;
  esac
  shift
done

if [ -z "$attlist" ]
then
   echo "$EUSAGE"
   exit 1
fi

case "$NOSQL_CHARSET" in
  [a-zA-Z]*) ;;
  *)  NOSQL_CHARSET=utf-8 ;;
esac

# Run ldapsearch. Double quotes aroud "$@" are mandatory!!

#echo $# "$@" $attlist ; exit		# uncomment for debugging

awk_tmp=`mktemp $TMPDIR/nosql.XXXXXX` || slapdExit 1
trap "rm -f $awk_tmp" 0
trap "exit 2" 1 2 3 15

cat <<'EOF' > $awk_tmp
BEGIN{
   attlist = tolower(attlist)
   sub(/^ */,"",attlist)		# strip trailing blank
   sub(/ *$/,":",attlist)		# strip leading blank
   gsub(/ +/,": ",attlist)		# add colons
   cols=split(attlist,a," ")
}
NR==1 {print ""}
$1==""{
   if (NR < 2) exit(rc=1)	# unexpected output from ldapsearch(1)
   for (i=1; i<=cols; i++) {
       a[i] = tolower(a[i])
       if (b64[a[i]]) {
	  out = a[i] _b64decode(b[a[i]])
	  # handle continuations in decoded Base64 data.
	  #gsub(/[\r]?\n/,"\n\t",out)
	  gsub(/\001/,"\n\t",out)
	  b64[a[i]] = 0
       }
       else out = a[i] b[a[i]]
       sub(/:/,"\t",out)
       print out
   }
   delete b
   print ""
   next
}

# handle continuation lines.

sub(/^ /,"") {
   b[name] = b[name] $0
   next
}

# handle cleartext fields.

/[^:]+: / {
   name = tolower($1)
   sub(/[^:]+: /,"")
   b[name] = $0
   next
}

# handle base64-encoded fields.

/[^:]+:: / {
   sub(/::/,":")
   name = tolower($1)
   b64[name] = 1
   sub(/[^:]+: /,"")
   b[name] = $0
   next
}

END{
   if (rc) exit(rc)
   # cope with no match input.
   if (NR < 2) {
      print ""
      for (i=1; i<=cols; i++) {
	  sub(/:/,"",a[i])
	  print a[i]
      }
      print ""
   }
}
EOF

[ "$o_file" = "" ] || exec > "$o_file"

ldapsearch -LLL "$@" $attlist |
   _awk -v attlist="$attlist" -f $SWU_INSTALL/lib/BEGIN.awk \
	-f $SWU_INSTALL/lib/swulib.awk -f $awk_tmp -- |
	iconv -f utf-8 -t "$NOSQL_CHARSET"

exit $?

# End of program.
