1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987
|
#!/bin/sh
# ############################################################################ #
# ############################################################################ #
# ############################################################################ #
# #
# SuRep (2015-05-10 00:15:51) by Fravadona #
# Adapted for DSM6 by CoolRaoul
# #
version=1.0.2
# #
# Send an email to notify changes made in a directory of the NAS #
# #
# TODO: #
# * option to set a minimum number of modifications before sending email #
# * rollback logging support #
# * demonize the script #
# * plain text connection with telnet (it shouldn't worth it) #
# #
# LIMITATIONS: #
# * this script is not intended to monitor a directory with waaaay too #
# much files inside it #
# * UTF8 and strange (but legal) ASCII email addresses may cause problems #
# * encoding of email message may be limited #
# #
# COMMENT: #
# * an implementation with "inotify" and "sendmail" is without a doubt a #
# much better approach, but DSM doesn't provide it by default #
# #
# ############################################################################ #
# ############################################################################ #
# ############################################################################ #
# ============================================================================ #
#IFS=' '$'\t'$'\n'
#PATH=/bin:/usr/bin:/usr/syno/bin
# ============================================================================ #
ddbfile="/tmp/SuRep-`/bin/date '+%s'`-$$.ddb"
nodfile="/tmp/SuRep-`/bin/date '+%s'`-$$.nod"
trap "exit 2" 1 2 3 15
trap "/bin/rm -f '${ddbfile}' '${nodfile}' >& /dev/null" 0
# ============================================================================ #
# ############################################################################ #
# #
# surep_sendmail () : function for sending an email #
# #
# ############################################################################ #
surep_sendmail () {
local FNAME="surep_sendmail"
local usage="
${FNAME} -- Send an email
Usage: ${FNAME} OPTION...
OPTION:
-h display this help and exit
-f ADDRESS from (=sender) email address
-t ADDRESS to (=recipient) email address(es)
-u SUBJECT message subject (def: empty)
-m MESSAGE message body (def: empty)
-s SERVER:PORT smtp mail relay
-o username=USERNAME username for SMTP authentication
-o password=PASSWORD password for SMTP authentication
-o fqdn=FQDN FQDN of this computer
-o isp=<none|ssl|tls> internet security protocol (def: tls)
-o pause=SECONDS wait time between each SMTP command (def: 1)
"
if [ $# -eq 0 ]
then
printf '%s\n' "${usage}"
return 1
fi
# ---------------------------------------------------------------------------- #
local _from _to _subject _message _server _username _password _fqdn _isp _pause
local _from_email _to_email _server_fqdn _server_port
_isp='tls'
_pause=1
local OPTION OPTIND OPTARG
while getopts ":f:t:u:m:s:o:h" OPTION
do
case "${OPTION}" in
h)
printf '%s\n' "${usage}"
return 0
;;
f)
_from="${OPTARG}"
;;
t)
if [ -z ${_to} ]
then
_to="${OPTARG}"
else
_to="${_to}, ${OPTARG}"
fi
;;
u)
_subject="${OPTARG}"
;;
m)
_message="${OPTARG}"
;;
s)
_server="${OPTARG}"
_server_fqdn="${_server%:*}"
_server_port="${_server#*:}"
;;
o)
case "${OPTARG}" in
username=*) _username="${OPTARG#username=}" ;;
password=*) _password="${OPTARG#password=}" ;;
fqdn=*) _fqdn="${OPTARG#fqdn=}" ;;
isp=*) _isp="${OPTARG#isp=}" ;;
pause=*) _pause="${OPTARG#pause=}" ;;
*)
printf '%s\n' "${FNAME}: illegal option -o ${OPTARG}" >&2
return 1
;;
esac
;;
:)
printf '%s\n' "${FNAME}: option requires an argument -${OPTARG}" >&2
return 1
;;
?)
printf '%s\n' "${FNAME}: illegal option -${OPTARG}" >&2
return 1
;;
esac
done
# check mandatory arguments
local _opt
for _opt in _from _to _server _username _password _fqdn
do
if [ -z "`eval printf '%s\n' \\${${_opt}}`" ]
then
case "${_opt}" in
_from)
printf '%s\n' "${FNAME}: option is mandatory -f" 1>&2
return 1
;;
_to)
printf '%s\n' "${FNAME}: option is mandatory -t" 1>&2
return 1
;;
_server)
printf '%s\n' "${FNAME}: option is mandatory -s" 1>&2
return 1
;;
_username)
printf '%s\n' "${FNAME}: option is mandatory -o username=" 1>&2
return 1
;;
_password)
printf '%s\n' "${FNAME}: option is mandatory -o password=" 1>&2
return 1
;;
_fqdn)
printf '%s\n' "${FNAME}: option is mandatory -o fqdn=" 1>&2
return 1
;;
esac
fi
done
# check server
if [ -z ${_server_fqdn} ] || \
[ -z ${_server_port} ] || \
[ X"${_server}" != X"${_server_fqdn}:${_server_port}" ]
then
printf '%s\n' "${FNAME}: wrong format for option -s '${_server}'" >&2
return 1
fi
# check protocol
case "${_isp}" in
[tT][lL][sS])
_isp="-starttls smtp"
;;
[sS][sS][lL])
_isp=""
;;
[nN][oO][nN][eE])
printf '%s\n' "${FNAME}: plain text connexion is not supported -o isp=none"
return 0
;;
*)
printf '%s\n' "${FNAME}: unknown protocol for option -o isp='${_isp}'" >&2
return 1
;;
esac
# ---------------------------------------------------------------------------- #
# reformat the sender string
_from=`printf '%s\n' "${_from}" | /bin/sed -e 's/</ /' -e 's/>//' \
-e 's/ */ /g' \
-e 's/\([^ ]*@[^ ]*\) */<\1>/' \
-e 's/^ //'`
# extract the "pure" email from the sender string
_from_email=`printf '%s\n' "${_from}" | /bin/sed -e 's/[^<]*<\([^>]*\)>.*/\1/g'`
# reformat the receivers string
_to=`printf '%s\n' "${_to}" | /usr/bin/tr '\n' ','`
_to=`printf '%s\n' "${_to}" | /bin/sed -e 's/</ /g' -e 's/>//g' \
-e 's/,/, /g' -e 's/ */ /g' \
-e 's/\([^ ]*@[^ ,)]*\) */<\1>/g' \
-e 's/^ //'`
# extract the list of "pure" emails from the receiver string
_to_email=`printf '%s\n' "${_to}" | /bin/sed -e 's/[^<]*<\([^>]*\)>[^<]*/\1 /g' \
-e 's/ $//'`
# ---------------------------------------------------------------------------- #
# create a shell pipe for communating with the SMTP client software
if [ ! -e "${nodfile}" ]
then
/bin/mknod "${nodfile}" p
exec 3<> "${nodfile}"
fi
# ---------------------------------------------------------------------------- #
# launch the SMTP client and send the email
eval /usr/bin/openssl s_client "${_isp}" -connect "${_server}" -crlf -quiet -ign_eof <&3 2> /dev/null &
local _pid=$!
#
# _auth : base64 authentification string for SMTP server
#
local _auth=`printf '\000%s\000%s' "${_username}" "${_password}" \
| /usr/bin/openssl enc -base64 -A 2>/dev/null`
local _email=
printf '%s\n' "EHLO ${_server_fqdn}" >&3 ; /bin/sleep ${_pause}
printf '%s\n' "AUTH PLAIN ${_auth}" >&3 ; /bin/sleep ${_pause}
printf '%s\n' "HELO ${_fqdn}" >&3 ; /bin/sleep ${_pause}
printf '%s\n' "MAIL FROM: <${_from_email}>" >&3 ; /bin/sleep ${_pause}
for _email in ${_to_email}
do
printf '%s\n' "RCPT TO: <${_email}>" >&3 ; /bin/sleep ${_pause}
done
printf '%s\n' "DATA" >&3 ; /bin/sleep ${_pause}
printf '%s\n' "\
Date: `/bin/date --rfc-2822`
Subject: ${_subject}
From: ${_from}
To: ${_to}
${_message}
." >&3 ; /bin/sleep ${_pause}
printf '%s\n' "QUIT" >&3 ; /bin/sleep ${_pause}
wait ${_pid}
}
# ############################# (surep_sendmail) ############################# #
# ============================================================================ #
#
# surep_snapshot_header : first bytes of a snapshot file
#
surep_snapshot_header="SuRep snapshot format 1"
# ============================================================================ #
# ############################################################################ #
# #
# surep_mksnapshot () : function that takes a snapshot of a directory #
# #
# ############################################################################ #
surep_mksnapshot () {
local FNAME="surep_mksnapshot"
local usage="
${FNAME} -- Take a snapshot of the files in a directory
Usage: ${FNAME} DIR...
Take a snapshot of all the files in DIR(s) with the following format :
file size blocks mode uid gid devid inode hard major minor access modify change iob
Where :
file = File name encoded in base64
size = File size in bytes
blocks = Number of used blocks
mode = File type and ACLs
uid = Owner UID
gid = Owner GID
devid = Device number
inode = Inode number
hard = Number of hardlinks referencing the file
major = Major number
Minor = Minor number
access = Last access date in second since Epoch
modify = Last modify date in second since Epoch
change = Last change date in second since Epoch
iob = Block size in bytes
"
if [ $# -eq 0 ]
then
printf '%s\n' "${usage}"
return 1
fi
# ---------------------------------------------------------------------------- #
printf '%s\n' "${surep_snapshot_header}"
/usr/bin/find "${@}" -type f -print0 | /usr/bin/xargs -0 /bin/sh -c '
for file in "${0}" "${@}"
do
stat=$(/bin/stat -t "${file}")
stat=${stat#"${file} "}
file=$(printf "%s" "${file}" | /usr/bin/openssl enc -base64 -A 2> /dev/null)
printf "%s %s\n" "${file}" "${stat}"
done' | /usr/bin/sort
}
# ############################ (surep_mksnapshot) ############################ #
# ============================================================================ #
#
# surep_diffdb_header : first bytes of a SuRep diff database file
#
surep_diffdb_header="SQLite format 3"
# ============================================================================ #
# ############################################################################ #
# #
# surep_mkdiffdb () : function that compares two snapshots and stores the #
# the differences in a database #
# #
# ############################################################################ #
surep_mkdiffdb () {
local FNAME="surep_mkdiffdb"
local usage="
${FNAME} -- Make a database of differences between snapshots
Usage: ${FNAME} DIFFDB SNAPSHOT SNAPSHOT
Create a database file DIFFDB filled with the non matching lines between the
two SNAPSHOT files
"
if [ $# -ne 3 ]
then
printf '%s\n' "${usage}"
return
fi
# ---------------------------------------------------------------------------- #
local _diffdb="${1}"
local _snap_1="${2}"
local _snap_2="${3}"
# verify DIFFDB
if [ -s "${_diffdb}" ]
then
if [ ! -f "${_diffdb}" ] || [ X"`/usr/bin/head -c ${#surep_diffdb_header} "${_diffdb}" 2> /dev/null`" != X"${surep_diffdb_header}" ]
then
printf '%s\n' "${FNAME}: ${_diffdb}: not a diffdb file" 1>&2
return 1
fi
else
if [ -n "${_diffdb%/*}" ]
then
/bin/mkdir -p "${_diffdb%/*}" 2> /dev/null
if [ $? -ne 0 ]
then
printf '%s\n' "${FNAME}: can't create diffdb file '${_diffdb}': Permission denied" 1>&2
return 1
fi
fi
/bin/touch "${_diffdb}" 2> /dev/null
if [ $? -ne 0 ]
then
printf '%s\n' "${FNAME}: can't create diffdb file '${_diffdb}': Permission denied" 1>&2
return 1
fi
fi
# verify SNAPSHOT 1
if [ ! -e "${_snap_1}" ]
then
printf '%s\n' "${FNAME}: ${_snap_1}: no such file" 1>&2
return 1
fi
if [ ! -r "${_snap_1}" ]
then
printf '%s\n' "${FNAME}: ${_snap_1}: permission denied" 1>&2
return 1
fi
if [ ! -f "${_snap_1}" ] || [ X"`/usr/bin/head -c ${#surep_snapshot_header} "${_snap_1}" 2> /dev/null`" != X"${surep_snapshot_header}" ]
then
printf '%s\n' "${FNAME}: ${_snap_1}: not a snapshot file" 1>&2
return 1
fi
# verify SNAPSHOT 2
if [ ! -e "${_snap_2}" ]
then
printf '%s\n' "${FNAME}: ${_snap_2}: no such file" 1>&2
return 1
fi
if [ ! -r "${_snap_2}" ]
then
printf '%s\n' "${FNAME}: ${_snap_2}: permission denied" 1>&2
return 1
fi
if [ ! -f "${_snap_2}" ] || [ X"`/usr/bin/head -c ${#surep_snapshot_header} "${_snap_2}" 2> /dev/null`" != X"${surep_snapshot_header}" ]
then
printf '%s\n' "${FNAME}: ${_snap_2}: not a snapshot file" 1>&2
return 1
fi
# ---------------------------------------------------------------------------- #
# create tables in database
/usr/bin/sqlite3 "${_diffdb}" <<EOF
drop table if exists T_PLUS;
create table T_PLUS (
file text, -- file name (base64 encoded)
size integer, -- size in bytes
blocks integer, -- number of blocks
type integer, -- file type
acl integer, -- access control list (sugo)
uid integer, -- user id of owner
gid integer, -- group id of owner
devid integer, -- device id
inode integer, -- inode number
hard integer, -- number of hard hard pointing to this file
major integer, -- major number
minor integer, -- minor number
access integer, -- last access date
modify integer, -- last modify date
change integer, -- last change date
iob integer -- size of blocks
);
drop table if exists T_MINUS;
create table T_MINUS (
file text, -- file name (base64 encoded)
size integer, -- size in bytes
blocks integer, -- number of blocks
type integer, -- file type
acl integer, -- access control list (sugo)
uid integer, -- user id of owner
gid integer, -- group id of owner
devid integer, -- device id
inode integer, -- inode number
hard integer, -- number of hard hard pointing to this file
major integer, -- major number
minor integer, -- minor number
access integer, -- last access date
modify integer, -- last modify date
change integer, -- last change date
iob integer -- size of blocks
);
EOF
# ---------------------------------------------------------------------------- #
# right order for reading the lines of surep_mksnapshot
local _file _size _blocks _mode _uid _gid _devid _inode _hard _major _minor _access _modify _change _iob
local _type _acl _table
# inserting the file stats in the diff database
while read _file _size _blocks _mode _uid _gid _devid _inode _hard _major _minor _access _modify _change _iob
do
if [ -z "${_file}" ]
then
continue
fi
case "${_file}" in
-*) _table=T_MINUS
;;
+*) _table=T_PLUS
;;
esac
_file=${_file#?}
_type=${_mode%???}
_acl=${_mode#?}
printf "insert into ${_table} values ('%s',"%d","%d","%d","%d","%d","%d","%d","%d","%d","%d","%d","%d","%d","%d","%d") ;\n" \
"${_file}" \
"${_size}" \
"${_blocks}" \
"0x${_type}" \
"0x${_acl}" \
"${_uid}" \
"${_gid}" \
"0x${_devid}" \
"${_inode}" \
"${_hard}" \
"${_major}" \
"${_minor}" \
"${_access}" \
"${_modify}" \
"${_change}" \
"${_iob}" \
done <<EOF | /usr/bin/sqlite3 "${_diffdb}"
`/usr/bin/diff -U 0 "${_snap_1}" "${_snap_2}" | /bin/grep -v -e '^[@+-][@+-]'`
EOF
}
# ############################# (surep_mkdiffdb) ############################# #
# ============================================================================ #
# ############################################################################ #
# #
# surep_lsdiffdb () : function for displaying different views of the content #
# of a diff database #
# #
# ############################################################################ #
surep_lsdiffdb () {
local FNAME="surep_lsdiffdb"
local usage="
Usage: ${FNAME} [OPTION]... DIFFDB
Extract various views from the DIFFDB database file
OPTIONS
-h display this help and exit
-n display new files
-d display deleted files
-m display modified files
-r display renamed files
-x display new files excluding the renamed ones
"
local _view=
local OPTION OPTIND OPTARG
while getopts ":hndmrx" OPTION
do
case "${OPTION}" in
h)
printf '%s\n' "${usage}"
return 0
;;
n)
_view="${_view} n"
;;
d)
_view="${_view} d"
;;
m)
_view="${_view} m"
;;
r)
_view="${_view} r"
;;
x)
_view="${_view} x"
;;
:)
printf '%s\n' "${FNAME}: option requires an argument -${OPTARG}" >&2
return 1
;;
?)
printf '%s\n' "${FNAME}: illegal option -${OPTARG}" >&2
return 1
;;
esac
done
shift `/usr/bin/expr ${OPTIND} - 1`
if [ $# -ne 1 ]
then
printf '%s\n' "${usage}" 1>&2
return 1
fi
# ---------------------------------------------------------------------------- #
local _diffdb="${1}"
# verify DIFFDB
if [ ! -e "${_diffdb}" ]
then
printf '%s\n' "${FNAME}: ${_diffdb}: no such file" 1>&2
return 1
fi
if [ ! -r "${_diffdb}" ]
then
printf '%s\n' "${FNAME}: ${_diffdb}: permission denied" 1>&2
return 1
fi
if [ ! -f "${_diffdb}" ] || [ X"`/usr/bin/head -c ${#surep_diffdb_header} "${_diffdb}" 2> /dev/null`" != X"${surep_diffdb_header}" ]
then
printf '%s\n' "${FNAME}: ${_diffdb}: not a diffdb file" 1>&2
return 1
fi
# ---------------------------------------------------------------------------- #
# We suppose that two files with the same Name, Inode, ModDate and Size
# are identical (rsync algorithm)
local _file
for _view in ${_view}
do
case ${_view} in
n) # display new files
/usr/bin/sqlite3 "${_diffdb}" <<SQLITE
.separator " "
select file from T_PLUS where file not in (select file from T_MINUS);
SQLITE
;;
d) # display deleted files
/usr/bin/sqlite3 "${_diffdb}" <<SQLITE
.separator " "
select file from T_MINUS where file not in (select file from T_PLUS);
SQLITE
;;
m) # display modified files
/usr/bin/sqlite3 "${_diffdb}" <<SQLITE
.separator " "
select P.file from T_PLUS P left join T_MINUS M
on P.file = M.file
where P.inode != M.inode or P.modify != M.modify or P.size != M.size ;
SQLITE
;;
r) # display renamed files (not 100% accurate because an inode may
# be recycled and allocated for a file of
# the same size and modification time)
/usr/bin/sqlite3 "${_diffdb}" <<SQLITE
.separator " "
select P.file from T_PLUS P left join T_MINUS M
on M.inode = P.inode
where M.file != P.file and M.modify = P.modify and M.size = P.size;
SQLITE
;;
x) # display new file excluding the renamed ones
/usr/bin/sqlite3 "${_diffdb}" <<SQLITE
.separator " "
select file from T_PLUS where file not in (select file from T_MINUS)
except
select P.file from T_PLUS P left join T_MINUS M
on M.inode = P.inode
where M.file != P.file and M.modify = P.modify and M.size = P.size;
SQLITE
;;
esac
done
}
# ############################# (surep_lsdiffdb) ############################# #
# ============================================================================ #
SCRIPTNAME="${0##*/}"
usage="
Usage: ${SCRIPTNAME} -c CONFIG
"
while getopts ":c:h" OPTION
do
case "${OPTION}" in
h)
printf '%s\n' "${usage}"
exit 0
;;
c)
config="${OPTARG}"
;;
:)
printf '%s\n' "${FNAME}: option requires an argument -${OPTARG}" 1>&2
return 1
;;
?)
printf '%s\n' "${FNAME}: illegal option -${OPTARG}" 1>&2
return 1
;;
esac
done
shift `/usr/bin/expr ${OPTIND} - 1`
# ============================================================================ #
# check if configuration file is correct
if [ ! -e "${config}" ]
then
printf '%s\n' "${SCRIPTNAME}: ${config}: no such configuration file" 1>&2
exit 1
fi
if [ ! -f "${config}" ]
then
printf '%s\n' "${SCRIPTNAME}: ${config}: not a configuration file" 1>&2
exit 1
fi
if [ ! -r "${config}" ]
then
printf '%s\n' "${SCRIPTNAME}: ${config}: permission denied" 1>&2
exit 1
fi
# load the configuration file
. "${config}"
# verify compatibility of the configuration
if [ -z "${conf_compat}" ] || [ X"${version%.*}" != X"${conf_compat}" ]
then
printf '%s\n' "${SCRIPTNAME}: ${config}: incompatible configuration file" 1>&2
exit 1
fi
# verify nas_dir
if [ ! -d "${nas_dir}" ]
then
printf '%s\n' "${SCRIPTNAME}: ${nas_dir}: no such directory" 1>&2
exit 1
fi
# verify snapshot_dir
if [ ! -d "${snapshot_dir}" ]
then
/bin/mkdir -p "${snapshot_dir}" 2> /dev/null
if [ $? -ne 0 ]
then
printf '%s\n' "${SCRIPTNAME}: ${snapshot_dir}: cannot create snapshot directory" 1>&2
exit 1
fi
fi
# ============================================================================ #
/bin/date '+[%Y-%m-%d %H:%M:%S] launched SuRep'
# snapshot_id : unique identifier for the snapshots of this nas_dir
snapshot_id="`printf '%s\n' "${nas_dir}" | /usr/bin/openssl enc -base64 -A 2> /dev/null`"
# snapshot_file: file containing the snapshot
snapshot_file="${snapshot_dir}/${snapshot_id}.ss"
# save previous snapshot file
if [ -e "${snapshot_file}" ]
then
/bin/mv "${snapshot_file}" "${snapshot_file}.0"
fi
# make a new snapshot of nas_dir
/bin/date "+[%Y-%m-%d %H:%M:%S] taking a new snapshot of '${nas_dir}'"
surep_mksnapshot "${nas_dir}" > "${snapshot_file}"
/bin/date "+[%Y-%m-%d %H:%M:%S] snapshot done"
# is that the first run for 'nas_dir' ?
if [ ! -e "${snapshot_file}.0" ]
then
/bin/date "+[%Y-%m-%d %H:%M:%S] detected initial run, see you next time !"
exit 0
fi
# ============================================================================ #
# generating a temporary diff database
/bin/date "+[%Y-%m-%d %H:%M:%S] creating diff database by comparing snapshots"
surep_mkdiffdb "${ddbfile}" "${snapshot_file}.0" "${snapshot_file}"
/bin/date "+[%Y-%m-%d %H:%M:%S] diff database generated"
# clean old snapshot
/bin/rm -f "${snapshot_file}.0"
# ============================================================================ #
# what are we asked to display ?
/bin/date "+[%Y-%m-%d %H:%M:%S] getting the requested file list from the diff database"
case ${notify_level} in
0) # new - renamed files
filelist="`surep_lsdiffdb -x "${ddbfile}"`"
;;
1) # new files
filelist="`surep_lsdiffdb -n "${ddbfile}"`"
;;
2) # new - renamed + edited files
filelist="`surep_lsdiffdb -x -m "${ddbfile}"`"
;;
3) # new + edited files
filelist="`surep_lsdiffdb -n -m "${ddbfile}"`"
;;
esac
# filter the result
if [ -z "${exclude_filter}" ] && [ -z "${include_filter}" ]
then
filtlist="${filelist}"
else
filtlist=
while read file64
do
file=`printf '%s\n' "${file64}" | /usr/bin/openssl enc -base64 -d -A 2>/dev/null`
filt=
if [ ! -z "${exclude_filter}" ] && [ ! -z "${include_filter}" ]
then
filt=`eval "case \"\${file}\" in
${exclude_filter}) ;;
${include_filter}) printf '%s\n' \"\${file64}\" ;;
esac"`
elif [ ! -z "${exclude_filter}" ]
then
filt=`eval "case \"\${file}\" in
${exclude_filter}) ;;
*) printf '%s\n' \"\${file64}\" ;;
esac"`
else
# [ ! -z "${include_filter}" ]
filt=`eval "case \"\${file}\" in
${include_filter}) printf '%s\n' \"\${file64}\" ;;
esac"`
fi
if [ -n "${filt}" ]
then
filtlist="${filtlist}"$'\n'"${filt}"
fi
done <<EOF
${filelist}
EOF
filtlist="${filtlist#?}"
fi
# is there something to display ?
if [ -z "${filtlist}" ]
then
/bin/date "+[%Y-%m-%d %H:%M:%S] no changes to report, see you next time !"
exit 0
fi
# ============================================================================ #
# convert the file list from base64 to human language and apply the user view
viewlist=
while read file64
do
file=`printf '%s\n' "${file64}" | /usr/bin/openssl enc -base64 -d -A 2>/dev/null`
if [ ! -z ${message_nasdir+x} ]
then
file="${message_nasdir}${file#${nas_dir}}"
fi
viewlist="${viewlist}"$'\n'"${file}"
done <<EOF
${filtlist}
EOF
viewlist="${viewlist#?}"
# ============================================================================ #
# replace @FILELIST@ with the file list in the email message
case "${message_body}" in
*@FILELIST@*)
message_head=${message_body%@FILELIST@*}
message_tail=${message_body#*@FILELIST@}
message_body="${message_head}${viewlist}${message_tail}"
;;
esac
# ============================================================================ #
#
# nas_fqdn : NAS Full Qualified Domain Name (extracted from the NAS url)
#
nas_fqdn="`printf '%s\n' "${nas_url}" | /bin/sed -e 's#^.*://\([^/: ]*\).*#\1#'`"
# send the email
/bin/date "+[%Y-%m-%d %H:%M:%S] sending notification email :"
printf -- '--------------------------------------------------\n'
printf '%s\n' "${message_body}"
printf -- '--------------------------------------------------\n'
surep_sendmail -f "${sender_email}" \
-t "${recipient_email}" \
-u "${message_subject}" \
-m "${message_body}" \
-s "${smtp_server}" \
-o username="${smtp_username}" \
-o password="${smtp_password}" \
-o fqdn="${nas_fqdn}" \
-o isp="${smtp_isp}" \
-o pause="${smtp_cmdwait}"
/bin/date "+[%Y-%m-%d %H:%M:%S] a notification should have been sent by email, goodbye !"
# ############################################################################ #
# ############################################################################ #
# ############################################################################ # |
Partager