isdn4k-utils-3.0beta2) logs
incoming and outgoing calls by listening to the D channel of the ISDN
S0 bus via my Teles S0 card. The remote number is only known for
incoming calls. Numbers are translated into names via an
"alias file".
/usr/local/sbin/esticd.
This was accomplished by some brute hacks in the ESTIC sources:
Here are the modified sources: estic-daemon.tar.gz
The daemon is started and stopped with this SuSE-style script,
/sbin/init.d/estic:
#! /bin/bash
. /etc/rc.config
return=$rc_done
case "$1" in
start)
echo -n "Starting service estic"
(cd /etc/estic; /usr/local/sbin/esticd > /dev/null &)
echo -e "$return"
;;
stop)
echo -n "Shutting down service estic"
killproc -TERM /usr/local/sbin/esticd || return=$rc_failed
echo -e "$return"
;;
restart)
$0 stop && $0 start || return=$rc_failed
;;
*)
echo "Usage: $0 {start|stop|restart}"
exit 1
esac
test "$return" = "$rc_done" || exit 1
exit 0
This is my ESTIC configuration file, /etc/estic/estic.ini:
[ESTIC] SettingsFile = "" [Port] PortName = "ttyS1" [Windows] ShowDateTime = None ShowInfoOnStartup = no [AreaCode] AreaCodeFile = "/usr/lib/isdn/areacodes" CountryCode = "49" AreaCode = "391" DialPrefix = "0" [Call-Logs] OutgoingLog1 = "/var/log/estic-outgoing.log" IncomingLog1 = "/var/log/estic-incoming.log" OutgoingLog2 = "/dev/console" LogZeroCostCalls = yes [Alias] AliasFile = "/etc/estic/alias.dat" AutoReadAliases = yes [Cron] CronFile = "/etc/estic/cron.dat" [Debug] WaitAfterCall = 700 ShortWaitAfterMsg = on [Firmware] DiagModeUpdate = auto
The tricky part is to get it work even if the display is locked with XLock or the XDM login screen is active.
X11/xdm/xdm-config file:
! ! We use a named authfile for :0; this allows root to take this ! authorization and provide funny services. ! DisplayManager._0.authFile: /var/lib/xdm/authdir/authfiles/the-console-xauthority
[ISDNLOG] section of the /etc/isdn/isdn.conf
file:
START={
[FLAG]
FLAGS=IR
PROGRAM=/usr/local/bin/show-callerid "\$2" "\$19" "\$17"
}
/usr/local/bin/show-callerid:
#! /bin/sh
if [ -r /var/lib/xdm/authdir/authfiles/the-console-xauthority ]; then
export XAUTHORITY=/var/lib/xdm/authdir/authfiles/the-console-xauthority
fi
export DISPLAY=:0
# for debugging purposes:
echo "show-callerid: NUMBER $1 ALIAS $2 LOCATION $3" > /dev/console
if [ "$1" != "?" ]; then
# Build the string to be shown
if [ "$2" != "?" ]; then
# Alias is known
export n="$2"
else
# Alias is not known, show number and location
export n="$3\n$1"
fi
# Deactivate screen saver
/usr/X11R6/bin/xset s reset
/usr/X11R6/bin/xset q | grep "Monitor is Off" > /dev/null
export o=$?
/usr/X11R6/bin/xset dpms force on 2> /dev/null
# Suspend xlock
killall -STOP xlock 2> /dev/null
# Display id
xterm -title "Phone call from:" \
-font "-bitstream-courier-bold-r-*-*-50-400-*-*-*-*-*-*" \
-bg IndianRed -b 10 -fg White +sb -cr White -name callerid \
-geometry 25x2+260+610 -e /bin/sh -c "(echo -n -e \"$n\" && read)" &
export xtermpid=$!
(sleep 35; kill $xtermpid 2> /dev/null; \
killall -CONT xlock 2> /dev/null; \
[ $o == 0 ] && /usr/X11R6/bin/xset dpms force off > /dev/null 2> /dev/null) &
fi
~/.fvwm2rc:
Style "callerid" Sticky, StaysOnTop, DumbPlacement
~/.estic-alias
and ~/.isdnlog-alias; this is ~/lisp/bbdb-phone.el.
;;; bbdb-phone.el --- BBDB/Isdnlog/ESTIC integration
;; Copyright (C) 1999 by Free Software Foundation, Inc.
;; Author: Matthias Koeppe <mkoeppe@mail.math.uni-magdeburg.de>
;; Keywords: local
;; This file is NOT part of GNU Emacs.
;; 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; either version 2, or (at
;; your option) any later version.
;; 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; see the file COPYING. If not, write to
;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.
;;; Commentary:
;; BBDB & phone integration
;;; Code:
(require 'bbdb)
(defvar phone-area-prefix "391")
(defun my-canonicalize-phone-number (number)
"Canonicalize phone number NUMBER, which must be a string."
(cond ((= (aref number 0) ?+) number) ; already has international prefix
((= (aref number 0) ?0) (concat "+49 " (substring number 1)))
(t (concat "+49 " phone-area-prefix number))))
(defun my-localize-phone-number (number)
"Make NUMBER ready for dialing from local site."
(cond ((string-match (concat "^\\(\\++49[^0-9]*\\|0\\)"
phone-area-prefix
"[^0-9]*")
number) ; make local number
(substring number (match-end 0)))
((string-match "^\\++49[^0-9]*"
number) ; make long-distance number
(concat "0" (substring number (match-end 0))))
((string-match "^\\++"
number) ; make international number
(concat "00" (substring number (match-end 0))))
(t number))) ; number is ok
(defun my-strip-nondigits (string)
"Return STRING stripped of all non-digits."
(while (string-match "[^0-9]+" string)
(setq string (replace-match "" t t string)))
string)
(defun my-extract-phone-aliases-from-bbdb ()
"Extract phone aliases from BBDB."
(let ((records (bbdb-records))
(isdnlog-alias-buffer (get-buffer-create " *isdnlog-alias*"))
(estic-alias-buffer (get-buffer-create " *estic-alias*")))
(while (not (null records))
(let* ((record (car records))
(phones (bbdb-record-phones record))
(name (bbdb-record-name record))
(comp (bbdb-record-company record))
(name-comp
(cond ((and name comp) (concat name " - " comp))
((or name comp))
(t "???"))))
(while phones
(let* ((phone (car phones))
(location (aref phone 0))
(number (aref phone 1))
(name-comp-loc
(concat name-comp " (" location ")")))
(set-buffer isdnlog-alias-buffer)
(insert "[number]\n"
"NUMBER = " (my-canonicalize-phone-number number) "\n"
"SI = 1\n" ; service indicator is voice
"ZONE = 1\n" ; this is incorrect but who cares?
"ALIAS = " name-comp-loc "\n\n")
(set-buffer estic-alias-buffer)
(insert (my-strip-nondigits (my-localize-phone-number number))
" \"" name-comp-loc "\"\n"))
(setq phones (cdr phones))))
(setq records (cdr records)))
(set-buffer isdnlog-alias-buffer)
(set-buffer-file-coding-system 'latin-1-unix)
(write-file "~/.isdnlog-alias")
(kill-buffer isdnlog-alias-buffer)
(set-buffer estic-alias-buffer)
(set-buffer-file-coding-system 'latin-1-unix)
(write-file "~/.estic-alias")
(kill-buffer estic-alias-buffer)))
(defvar incoming-phone-messages-file "/var/log/messages")
(defun last-unnamed-caller (output-to-buffer-p)
"Show the phone number of the last unnamed caller.
With prefix argument, insert in current buffer."
(interactive "P")
(let ((buffer (get-buffer-create " *last-caller*"))
(old-buffer (current-buffer)))
(set-buffer buffer)
(let ((len (nth 7 (file-attributes incoming-phone-messages-file))))
(insert-file-contents incoming-phone-messages-file nil
(max 0 (- len 20000)) len))
(goto-char (point-max))
(if (search-backward-regexp "Call from \\(\\+[0-9]+ [0-9]+/[0-9]+\\).*RING" nil t)
(if output-to-buffer-p
(progn
(set-buffer old-buffer)
(insert-buffer-substring buffer (match-beginning 1) (match-end 1)))
(message "Last unnamed caller: %s"
(buffer-substring (match-beginning 1) (match-end 1))))
(error "No unnamed caller."))
(set-buffer old-buffer)
(kill-buffer buffer)))
(defvar outgoing-phone-messages-file "/var/log/estic-outgoing.log")
(defun last-unnamed-destination (output-to-buffer-p)
"Show the phone number of the last unnamed call destination.
With prefix argument, insert in current buffer."
(interactive "P")
(let ((buffer (get-buffer-create " *last-caller*"))
(old-buffer (current-buffer)))
(set-buffer buffer)
(let ((len (nth 7 (file-attributes outgoing-phone-messages-file))))
(insert-file-contents outgoing-phone-messages-file nil
(max 0 (- len 20000)) len))
(goto-char (point-max))
(if (search-backward-regexp "Called \\([0-9]+\\) with" nil t)
(if output-to-buffer-p
(progn
(set-buffer old-buffer)
(insert-buffer-substring buffer (match-beginning 1) (match-end 1)))
(message "Last unnamed call destination: %s"
(buffer-substring (match-beginning 1) (match-end 1))))
(error "No unnamed call destination."))
(set-buffer old-buffer)
(kill-buffer buffer)))
;;; bbdb-phone.el ends here
/usr/local/bin/frobnicate-phone-aliases:
#! /bin/sh emacs -q -batch -l ~/lisp/bbdb/bbdb.el -l ~/lisp/bbdb-phone.el \ -f my-extract-phone-aliases-from-bbdb -kill
/usr/local/sbin/make-phone-aliases, calls
frobnicate-phone-aliases for some users and concatenates
the generated user alias files and the system alias templates,
/etc/estic/alias.dat.in and
/etc/isdn/callerid.conf.in, creating the system alias
files, /etc/estic/alias.dat and
/etc/isdn/callerid.conf.
#! /bin/sh
#
# These users can generate .isdnlog-alias and .estic-alias files
# from their Emacs/BBDB.
PHONE_ALIAS_USERS=mkoeppe
# So let them generate these files.
for a in $PHONE_ALIAS_USERS; do
su -c /usr/local/bin/frobnicate-phone-aliases $a
done
# Write the ESTIC aliases
if [ -f /etc/estic/alias.dat ]; then
mv /etc/estic/alias.dat /etc/estic/alias.dat.orig
fi
(echo "; Automagically generated by $0; do not edit."; \
cat /etc/estic/alias.dat.in; \
for a in $PHONE_ALIAS_USERS; do \
echo "; From ~$a/.estic-alias:"; \
cat /home/$a/.estic-alias; \
done) > /etc/estic/alias.dat
# Write the Isdnlog aliases
if [ -f /etc/isdn/callerid.conf ]; then
mv /etc/isdn/callerid.conf /etc/isdn/callerid.conf.orig
fi
(echo "# Automagically generated by $0; do not edit."; \
cat /etc/isdn/callerid.conf.in; \
for a in $PHONE_ALIAS_USERS; do \
echo "# From ~$a/.isdnlog-alias:"; \
cat /home/$a/.isdnlog-alias; \
done) > /etc/isdn/callerid.conf
/usr/local/sbin/update-phone-aliases, rebuilds the alias
files and restarts Isdnlog, so that the changes take effect. Nothing
special must be done for ESTIC because it reads its alias file at
every call.
#! /bin/sh ## Rebuild the phone alias files /usr/local/sbin/make-phone-aliases ## Restart isdnlog kill -HUP $(cat /var/run/isdnlog.isdnctrl0.pid)
/usr/local/sbin/update-phone-aliases
as root every day.