#!/bin/bash

###########################################################
## Copyright (c) 2002-2025 Alexey Kuryakin daqgroup@mail.ru
###########################################################

###########################################################
## Find (or list) known system shared libraries (lib*.so).
###########################################################

###########################################################
source $(crwkit which crwlib_base.sh); # Use base library #
source $(crwkit which crwlib_file.sh); # Use file library #
###########################################################

declare -i opt_s=0;

function do_help(){
 local name="$scriptname";
 echo "$name version 1.0";
 if [ $1 -eq 0 ]; then return 0; fi;
 echo "Copyright (c) 2002-2025 Alexey Kuryakin daqgroup@mail.ru";
 echo "$name - find a library (lib*.so).";
 echo "Usage:";
 echo " $name [-option] [pattern]";
 echo "Options:";
 echo " -h,--help       - print help.";
 echo " --version       - print version.";
 echo " -l,--list       - list all known shared libraries.";
 echo "                   (only files registered by ldconfig).";
 echo " -p,--path       - print path of all known shared libraries.";
 echo "                   (only files registered by ldconfig).";
 echo " -d,--dirs       - print known shared libraries directories.";
 echo "                   (only directories registered by ldconfig).";
 echo " -f,--find [p]   - find all *.so* libraries with pattern [p].";
 echo "                   (all libraries in ldconfig-known directories).";
 echo " -s,--search [p] - search all *.so* libraries with pattern [p].";
 echo "                   (all libraries in ldconfig-known directories).";
 echo "Note:";
 echo " The search (-s) procerure is slower but more complete compare";
 echo " to find (-f), because uses recursive search in subdirectories.";
 echo "Parametes:"
 echo " pattern       - library file pattern (lib*.so) to search.";
 echo "Examples:";
 echo " unix $name --help         # print help";
 echo " unix $name --version      # print version";
 echo " unix $name -l             # list (registered libs => path)";
 echo " unix $name -p             # list (path of registered libs)";
 echo " unix $name -d             # list (dirs of registered dirs)";
 echo " unix $name -f             # find (all libs in known dirs)";
 echo " unix $name -f sqlite      # find (any library by pattern)";
 echo " unix $name -s sqlite3     # find (by pattern, recursive)";
 echo " unix $name libsqlite3.so  # find (registered libs only)";
};

function do_warn(){
 echo_to_stderr "$(langstr ru "Ошибка: Недопустимые аргументы. Используйте $scriptname --help для справки." en "Error: Invalid arguments. Use $scriptname --help for help.")";
};

function list_libs(){
 local ldconfig="$(unix whichis ldconfig)";
 if [[ -x "$ldconfig" ]]; then
  $ldconfig -p | grep '=>' | sed 's/^\s*//';
 else
  fatal 1 "$(langstr ru "Ошибка: Не могу найти ldconfig." en "Error: Could not find ldconfig.")";
 fi;
};

function path_libs(){
 list_libs | sed 's/.*\s=>\s*//';
};

function find_libso(){
 path_libs | grep "$1";
};

function dirs_libs(){
 local how=1;
 case $how in
  0) path_libs | xargs -l1 dirname     | sort -u; ;; # slow version with dirname
  1) path_libs | sed -E 's|/[^/]+$||'  | sort -u; ;; # fast version without dirname
  *) path_libs | sed 's|/[^/][^/]*$||' | sort -u; ;; # fast version without dirname
 esac;
};

function find_libso_in_dirs(){
 if [[ $opt_s -eq 0 ]]; then
  for dir in $(dirs_libs); do
   if [[ -e $dir ]]; then
    ls -1 $dir/*.so*;
   fi;
  done;
 else
  local dirs="$(dirs_libs | grep '/' | sed 's/$/\//')";
  if [[ -n $dirs ]]; then
   find $dirs -type f,l -name '*.so*' 2>/dev/null;
  fi;
 fi;
};

function find_libso_files(){
 if [[ -z "$1" ]]; then
  find_libso_in_dirs | sort -u;
 else
  find_libso_in_dirs | sort -u | grep "$1";
 fi;
};

function main(){
 case $1 in
  -version|--version)  do_help 0; exit 0; ;;
  -h|-help|--help)     do_help 1; exit 0; ;;
  -l|-list|--list)     list_libs; return; ;;
  -p|-path|--path)     path_libs; return; ;;
  -d|-dirs|--dirs)     dirs_libs; return; ;;
  -f|-find|--find)     find_libso_files "$2"; ;;
  -s|-search|--search) let opt_s=1; find_libso_files "$2"; ;;
  lib*.so*|*.so*)      find_libso "$1"; ;;
  [a-zA-Z0-9]*)        find_libso "$1.so"; ;;
  ''|*)                colorize_bold do_warn; exit 1;   ;;
 esac;
};

main "$@";

##############
## END OF FILE
##############
