X-Git-Url: http://git.jankratochvil.net/?p=mdsms.git;a=blobdiff_plain;f=mdsms.c;h=21d69992354c48f2f2e821855dae8778b31085cc;hp=932dc490f6cbc8e7d265e2555988b513ed8c5843;hb=30abdc172e133a85bd88a9831450d0fffac1f258;hpb=7729b272cf9804c3061f2a393d9cfa4f2275be01 diff --git a/mdsms.c b/mdsms.c index 932dc49..21d6999 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 @@ -309,7 +320,7 @@ Usage: %s [-c|--config ] [-d|--device ]\n\ \t\t* Group gfx : Specify \"%s\" to send logo as group graphics\n\ \n\ You may need to use the following line to catch all of this help text:\n\ -./mdsms 2>&1|more\n\ +./mdsms -h 2>&1|more\n\ \n"),version,PACKAGE,CONFIG_MAIN,CONFIG_HOME,DEF_DEVICE,DEF_LOGNAME,DEF_LOCKFILE,DEF_BAUD, #ifdef HAVE_CRTSCTS "", @@ -863,7 +874,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 +904,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 +941,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 +1034,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 +1475,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 +1491,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 +1522,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; @@ -1616,6 +1641,22 @@ int i; #undef DIGIT2ASC } +static void signal_chld(int signo) +{ +int status; +pid_t pid; + + signal(SIGCHLD,(RETSIGTYPE (*)(int))signal_chld); + /* we don't care about siginterrupt(3) as it doesn't matter how it is set */ + + d2("signal_chld: signo=%d\n",signo); + while (0<(pid=waitpid(-1 /* ANY process */,&status,WNOHANG /* options */))) { + if (verbose>=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")); } @@ -2137,38 +2183,42 @@ 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:"," "))) + datawait(0); + if (!lockdevice(1)) { + if (verbose>=1) + error(_(".Dialout detected, waiting for lock..")); + lockdevice(0); 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); } - 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 +2231,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); }