X-Git-Url: http://git.jankratochvil.net/?a=blobdiff_plain;f=mdsms.c;h=bf307b5c8d4557cace8303605cfb8afa55d1494d;hb=839c0bbc84bf2bdbcf7e5d7f820350e5e69222ca;hp=c20097d4bf9c4bf3e71ec6d1e7084b77ac479a58;hpb=5297e3e70a47948fa84615a6bc7a6a4aeb49e1a2;p=mdsms.git diff --git a/mdsms.c b/mdsms.c index c20097d..bf307b5 100644 --- a/mdsms.c +++ b/mdsms.c @@ -1,3 +1,4 @@ +#define WANT_DECLARATIONS 1 #include "config.h" #ifndef lint static char rcsid[] ATTR_UNUSED = "$Id$"; @@ -38,6 +39,9 @@ static char rcsid[] ATTR_UNUSED = "$Id$"; #ifdef HAVE_SYS_TYPES_H #include #endif +#ifdef HAVE_SYS_WAIT_H +#include +#endif #ifdef HAVE_SYS_STAT_H #include #endif @@ -66,6 +70,13 @@ static char rcsid[] ATTR_UNUSED = "$Id$"; #include "getopt.h" #endif + +/* Always override possible system defintions as it is safe (used by glib) */ +#undef MAX +#define MAX(a,b) ((a)>(b)?(a):(b)) +#undef MIN +#define MIN(a,b) ((a)<(b)?(a):(b)) + #define NELEM(x) (sizeof((x))/sizeof(*(x))) #ifndef DEBUG @@ -614,7 +625,9 @@ int i; readbody++; break; case 'v': +#ifndef DEBUG /* prevent suppositious overflow */ verbose++; +#endif break; case 'V': fprintf(stderr,version); @@ -774,7 +787,7 @@ static void lockclose(int fd) error(_("Error closing lockfile \"%s\""),lockreal); } -static inline int lockdevice(int attempt) +static int lockdevice(int attempt) { int fd=-1; char buf[64]; @@ -863,7 +876,7 @@ static const char *record,*recordend; static char *catchdata; static size_t catchdatal,catchdatasiz; -static char *reform(const char *s,int slot); +static const char *reform(const char *s,int slot); static void catched(const char *end,char edata) { size_t len; @@ -893,7 +906,7 @@ static void retrying(void) if (verbose>=2) error(_(".Retrying phase, %d out of %ld.."),retrycnt,maxretryn); } -static char *reform(const char *s,int slot) +static const char *reform(const char *s,int slot) { static struct formslot { char *s; @@ -930,6 +943,8 @@ off_t o=d-fs->s; return(fs->s); } +static char devcmd_empty_return='\0'; /* returned as catch when only newlines found */ + static char *devcmd(const char *term,const char *catch,const char *send,...) ATTR_PRINTFORMAT(3,4); static char *devcmd(const char *term,const char *catch,const char *send,...) { @@ -1021,6 +1036,14 @@ err: got=read(devfd,buf+bufl,1); } if (got<=0) { + buf[bufl]='\0'; /* for strspn() below */ + if (!strcmp(term,"\n") && catch /* written to trap on 'devcmd("\n","+CMT:"," ")' */ + && bufl==strspn(buf,"\n" /* accept */)) { /* only newlines found */ + if (verbose>=2) + error(_(".Blank (%d newlines) input read, ignoring it"),bufl); + bufl=0; /* discard newlines */ + return(&devcmd_empty_return); + } if (wasalarm) error(_("Maximum response timeout (%lds) exceeded"),alarmtime); else error(_("^Couldn't read device data (ret=%d)"),got); goto err; @@ -1454,12 +1477,13 @@ fd_set rfds,xfds; assert(devfd>=0); retry: - errno=0; - + if (!immed && verbose>=2) + error(_(".Waiting for device incoming data..")); #ifdef HAVE_POLL ufd.fd=devfd; ufd.events=POLLIN; ufd.revents=0; + errno=0; i=poll(&ufd,1,(immed?0:-1)); #else /* HAVE_POLL */ #ifdef HAVE_FD_SETSIZE @@ -1469,9 +1493,12 @@ retry: #endif /* HAVE_FD_SETSIZE */ FD_ZERO(&rfds); FD_SET(devfd,&rfds); FD_ZERO(&xfds); FD_SET(devfd,&xfds); + errno=0; i=select(devfd+1,&rfds,NULL,&xfds,NULL); #endif /* HAVE_POLL */ if (immed && i==0) return(0); + if (i==-1 && errno==EINTR) + goto retry; /* silent retry, for example SIGCHLD could occur */ if (i!=1) error(_("^Failed (retval %d) while waiting for data, ignoring"),i); @@ -1497,8 +1524,8 @@ retry: static char *check_format(const char *fmt,const char *string) { static char err[LINE_MAX],sub[50]; -char *subp,cf,cs; -const char *sf,*ss; +char cf,cs; +const char *sf,*ss,*subp; for (sf=fmt,ss=string;(cf=*sf) && (cs=*ss);sf++,ss++) { subp=NULL; @@ -1609,13 +1636,27 @@ int i; memset(&tm,0,sizeof(tm)); /* may be redundant */ for (i=0;i=2) + error(_(".Child process w/PID %d has exited, %s, status=%d"), + pid,(WIFEXITED(status)? _("normally") : _("abnormally")),(WIFEXITED(status) ? WEXITSTATUS(status) : -1)); + } +} + static void receive_text(char *bodyline) { char *buf,*s,*s1,*s2,*s3; @@ -1625,12 +1666,17 @@ int i; FILE *f; d2("receive_text: %s\n",bodyline); + signal(SIGCHLD,(RETSIGTYPE (*)(int))signal_chld); #if RECEIVE_TEST pid=0; #else pid=fork(); #endif - if (pid>0) return; /* parent context */ + if (pid>0) { + if (verbose>=2) + error(_(".Spawned child receive-SMS process w/PID %d"),pid); + return; /* parent context */ + } if (pid==-1) { error(_("Can't fork(2), process spawning may block receive")); } @@ -2047,34 +2093,38 @@ time_t start,end; if ((end-=start)>LOCKREPORT) logmsg(_("Device lock succeeded after %ld seconds"),(long)end); } + +retryopen: + if (verbose>=1) error(_(".Opening device \"%s\".."),device); if ((devfd=open(device,O_RDWR|O_NDELAY))<0) error(_("^!Cannot open device \"%s\" for r/w access"),device); - if (tcgetattr(devfd,&restios)) - error(_("^Unable to get termios settings")); - else { - restios.c_cflag=(restios.c_cflag&~(CBAUD|CBAUDEX))|B0|HUPCL; - restios_yes=1; - } - tios.c_iflag=IGNBRK|IGNPAR|(handshake_rtscts ? 0 : IXON|IXOFF); - tios.c_oflag=0; - tios.c_cflag=CS8|CREAD|CLOCAL|HUPCL|portbaud|(handshake_rtscts ? CRTSCTS : 0); - tios.c_lflag=IEXTEN|NOFLSH; - memset(tios.c_cc,_POSIX_VDISABLE,sizeof(tios.c_cc)); - tios.c_cc[VTIME]=0; - tios.c_cc[VMIN ]=1; - cfsetispeed(&tios,portbaud); - if (cfsetospeed(&tios,portbaud)|cfsetispeed(&tios,portbaud)) - error(_("^Error setting termios baudrate on device")); - if (tcflush(devfd,TCIOFLUSH)) - error(_("^Error flushing termios (TCIOFLUSH) on device")); - if (tcsetattr(devfd,TCSANOW,&tios)) - error(_("^!Unable to set initial termios device settings")); +retryall: - setalarm(); + if (tcgetattr(devfd,&restios)) + error(_("^Unable to get termios settings")); + else { + restios.c_cflag=(restios.c_cflag&~(CBAUD|CBAUDEX))|B0|HUPCL; + restios_yes=1; + } + tios.c_iflag=IGNBRK|IGNPAR|(handshake_rtscts ? 0 : IXON|IXOFF); + tios.c_oflag=0; + tios.c_cflag=CS8|CREAD|CLOCAL|HUPCL|portbaud|(handshake_rtscts ? CRTSCTS : 0); + tios.c_lflag=IEXTEN|NOFLSH; + memset(tios.c_cc,_POSIX_VDISABLE,sizeof(tios.c_cc)); + tios.c_cc[VTIME]=0; + tios.c_cc[VMIN ]=1; + cfsetispeed(&tios,portbaud); + if (cfsetospeed(&tios,portbaud)|cfsetispeed(&tios,portbaud)) + error(_("^Error setting termios baudrate on device")); + if (tcflush(devfd,TCIOFLUSH)) + error(_("^Error flushing termios (TCIOFLUSH) on device")); + if (tcsetattr(devfd,TCSANOW,&tios)) + error(_("^!Unable to set initial termios device settings")); + + setalarm(); -retryall: devcmd("",NULL,"\r\nAT\033\032"); /* ESCAPE, CTRL-Z */ devcmd(NULL,NULL,"\r\nAT"); smscset(); @@ -2137,38 +2187,45 @@ struct hexdata *hd; restore="\r\nAT+CNMI=,0"; devcmd(NULL,NULL,"\r\nAT+CNMI=,2"); devcmd(NULL,NULL,"\r\nAT+CSDH=0"); - unlockdevice(0); - /* Never bail-out when we got up to this point */ - if (maxretryn!=-1 && verbose>=1) - error(_(".Initialization successful, infinite retry count set")); - maxretryn=-1; + for (;;) { +continue_receive: + unlockdevice(0); + /* Never bail-out when we got up to this point */ + if (maxretryn!=-1 && verbose>=1) + error(_(".Initialization successful, infinite retry count set")); + maxretryn=-1; #if RECEIVE_TEST receive_headerparse(" \"+420602123456\",,\"99/10/25,03:21:03-00\""); receive_accept("TESTBODY"); exit(EXIT_SUCCESS); #endif - datawait(0); - if (!lockdevice(1)) { - if (verbose>=1) - error(_(".Dialout detected, waiting for lock..")); - lockdevice(0); - goto retryall; - } - d1("Lock-device succeeded\n"); - do { - d1("Reading a message for us...\n"); - if (!(s=devcmd("\n","+CMT:"," "))) - goto retryall; - if (cmgf && !(i=receive_headerparse(s))) - error(_("Receive-header parsing failed on: %s"),s); - if (!(s=devcmd("\n","@"," "))) - goto retryall; - if (cmgf) { - if (i) receive_text(s); + datawait(0); + if (!lockdevice(1)) { + if (verbose>=1) + error(_(".Dialout detected, waiting for lock..")); + if (verbose>=1) error(_(".Closing device \"%s\".."),device); + if (close(devfd)) + error(_("Error closing device \"%s\""),device); + lockdevice(0); + goto retryopen; } - else receive_pdu(s); - } while (datawait(1)); - goto retryall; + d1("Lock-device succeeded\n"); + do { + d1("Reading a message for us...\n"); + if (!(s=devcmd("\n","+CMT:"," "))) + goto retryall; + if (s==&devcmd_empty_return) /* only newlines found */ + goto continue_receive; + if (cmgf && !(i=receive_headerparse(s))) + error(_("Receive-header parsing failed on: %s"),s); + if (!(s=devcmd("\n","@"," "))) + goto retryall; + if (cmgf) { + if (i) receive_text(s); + } + else receive_pdu(s); + } while (datawait(1)); + } /* return to 'continue receive' point */ break; default: assert(0); } @@ -2181,6 +2238,9 @@ struct hexdata *hd; } devcmd(NULL,NULL,"\r\nAT"); - logmsg(_("SMS sent (after %d retries), %d part(s)"),retrycnt,parts); + if (parts) + logmsg(_("SMS sent (after %d retries), %d part(s)"),retrycnt,parts); + else + logmsg(_("SMS sent (after %d retries)"),retrycnt); return(EXIT_SUCCESS); }