Beispiel #1
0
void write_tcp(struct iface *ifa)
{
	struct if_tcp *ift = (struct if_tcp *) ifa->info;
	senblk_t *sptr;

/* Porters: MSG_NOSIGNAL / SO_NOSIGPIPE are redundant as of v0.3: We're
 * ignorning SIGPIPE so you can forget this if porting to a platform on
 * which none of this is supported. Will be removed in a later release.
 */

#ifndef MSG_NOSIGNAL
    #define MSG_NOSIGNAL 0
    int n=1;
    setsockopt(ift->fd,SOL_SOCKET, SO_NOSIGPIPE, (void *)&n, sizeof(int));
#endif

	for(;;) {
		if ((sptr = next_senblk(ifa->q)) == NULL)
			break;

        if (senfilter(sptr,ifa->ofilter)) {
            senblk_free(sptr,ifa->q);
            continue;
        }

        if ((send(ift->fd,sptr->data,sptr->len,MSG_NOSIGNAL)) <0)
		    break;
		senblk_free(sptr,ifa->q);
	}

	iface_thread_exit(errno);
}
Beispiel #2
0
/*
 * Write nmea sentences to serial output
 * Args: pointer to interface
 * Returns: Nothing. errno supplied to iface_thread_exit()
 */
void write_serial(struct iface *ifa)
{
    struct if_serial *ifs = (struct if_serial *) ifa->info;
    senblk_t *senblk_p;
    int fd=ifs->fd;
    int n=0;
    char *ptr;

    while(n >= 0) {
        /* NULL return from next_senblk means the queue has been shut
         * down. Time to die */
        if ((senblk_p = next_senblk(ifa->q)) == NULL)
            break;

        if (senfilter(senblk_p,ifa->ofilter)) {
            senblk_free(senblk_p,ifa->q);
            continue;
        }

        ptr=senblk_p->data;
        while(senblk_p->len) {
            if ((n=write(fd,ptr,senblk_p->len)) < 0)
                break;
            senblk_p->len -=n;
            ptr+=n;
        }
        senblk_free(senblk_p,ifa->q);
    }
    iface_thread_exit(errno);
}
Beispiel #3
0
void write_file(iface_t *ifa)
{
    struct if_file *ifc = (struct if_file *) ifa->info;
    senblk_t *sptr;

    /* ifc->fp will only be NULL if we're opening a FIFO.
     */
    if (ifc->fp == NULL) {
        if ((ifc->fp=fopen(ifc->filename,"w")) == NULL) {
            logerr(errno,"Failed to open FIFO %s for writing\n",ifc->filename);
            iface_thread_exit(errno);
        }
        if ((ifa->q =init_q(ifc->qsize)) == NULL) {
            logerr(errno,"Could not create queue for FIFO %s",ifc->filename);
            iface_thread_exit(errno);
        }
        if (setvbuf(ifc->fp,NULL,_IOLBF,0) !=0)
            iface_thread_exit(errno);
    }

    for(;;)  {
        if ((sptr = next_senblk(ifa->q)) == NULL) {
		    break;
        }

        if (senfilter(sptr,ifa->ofilter)) {
            senblk_free(sptr,ifa->q);
            continue;
        }
            
        if (ifc->usereturn == 0) {
            sptr->data[sptr->len-2] = '\n';
            sptr->data[sptr->len-1] = '\0';
        }
        if (fputs(sptr->data,ifc->fp) == EOF) {
            if (!(ifa->persist && errno == EPIPE) )
		        break;
            if (((ifc->fp=freopen(ifc->filename,"w",ifc->fp)) == NULL) ||
                    (setvbuf(ifc->fp,NULL,_IOLBF,0) !=0))
                break;
        }
        senblk_free(sptr,ifa->q);
    }
    iface_thread_exit(errno);
}
Beispiel #4
0
/*
 * 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);
}
Beispiel #5
0
/*
 * Start processing an interface and add it to an iolist, input or output, 
 * depending on direction
 * Args: Pointer to interface structure (cast to void *)
 * Returns: Nothing
 * We should come into this with SIGUSR1 blocked
 */
void start_interface(void *ptr)
{
    iface_t *ifa = (iface_t *)ptr;
    iface_t **lptr;
    iface_t **iptr;
    sigset_t set;

    sigemptyset(&set);
    sigaddset(&set, SIGUSR1);

    pthread_mutex_lock(&ifa->lists->io_mutex);
    ifa->tid = pthread_self();

    if (pthread_setspecific(ifkey,ptr)) {
        perror("Falied to set key");
        exit(1);
    }

    for (iptr=&ifa->lists->initialized;*iptr!=ifa;iptr=&(*iptr)->next)
        if (*iptr == NULL) {
            perror("interface does not exist on initialized list!");
            exit(1);
        }

    *iptr=(*iptr)->next;

    /* We've unlinked from initialized. Exit if we've been told to already */
    if (ifa->direction == NONE) {
        pthread_mutex_unlock(&ifa->lists->io_mutex);
        iface_thread_exit(0);
    }

    /* Set lptr to point to the input or output list, as appropriate */
    lptr=(ifa->direction==IN)?&ifa->lists->inputs:&ifa->lists->outputs;
    if (*lptr)
        ifa->next=(*lptr);
    else
        ifa->next=NULL;
    (*lptr)=ifa;

    if (ifa->lists->initialized == NULL)
        pthread_cond_broadcast(&ifa->lists->init_cond);
    else 
        while (ifa->lists->initialized)
            pthread_cond_wait(&ifa->lists->init_cond,&ifa->lists->io_mutex);

    pthread_mutex_unlock(&ifa->lists->io_mutex);
    pthread_sigmask(SIG_UNBLOCK,&set,NULL);
    if (ifa->direction == IN) {
        ifa->read(ifa);
    } else
        ifa->write(ifa);
}
Beispiel #6
0
void file_read_wrapper(iface_t *ifa)
{
    struct if_file *ifc = (struct if_file *) ifa->info;

    /* Create FILE stream here to allow for non-blocking opening FIFOs */
    if (ifc->fd == -1)
        if ((ifc->fd = open(ifc->filename,O_RDONLY)) < 0) {
            logerr(errno,"Failed to open FIFO %s for reading\n",ifc->filename);
            iface_thread_exit(errno);
        }

    do_read(ifa);
}
Beispiel #7
0
void tcp_server(iface_t *ifa)
{
    struct if_tcp *ift=(struct if_tcp *)ifa->info;
    int afd;


    if (listen(ift->fd,5) == 0) {
        while(ifa->direction != NONE) {
         if ((afd = accept(ift->fd,NULL,NULL)) < 0)
             break;
    
         if (new_tcp_conn(afd,ifa) == NULL)
             close(afd);
        }
    }
    iface_thread_exit(errno);
}
Beispiel #8
0
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);
}
Beispiel #9
0
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);
}
Beispiel #10
0
/* 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);
}
Beispiel #11
0
void write_file(iface_t *ifa)
{
    struct if_file *ifc = (struct if_file *) ifa->info;
    senblk_t *sptr;
    int usereturn=flag_test(ifa,F_NOCR)?0:1;
    int data=0;
    int cnt=1;
    struct iovec iov[2];

    /* ifc->fd will only be < 0 if we're opening a FIFO.
     */
    if (ifc->fd < 0) {
        if ((ifc->fd=open(ifc->filename,O_WRONLY)) < 0) {
            logerr(errno,"Failed to open FIFO %s for writing\n",ifc->filename);
            iface_thread_exit(errno);
        }
        if ((ifa->q =init_q(ifc->qsize)) == NULL) {
            logerr(errno,"Could not create queue for FIFO %s",ifc->filename);
            iface_thread_exit(errno);
        }
    }

    if (ifa->tagflags) {
        if ((iov[0].iov_base=malloc(TAGMAX)) == NULL) {
                logerr(errno,"Disabing tag output on interface id %u (%s)",
                        ifa->id,(ifa->name)?ifa->name:"unlabelled");
                ifa->tagflags=0;
        } else {
            cnt=2;
            data=1;
        }
    }


    for(;;)  {
        if ((sptr = next_senblk(ifa->q)) == NULL) {
            break;
        }

        if (senfilter(sptr,ifa->ofilter)) {
            senblk_free(sptr,ifa->q);
            continue;
        }

        if (!usereturn) {
            sptr->data[sptr->len-2] = '\n';
            sptr->len--;
        }

        if (ifa->tagflags)
            if ((iov[0].iov_len = gettag(ifa,iov[0].iov_base,sptr)) == 0) {
                logerr(errno,"Disabing tag output on interface id %u (%s)",
                        ifa->id,(ifa->name)?ifa->name:"unlabelled");
                ifa->tagflags=0;
                cnt=1;
                data=0;
                free(iov[0].iov_base);
            }

        iov[data].iov_base=sptr->data;
        iov[data].iov_len=sptr->len;
        if (writev(ifc->fd,iov,cnt) <0) {
            if (!(flag_test(ifa,F_PERSIST) && errno == EPIPE) )
                break;
            if ((ifc->fd=open(ifc->filename,O_WRONLY)) < 0)
                break;
        }
        senblk_free(sptr,ifa->q);
    }

    if (cnt == 2)
        free(iov[0].iov_base);

    iface_thread_exit(errno);
}