/*
* $Log$
+ * Revision 1.3 1999/06/03 11:46:41 short
+ * Logging (--log) implemented.
+ *
* Revision 1.2 1999/06/03 10:38:52 short
* Implemented remaining communication timeouts and maximum retry count.
*
#include <fcntl.h>
#include <errno.h>
#include <signal.h>
+#include <time.h>
#ifdef HAVE_GETOPT_LONG
#include <getopt.h>
static char *pname;
static int dis_cleanup=0,devfd=-1;
-static char *phone,*body,*device,*lockfile,*smsc,*maxretry,*readtime,*chartime,*cmdtime;
+static char *phone,*body,*device,*logname,*lockfile,*smsc,*maxretry,*readtime,*chartime,*cmdtime;
static int readbody;
static long maxretryn=DEF_MAXRETRY,readtimen=DEF_READTIME,chartimen=DEF_CHARTIME,cmdtimen=DEF_CMDTIME;
static size_t bodylen;
static struct termios restios;
static char restios_yes;
+static FILE *logf;
+
+static void vlogmsg(
+#ifndef PRINTF_WORKS_PM
+ char outerr,
+#endif
+ const char *fmt,va_list ap)
+{
+time_t stamp;
+char *ctm,*s;
+pid_t mypid=-1;
+char host[LINE_MAX];
+
+ if (!logf) return;
+ if (mypid==-1) {
+ mypid=getpid();
+ if (gethostname(host,sizeof(host))) strcpy(host,"<ERROR>");
+ }
+ time(&stamp);
+ ctm=ctime(&stamp);
+ if ((s=strchr(ctm,'\n'))) *s='\0';
+ fprintf(logf,"%s %s %s[%d]: ",ctm,host,pname,mypid);
+ vfprintf(logf,fmt,ap);
+#ifndef PRINTF_WORKS_PM
+ if (outerr) fputs(strerror(errno),logf);
+#endif
+ fputc('\n',logf);
+ fflush(logf);
+}
+
+static void logmsg(const char *fmt,...)
+{
+va_list ap;
+ va_start(ap,fmt);
+ vlogmsg(
+#ifndef PRINTF_WORKS_PM
+ 0,
+#endif
+ fmt,ap);
+ va_end(ap);
+}
static void error(const char *fmt,...)
{
nfmt
#endif
,ap);
+ if (fatal=='!') vlogmsg(
+#ifdef PRINTF_WORKS_PM
+ fmt
+#else
+ pm,nfmt
+#endif
+ ,ap);
va_end(ap);
#ifndef PRINTF_WORKS_PM
%s\
\n\
Usage: " PACKAGE " [-c|--config <cfgfile>] [-d|--device <device>]\n\
+ [-L|--log <file>]\n\
[-l|--lockfile <lock>] [-s|--smsc <smsc #>] [-m|--maxretry <#>]\n\
[-r|--readtime <sec>] [-t|--chartime <msec>] [-T|--cmdtime <msec>]\n\
[-f|--file] [-v|--verbose] [-h|--help] [-V|--version]\n\
-c, --config\tRead this additional config file\n\
\t\t(def. \"" CONFIG_MAIN "\" and \"$HOME" CONFIG_HOME "\")\n\
-d, --device\tMobilDock on this serial device (def. \"" DEF_DEVICE "\")\n\
+ -L, --log\tLog all important messages to this file (def. \"" DEF_LOGNAME "\")\n\
-l, --lockfile\tLock serial port by this file, \"%%s\" is basename of device\n\
\t\t(def. \"%s\")\n\
-s, --smsc\tUse this SMS Center number (def. query from Siemens A1)\n\
static const struct option longopts[]={
{"config" ,1,0,'c'},
{"device" ,1,0,'d'},
+{"log" ,1,0,'l'},
{"lockfile",1,0,'l'},
{"smsc" ,1,0,'s'},
{"maxretry",1,0,'m'},
unsigned stamp;
} optset[]={
{ 'd',&device },
+ { 'L',&logname },
{ 'l',&lockfile },
{ 's',&smsc },
{ 'm',&maxretry },
seq++;
optarg=NULL; optind=0; /* FIXME: Possible portability problem. */
- while ((optc=getopt_long(argp,args,"c:d:l:s:m:r:t:T:fvhV",longopts,NULL))!=EOF) switch (optc) {
+ while ((optc=getopt_long(argp,args,"c:d:L:l:s:m:r:t:T:fvhV",longopts,NULL))!=EOF) switch (optc) {
case 'c':
if (cfgstacki>=NELEM(cfgstack)) {
error("Looping (%d) during attempt to read config file \"%s\", break-out",NELEM(cfgstack),optind);
}
chk(cfgstack[cfgstacki++]=strdup(optarg));
break;
- case 'd': case 'l': case 's': case 'm': case 'r': case 't': case 'T':
+ case 'd': case 'L': case 'l': case 's': case 'm': case 'r': case 't': case 'T':
for (i=0;i<NELEM(optset);i++)
if (optset[i].c==optc) {
if (optset[i].stamp && optset[i].stamp!=seq) {
{&device,"device for communication"},
#endif
};
-static char **emptycheck[]={&smsc,&body};
+static char **emptycheck[]={&logname,&smsc,&body};
static void lockclose(int fd)
{
lockclose(fd);
}
+static char wasalarm=0;
static void sigalarm(int signo)
{
signal(SIGALRM,(RETSIGTYPE (*)(int))sigalarm);
+ wasalarm=1;
if (verbose>=1) error("Timed out");
}
assert(catchdatal<=catchdatasiz);
}
+static int retrycnt=0;
static void retrying(void)
{
-static int cnt=0;
-
- if (++cnt>maxretryn) error("!Maximum command retry count (%d) exceeded",maxretryn);
- if (verbose>=2) error(".Retrying phase, %d out of %d..",cnt,maxretryn);
+ if (++retrycnt>maxretryn) error("!Maximum command retry count (%d) exceeded",maxretryn);
+ if (verbose>=2) error(".Retrying phase, %d out of %d..",retrycnt,maxretryn);
}
static char *devcmd(const char *term,const char *catch,const char *send,...)
fragl=MAX(fragl,MAX(strlen(ERROR_SUBSTR1),strlen(ERROR_SUBSTR2)));
bufl=0;
record=NULL;
+ wasalarm=0;
alarm(readtimen);
for (;;) {
blocking(0);
got=read(devfd,buf+bufl,1);
}
if (got<=0) {
- error("Could read device data (ret=%d): %m",got);
+ if (wasalarm) error("!Maximum response timeout (%ds) exceeded",readtimen);
+ error("Couldn't read device data (ret=%d): %m",got);
goto err;
}
s=buf+bufl;
unsigned fatal=0;
struct termios tios;
- pname=*argv;
+ if ((s=strrchr((pname=*argv),'/'))) pname=s+1;
atexit(cleanup);
signal(SIGTERM,(RETSIGTYPE (*)(int))cleanup);
signal(SIGQUIT,(RETSIGTYPE (*)(int))cleanup);
free(*emptycheck[i]);
*emptycheck[i]=NULL;
}
+ if (!logname) logname=DEF_LOGNAME;
if (!lockfile) lockfile=DEF_LOCKFILE;
if (!device) device=DEF_DEVICE;
if (body && readbody) {
}
error("!Invalid format-character '%c' in lockfile format-string, only \"%%s\" allowed",*s);
}
+
+ if (*logname) {
+ if (!(logf=fopen(logname,"a")))
+ error("!Error opening log \"%s\" for append: %m",logname);
+ logmsg("Starting up: " PACKAGE " " VERSION);
+ }
genpdu();
if (lockfile && *lockfile && VARPRINTF(lockreal,lockfile,devicename)>0) {
+time_t start,end;
if (verbose>=1) error(".Locking device \"%s\" by \"%s\"..",device,lockreal);
+ time(&start);
lockdevice();
+ time(&end);
+ if ((end-=start)>LOCKREPORT)
+ logmsg("Device lock succeeded after %d seconds",end);
}
if (verbose>=1) error(".Opening device \"%s\"..",device);
if ((devfd=open(device,O_RDWR|O_NDELAY))<0)
if (verbose>=1) error("\nMessage successfuly sent with MR: %s",s);
devcmd(NULL,NULL,"\r\nAT");
+ logmsg("SMS sent (after %d retries), message reference: %s",retrycnt,s);
return(EXIT_SUCCESS);
}