/* * Read from a serial interface * Args: pointer to interface structure * Returns: Nothing. errno supplied to iface_thread_exit() */ void read_serial(struct iface *ifa) { char buf[BUFSIZ]; /* Buffer for serial reads */ char *bptr,*eptr=buf+BUFSIZ,*senptr; senblk_t sblk; struct if_serial *ifs = (struct if_serial *) ifa->info; int nread,cr=0,count=0,overrun=0; int fd; senptr=sblk.data; sblk.src=ifa->id; fd=ifs->fd; /* Read up to BUFSIZ data */ while ((ifa->direction != NONE) && (nread=read(fd,buf,BUFSIZ)) > 0) { /* Process the data we just read */ for(bptr=buf,eptr=buf+nread;bptr<eptr;bptr++) { /* Copy to our senblk if we haven't exceeded max * sentence length */ if (count < SENMAX+2) { ++count; *senptr++=*bptr; } else /* if max length exceeded, note that we've overrrun */ ++overrun; if ((*bptr) == '\r') { /* <CR>: If next char is <LF> that's our sentence */ ++cr; } else { if (*bptr == '\n' && cr) { /* <CR><LF>: End of sentence */ if (overrun) { /* This sentence invalid: discard */ overrun=0; } else { /* send the sentence on its way */ sblk.len=count; if ((!(ifa->checksum && checkcksum(&sblk)) && senfilter(&sblk,ifa->ifilter) == 0)) push_senblk(&sblk,ifa->q); } /* Reset the sentence */ senptr=sblk.data; count=0; } /* The last char was NOT <CR> */ cr=0; } } } iface_thread_exit(errno); }
void read_tcp(struct iface *ifa) { char buf[BUFSIZ]; char *bptr,*eptr=buf+BUFSIZ,*senptr; senblk_t sblk; struct if_tcp *ift = (struct if_tcp *) ifa->info; int nread,cr=0,count=0,overrun=0; int fd; senptr=sblk.data; sblk.src=ifa->id; fd=ift->fd; while ((ifa->direction != NONE) && (nread=read(fd,buf,BUFSIZ)) > 0) { for(bptr=buf,eptr=buf+nread;bptr<eptr;bptr++) { if (count < SENMAX+2) { ++count; *senptr++=*bptr; } else ++overrun; if ((*bptr) == '\r') { ++cr; } else { if (*bptr == '\n' && cr) { if (overrun) { overrun=0; } else { sblk.len=count; if (!(ifa->checksum && checkcksum(&sblk)) && senfilter(&sblk,ifa->ifilter) == 0) push_senblk(&sblk,ifa->q); } senptr=sblk.data; count=0; } cr=0; } } } iface_thread_exit(errno); }
void read_file(iface_t *ifa) { struct if_file *ifc = (struct if_file *) ifa->info; senblk_t sblk; int len; int maxread; char *eptr; maxread = SENMAX + 2 + ifc->usereturn; /* Create FILE stream here to allow for non-blocking opening FIFOs */ if (ifc->fp == NULL) if ((ifc->fp = fopen(ifc->filename,"r")) == NULL) { logerr(errno,"Failed to open FIFO %s for reading\n",ifc->filename); iface_thread_exit(errno); } sblk.src=ifa->id; for(;;) { if (fgets(sblk.data,maxread,ifc->fp) != sblk.data) { if (feof(ifc->fp) && (ifa->persist)) { if ((ifc->fp = freopen(ifc->filename,"r",ifc->fp)) == NULL) { logerr(errno,"Failed to re-open FIFO %s for reading\n", ifc->filename); break; } continue; } break; } if ((len = strlen(sblk.data)) == 0) { break; } if (sblk.data[len-1] != '\n') { logwarn("Line exceeds max sentence length (discarding)"); while ((eptr = fgets(sblk.data,SENBUFSZ,ifc->fp)) == sblk.data) { if (sblk.data[strlen(sblk.data)-1] == '\n') { break; } } if (eptr == NULL && (ifa->persist == 0)) break; continue; } if (ifc->usereturn) { if (sblk.data[len-2] != '\r') { continue; } } else { sblk.data[len-1]='\r'; sblk.data[len]='\n'; len++; } sblk.len=len; if (ifa->checksum && checkcksum(&sblk)) continue; if (senfilter(&sblk,ifa->ifilter)) continue; push_senblk(&sblk,ifa->q); } iface_thread_exit(errno); }
/* generic read routine * Args: Interface Pointer * Returns: nothing */ void do_read(iface_t *ifa) { senblk_t sblk; char buf[BUFSIZ]; char tbuf[TAGMAX]; char *bptr,*eptr,*ptr; int nread,countmax,count=0; enum sstate senstate; int nocr=flag_test(ifa,F_NOCR)?1:0; int loose = (ifa->strict)?0:1; sblk.src=ifa->id; senstate=SEN_NODATA; while ((nread=(*ifa->readbuf)(ifa,buf)) > 0) { for(bptr=buf,eptr=buf+nread;bptr<eptr;bptr++) { switch (*bptr) { case '$': case '!': ptr=sblk.data; countmax=SENMAX-(nocr|loose); count=1; *ptr++=*bptr; senstate=SEN_SENPROC; continue; case '\\': if (senstate==SEN_TAGPROC) { *ptr++=*bptr; senstate=SEN_TAGSEEN; } else { senstate=SEN_TAGPROC; ptr=tbuf; countmax=TAGMAX-1; *ptr++=*bptr; count=1; } continue; case '\r': case '\n': case '\0': if (senstate == SEN_SENPROC || senstate == SEN_TAGSEEN) { if (loose || (nocr && *bptr == '\n')) { *ptr++='\r'; *ptr='\n'; sblk.len = count+2; } else { if ((!nocr) && *bptr == '\r') { senstate = SEN_CR; *ptr++=*bptr; ++count; } else { senstate = SEN_NODATA; } continue; } } else if (senstate == SEN_CR) { if (*bptr != '\n') { senstate = SEN_NODATA; continue; } *ptr=*bptr; sblk.len = ++count; } else { senstate = SEN_NODATA; continue; } if (!(ifa->checksum && checkcksum(&sblk) && (sblk.len > 0 )) && senfilter(&sblk,ifa->ifilter) == 0) { push_senblk(&sblk,ifa->q); } senstate=SEN_NODATA; continue; default: break; } if (senstate != SEN_SENPROC && senstate != SEN_TAGPROC) { if (senstate != SEN_NODATA ) senstate=SEN_NODATA; continue; } if (count++ > countmax) { senstate=SEN_NODATA; continue; } *ptr++=*bptr; } } iface_thread_exit(errno); }