📄 parsestreams.c
字号:
/* * /src/NTP/ntp4-dev/libparse/parsestreams.c,v 4.11 2005/04/16 17:32:10 kardel RELEASE_20050508_A * * parsestreams.c,v 4.11 2005/04/16 17:32:10 kardel RELEASE_20050508_A * * STREAMS module for reference clocks * (SunOS4.x) * * Copyright (c) 1995-2005 by Frank Kardel <kardel <AT> ntp.org> * Copyright (c) 1989-1994 by Frank Kardel, Friedrich-Alexander Universit鋞 Erlangen-N黵nberg, Germany * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the author nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * */#define KERNEL /* MUST */#define VDDRV /* SHOULD */#ifdef HAVE_CONFIG_H# include "config.h"#endif#ifndef lintstatic char rcsid[] = "parsestreams.c,v 4.11 2005/04/16 17:32:10 kardel RELEASE_20050508_A";#endif#ifndef KERNEL#include "Bletch: MUST COMPILE WITH KERNEL DEFINE"#endif#include <sys/types.h>#include <sys/conf.h>#include <sys/buf.h>#include <sys/param.h>#include <sys/sysmacros.h>#include <sys/time.h>#include <sundev/mbvar.h>#include <sun/autoconf.h>#include <sys/stream.h>#include <sys/stropts.h>#include <sys/dir.h>#include <sys/signal.h>#include <sys/termios.h>#include <sys/termio.h>#include <sys/ttold.h>#include <sys/user.h>#include <sys/tty.h>#ifdef VDDRV#include <sun/vddrv.h>#endif#include "ntp_stdlib.h"#include "ntp_fp.h"/* * just make checking compilers more silent */extern int printf P((const char *, ...));extern int putctl1 P((queue_t *, int, int));extern int canput P((queue_t *));extern void putbq P((queue_t *, mblk_t *));extern void freeb P((mblk_t *));extern void qreply P((queue_t *, mblk_t *));extern void freemsg P((mblk_t *));extern void panic P((const char *, ...));extern void usec_delay P((int));#include "parse.h"#include "sys/parsestreams.h"/* * use microtime instead of uniqtime if advised to */#ifdef MICROTIME#define uniqtime microtime#endif#ifdef VDDRVstatic unsigned int parsebusy = 0;/*--------------- loadable driver section -----------------------------*/extern struct streamtab parseinfo;#ifdef PPS_SYNCstatic char mnam[] = "PARSEPPS "; /* name this baby - keep room for revision number */#elsestatic char mnam[] = "PARSE "; /* name this baby - keep room for revision number */#endifstruct vdldrv parsesync_vd = { VDMAGIC_PSEUDO, /* nothing like a real driver - a STREAMS module */ mnam,};/* * strings support usually not in kernel */static intStrlen( register const char *s ){ register int c; c = 0; if (s) { while (*s++) { c++; } } return c;}static voidStrncpy( register char *t, register char *s, register int c ){ if (s && t) { while ((c-- > 0) && (*t++ = *s++)) ; }}static intStrcmp( register const char *s, register const char *t ){ register int c = 0; if (!s || !t || (s == t)) { return 0; } while (!(c = *s++ - *t++) && *s && *t) /* empty loop */; return c;}static intStrncmp( register char *s, register char *t, register int n ){ register int c = 0; if (!s || !t || (s == t)) { return 0; } while (n-- && !(c = *s++ - *t++) && *s && *t) /* empty loop */; return c;} voidntp_memset( char *a, int x, int c ){ while (c-- > 0) *a++ = x;}/* * driver init routine * since no mechanism gets us into and out of the fmodsw, we have to * do it ourselves *//*ARGSUSED*/intxxxinit( unsigned int fc, struct vddrv *vdp, addr_t vdin, struct vdstat *vds ){ extern struct fmodsw fmodsw[]; extern int fmodcnt; struct fmodsw *fm = fmodsw; struct fmodsw *fmend = &fmodsw[fmodcnt]; struct fmodsw *ifm = (struct fmodsw *)0; char *mname = parseinfo.st_rdinit->qi_minfo->mi_idname; switch (fc) { case VDLOAD: vdp->vdd_vdtab = (struct vdlinkage *)&parsesync_vd; /* * now, jog along fmodsw scanning for an empty slot * and deposit our name there */ while (fm <= fmend) { if (!Strncmp(fm->f_name, mname, FMNAMESZ)) { printf("vddrinit[%s]: STREAMS module already loaded.\n", mname); return(EBUSY); } else if ((ifm == (struct fmodsw *)0) && (fm->f_name[0] == '\0') && (fm->f_str == (struct streamtab *)0)) { /* * got one - so move in */ ifm = fm; break; } fm++; } if (ifm == (struct fmodsw *)0) { printf("vddrinit[%s]: no slot free for STREAMS module\n", mname); return (ENOSPC); } else { static char revision[] = "4.7"; char *s, *S, *t; s = rcsid; /* NOOP - keep compilers happy */ Strncpy(ifm->f_name, mname, FMNAMESZ); ifm->f_name[FMNAMESZ] = '\0'; ifm->f_str = &parseinfo; /* * copy RCS revision into Drv_name * * are we forcing RCS here to do things it was not built for ? */ s = revision; if (*s == '$') { /* * skip "$Revision: " * if present. - not necessary on a -kv co (cvs export) */ while (*s && (*s != ' ')) { s++; } if (*s == ' ') s++; } t = parsesync_vd.Drv_name; while (*t && (*t != ' ')) { t++; } if (*t == ' ') t++; S = s; while (*S && (((*S >= '0') && (*S <= '9')) || (*S == '.'))) { S++; } if (*s && *t && (S > s)) { if (Strlen(t) >= (S - s)) { (void) Strncpy(t, s, S - s); } } return (0); } break; case VDUNLOAD: if (parsebusy > 0) { printf("vddrinit[%s]: STREAMS module has still %d instances active.\n", mname, parsebusy); return (EBUSY); } else { while (fm <= fmend) { if (!Strncmp(fm->f_name, mname, FMNAMESZ)) { /* * got it - kill entry */ fm->f_name[0] = '\0'; fm->f_str = (struct streamtab *)0; fm++; break; } fm++; } if (fm > fmend) { printf("vddrinit[%s]: cannot find entry for STREAMS module\n", mname); return (ENXIO); } else return (0); } case VDSTAT: return (0); default: return (EIO); } return EIO;}#endif/*--------------- stream module definition ----------------------------*/static int parseopen P((queue_t *, dev_t, int, int));static int parseclose P((queue_t *, int));static int parsewput P((queue_t *, mblk_t *));static int parserput P((queue_t *, mblk_t *));static int parsersvc P((queue_t *));static char mn[] = "parse";static struct module_info driverinfo ={ 0, /* module ID number */ mn, /* module name */ 0, /* minimum accepted packet size */ INFPSZ, /* maximum accepted packet size */ 1, /* high water mark - flow control */ 0 /* low water mark - flow control */};static struct qinit rinit = /* read queue definition */{ parserput, /* put procedure */ parsersvc, /* service procedure */ parseopen, /* open procedure */ parseclose, /* close procedure */ NULL, /* admin procedure - NOT USED FOR NOW */ &driverinfo, /* information structure */ NULL /* statistics */};static struct qinit winit = /* write queue definition */{ parsewput, /* put procedure */ NULL, /* service procedure */ NULL, /* open procedure */ NULL, /* close procedure */ NULL, /* admin procedure - NOT USED FOR NOW */ &driverinfo, /* information structure */ NULL /* statistics */};struct streamtab parseinfo = /* stream info element for dpr driver */{ &rinit, /* read queue */ &winit, /* write queue */ NULL, /* read mux */ NULL, /* write mux */ NULL /* module auto push */};/*--------------- driver data structures ----------------------------*//* * we usually have an inverted signal - but you * can change this to suit your needs */int cd_invert = 1; /* invert status of CD line - PPS support via CD input */int parsedebug = ~0;extern void uniqtime P((struct timeval *));/*--------------- module implementation -----------------------------*/#define TIMEVAL_USADD(_X_, _US_) {\ (_X_)->tv_usec += (_US_);\ if ((_X_)->tv_usec >= 1000000)\ {\ (_X_)->tv_sec++;\ (_X_)->tv_usec -= 1000000;\ }\ } while (0)static int init_linemon P((queue_t *));static void close_linemon P((queue_t *, queue_t *));#define M_PARSE 0x0001#define M_NOPARSE 0x0002static intsetup_stream( queue_t *q, int mode ){ mblk_t *mp; mp = allocb(sizeof(struct stroptions), BPRI_MED); if (mp) { struct stroptions *str = (struct stroptions *)(void *)mp->b_rptr; str->so_flags = SO_READOPT|SO_HIWAT|SO_LOWAT; str->so_readopt = (mode == M_PARSE) ? RMSGD : RNORM; str->so_hiwat = (mode == M_PARSE) ? sizeof(parsetime_t) : 256; str->so_lowat = 0; mp->b_datap->db_type = M_SETOPTS; mp->b_wptr += sizeof(struct stroptions);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -